FirewalldでLinuxFirewallを

RaspberryPi3にインストールしたUbuntu16.04にFirewalldをインストールしたが、これにルールを追加し、LinuxFirewallとして動作させる。

最初は、–add-rich-ruleでできるかと思ったが、実際には–directでちゃんとiptablesのルールを書かないとできないことが分かった。
今回はこちらの図書を参考にした。

インタフェースとゾーン

今回は、VPNで構築したトンネルインタフェースtun0をdmz、イーサネットのインタフェースenxb827eb55dbe9をinternalとして
NATしないゾーン間のフィルタリングを行った。

# firewall-cmd --get-active-zone
internal
  interfaces: enxb827eb55dbe9
dmz
  interfaces: tun0

(失敗)rich-ruleでフォワードするパケットのACLを書けばいい?

カーネルパラメータnet.ipv4.ip_forwardnに1を設定すればルータとして動作するのだから、あとはrich-ruleで入力パケットを制限してやればいいのかなと最初は勘違いしていた。
実際には、ファイアウォールとして動作するときに使うチェインと、rich-ruleとしたときに扱われるチェインが違うため、全く働くことのないACLを設定するだけだった。

# 192.168.0.101/24から192.168.1.0/24へのSSHを許可したかった
# でもこれではダメ
firewall-cmd --zone=dmz --add-rich-rule='rule family="ipv4" source address="192.168.0.101/32" destination address="192.168.1.0/24" port protocol="tcp" port=22 accept'

ちゃんとチェインを見てみる

Netfiterのチェインはこうなっている。

この中でFirewalldは

  • port/serviceではINPUTチェイン
  • forward-portではPREROUTINGチェイン
  • masqueradeではPOSTROUTINGチェイン

を扱っている。
しかし、ポート転送を行うのはFORWARDチェインであり、そしてこれを操作するには–directで設定するしかない。
なので、–directルールを設定する。

FORWARDチェインを操作する

管理しやすいようFORWARDチェインを分割する

アクセス制御をゾーン間ごと制御しやすいよう以下のチェインを作る。
これらのチェインに適宜ルールを追加する。

  • FORWARD_global_allow: 全てのゾーンに適用される許可ルール用
  • FORWARD_global_deny: 全てのゾーンに適用される拒否ルール用
  • FORWARD_dmz_internal_allow: dmzからinternalへの許可ルール用
  • FORWARD_dmz_internal_deny: dmzからinternalへの拒否ルール用
  • FORWARD_internal_dmz_allow: internalからdmzへの許可ルール用
  • FORWARD_internal_dmz_deny: internalからdmzへの拒否ルール用

同じゾーンに属するNIC/ネットワークが複数あり、同一ゾーン間のフィルタリングをする場合は考慮しないものとした。

_n=1
firewall-cmd --direct --add-rule ipv4 filter FORWARD ${_n} -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
((_n = _n + 1))
for _z in global dmz_internal internal_dmz
do
    for _a in deny allow
    do
        _chain=FORWARD_${_z}_${_a}
        echo "${_chain}"
        firewall-cmd --direct --add-chain ipv4 filter ${_chain}
        firewall-cmd --direct --add-rule ipv4 filter FORWARD ${_n} -j ${_chain}
        ((_n = _n + 1))
    done
done
firewall-cmd --direct --add-rule ipv4 filter FORWARD 255 -j REJECT


# 確認
firewall-cmd --direct --get-all-chains
firewall-cmd --direct --get-all-rules

ルール設定例:192.168.0.101(dmz)から192.168.1.0/24(internal)へのSSHを許可

firewall-cmd --direct --add-rule ipv4 filter FORWARD_dmz_internal_allow 1 -m conntrack --ctstate NEW -p tcp -s 192.168.0.101/32 -d 192.168.1.0/24 --dport 22 -j ACCEPT

最後に、これまでの変更を保存する。

firewall-cmd --runtime-to-permanent

AnsibleのfirewalldモジュールではDirectルールはサポートされいないので、Ansible化するときは一苦労しそう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です