Postfix 未使用本地 IP 地址连接到 Postgres 池

Postfix 未使用本地 IP 地址连接到 Postgres 池

我有一个postfix电子邮件服务器,它正在联系数据库来查询和验证电子邮件地址等。它使用pgbouncer循环连接进行连接,但我的问题是“保镖”位于数据库端,因此与数据库的连接未加密,可能会存在安全问题。

pgbouncer我在邮件服务器上安装了 的本地实例stunnel,以及至少让两者有机会在两者之间建立 SSL 连接,但是出于某些令人恼火的原因,postfix出于多愁善感、恶意或仅仅因为它很固执,拒绝遵守切换。以下是位于 postfix 目录中的虚拟别名查找文件之一的示例:

# -------
# p-alias
# -------
hosts=10.0.0.123
port=6432
dbname=mail
user=user1
password=password
query=SELECT destination FROM v_alias WHERE source = '%s'

要测试它,您可以像这样查询测试电子邮件地址

console:~$ postmap -q [email protected] pgsql:/etc/postfix/p-alias

结果:

tester.mc_testy_tester@test_email_address.com

一切顺利,现在创建一个几乎相同的配置,指向本地池

console:~$ cp /etc/postfix/p-alias /etc/postfix/p-alias2
console:~$ vi /etc/postfix/p-alias2

将 ip 更改为 localhost:

# -------
# p-alias2
# -------
hosts=localhost
port=6432
dbname=mail
user=user1
password=password
query=SELECT destination FROM v_alias WHERE source = '%s'

对其发出相同的命令:

console:~$ postmap -q [email protected] pgsql:/etc/postfix/p-alias2

并出现以下错误

postmap: warning: connect to pgsql server localhost: could not connect to server: Connection refused??
Is the server running on host "localhost" (::1) and accepting??
TCP/IP connections on port 5432??
could not connect to server: Connection refused??
Is the server running on host "localhost" (127.0.0.1) and accepting??
TCP/IP connections on port 5432??
postmap: fatal: table pgsql:/etc/postfix/p-alias2: query error: Operation now in progress

这两个弹跳器几乎完全相同,pgbouncer.ini 文件相同,userlist.txt 也相同,唯一明显的区别是它们的物理位置和连接。因为我没有psql在电子邮件服务器上安装客户端(尝试通过 Linux 发行版安装会添加太多依赖项,我不喜欢),所以我改用 python 模拟查询来检查我没有错过任何愚蠢的东西:

import psycopg2

conn = psycopg2.connect( "host='10.0.0.123' port='6432' dbname=mail user='user1' password='password'" )
dbh = conn.cursor()
dbh.execute( "SELECT destination FROM v_alias WHERE source = '[email protected]'" )
dbh.fetchone()

# Result:
# ('tester.mc_testy_tester@test_email_address.com',)

conn.commit()
conn.close()

# -----------------------------------
# All is tickety boo, as it should be
# now let's repeat with the local ip
# -----------------------------------

conn = psycopg2.connect( "host='localhost' port='6432' dbname=mail user='user1' password='password'" )
dbh = conn.cursor()
dbh.execute( "SELECT destination FROM v_alias WHERE source = '[email protected]'" )
dbh.fetchone()

# Result:
# ('tester.mc_testy_tester@test_email_address.com',)

conn.commit()
conn.close()

两个都运行顺利,所以据我所知,这是可行的,应该不会有问题。Postfix 显然不这么认为。

因此我假设问题可能出在 stunnel 上,以下是配置:

client = yes
pid = /var/run/stunnel.pid
[pgbouncer]
        protocol = pgsql
        accept = 6433
        connect = 10.0.0.123:5432

我绕过 pgbouncer 并查询本地 stunnel

# -------
# p-alias3
# -------
hosts=127.0.0.1
port=6433
dbname=mail
user=user1
password=password
query=SELECT destination FROM v_alias WHERE source = '%s'

postmap 拒绝遵守

console:~$ postmap -q [email protected] pgsql:/etc/postfix/p-alias3
postmap: warning: connect to pgsql server 127.0.0.1: could not connect to server: Connection refused??
Is the server running on host "127.0.0.1" and accepting??
TCP/IP connections on port 5432??
postmap: fatal: table pgsql:/etc/postfix/p-alias3: query error: Operation now in progress

没有运气。

为了完整起见,这里列出了 pgbouncer.ini 的大部分内容

[databases]

; ...
;mail = host=localhost port=6433 dbname=mail
mail = host=10.0.0.123 port=5432 dbname=mail

[pgbouncer]

listen_addr = *
listen_port = 6432

; ...

auth_type = md5

auth_file = /etc/pgbouncer/userlist.txt


pool_mode = transaction

server_reset_query = DISCARD ALL

server_check_query = SELECT 1

server_check_delay = 30

; ...

我尝试使用带有 stunnel 的 pgbouncer,或者不使用 stunnel 直接连接到数据库,但 postfix 拒绝接受存在本地主机,它可以与 python 一起使用,但与 postmap 一起使用会失败。

显然它只是不喜欢本地主机。

那么,Postfix,你想从我这里得到什么?!!!

(Postfix 是 2.11.0 版本)

答案1

在 irc 上进行一些讨论之后,有人指出 Postfix 似乎没有遵守port=本地连接的设置 - 错误消息显然是试图与端口 5432 对话,因此将 pgbouncer 监听端口更改为 5432 可以解决问题。

谢谢 -Myon!

(一旦你知道答案,一切就变得如此简单……)

答案2

根据此处的手册页:

http://www.postfix.org/pgsql_table.5.html

可选端口需要在主办方字段语法如下hostname:port

  hosts  The hosts that Postfix will try to connect to  and  query  from.
          Specify unix: for UNIX-domain sockets, inet: for TCP connections
          (default).  Example:
              hosts = host1.some.domain host2.some.domain:port
              hosts = unix:/file/name

独立港口字段似乎不存在。

相关内容