我已尝试在这篇文章中包含尽可能多的信息。
我在 Amazon EC2 Ubuntu 服务器上使用 Postfix,我为某个地址设置了别名的 PHP 脚本似乎没有触发。邮寄工作正常,但脚本没有触发。我可能错过了一些简单的事情,并且会很感激任何其他想法。
下面的代码是脚本的代码。目前,它只是一个基本脚本,用于将 php://stdin
的内容写入文件。我不确定这是否是编写此脚本的最佳方式,但目前看来还可以,因为它只是用于解决此问题的临时方法。
#!/usr/bin/php -q
<?php
$data = '';
$fileName = "parsedData.txt";
$stdin = fopen('php://stdin', 'r');
$fh = fopen($fileName, 'w');
while(!feof($stdin))
{
$data .= fgets($stdin, 8192);
}
fwrite($fh, $data);
fclose($stdin);
fclose($fh);
?>
我已通过将包含一些文本的 .txt 文件传递给它来验证它是否有效。
./test2.php < data.txt
现在我的 PHP 脚本似乎在本地运行良好,我需要确保它被正确调用。 sudo chmod 777
已在 test2.php 脚本上运行。这是相关的/etc/aliases 文件条目。
test: "|/usr/bin/php -q /var/test/php/test2.php"
我每次更改它时都会运行 newaliases。这似乎是最正确的语法,因为它完全指定了 php 的位置。 test@mydomain
在未设置为别名时可以很好地接收来自内部和外部的电子邮件。根据系统日志,这已成功传送到命令而不是 maildir。
postfix/local[2117]: 022AB407CC: to=<test@mydomain.com>, relay=local, delay=0.5, delays=0.43/0.02/0/0.05, dsn=2.0.0, status=sent **(delivered to command: /usr/bin/php -q /var/test/php/test2.php)**
别名也已通过以下方式写入但没有成功(因为语法错误导致它们转到 maildir 而不是命令,或者脚本没有触发)。
test: |"php -q /var/test/php/test2.php"
test: "|php -q /var/test/php/test2.php"
test: |"/usr/bin/php -q /var/test/php/test2.php"
test: "| php -q /var/test/php/test2.php"
test: "|/var/test/php/test2.php"
test: |"/var/test/php/test2.php"
我的 postfix main.cf 文件的相关部分如下所示 -
myhostname = domainnamehere.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = domainnamehere.com, internalawsiphere, localhostinternalaws, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command =
home_mailbox = Maildir/
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
我有 error_log("script has started!");
在 test2.php
的开头,这样如果脚本是调用成功。我确保进入 php.ini 以打开 error_logging 并指定一个位置来保存它,但我无法让它工作。能够让它工作会有所帮助,因为我可以判断脚本在转到 php://stdin
函数时是否失败,因为它处理电子邮件而不是处理电子邮件可能存在一些问题cat'ed .txt 文件。
我的最终目标是获得一项服务,将特定地址的电子邮件及其附件保存到 MySQL 数据库,然后将每个文件/电子邮件的唯一代码返回给用户。有没有比使用 php 脚本更简单的方法来做这样的事情?像 squirrelmail 或 dbmail 这样的东西会这样做吗?
我已经用尽了我的所有想法。也许我应该试试其他电子邮件服务?
哦,StackOverflow 的聪明人,帮帮我吧!
最佳答案
首先,chmod 777 <foo>
几乎总是一个巨大的错误。我知道您正处于绝望的状态——正如您运行此命令的事实所表明的那样。您想要使用 least amount of required privilege 配置您的系统使系统的每个部分都能正确完成其工作。这有助于防止安全漏洞并减少needless coupling .但是可执行文件应该不可以被可执行文件所有者以外的任何人写入——即便如此,我还是强烈建议不要这样做。
现在,进入你的问题:
#!/usr/bin/php -q
<?php
$data = '';
$fileName = "parsedData.txt";
您指的是使用相对 路径名的文件。这很好,如果您始终对它的启动目录充满信心,或者如果您希望 用户 控制它启动的目录,但它通常是 坏自动化工具的想法。 /etc/aliases
机制可以运行 postfix
中的别名命令主目录,它可能会在 /var
中选择一个空目录只是为了这个目的而创建的, future 的版本或多或少可以随意改变这种行为。将此路径名更改为一个绝对 路径名,以准确显示您希望创建此文件的位置——或者插入一个明确的 chdir()
在脚本的开头调用以将目录更改为您希望数据存放的位置。
下一步:
$fh = fopen($fileName, 'w');
while(!feof($stdin))
{
$data .= fgets($stdin, 8192);
}
fwrite($fh, $data);
您没有确保该文件确实已打开。检查那些返回值。他们会很快为您报告故障,帮助您找到代码中的错误或本地错误配置。我不太了解 PHP,无法告诉您相当于 perror(3)
的内容函数会确切地告诉您 什么 失败了,但是从解释器中获取人类可读的错误代码肯定不会太难。不要忽略错误代码——了解 Permission Denied
之间的区别对比File or directory not found
部署代码后可以节省小时。
并且,作为 Michael points out , 一个 mandatory access control工具可以防止应用程序在特定位置写入。 Ubuntu 上的“默认”MAC 工具是 AppArmor , 但是 SELinux , TOMOYO , 或 SMACK都是极好的选择。运行 dmesg
并查看 /var/log/audit/audit.log
看看是否有任何违反政策的行为。如果有,解决问题的步骤因您使用的 MAC 系统而异。由于您使用的是 Ubuntu,因此最有可能使用 AppArmor;运行 aa-status
快速了解系统中限制的服务,以及 aa-logprof
应提示您根据需要修改策略。 (也不要盲目说“允许”——也许主动攻击尝试已被拒绝。)
(如果您还没有使用 MAC 系统,请考虑这样做。我在 AppArmor 项目上工作了 12 年,不会考虑不限制所有通过 MAC 系统通信的应用程序网络——但那是我自己的安全需求。更多偏执的人可能希望限制更多的系统,较少偏执的人可能希望限制更少的系统。)
关于PHP 脚本在被 Postfix 别名为时不触发 - 我无能为力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10116341/