我在系统启动时运行 wg-quick.service 来建立 VPN 隧道:
root@db ~ # cat /usr/lib/systemd/system/[email protected]
[Unit]
Description=WireGuard via wg-quick(8) for %I
After=network-online.target nss-lookup.target
Wants=network-online.target nss-lookup.target
PartOf=wg-quick.target
Documentation=man:wg-quick(8)
Documentation=man:wg(8)
Documentation=https://www.wireguard.com/
Documentation=https://www.wireguard.com/quickstart/
Documentation=https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
Documentation=https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/wg-quick up %i
ExecStop=/usr/bin/wg-quick down %i
Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
[Install]
WantedBy=multi-user.target
我希望 postgresql 监听wireguard地址 - 10.100.0.107
:
root@db ~ # cat /etc/postgresql/13/main/conf.d/db1.conf | grep listen
listen_addresses = '127.0.0.1,10.100.0.107' # what IP address(es) to listen on;
重新启动后,我的 postgresql 日志中出现以下错误:
2021-06-23 19:44:26.389 UTC [831] LOG: starting PostgreSQL 13.3 (Ubuntu 13.3-1.pgdg20.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, 64-bit
2021-06-23 19:44:26.389 UTC [831] LOG: listening on IPv4 address "127.0.0.1", port 5432
2021-06-23 19:44:26.395 UTC [831] LOG: could not bind IPv4 address "10.100.0.107": Cannot assign requested address
2021-06-23 19:44:26.395 UTC [831] HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
2021-06-23 19:44:26.395 UTC [831] WARNING: could not create listen socket for "10.100.0.107"
2021-06-23 19:44:26.395 UTC [831] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2021-06-23 19:44:26.411 UTC [880] LOG: database system was shut down at 2021-06-23 19:43:14 UTC
2021-06-23 19:44:26.422 UTC [831] LOG: database system is ready to accept connections
遗憾的是,postgresql 不接受位于 的连接10.100.0.107
。
服务器重新启动后重新启动 postgresql 会有所帮助。也设置listen_addresses='*'
也有帮助。
但我只想接受到指定地址的连接:127.0.0.1
, 10.100.0.107
。成功初始化wg-quick服务后如何启动postgresql服务?
谢谢!
答案1
postgresql 服务启动和wireguard 隧道设备的配置之间存在竞争条件。
有几种方法可以处理这个问题:
After=/Wants=
对 postgres 服务的直接依赖- 将 Postgres 绑定到任何 IP 地址(即通过添加或
0.0.0.0
或::
),并且仅依赖您的防火墙/数据包过滤器限制 Postgres 对您的wireguard 地址/接口(和本地主机)的访问。*
listen_addresses
- 启用非本地绑定。
对于此用例,配置 systemd 依赖项非常繁琐且容易出错,并且还取决于您的发行版/systemd 版本。最后,人们甚至无法确定与wireguard 相关的服务是否仅在wireguard 设备分配了IP 地址后才可靠地发出启动信号。
不幸的是,Postgres 似乎不支持绑定重试功能,即在几分钟后简单地重试绑定到指定地址,以防接口只是暂时消失。
默认情况下,Linux 非本地绑定支持被禁用 - 但可以使用 sysctl 进行配置,例如:
sysctl net.ipv4.ip_nonlocal_bind=1
(参见/etc/sysctl.d/
持久配置)
此后,启动期间的 Postgres 绑定操作始终会成功,即使尚未配置 Wireguard 设备也是如此。
去测试:
networkctl down wg0
ip -o a
systemctl restart postgresql.service
networkctl up wg0