2

我试图在这篇文章中包含尽可能多的信息。

我在 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未设置别名时,可以正常接收来自内部和外部的电子邮件。根据 syslog,这已成功交付给命令而不是 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"

我的后缀 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!");在开始时会出现在 php 日志文件中。test2.php我确保进入 php.ini 以打开 error_logging 并指定保存位置,但我无法让它工作。能够让它工作会有所帮助,因为我可以判断脚本在执行该php://stdin函数时是否失败,因为它处理电子邮件而不是 cat'ed .txt 文件可能存在一些问题。

我的最终目标是获得一项服务,将特定地址上的电子邮件及其附件保存到 MySQL 数据库,然后将每个文件/电子邮件的唯一代码返回给用户。有没有比使用 php 脚本更简单的方法来做这样的事情?squirrelmail 或 dbmail 之类的东西会这样做吗?

我已经完全用尽了我的想法。也许我应该尝试其他电子邮件服务?

哦,StackOverflow 的聪明人,帮助我!

4

1 回答 1

1

首先,chmod 777 <foo>几乎总是一个巨大的错误。我认识到您处于绝望的状态 - 正如您运行此命令的事实所表明的那样。您希望为系统的每个部分配置所需的最少权限,以正确完成其工作。这有助于防止安全漏洞减少不必要的耦合。但是可执行文件应该被除可执行所有者之外的任何人写入——即便如此,我强烈建议不要这样做。

现在,解决您的问题:

#!/usr/bin/php -q
<?php
$data = '';
$fileName = "parsedData.txt";

您指的是使用相对路径名的文件。这很好,如果您总是对它的启动目录有信心,或者如果您希望用户控制它的启动目录,但对于自动化工具来说这通常是一个坏主意。/etc/aliases机制可能会在主目录中运行别名命令postfix,它可能会选择一个仅为此目的而创建的空目录/var,并且未来的版本或多或少可以随意更改此行为。将此路径名更改为绝对路径名,以准确显示您希望创建此文件的位置 - 或插入显式chdir()在脚本开始时调用以将目录更改为您希望数据去往的确切位置。

下一个:

$fh = fopen($fileName, 'w');
while(!feof($stdin))
{
     $data .= fgets($stdin, 8192);
}
fwrite($fh, $data);

您没有确保该文件实际上已打开。检查这些返回值。他们会很快为您报告故障,帮助您找到代码中的错误或本地错误配置。我不太了解 PHP,无法告诉您确切地告诉您失败的函数的等价物perror(3)但从解释器中获取人类可读的错误代码肯定不会太难。不要忽视错误代码——一旦你的代码被部署,知道vs之间的区别可以节省几个小时。Permission DeniedFile or directory not found

而且,正如迈克尔指出的那样强制访问控制工具可以防止应用程序在特定位置写入。Ubuntu 上的“默认”MAC 工具是 AppArmor,但SELinuxTOMOYOSMACK都是很好的选择。运行dmesg/var/log/audit/audit.log查看是否有任何违反政策的行为。如果有,解决问题的步骤会因您使用的 MAC 系统而异。由于您使用的是 Ubuntu,因此很可能是 AppArmor;运行aa-status以快速了解您系统上受限的服务,并aa-logprof应提示您根据需要修改策略。(不要盲目要么说“允许”——也许主动利用尝试已被拒绝。)

(如果您还没有使用 MAC 系统,请考虑这样做。我在 AppArmor 项目上工作了 12 年,不会考虑限制所有通过网络通信的应用程序——但这是我自己的安全需求. 更多偏执的人可能希望限制他们更多的系统,不那么偏执的人可能希望限制他们的系统更少。)

于 2012-04-12T02:07:10.503 回答