ricsanfre.firewall
Ansible Role: ファイアウォール
Linuxでファイアウォール(nftablesベース)をインストールおよび設定します。
要件
特になし。
ロール変数
利用可能な変数は以下に示されており、デフォルト値とともに記載されています(defaults/main.yaml
を参照)。
NATおよびトラフィックフォワーディングの有効化
- firewall_forward_enabled:指定したホストでのトラフィックフォワーディングサポートを有効または無効にします。[デフォルト:
false
] - firewall_nat_enabled:指定したホストでのNATサポートを有効または無効にします。[デフォルト:
false
]
デフォルトのオープンポートを定義
- in_tcp_port:このポートでIN TCPトラフィックを許可します。[デフォルト:
{ ssh }
] - in_udp_port:このポートでIN UDPトラフィックを許可します。[デフォルト:
{ snmp }
] - out_tcp_port:このポートでOUT TCPトラフィックを許可します。[デフォルト:
{ http, https, ssh }
] - out_udp_port:このポートでOUT UDPトラフィックを許可します。[デフォルト:
{ domain, bootps , ntp }
]
ルール辞書
ipテーブル(input、output、forward)およびnatテーブル(nat-preroutingおよびnat-postrouting)内の各チェーンに対して、nftルールは辞書に保存され、グループおよびホストレベルでオーバーライドできます。
変数と定義セットおよびグローバルルール
さまざまなルールチェーンおよび他のチェーンからjump global
ルールを使用して呼び出すことができるグローバルチェーンルールのための変数と定義セット。
定義 | セット | グローバルチェーン |
---|---|---|
nft_define_default | nft_set_default | nft_global_default |
nft_define_group | nft_set_group | nft_global_group_rules |
nft_define_host | nft_set_host | nft_global_host_rules |
IPテーブルルール
inputチェーン | outputチェーン | forwardチェーン |
---|---|---|
nft_input_default_rules | nft_output_default_rules | nft_forward_default_rules |
nft_input_group_rules | nft_output_group_rules | nft_forward_group_rules |
nft_input_host_rules | nft_output_host_rules | nft_forward_host_rules |
Natテーブルルール
preroutingチェーン | postroutingチェーン |
---|---|
nft_nat_default_prerouting_rules | nft_nat_default_postrouting_rules |
nft_nat_group_prerouting_rules | nft_nat_group_postrouting_rules |
nft_nat_host_prerouting_rules | nft_nat_host_postrouting_rules |
各ルール辞書のタイプはマージされ、ルールはキーのアルファベット順で適用されます(000から999の接頭辞を使用する理由)。以下:
- nft_*_default_rules:すべてのノードのデフォルトルールを定義します。
group_vars/all
で定義できます。 - nft_*_group_rules:nft_*_default_rulesおよびnft_*_rulesで定義されたルールを追加およびオーバーライドできます。
group_vars/group_servers
で定義できます。 - nft_*_host_rules:nft_*_default_rules、nft_*_group_rulesおよびnft_*_rulesで定義されたルールを追加およびオーバーライドできます。
host_vars/specific_host
で定義できます。
デフォルトnftables設定
デフォルトでは、ロールは以下の構成ファイルを生成します:
/etc/nftables.conf
#!/usr/sbin/nft -f
# Ansible managed
# clean
flush ruleset
include "/etc/nftables.d/defines.nft"
table inet filter {
chain global {
# 000 state management
ct state established,related accept
ct state invalid drop
}
include "/etc/nftables.d/sets.nft"
include "/etc/nftables.d/filter-input.nft"
include "/etc/nftables.d/filter-output.nft"
}
/etc/nftables.d/defines.nft
# broadcast and multicast
define badcast_addr = { 255.255.255.255, 224.0.0.1, 224.0.0.251 }
# broadcast and multicast
define ip6_badcast_addr = { ff02::16 }
# in_tcp_accept
define in_tcp_accept = { ssh }
# in_udp_accept
define in_udp_accept = { snmp }
# out_tcp_accept
define out_tcp_accept = { http, https, ssh }
# out_udp_accept
define out_udp_accept = { domain, bootps , ntp }
/etc/nftables.d/sets.nft
set blackhole {
type ipv4_addr;
elements = $badcast_addr
}
set in_tcp_accept {
type inet_service; flags interval;
elements = $in_tcp_accept
}
set in_udp_accept {
type inet_service; flags interval;
elements = $in_udp_accept
}
set ip6blackhole {
type ipv6_addr;
elements = $ip6_badcast_addr
}
set out_tcp_accept {
type inet_service; flags interval;
elements = $out_tcp_accept
}
set out_udp_accept {
type inet_service; flags interval;
elements = $out_udp_accept
}
/etc/nftables.d/filter-input.nft
chain input {
# 000 policy
type filter hook input priority 0; policy drop;
# 005 global
jump global
# 010 drop unwanted
ip daddr @blackhole counter drop
# 011 drop unwanted ipv6
ip6 daddr @ip6blackhole counter drop
# 015 localhost
iif lo accept
# 050 icmp
meta l4proto {icmp,icmpv6} accept
# 200 input udp accepted
udp dport @in_udp_accept ct state new accept
# 210 input tcp accepted
tcp dport @in_tcp_accept ct state new accept
}
/etc/nftables.d/filter-output.nft
chain output {
# 000 policy
type filter hook output priority 0; policy drop;
# 005 global
jump global
# 015 localhost
oif lo accept
# 050 icmp
ip protocol icmp accept
ip6 nexthdr icmpv6 counter accept
# 200 output udp accepted
udp dport @out_udp_accept ct state new accept
# 210 output tcp accepted
tcp dport @out_tcp_accept ct state new accept
# 250 reset-ssh
tcp sport ssh tcp flags { rst, psh | ack } counter accept
}
ホスト上の次のルールセット(nft list ruleset
コマンドを実行したもの):
table inet filter {
set blackhole {
type ipv4_addr
elements = { 224.0.0.1, 224.0.0.251,
255.255.255.255 }
}
set in_tcp_accept {
type inet_service
flags interval
elements = { 22 }
}
set in_udp_accept {
type inet_service
flags interval
elements = { 161 }
}
set ip6blackhole {
type ipv6_addr
elements = { ff02::16 }
}
set out_tcp_accept {
type inet_service
flags interval
elements = { 22, 80, 443 }
}
set out_udp_accept {
type inet_service
flags interval
elements = { 53, 67, 123 }
}
chain global {
ct state established,related accept
ct state invalid drop
}
chain input {
type filter hook input priority filter; policy drop;
jump global
ip daddr @blackhole counter packets 0 bytes 0 drop
ip6 daddr @ip6blackhole counter packets 0 bytes 0 drop
iif "lo" accept
meta l4proto { icmp, ipv6-icmp } accept
udp dport @in_udp_accept ct state new accept
tcp dport @in_tcp_accept ct state new accept
}
chain output {
type filter hook output priority filter; policy drop;
jump global
oif "lo" accept
ip protocol icmp accept
ip6 nexthdr ipv6-icmp counter packets 0 bytes 0 accept
udp dport @out_udp_accept ct state new accept
tcp dport @out_tcp_accept ct state new accept
tcp sport 22 tcp flags { rst, psh | ack } counter packets 0 bytes 0 accept
}
}
依存関係
特になし。
例題プレイブック
デフォルトルールの適用
デフォルトルールでホストにファイアウォールをインストールおよび設定します。
- hosts: serverx
roles:
- ricsanfre.firewall
group_vars/all.yml
で、すべてのホストのデフォルトルールをオーバーライドできます:
nft_input_default_rules:
000 policy:
- type filter hook input priority 0; policy drop;
005 global:
- jump global
010 drop unwanted:
- ip daddr @blackhole counter drop
011 drop unwanted ipv6:
- ip6 daddr @ip6blackhole counter drop
015 localhost:
- iif lo accept
050 icmp:
- meta l4proto {icmp,icmpv6} accept
200 input udp accepted:
- udp dport @in_udp_accept ct state new accept
210 input tcp accepted:
- tcp dport @in_tcp_accept ct state new accept
グループレベルでデフォルトルールを変更
webservers
グループに対してHTTP受信トラフィックを開放します。
group_vars/webservers.yml
で、in_tcp_port
を変更することで実現できます。
in_tcp_port: { ssh, http }
または新しい特定のルールを追加することもできます。
nft_input_group_rule:
220 input web accepted:
- tcp dport http ct state new accept
ホストレベルでデフォルト+グループルールを変更
secureweb
ホストに対してHTTPS受信トラフィックを開放したい場合、host_vars/secureweb.yml
にてHTTPSを開放し、HTTPへのアクセスを無効にできます。
nft_input_group_rule:
220 input web accepted: []
230 input secure web accepted:
- tcp dport https ct state new accept
デフォルトルールを削除することも可能
ルールを「削除」するには、既存の辞書キーに空のリストを割り当てます: 例:ICMP受信トラフィックを無効にする
nft_input_host_rules:
050 icmp: []
特定のgroup_vars/group.yml
で、すべての送信トラフィックを許可するためのデフォルトルールを削除します。
nft_output_group_rules:
000 policy:
- type filter hook output priority 0;
005 global:
-
015 localhost:
-
050 icmp:
-
200 output udp accepted:
-
210 output tcp accepted:
-
250 reset-ssh:
-
000 policy
デフォルトルールは、すべてのトラフィックを受け入れるようにオーバーライドされ、他のルールは削除されます。
要約すると、nft_X_host_rules
のルールはnft_X_group_rules
のルールをオーバーライトし、その後nft_X_group_rules
のルールはnft_X_default_rules
のルールをオーバーライトします。
ライセンス
MIT/BSD
著者情報
リカルド・サンチェス (ricsanfre)