我目前正在做一个相当小的项目。我的工作基于smtp .py,但慢慢地转向完全不同的东西。
这是smtp服务器。它目前可以接收和转发邮件。这是相当直接的,但我到达了一个点,我问自己一些问题。
smtpp .py使用asyncore和asychat。问题是它是使用异步api的单个进程。一切正常,我可以走得更远,没有太多问题。
问题是,如果服务器绑定在端口25上,它必须在根uid下。这是一个大问题。smtp服务器背后的想法是,我可以使用python实现很多东西。我希望能够访问本地用户,数据库或任何数据存储可能。从哈希表或python当前支持的任何东西,或者如果需要的话,我甚至可以添加支持。
问题是,我觉得使用根用户拥有所有这些控制是非常不安全的…如果有人可以做一些事情,我们最终与根python shell…
所以起初我想创建线程并使用os为它们设置一个不同的uid。这很好,但似乎不起作用,或者也可能很危险。
我的第二个想法:接受连接,然后分叉并更改uid。我应该能够从分叉进程中写入/读取套接字,并且一切都应该很好。
第三个想法是使用代理服务器将所有消息中继到本地服务器,由本地服务器自己处理消息。唯一的问题是,如果有人不应该使用我的smtp服务器代理不能认证或做任何事情,因为它只是一个代理没有实际访问任何东西。
我相信分叉是最有趣的解决方案。
或者可能有我还没有想到的事情。
无论如何谢谢
——编辑——
显然,如果进程是用root启动的,一旦创建了套接字,就可以使用os.setuid切换到不同的用户。我想它不是很便携,但现在这不是一个大问题。在搜索了Pyramid/Pylons/Paste的代码后,我终于找到了那个东西!SocketServer模块。我可能会使用ForkingMixIn或ThredingMixIn。可以定义线程的数量等。
在任何情况下,对于那些想知道为什么我不使用后缀,exim或qmail..这很简单,我并没有真正制作smtp服务器。smtp协议是相当简单的,如果你只实现最低要求,这是接收电子邮件,接受或拒绝收件人或发件人等。转义每个新行的第一个"。",因为RFC说数据以"rn.rn"结束。
在我看来,python更像是积木。这个想法不是制作一个smtp服务器(我肯定会实现ESMTP),而是制作一个"框架"来构建您自己的服务器。我的问题,我不相信我是一个人。有人设计了一个配置文件和一种方法来配置后缀。它是硬编码的,并不适用于所有情况。制作一个适合所有情况的服务器也不会奏效。它可能会变得巨大而丑陋。这样做的目的是使在服务器上添加您想要的部件变得容易。如果您想要使用数据库,请使用现有模块中所需的数据库。做你的查询并发回你的结果。
如果你真的想定义适用于所有域或某些域甚至用户名的规则,这应该是可能的。
例如,我看到一个用例。真的很奇怪,但仍然。仅使用一台服务器在后缀上设置这种设置有多容易?有三个定义域。com, b.com, c.com
用相同的用户名将所有收到的邮件发送到maildir和b.com。用相同的用户名将所有收到的邮件发送到maildir和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
帖子的标题似乎与所问的问题不匹配。尽管如此,我对其中的一些问题和评论表示同情。特别是,我同意Jim Garrison的观点,即这将是一个有用的学习经验,可以深入了解SMTP和邮件服务器原理。然而,如果目的不是学习,那么使用现有的、经过良好测试的、可能更安全的选项可能更实用、更经济。值得考虑的是Lamson,因为您已经在使用Python和其他邮件服务器,特别是Exim,它提供了非常灵活和强大的配置选项和过滤。这些应用程序的开发人员和支持社区非常重要,并且都有良好的文档记录。然后,你可以把时间花在解决项目的具体问题上,而不是那些已经解决的问题上。
这个问题的答案是使用ServerSocket。我将使用线程或分支子类。它非常灵活,可以毫无顾虑地取代asyncore。它已经被用于塔架、金字塔等。但在我的情况下,它将处理smtp消息,而不是http。