![为 Corosync 提供安全 IPTables 规则](https://linux22.com/image/593230/%E4%B8%BA%20Corosync%20%E6%8F%90%E4%BE%9B%E5%AE%89%E5%85%A8%20IPTables%20%E8%A7%84%E5%88%99.png)
我有两个运行 Corosync 和 Pacemaker 的HA 负载均衡器(hollywood
和)。接口连接到 WAN,接口连接到 LAN,使用虚拟 IP 作为后端服务器的网关。的 IP 为,的IP 为。Corosync中的 为,与 WAN 的网络地址相同,Corosync 端口为默认的。wolfman
eth1
eth0
eth1
hollywood
xxx.xxx.195.45
eth1
wolfman
xxx.xxx.195.46
bindnetaddr
xxx.xxx.195.32
5405
两台服务器上相关的IP表规则是:
*filter
--flush
:INPUT DROP
--append INPUT --protocol udp --destination-port 5404 --jump ACCEPT
--append INPUT --protocol udp --destination-port 5405 --jump ACCEPT
此设置似乎工作正常,但最初我将--in-interface eth1
和添加--source xxx.xxx.195.46
到wolfman
,并将--source xxx.xxx.195.45
添加到hollywood
。大多数情况下,这似乎有效,但重新启动被动平衡器有时会终止负载平衡器之间的通信,将这些错误写入系统日志:
[TOTEM ] Totem 因操作系统或网络故障无法形成集群。此消息最常见的原因是本地防火墙配置不正确。
因此,看起来要么是我过于简单地认为所有的 Corosync 流量都直接在两个负载平衡器之间传输,这种想法eth1
是错误的,要么是其他原因导致了问题。
我想将5404/5405
IPTables 中的端口锁定到集群。我需要做什么才能实现这一点?
编辑:corosync.conf
按要求。除 外,这都是默认的 Ubuntu bindnetaddr
。
# Please read the openais.conf.5 manual page
totem {
version: 2
# How long before declaring a token lost (ms)
token: 3000
# How many token retransmits before forming a new configuration
token_retransmits_before_loss_const: 10
# How long to wait for join messages in the membership protocol (ms)
join: 60
# How long to wait for consensus to be achieved before starting a new round of membership configuration (ms)
consensus: 3600
# Turn off the virtual synchrony filter
vsftype: none
# Number of messages that may be sent by one processor on receipt of the token
max_messages: 20
# Limit generated nodeids to 31-bits (positive signed integers)
clear_node_high_bit: yes
# Disable encryption
secauth: off
# How many threads to use for encryption/decryption
threads: 0
# Optionally assign a fixed node id (integer)
# nodeid: 1234
# This specifies the mode of redundant ring, which may be none, active, or passive.
rrp_mode: none
interface {
# The following values need to be set based on your environment
ringnumber: 0
bindnetaddr: xxx.xxx.195.32
mcastaddr: 226.94.1.1
mcastport: 5405
}
}
amf {
mode: disabled
}
service {
# Load the Pacemaker Cluster Resource Manager
ver: 0
name: pacemaker
}
aisexec {
user: root
group: root
}
logging {
fileline: off
to_stderr: yes
to_logfile: no
to_syslog: yes
syslog_facility: daemon
debug: off
timestamp: on
logger_subsys {
subsys: AMF
debug: off
tags: enter|leave|trace1|trace2|trace3|trace4|trace6
}
}
答案1
默认情况下,Corosync 使用 IP 多播在节点间进行通讯:
mcastaddr: 226.94.1.1
mcastport: 5405
配置防火墙以允许多播流量:
# iptables -A INPUT -p igmp -j ACCEPT
# iptables -A INPUT -m addrtype --dst-type MULTICAST -j ACCEPT
# iptables -A INPUT -p udp -m state --state NEW -m multiport --dports 5404,5405 -j ACCEPT
或切换到单播。
答案2
使用多播通信(Corosync 的默认设置)时,应允许 IGMP 流量,并且可以允许 Corosync 数据包,规则比其他答案更具体。以下规则就足够了(假设链OUTPUT
不阻止任何流量):
iptables -A INPUT -p igmp -i $corosync_interface -j ACCEPT
for src_addr in $ip_addr_self $ip_addr_partner1 $ip_addr_partner2; do
iptables -A INPUT -i $corosync_interface -s $src_addr -d $ip_addr_self \
-p udp --source-port $(($corosync_port - 1)) \
--destination-port $corosync_port -j ACCEPT
iptables -A INPUT -i $corosync_interface -s $src_addr -d $ip_addr_mcast \
-p udp --source-port $(($corosync_port - 1)) \
--destination-port $corosync_port -j ACCEPT
done
在此示例中,假设定义了以下变量:
$corosync_interface
:Corosync 使用的网络接口$ip_addr_self
:Corosync 本地绑定的 IP 地址(按bindnetaddr
指定corosync.conf
)$ip_addr_partner1
,$ip_addr_partner2
:其他 Corosync 节点的 IP 地址 - 如果集群有三个以上的节点,则可以添加更多节点。$ip_addr_mcast
:用于 Corosync 的多播地址(按mcastaddr
指定corosync.conf
)$corosync_port
:Corosync 使用的(目标)端口(如mcastport
中指定corosync.conf
)
在一个节点上,Corosync 使用的接口是 Open vSwitch 桥的成员端口,一些多播数据包在桥的接口上接收,而不是在具有 IP 地址的接口上接收。因此,我必须添加一条允许在此接口上接收多播数据包的附加规则:
for src_addr in $ip_addr_self $ip_addr_partner1 $ip_addr_partner2; do
iptables -A INPUT -i $bridge_interface -s $src_addr -d $ip_addr_mcast -p udp --source-port $(($corosync_port - 1)) --destination-port $corosync_port -j ACCEPT
done
如果OUTPUT
链默认不接受数据包,则需要添加允许 IGMP 流量和允许发送 Corosync 数据包的规则:
iptables -A OUTPUT -p igmp -o $corosync_interface -j ACCEPT
for dst_addr in $ip_addr_self $ip_addr_mcast $ip_addr_partner1 $ip_addr_partner2; do
iptables -A OUTPUT o $corosync_interface -s $ip_addr_self -d $dst_addr \
-p udp --source-port $(($corosync_port - 1)) \
--destination-port $corosync_port -j ACCEPT
done