Postfix-在没有本地主机或邮件服务器的情况下以新方式进行的amavisd-new

关于如何在一堆postfix-amavisd-new-dovecot上提高邮件服务器有很多说明。 他们中的绝大多数人几乎都是逐字重复,包括错误和不准确之处。

我似乎无所顾忌地按了按钮,所以我决定优化标准配置:如果我不是通过localhost,而是在unix套接字上构建postfix和amavisd-new的交互,该怎么办?

事实证明,一切并不是那么简单,但是我做到了! 说明书和补丁下切。

老实说,我通常不喜欢在同一台计算机上通过本地主机进行交互。 如果要组织两个应用程序之间的数据交换,那么通过文件系统上的unix套接字执行此操作更正确,更安全且资源占用更少。 此外,即使在应用程序或协议级别上缺少保护,也可以通过文件系统上的权限来组织保护。

因此,讨论的束中的邮件路径如下所示:



事实证明,我们需要组织两个连接:转移到筛选时和返回MTA时。 由于套接字是由侦听器创建的,因此在第一种情况下将被修改,而在第二种情况下-后缀。

让我们从第二个开始,因为它更简单并且描述得更好。 为了使postfix创建一个监听套接字,您只需要在master.cf的第二列(类型列)中指定unix,而不是inet。 在这种情况下,第一列定义套接字的路径和文件名。

由于postfix进程在chroot中工作(可以为特定进程禁用,但不值得),因此您需要在postfix主目录内创建一个文件夹:/ var / spool / postfix。 它将具有两个套接字:

mkdir /var/spool/postfix/amavis chown amavis:postfix /var/spool/postfix/amavis chmod 770 /var/spool/postfix/amavis 

以及后缀配置:

 amavis/postfix-in unix y - y - - smtpd -o smtpd_client_restrictions=$local_clients_only -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions= -o smtpd_milters= 

具体选项取决于您的设置,这是我的选择。

有两个麻烦:

  1. 该路径是相对于/ var / spool / postfix / private的,该路径必须具有非常严格的权限。
  2. 不确定在所有发行版中是否都适用,但是可以肯定在Ubuntu上。 最好不要触摸文件夹的权限(所有postfix服务的套接字都在其中),最好仅创建符号链接。
  3. 除套接字外,postfix还为该进程创建了一个pid文件,其名称由$ type的掩码自动生成。 其中type等于unix,名称取自master.cf的第一列。 原来是unux.amavis / postfix-in 文件放在子文件夹中。 他本人将不会创建它,并且会出错。

因此,我们用拐杖代替:

 cd /var/spool/postfix/private ln -s ../amavis . mkdir /var/spool/postfix/pid/unix.amavis 

不是很好,但对包的常规文件夹结构没有破坏性。

我们重新启动后缀,并确保套接字文件出现在amavis文件夹中,并且pid文件出现在pid / unix.amavis中。 不幸的是,套接字的权限为666,但是您之前创建的文件夹的权限将保护文件免受不必要的注意。

您可以使用以下命令检查工作:

 netcat -U /var/spool/postfix/amavis/postfix-in 220 mail.example.ru ESMTP Postfix 

好吧,他们做到了。 现在建议。

首先,通过postfix拥有的unix套接字配置邮件返回路径。 开箱即用:

 $forward_method = 'smtp:/var/spool/postfix/amavis/postfix-in'; $notify_method = \$forward_method; 

好吧,现在最困难的部分是在amavisd中设置套接字。 该解决方案可以在Internet上找到,但是建议使用$ unix_socketname参数指定的单个套接字。 我还想要自己的改良协议(AM.PDP)和通过套接字接收邮件。

默认配置文件包含对@listen_sockets指令的引用,但没有描述。 但是它在发行说明中 ,甚至带有示例! 是的,只有一个套接字,但是什么阻止了您尝试呢?

好的,但是如何设置套接字的协议(在策略库中指定)? 在所有示例中,他们只是写SOCK。 类似于inet套接字(您可以在此处指定主机端口),我建议您需要指定套接字文件的完整路径。 这是发生了什么:

 $unix_socketname = undef; $inet_socket_bind = undef; $inet_socket_port = undef; @listen_sockets = ('/var/lib/amavis/amavisd.sock', '/var/spool/postfix/amavis/amavis-in.sock'); $unix_socket_mode = 0660; %interface_policy = ( '/var/lib/amavis/amavisd.sock' => 'AM.PDP-SOCK', '/var/spool/postfix/amavis/amavis-in.sock' => 'LMTP-SOCK' ); $policy_bank{'LMTP-SOCK'} = { protocol => 'LMTP' }; $policy_bank{'AM.PDP-SOCK'} = { protocol => 'AM.PDP', auth_required_release => 0, # don't require secret-id for release }; 

重新启动,检查-实际上,两个套接字都已创建! 胜利的 并非如此,当您尝试连接到套接字时,什么也没有发生,并且将错误写入协议未为其定义的日志。 事实证明,保单行不适用于他们。

怎么会这样 我不得不去看代码。

这场运动带来了两个消息-和往常一样,好坏。 好的一面是,关于%interface_policy的假设是正确的:

 # load policy banks according to my socket (destination), # then check for allowed access from the peer (client/source) # sub access_is_allowed($;$$$$) { my($unix_socket_path, $src_addr, $src_port, $dst_addr, $dst_port) = @_; my(@bank_names); if (defined $unix_socket_path) { push(@bank_names, $interface_policy{"SOCK"}); push(@bank_names, $interface_policy{$unix_socket_path}); } elsif (defined $dst_addr && defined $dst_port) { $dst_addr = '['.lc($dst_addr).']' if $dst_addr =~ /:[0-9a-f]*:/i; # IPv6? push(@bank_names, $interface_policy{$dst_port}); push(@bank_names, $interface_policy{"$dst_addr:$dst_port"}); } load_policy_bank($_) for @bank_names; 

不好的是,$ unix_socket_path进入此函数为空。 填写如下:

 my $is_ux = $sock && $sock->UNIVERSAL::can('NS_proto') && $sock->NS_proto eq 'UNIX'; 

并且两个属性在那都是空的。

文档的研究建议使用此选项:

 my $unix_socket_path = $sock->hostpath(); 

而且有效! 准备好了.patch可以在这里说。

最后一点。 由于amavisd创建了自己的仅具有自身权限的套接字,并且我们拒绝了对其余套接字的访问(这是正确的),因此我们需要在amavis组中添加后缀,以便它可以写入套接字:

 gpasswd -a postfix amavis 

做完了

PS:我通过电子邮件发送了Mark Martinec的补丁和问题描述,因为我在网站上未发现任何有关bug跟踪器的信息。 我仍然没有得到答案,但是我真的没有指望它-该项目看起来已经被放弃(两年多以前的最新版本)。

Source: https://habr.com/ru/post/zh-CN415597/


All Articles