以前、IPVS Connection Synchronization を試したので、今回は conntrack-tools の Connection Synchronization を試してみた。意味が分かっていない項目も多いので、このページに書いてあることを真似する際は要注意。
ホストの OS はいずれも CentOS 7.1 を使用した。
conntrack-tools と IPVS Connection Synchronization は使いどころが異なるので比較表の形式でまとめるのは不適切な気がするけど、まあいいや。
conntrack-tools | IPVS Connection Synchronization | |
---|---|---|
適用場所 | FW | LB |
インストールの容易さ | 自分でビルドする必要あり | yum で簡単にインストールできる |
SELinux 対策 | 難しい。無理やり色々書いて乗り切った | setsebool を一回叩いて解決 |
コネクション情報の同期 | 同期しているようだ (*2) | イベントを通知しているだけのようだ (*1) |
(*1) IPVS のコネクション同期はイベントを通知しているだけらしく、LB 再起動時の挙動に難があった。そのあたりの説明はこちらを参照。
(*2) conntrack-tools のコネクション同期は FW 一号機と二号機が持つ情報の差分を検出して不足分を同期しているのかもしれない。FW を再起動しても情報は欠損せず引き継がれる。素晴らしい。
図の左上に存在する cent7i と cent7j が firewall で、今回はここに注目。いずれも NIC を三つ持つ。192.168.0.0/24 が表側で、192.168.1.0/24 は裏側。192.168.3.0/24 は iptables の情報を cent7i と cent7j で同期するために使う。
図の中央に存在する cent7g と cent7h は load balancer である。
load balancer の振り分け先は cent7a と cent7b で、postfix を動作させている。
cent7d には背景水色で vsftpd と書いてあるが試してはいない。
図の右側。動作確認用に cent7m, cent7k cent7c を用意した。
package もしくは操作 | firewall | load balancer | firewall | ||
---|---|---|---|---|---|
cent7i | cent7j | cent7g | cent7h | cent7m | |
deltarpm | yes | yes | yes | yes | yes |
bash-completion | yes | yes | yes | yes | yes |
bind-utils | yes | yes | yes | yes | yes |
screen | yes | yes | yes | yes | yes |
tcpdump | yes | yes | yes | yes | yes |
telnet | yes | yes | yes | yes | yes |
vim | yes | yes | yes | yes | yes |
好みに応じて、deltarpm や vim 等をインストールする。
package もしくは操作 | firewall | load balancer | firewall | ||
---|---|---|---|---|---|
cent7i | cent7j | cent7g | cent7h | cent7m | |
firewalld の stop と mask | yes | yes | yes | yes | yes |
net.ipv4.ip_forward = 1 | yes | yes | yes | yes | yes |
上記の二つは必須。
package もしくは操作 | firewall | load balancer | firewall | ||
---|---|---|---|---|---|
cent7i | cent7j | cent7g | cent7h | cent7m | |
iptables-services | yes | yes | yes | ||
gcc-c++ | yes | ||||
bzip2 | yes | ||||
bison | yes | ||||
flex | yes | ||||
libnfnetlink-devel | yes | ||||
libnetfilter_conntrack-devel | yes | ||||
libmnl-devel | yes | ||||
libnetfilter_queue-devel | yes | ||||
keepalived | yes | yes | yes | yes | |
selinux-policy-devel | yes | [*1] | |||
libnetfilter_queue | [*2] | yes |
firewalld を通さず、iptables を直接使いたいから iptables-services をインストール。
CentOS 7.1 には conntrack-tools はパッケージ化されていないから自分でビルドする必要がある。gcc-c++ から libnetfilter_queue-devel はそのためにインストール。
HA を組むため、keepalived をインストール。
ipvsadm パッケージは不要だから表には記載していない。動作確認のために ipvsadm コマンドを使いたいならインストールすべし。
[*1] 一号機で生成した mypolicy.pp を二号機にコピーするなら (二号機で make しないなら) インストール不要だと思う。
[*2] 明示的にインストールしていないが、他のパッケージの依存でインストールされていた。
[root@cent7i ~]# grep -w CONFIG_NF_CONNTRACK /boot/config-$( uname -r )
CONFIG_NF_CONNTRACK=m
[root@cent7i ~]# grep -w CONFIG_NF_CONNTRACK_IPV4 /boot/config-$( uname -r )
CONFIG_NF_CONNTRACK_IPV4=m
[root@cent7i ~]# grep -w CONFIG_NETFILTER_NETLINK /boot/config-$( uname -r )
CONFIG_NETFILTER_NETLINK=m
[root@cent7i ~]# grep -w CONFIG_NF_CT_NETLINK /boot/config-$( uname -r )
CONFIG_NF_CT_NETLINK=m
[root@cent7i ~]# grep -w CONFIG_NF_CONNTRACK_EVENTS /boot/config-$( uname -r )
CONFIG_NF_CONNTRACK_EVENTS=y
[root@cent7i ~]#
[root@cent7i ~]# cd /usr/local/src/
[root@cent7i src]# curl -sSO http://www.netfilter.org/projects/conntrack-tools/files/conntrack-tools-1.4.3.tar.bz2
[root@cent7i src]# curl -sSO http://www.netfilter.org/projects/conntrack-tools/files/conntrack-tools-1.4.3.tar.bz2.sig
[root@cent7i src]# curl -sSO http://www.netfilter.org/files/coreteam-gpg-key-BB5F58CC.txt
[root@cent7i src]# gpg --import coreteam-gpg-key-BB5F58CC.txt
[root@cent7i src]# gpg --verify conntrack-tools-1.4.3.tar.bz2.sig conntrack-tools-1.4.3.tar.bz2
[root@cent7i src]# curl -sSO http://www.netfilter.org/projects/libnetfilter_cttimeout/files/libnetfilter_cttimeout-1.0.0.tar.bz2
[root@cent7i src]# curl -sSO http://www.netfilter.org/projects/libnetfilter_cttimeout/files/libnetfilter_cttimeout-1.0.0.tar.bz2.sig
[root@cent7i src]# gpg --verify libnetfilter_cttimeout-1.0.0.tar.bz2.sig libnetfilter_cttimeout-1.0.0.tar.bz2
[root@cent7i src]# tar xf libnetfilter_cttimeout-1.0.0.tar.bz2
[root@cent7i src]# cd libnetfilter_cttimeout-1.0.0/
[root@cent7i libnetfilter_cttimeout-1.0.0]# ./configure
[root@cent7i libnetfilter_cttimeout-1.0.0]# make
[root@cent7i libnetfilter_cttimeout-1.0.0]# make install
[root@cent7i libnetfilter_cttimeout-1.0.0]# cd /usr/local/src/
[root@cent7i src]# curl -sSO http://www.netfilter.org/projects/libnetfilter_cthelper/files/libnetfilter_cthelper-1.0.0.tar.bz2
[root@cent7i src]# curl -sSO http://www.netfilter.org/projects/libnetfilter_cthelper/files/libnetfilter_cthelper-1.0.0.tar.bz2.sig
[root@cent7i src]# gpg --verify libnetfilter_cthelper-1.0.0.tar.bz2.sig libnetfilter_cthelper-1.0.0.tar.bz2
[root@cent7i src]# tar xf libnetfilter_cthelper-1.0.0.tar.bz2
[root@cent7i src]# cd libnetfilter_cthelper-1.0.0
[root@cent7i libnetfilter_cthelper-1.0.0]# ./configure
[root@cent7i libnetfilter_cthelper-1.0.0]# make
[root@cent7i libnetfilter_cthelper-1.0.0]# make install
[root@cent7i libnetfilter_cthelper-1.0.0]# cd /usr/local/src/
[root@cent7i src]# tar xf conntrack-tools-1.4.3.tar.bz2
[root@cent7i src]# cd conntrack-tools-1.4.3/
[root@cent7i conntrack-tools-1.4.3]# PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ ./configure
[root@cent7i conntrack-tools-1.4.3]# make
[root@cent7i conntrack-tools-1.4.3]# make install
[root@cent7i ~]# tar cf - /usr/local/sbin/conntrack /usr/local/sbin/conntrackd /usr/local/sbin/nfct | ssh cent7j 'tar xf - -C /'
tar: Removing leading `/' from member names
[root@cent7i ~]# tar cf - /usr/local/lib | ssh cent7j 'tar xf - -C /'
tar: Removing leading `/' from member names
SELinux の属性はコピーできていないかもしれないが、動作に問題は無い。
色々少しずつ書き足して解決。自分が書いたことを理解できていない。
[root@cent7i policy]# md5sum mypolicy.te
ead3fcc040631dee4f752b7730f55adb mypolicy.te
[root@cent7i policy]# cat mypolicy.te
module mypolicy 1.0;
require {
type kernel_t;
type var_lock_t;
type keepalived_t;
type var_run_t;
type unreserved_port_t;
class lnk_file read;
class dir write;
class dir add_name;
class dir remove_name;
class file create;
class file { read open };
class capability sys_nice;
class process setsched;
class file unlink;
class sock_file create;
class sock_file write;
class sock_file unlink;
class udp_socket name_bind;
class unix_stream_socket connectto;
class system module_request;
}
#============= keepalived_t ==============
allow keepalived_t var_lock_t:lnk_file read;
allow keepalived_t var_lock_t:dir write;
allow keepalived_t var_lock_t:dir add_name;
allow keepalived_t var_lock_t:file create;
allow keepalived_t var_lock_t:file { read open };
allow keepalived_t var_lock_t:dir remove_name;
allow keepalived_t self:capability sys_nice;
allow keepalived_t self:process setsched;
allow keepalived_t var_lock_t:file unlink;
allow keepalived_t var_run_t:sock_file create;
allow keepalived_t unreserved_port_t:udp_socket name_bind;
allow keepalived_t var_run_t:sock_file write;
allow keepalived_t self:unix_stream_socket connectto;
allow keepalived_t var_run_t:sock_file unlink;
allow keepalived_t kernel_t:system module_request;
[root@cent7i policy]#
[root@cent7i policy]# make -f /usr/share/selinux/devel/Makefile mypolicy.pp
[root@cent7i policy]# semodule -i mypolicy.pp
[root@cent7j policy]# make -f /usr/share/selinux/devel/Makefile mypolicy.pp
[root@cent7j policy]# semodule -i mypolicy.pp
[root@cent7i keepalived]# md5sum keepalived.conf
a6a679fa1f6ac5a361c4cfc2376eab5a keepalived.conf
[root@cent7i keepalived]# cat keepalived.conf
#
# Simple script for primary-backup setups
#
vrrp_sync_group G1 { # must be before vrrp_instance declaration
group {
VI_1
VI_2
}
notify_master "/etc/conntrackd/primary-backup.sh primary"
notify_backup "/etc/conntrackd/primary-backup.sh backup"
notify_fault "/etc/conntrackd/primary-backup.sh fault"
}
vrrp_instance VI_1 {
interface enp0s3
state SLAVE
virtual_router_id 61
priority 80
advert_int 3
virtual_ipaddress {
192.168.0.40/24 brd 192.168.0.255
192.168.0.60/24 brd 192.168.0.255
192.168.0.88/24 brd 192.168.0.255
}
}
vrrp_instance VI_2 {
interface enp0s8
state SLAVE
virtual_router_id 62
priority 80
advert_int 3
virtual_ipaddress {
192.168.1.40/24 brd 192.168.1.255
}
}
[root@cent7i keepalived]#
[root@cent7i conntrackd]# md5sum primary-backup.sh
646a3c5a1f909fa09581e400ca99d335 primary-backup.sh
[root@cent7i conntrackd]# diff -u /usr/local/src/conntrack-tools-1.4.3/doc/sync/primary-backup.sh primary-backup.sh
--- /usr/local/src/conntrack-tools-1.4.3/doc/sync/primary-backup.sh 2013-02-25 07:23:57.000000000 +0900
+++ primary-backup.sh 2015-10-18 21:11:39.642000000 +0900
@@ -19,7 +19,7 @@
# Contributions to improve this script are welcome :).
#
-CONNTRACKD_BIN=/usr/sbin/conntrackd
+CONNTRACKD_BIN=/usr/local/sbin/conntrackd
CONNTRACKD_LOCK=/var/lock/conntrack.lock
CONNTRACKD_CONFIG=/etc/conntrackd/conntrackd.conf
[root@cent7i conntrackd]#
[root@cent7i conntrackd]# md5sum conntrackd.conf
33cf299cc988e52e9bf067461ec9fc81 conntrackd.conf
[root@cent7i conntrackd]# cat conntrackd.conf
Sync {
Mode FTFW {
}
UDP {
IPv4_address 192.168.3.41
IPv4_Destination_Address 192.168.3.42
Port 3780
Interface enp0s9
SndSocketBuffer 1249280
RcvSocketBuffer 1249280
Checksum on
}
}
General {
Nice -20
HashSize 32768
HashLimit 131072
LogFile off
Syslog on
LockFile /var/lock/conntrack.lock
UNIX {
Path /var/run/conntrackd.ctl
Backlog 20
}
NetlinkBufferSize 2097152
NetlinkBufferSizeMaxGrowth 8388608
Filter From Userspace {
Protocol Accept {
TCP
UDP
ICMP # This requires a Linux kernel >= 2.6.31
}
Address Ignore {
IPv4_address 127.0.0.1
IPv4_address 192.168.0.41
IPv4_address 192.168.1.41
IPv4_address 192.168.3.41
}
}
}
[root@cent7i conntrackd]#
[root@cent7j conntrackd]# diff -u <( ssh cent7i cat /etc/conntrackd/conntrackd.conf ) conntrackd.conf
--- /dev/fd/63 2015-10-24 21:15:31.024000000 +0900
+++ conntrackd.conf 2015-10-18 21:13:52.806000000 +0900
@@ -2,8 +2,8 @@
Mode FTFW {
}
UDP {
- IPv4_address 192.168.3.41
- IPv4_Destination_Address 192.168.3.42
+ IPv4_address 192.168.3.42
+ IPv4_Destination_Address 192.168.3.41
Port 3780
Interface enp0s9
SndSocketBuffer 1249280
@@ -32,9 +32,9 @@
}
Address Ignore {
IPv4_address 127.0.0.1
- IPv4_address 192.168.0.41
- IPv4_address 192.168.1.41
- IPv4_address 192.168.3.41
+ IPv4_address 192.168.0.42
+ IPv4_address 192.168.1.42
+ IPv4_address 192.168.3.42
}
}
}
[root@cent7j conntrackd]#
nmcli connection modify enp0s8 +ipv4.routes '192.168.2.0/24 192.168.1.50'
[root@cent7j ~]# md5sum iptables-cent7i-cent7j.sh
7c46273ae0a5843642b04c66af1fc692 iptables-cent7i-cent7j.sh
[root@cent7j ~]# cat iptables-cent7i-cent7j.sh
#!/bin/bash
set -e
set -u
iptables -t nat -F
iptables -t nat -A PREROUTING -i enp0s3 -p tcp -d 192.168.0.60 --dport 25 -j DNAT --to-destination 192.168.1.60
iptables -t nat -A PREROUTING -i enp0s3 -p tcp -d 192.168.0.88 --dport 3389 -j DNAT --to-destination 192.168.2.88
iptables -t nat -A POSTROUTING -o enp0s3 -p tcp -s 192.168.2.61 --dport 25 -j SNAT --to-source 192.168.0.60
iptables -t nat -A POSTROUTING -o enp0s3 -p tcp -s 192.168.2.62 --dport 25 -j SNAT --to-source 192.168.0.60
iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.1.0/24 -j SNAT --to-source 192.168.0.40
iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.2.0/24 -j SNAT --to-source 192.168.0.40
echo done1
iptables -F
iptables -P FORWARD DROP
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -i enp0s3 -p tcp -d 192.168.1.60 --dport 25 -j ACCEPT
iptables -A FORWARD -i enp0s3 -p tcp -d 192.168.2.88 --dport 3389 -j ACCEPT
iptables -A FORWARD -i enp0s8 -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -i enp0s8 -s 192.168.2.0/24 -j ACCEPT
iptables -A FORWARD -j LOG --log-prefix 'DROPPED ' --log-level info
echo done2
[root@cent7j ~]#
setsebool -P domain_kernel_load_modules on
[root@cent7g ~]# md5sum /etc/keepalived/keepalived.conf
7f92ce227724e11993bba494a1dc8d77 /etc/keepalived/keepalived.conf
[root@cent7g ~]# cat /etc/keepalived/keepalived.conf
vrrp_sync_group group500 {
group {
instance51
instance52
}
}
vrrp_instance instance51 {
state BACKUP
nopreempt
interface enp0s3
virtual_router_id 51
priority 100
advert_int 1
virtual_ipaddress {
192.168.1.50/24 brd 192.168.1.255
192.168.1.60/24 brd 192.168.1.255
}
}
vrrp_instance instance52 {
state BACKUP
nopreempt
interface enp0s8
virtual_router_id 52
priority 100
advert_int 1
virtual_ipaddress {
192.168.2.50/24 brd 192.168.2.255
}
lvs_sync_daemon_interface enp0s8
}
virtual_server_group SMTP {
192.168.1.60 25
}
virtual_server group SMTP {
delay_loop 10
lb_algo lc
lb_kind NAT
protocol TCP
real_server 192.168.2.61 25 {
weight 1
inhibit_on_failure
SMTP_CHECK {
connect_timeout 15
retry 2
delay_before_retry 6
}
}
real_server 192.168.2.62 25 {
weight 1
inhibit_on_failure
SMTP_CHECK {
connect_timeout 15
retry 2
delay_before_retry 6
}
}
}
[root@cent7g ~]#
[root@cent7m ~]# md5sum iptables-cent7m.sh
7caccd426d5c08e4303eeb451a320cf6 iptables-cent7m.sh
[root@cent7m ~]# cat iptables-cent7m.sh
#!/bin/bash
set -e
set -u
iptables -t nat -F
iptables -t nat -A PREROUTING -i enp0s3 -p tcp -d 192.168.0.202 --dport 25 -j DNAT --to-destination 192.168.9.202
iptables -t nat -A POSTROUTING -o enp0s3 -p tcp -s 192.168.9.202 --dport 25 -j SNAT --to-source 192.168.0.202
iptables -t nat -A POSTROUTING -o enp0s3 -s 192.168.9.0/24 -j SNAT --to-source 192.168.0.201
echo done1
iptables -F
iptables -P FORWARD DROP
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -i enp0s3 -p tcp --dport 25 -d 192.168.9.202 -j ACCEPT
iptables -A FORWARD -i enp0s8 -s 192.168.9.0/24 -j ACCEPT
iptables -A FORWARD -j LOG --log-prefix 'DROPPED ' --log-level info
echo done2
[root@cent7m ~]#