PHP 脚本在被 Postfix 别名为时不触发 - 我无能为力

标签 php linux email amazon-ec2 postfix-mta

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

我在 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/

相关文章:

javascript - Ajax回调仅适用于jquery表单组列表中的顶部div

linux - 在 awk 命令中使用 bash 脚本 $1 参数

Android:正确下载/保存电子邮件附件

php - 解码 pdf 字符串并通过 codeigniter 电子邮件功能发送

php - 为什么 strtotime ('x' ) 返回明天的日期

php - While 循环在满足条件时不中断

linux - 如何在 Linux 中更改文本文件扩展名类型?

python - yowsup - 集成发送和接收

c# - 从接收邮件服务器 (POP) 读取电子邮件

php - 可以访问键的array_map