ricsanfre.firewall
Ansible角色:防火墙
在Linux上安装和配置基于nftables的防火墙。
要求
无。
角色变量
可用的变量如下所列,并附带默认值(见defaults\main.yaml
)。
启用NAT和流量转发
- firewall_forward_enabled :在给定主机上启用或禁用流量转发支持。[默认 :
false
]. - firewall_nat_enabled :在给定主机上启用或禁用NAT支持。[默认 :
false
].
定义默认开放端口
- in_tcp_port :允许通过这些端口的入站TCP流量。[默认 :
{ ssh }
]. - in_udp_port :允许通过这些端口的入站UDP流量。[默认 :
{ snmp }
]. - out_tcp_port :允许通过这些端口的出站TCP流量。[默认 :
{ http, https, ssh }
]. - out_udp_port :允许通过这些端口的出站UDP流量。[默认 :
{ domain, bootps, ntp }
].
规则字典
对于每个ip表中的链(输入链、输出链、转发链)和nat表(nat-prerouting和nat-postrouting),nft规则存储在字典中,可以在组和主机级别覆盖。
变量、定义集和全局规则
由不同的规则链和全局链规则使用的一组变量和定义,可以从其他链使用规则jump global
调用。
define | sets | global chain |
---|---|---|
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表规则
输入链 | 输出链 | 转发链 |
---|---|---|
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表规则
转发链 | 后转链 |
---|---|
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管理
# 清理
flush ruleset
include "/etc/nftables.d/defines.nft"
table inet filter {
chain global {
# 000 状态管理
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
# 广播和多播
define badcast_addr = { 255.255.255.255, 224.0.0.1, 224.0.0.251 }
# 广播和多播
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 策略
type filter hook input priority 0; policy drop;
# 005 全局
jump global
# 010 拒绝不需要的
ip daddr @blackhole counter drop
# 011 拒绝不需要的ipv6
ip6 daddr @ip6blackhole counter drop
# 015 本地主机
iif lo accept
# 050 icmp
meta l4proto {icmp,icmpv6} accept
# 200 输入udp接收
udp dport @in_udp_accept ct state new accept
# 210 输入tcp接收
tcp dport @in_tcp_accept ct state new accept
}
/etc/nftables.d/filter-output.nft
chain output {
# 000 策略
type filter hook output priority 0; policy drop;
# 005 全局
jump global
# 015 本地主机
oif lo accept
# 050 icmp
ip protocol icmp accept
ip6 nexthdr icmpv6 counter accept
# 200 输出udp接收
udp dport @out_udp_accept ct state new accept
# 210 输出tcp接收
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 策略:
- type filter hook input priority 0; policy drop;
005 全局:
- jump global
010 拒绝不需要的:
- ip daddr @blackhole counter drop
011 拒绝不需要的ipv6:
- ip6 daddr @ip6blackhole counter drop
015 本地主机:
- iif lo accept
050 icmp:
- meta l4proto {icmp,icmpv6} accept
200 输入udp接收:
- udp dport @in_udp_accept ct state new accept
210 输入tcp接收:
- 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 输入web接受:
- tcp dport http ct state new accept
在主机级别修改默认+组规则
为secureweb
主机打开HTTPS入站流量,在host_vars/secureweb.yml
中,您希望打开HTTPS并移除对HTTP的访问:
nft_input_group_rule:
220 输入web接受: []
230 输入安全web接受:
- tcp dport https ct state new accept
可以删除默认规则
要“删除”规则,您只需将现有字典键赋值为空列表: 示例:禁用ICMP入站流量
nft_input_host_rules:
050 icmp: []
在特定的group_vars/group.yml
中,删除允许所有出站流量的默认规则:
nft_output_group_rules:
000 策略:
- type filter hook output priority 0;
005 全局:
-
015 本地主机:
-
050 icmp:
-
200 输出udp接收:
-
210 输出tcp接收:
-
250 reset-ssh:
-
000 策略
默认规则被覆盖为接受所有流量,其余规则被删除。
总结一下,nft_X_host_rules
中的规则将覆盖nft_X_group_rules
中的规则,而nft_X_group_rules
中的规则将覆盖nft_X_default_rules
中的规则。
许可证
MIT/BSD
作者信息
Ricardo Sanchez (ricsanfre)