CentOS7でポートフォワード設定
今更感がある話ですがCentOS7からiptablesからfirewalldに変更されてます。
今回、異なるゾーンに属するIF間でポートフォワードするときにちょっと戸惑ったのでメモ
基本的な概念とかはこのあたりを参照
2018/07/02 追記
CentOS7.3以前のfirewalldにはいくつかの重大なバグがありアップデートが必要です。
この記事で記載しているゾーンの変更も7.3以前では反映されないバグがあります。
Red Hat Customer Portal
やりたいイメージ
クライアントPCが192.168.10.120:80に接続したときに、192.168.10.254:80に転送します。
今回はWeb通信で動作を確認します。
+-----------+ | ClientPC | +-----------+ | 192.168.10.10 | | (192.168.10.0/25) | eth1 | 192.168.10.120:80 ( zone:external) +-----------+ | CentOS | *今回設定するところ +-----------+ eth0 | 192.168.10.230 ( zone:internal ) | | (192.168.10.128/25) | | 192.168.10.254:80 +-----------+ | WebServer | +-----------+
NICが所属するゾーンの変更
デフォルトではpublicゾーンに所属しているのでゾーンを変更します。
# firewall-cmd --get-active-zone
public
interfaces: eth0 eth1
【firewall-cmdで変更する場合】
# firewall-cmd --zone=external --change-interface=eth1 --permanent The interface is under control of NetworkManager, setting zone to 'external'. success # firewall-cmd --zone=internal --change-interface=eth0 --permanent The interface is under control of NetworkManager, setting zone to 'internal'. success # firewall-cmd --reload success # firewall-cmd --get-active-zone internal interfaces: eth0 external interfaces: eth1
【nmcliで変更する場合】
# nmcli con mod eth1 connection.zone external # nmcli con mod eth0 connection.zone internal # firewall-cmd --get-active-zone internal interfaces: eth0 external interfaces: eth1
ポートフォワード設定を追加する
externalゾーン側にポートフォワード設定を追加します。
# firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=80:toaddr=192.168.10.25 4 --permanent success # firewall-cmd --reload success # firewall-cmd --list-all --zone=external external (active) target: default icmp-block-inversion: no interfaces: eth1 sources: services: ssh ports: protocols: masquerade: yes forward-ports: port=80:proto=tcp:toport=80:toaddr=192.168.10.254 sourceports: icmp-blocks: rich rules:
もし通信ログを記録したい場合はrich ruleを使ってポートフォワード設定します。
また、このときdenyログを記録するように設定します。
# firewall-cmd --set-log-denied=all success # firewall-cmd --get-log-denied all # firewall-cmd --zone=external --add-rich-rule='rule family="ipv4" source address="192.168.10.0/25" destination address="192.168.10.120" forward-port port=80 protocol=tcp to-port=80 to-addr=192.168.10.254 log prefix="_[firewalld]_" level="info"' --permanent success # firewall-cmd --reload success # firewall-cmd --list-all --zone=external external (active) target: default icmp-block-inversion: no interfaces: eth1 sources: services: ssh ports: protocols: masquerade: yes forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.10.0/25" destination address="192.168.10.120" forward-port port="80" protocol="tcp" to-port="80" to-addr="192.168.10.254" log prefix="_[firewalld]_" level="info"
IPマスカレード設定を追加する(訂正有)
externalゾーンにはデフォルトでIPマスカレード設定がされています。
これだけで通信できると思っていたのですが、ブラウザで接続しても繋がりません。
どうもinternal側にも設定が必要なようです。
# firewall-cmd --zone=external --query-masquerade yes # firewall-cmd --zone=internal --query-masquerade no # firewall-cmd --zone=internal --add-masquerade --permanent success # firewall-cmd --reload success # firewall-cmd --zone=internal --query-masquerade yes # firewall-cmd --list-all --zone=internal internal (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client mdns samba-client ssh ports: protocols: masquerade: yes forward-ports: sourceports: icmp-blocks: rich rules:
2018/06/26 訂正
IPマスカレード設定が必要なのはinternal側のみです。
external側はポートフォワード設定があるため、IPマスカレード設定は削除すべきです。
実際には設定変更ではなくpublicゾーンを利用したほうが良いかもしれません。
# firewall-cmd --zone=external --query-masquerade yes # firewall-cmd --zone=external --remove-masquerade --permanent success # firewall-cmd --reload success # firewall-cmd --zone=external --query-masquerade no # firewall-cmd --list-all --zone=external external (active) target: default icmp-block-inversion: no interfaces: eth1 sources: services: ssh ports: protocols: masquerade: no forward-ports: port=80:proto=tcp:toport=80:toaddr=192.168.10.254 sourceports: icmp-blocks: rich rules:
接続する
ブラウザで192.168.10.120に接続すると192.168.10.254にポート転送されます。
IPマスカレードされているので、当然接続元IPはinternal側の192.168.10.230になっています。
# tail /var/log/httpd/access_log 192.168.10.230 - - [07/Nov/2017:00:10:19 +0900] "GET /favicon.ico HTTP/1.1" 404 209 "http://192.168.10.120/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
ポートフォワード設定でrich ruleを設定している場合は、firewalldのログが出力されています。
結構大量に出るので必要に応じてlog出力にlimit valueなどの設定が必要です。
# tail /var/log/messages Jul 2 01:47:33 vm02 kernel: _[firewalld]_IN=eth1 OUT= MAC=00:50:56:9a:b1:6b:00:50:56:9a:c5:00:08:00 SRC=192.168.10.10 DST=192.168.10.120 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=27326 DF PROTO=TCP SPT=32770 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0 Jul 2 01:47:33 vm02 kernel: _[firewalld]_IN=eth1 OUT= MAC=00:50:56:9a:b1:6b:00:50:56:9a:c5:00:08:00 SRC=192.168.10.10 DST=192.168.10.120 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=27327 DF PROTO=TCP SPT=32770 DPT=80 WINDOW=229 RES=0x00 ACK URGP=0 . . .