1

我目前正在做一个很小的项目。我的工作基于 smtpd.py,但慢慢地朝着完全不同的方向发展。

这是一个 smtp 服务器。它目前接收并可以中继邮件。这很简单,但我已经到了问自己一些问题的地步。

smtpd.py 使用 asyncore 和 asychat。问题是它是使用异步 api 的单个进程。一切正常,我可以毫无问题地走得更远。

问题是如果服务器绑定在端口 25 上,它必须在 root uid 下。所以这是个大问题。smtp 服务器背后的想法是我可以使用 python 实现很多东西。我希望能够访问本地用户、数据库或任何可能的数据存储。从哈希或python当前支持的任何东西,或者如果需要我什至可以添加对它的支持。

问题是我觉得使用 root 用户进行所有这些控制是非常不安全的......如果有人可以做某事并最终得到一个 root python shell 怎么办......

所以起初我想创建线程并使用 os.setuid 为它们设置不同的 uid,但它似乎不起作用或者也可能很危险。

我的第二个想法:接受连接然后分叉并更改uid。我应该能够从分叉的进程中写入/读取套接字,一切都应该没问题。

第三个想法是有一个代理服务器将所有消息中继到一个本地服务器,该服务器将自己处理这些消息。唯一的问题是,如果有人不应该使用我的 smtp 服务器,则代理无法进行身份验证或执行任何操作,因为它只是一个无法实际访问任何内容的代理。

我相信分叉是最有趣的解决方案。

或者可能有一些我还没有完成的事情。

不管怎样,谢谢

- 编辑 -

显然,如果进程以 root 启动并且一旦创建了套接字,就可以使用 os.setuid 切换到不同的用户。我想它不是真正的便携,但现在这不是一个大问题。在搜索了 Pyramid/Pylons/Paste 的代码后,我终于遇到了那个东西!SocketServer模块。我可能会使用 ForkingMixIn 或 ThredingMixIn。可以定义线程数量等。

无论如何,对于那些想知道我为什么不使用 postfix、exim 或 qmail 的人来说。这很简单,我并没有真正制作 smtp 服务器。如果您只实现接收电子邮件、接受或拒绝收件人或发件人等所需的最低要求,则 smtp 协议非常简单。转义第一个“。” 因为 RFC 说数据以“\r\n.\r\n”结尾。

在我看来,python 更像是积木。这个想法不是制作一个 smtp 服务器(我肯定会实现 ESMTP),而是制作一个“框架”来构建您自己的服务器。我遇到的问题,我不相信我是一个人。有人设计了一个配置文件和一种配置后缀的方法。它是硬编码的,并不适合所有情况。制作适合所有情况的服务器也行不通。它可能会变得巨大而丑陋。这样做的目的是让您可以轻松地在服务器上添加所需的部分。如果您想使用数据库,请使用您想要的现有模块。做你的查询并发回你的结果。

如果您真的想定义适用于所有域或某些域甚至用户名的规则,应该可以这样做。

例如,我看到一个用例。真的很奇怪,但仍然。仅使用一台服务器在 postfix 上设置这种设置是多么容易。你有三个域。a.com,b.com,c.com。

a.com 使用相同的用户名将所有收到的邮件发送到 maildir 和 b.com。b.com 使用相同的用户名将所有收到的邮件发送到 maildir 和 c.com。c.com 将所有收到的邮件发送到 maildir 和具有相同用户名的 a.com。

没有域接受他们已经发送的电子邮件。

换句话说

           a.com -> b.com -> c.com -x-> a.com
           b.com -> c.com -> a.com -x-> b.com
           ... 

这里的想法是邮件将在多个域中复制,但无法返回给其所有者。这种用例应该很简单。但是如果所有域都将他们的邮件保存在不同的位置,或者我们希望每 2 次退回来保存邮件怎么办。

 a -> b -> c(save)
 a -> b(save) -> c
 a(save) -> b -> c
 already saved to C so stop the mail would be sent 9 times 
4

2 回答 2

0

帖子的标题似乎与提出的问题不符。尽管如此,我可以理解提出的一些问题以及评论。特别是,我同意Jim Garrison的观点,即这对于深入了解 SMTP 和邮件服务器原理将是一次有用的学习经历。但是,如果目的不是为了学习,那么使用现有的、经过充分测试并且可能更安全的选项可能更实用、更经济。值得考虑的是Lamson,因为您已经在使用 Python 和替代邮件服务器,尤其是Exim它提供了非常灵活和强大的配置选项和过滤。这些应用程序的开发人员和支持社区非常重要,并且都有很好的文档记录。然后,您可以将时间用于解决特定于您的项目的问题,而不是那些已经解决的问题。

于 2011-10-08T21:52:28.967 回答
-1

问题的答案是使用ServerSocket。我将使用线程或分叉子类。它非常灵活,可以毫无畏惧地替换 asyncore。它已经被 pylons、pyramid 等使用。但在我的情况下,它将处理 smtp 消息而不是 http。

于 2011-10-09T13:28:18.177 回答