我运行了一些 haproxy 服务,其中一些在过去 12 小时内无法正确重启(之前几天它们运行正常)。当我意识到某个服务已关闭时,我会检查ss -tulpn
监听的端口 - 看到没有人监听主题中的端口并尝试重新启动服务:
# service haproxy-https restart
Shutting down haproxy-https: [FAILED]
Starting haproxy-https: daemon /usr/sbin/haproxy-https -D -f /etc/haproxy/haproxy-https.cfg -p /var/run/haproxy-https.pid
[WARNING] 294/170448 (22682) : Proxy 'httptat': in multi-process mode, stats will be limited to process assigned to the current request.
[ALERT] 294/170448 (22682) : Starting proxy httptat: cannot bind socket [0.0.0.0:3310]
[ALERT] 294/170448 (22682) : Starting proxy HTTPS: cannot bind socket [0.0.0.0:5008]
[FAILED]
我已经在 Google 上搜索过错误并尝试了所有找到的解决方案但都无济于事。
这是/etc/haproxy/haproxy-https.cfg
global
daemon
maxconn 5000
nbproc 7
log 127.0.0.1 local0 info
defaults
mode tcp
timeout connect 50000ms
timeout client 500000ms
timeout server 500000ms
timeout check 5s
timeout tunnel 50000ms
option redispatch
listen httptat
bind 0.0.0.0:3310
mode http
stats enable
stats refresh 5s
stats uri /httpstats
stats realm HTTPS proxy stats
stats auth https:user1@pass1
listen HTTPS
bind 0.0.0.0:5008
mode tcp
balance roundrobin
http-check expect status 200
server s1 127.0.0.1:8000 check
server s2 35.46.232.130:26000 check
更新:这似乎是某种类型的 SYN 洪水攻击的问题:我看不到任何正在监听的服务,因为没有服务。我检查了所有与主题中的端口相关的连接,发现其中只有少数处于以下SYN_SENT
状态:
tcp SYN-SENT 0 1 <server_ext_IP>:5008 <some_IP>:16767
过滤ss -tulpan
输出<some_IP>
并发现有大量来自此 IP 的连接处于相同的 SYN_SENT 状态。看起来像是某种简单的攻击。
更新 2:阻止洪水攻击后,我意识到我们仍然与本地服务器上的 5008 和 3310 端口有连接:
tcp SYN-SENT 0 1 <server_ext_IP>:5008 77.242.1.101:8080
但是他们是外发的!ip:port
对收件人进行 grepd 并在附近找到了他们haproxy-http2.cfg
。配置中的行是:
server pyhttps 77.242.1.101:8080 check
看来我很不走运,所以一项服务选择随机端口来从其配置中检查某些服务器,而该端口与想要监听我的其他服务的端口冲突。
请指教:如何避免这种冲突?我可以:1)停止所有 haproxy 服务,然后使用一个命令启动它们 -(尽量减少失败几率)- 手动停止工作服务不是一个好主意 2)通过防火墙关闭主题中的端口,直到这些端口上没有活动连接,然后重新启动所需的服务 - 可行,但需要一些时间和脚本 3)从服务可能用于传出连接的端口中排除重要端口。知道如何实现这个结果吗?
答案1
这是一个端口配置错误:sysctl.conf 包含一个指令:
net.ipv4.ip_local_port_range = 1024 65003
这允许系统为传出连接使用从 1024 到 65003 的随机本地端口号。这就是我遇到错误cannot bind socket
但没有看到任何服务在主题端口上侦听的原因。为了解决这个问题,我在 sysctl.conf 中将较低的端口增加到 6000,并使用 重新加载了 sysctl 设置sysctl -p
。
答案2
它对我有用。遵循以下步骤
- 检查是否已有某个进程与此端口绑定。停止该服务
- 禁用 SELinux 或设置为宽容模式。将行:setsebool -P haproxy_connect_any=1 添加到 /etc/sysconfig/selinux 文件并重新启动
- 还可以尝试在 /etc/sysctl.conf 中添加 net.ipv4.ip_nonlocal_bind=1 并运行 #sysctl -p