iptables与firewalld都是防火墙规则生成工具。iptables设置好策略后交由内核层面的netfilter网络过滤来处理,而firewalld设置好策略后交由内核层面的nftables包过滤框架来管理。
1. iptables防火墙
-
表和链
四表:filter表(过滤),nat表(地址转换),mangle表(拆、改、封),raw表。五链:INPUT,OUTPUT,FORWARD,PREROUTING,POSTROUTING
执行动作
ACCEPT,DROP,REJECT,DNAT,SNAT,REDIRECT,MASQUERADE,LOG,MARK常用选项
A 在链尾添加一条新的规则
I 插入一条新的规则,默认插入到第一条
D 删除指定的规则
R 替换指定的规则
F 清空规则
P 设定制定规则连的默认策略
N 定义一个新的空链
X 删除一个自定义链
Z 将指定规则连中的规则置零
E 重命名一条自定义的链
L 查看规则(-n 以数字形式显示ip地址和端口;-v 显示详细信息;-x 显示精确值;--line-numbers 显示序号)匹配项
通用匹配项:
-s,--src 源ip地址
-d.--dst 目标ip地址
-p 指定协议
-i [网卡名] 指定报文流入的接口
-o [网卡名] 指定报文流出的接口
-j 规则对应的动作
隐含扩展
-p tcp --sport 指定源端口
-p tcp --dport 指定目标端口
-p ICMP --icmp-type 0/8 0位响应报文,8为请求报文。
显式扩展
-m [扩展名] [选项]
-m state --state [会话连接状态] -j [动作] 对处于某个会话状态的连接执行相应的动作
四种连接状态:
NEW:新的连接
ESTABLISHED:已经建立的连接
INBALID:非法连接/无效连接
RELATED:相关联的连接。如ftp命令连接状态。
- 规则的保存
service iptables save
- 案例
添加防火墙规则使ftp主、被动模式能够正常被访问
分析:
主动模式 :首先客户端随机端口请求ftp服务端的21号命令端口,ftp服务器的20号端口主动连接客户端的随机数据端口。故此,在ftp服务器上添加防火墙规则为
没有添加规则之前:
[root@ftp-server ~]# iptables -L -n
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:22
添加规则:
[root@ftp-server ~]# iptables -t filter -I INPUT 2 -p tcp --dport 21 -j ACCEPT
[root@ftp-server ~]# iptables -t filter -I OUTPUT 2 -p tcp --sport 21 -j ACCEPT
[root@ftp-server ~]# iptables -t filter -I OUTPUT 3 -p tcp --sport 20 -j ACCEPT
[root@ftp-server ~]# iptables -t filter -I INPUT 3 -p tcp --dport 20 -j ACCEPT
在客户端访问测试:
[root@ftp-client ~]# ftp 10.1.1.20
Connected to 10.1.1.20 (10.1.1.20).
220 (vsFTPd 2.2.2)
Name (10.1.1.20:root): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive #关闭了被动模式
Passive mode off.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Mar 01 2013 pub
226 Directory send OK.
查看规则:
[root@ftp-server ~]# iptables -L -n
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:21
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:20
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:21
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:20
被动模式:客户端开启一个大于1024的随机命令端口去连接ftp服务器的21号命令端口,客户端再开启一个大于1024的随机数据端口去连接服务器上的一个大于1024的随机数据端口。故此,在ftp服务器首先要先规定好一个随机数据端口的范围(3000~3005),然后添加防火墙规则。
命令行连接方式与主动模式相同,故省略。
[root@ftp-server ~]# vim /etc/vsftpd/vsftpd.conf
pasv_min_port=3000
pasv_max_port=3005
重启ftp服务:
[root@ftp-server ~]# service vsftpd restart
添加规则:
[root@ftp-server ~]# iptables -I INPUT 4 -p tcp --dport 3000:3005 -j ACCEPT
[root@ftp-server ~]# iptables -I OUTPUT 4 -p tcp --sport 3000:3005 -j ACCEPT
客户端访问测试:
ftp> passive #开启被动模式
Passive mode on.
ftp> ls
227 Entering Passive Mode (10,1,1,20,11,186).
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Mar 01 2013 pub
226 Directory send OK.
[root@ftp-server ~]# iptables -L -n
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:21
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:20
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:3000:3005
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:21
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:20
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spts:3000:3005
规则优化
[root@ftp-server ~]# iptables -A INPUT -p tcp -m multiport --dports 22,20,21,3000:3005 -j ACCEPT
[root@ftp-server ~]# iptables -A OUTPUT -p tcp -m multiport --sports 22,20,21,3000:3005 -j ACCEPT
[root@ftp-server ~]# iptables -L -n --line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 22,20,21,3000:3005
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy DROP)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport sports 22,20,21,3000:3005
除上述方法外,还可以调用iptables的conntrack模块来解决ftp服务被动模式规则。不过首先要将命令端口添加到防火墙规则。
打开iptables配置文件添加模块
[root@ftp-server ~]# vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="nf_conntrack_ftp"
重启iptables服务
[root@ftp-server ~]# service iptables restart
[root@ftp-server ~]# iptables -I INPUT -p tcp -m multiport --dports 21,22 -j ACCEPT
[root@ftp-server ~]# iptables -I OUTPUT -p tcp -m multiport --sports 21,22 -j ACCEPT
[root@ftp-server ~]# iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@ftp-server ~]# iptables -I OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@ftp-server ~]# service iptables save
客户端访问测试:
[root@ftp-client ~]# ftp 10.1.1.20
Connected to 10.1.1.20 (10.1.1.20).
220 (vsFTPd 2.2.2)
Name (10.1.1.20:root): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (10,1,1,20,11,187).
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Mar 01 2013 pub
226 Directory send OK.
ftp> passive
Passive mode off.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Mar 01 2013 pub
226 Directory send OK.
查看规则:
[root@ftp-server ~]# iptables -L -n --line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 21,22
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy DROP)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport sports 21,22
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
- NAT表实现源地址转换和目标地址转换
源地址转换:以局域网内某台主机访问外网为例
要访问外网的主机server01:10.1.1.20(仅主机)
作为路由转发的主机(可以访问外网)server02:10.1.1.21(仅主机) 10.2.2.99(NAT)
1:在server02 开启路由转发功能
[root@server02 ipv4]# echo 1 > /proc/sys/net/ipv4/ip_forward
2:在server02 添加防火墙策略
[root@server02 ipv4]# iptables -t nat -I POSTROUTING -s 10.1.1.20 -j SNAT --to 10.2.2.99
3:将server01 的网关指向server02
[root@server01 ~]# route add default gw 10.1.1.21
4:在server01上ping 8.8.8.8测试
[root@server01 ~]# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=127 time=203 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=127 time=205 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=127 time=208 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2376ms
rtt min/avg/max/mdev = 203.127/205.624/208.274/2.104 ms
另外,在开启路由转发的前提下,也可以直接在server02添加地址伪装策略实现server01访问外网。
[root@server02 ipv4]# iptables -t nat -I POSTROUTING -s 10.1.1.20 -j MASQUERADE
目标地址转换:
server01:内网web服务主机 10.1.1.20
server02:作为路由转发的主机 10.1.1.21 11.11.11.11
server03:模拟外网主机 11.11.11.12
1:在server01 搭建web服务
[root@server01 ~]# yum -y install httpd httpd-devel
2:创建首页测试文件并启动web服务,并在本机测试访问。
[root@server01 ~]# echo "server01 for test" > /var/www/html/index.html
[root@server01 ~]# service httpd start
[root@server01 ~]# curl 10.1.1.20
server01 for test
3:在server03访问测试:
[root@server03 ~]# curl 10.1.1.20
curl: (7) Failed to connect to 10.1.1.20: 网络不可达
4:在server02开启目标地址转发,开启路由转发功能:
[root@server02 ~]# iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 10.1.1.20
[root@server02 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
5:在server01指定网关为10.1.1.21:
[root@server01 ~]# route del default gw 10.1.1.21
6:在server03访问测试:
[root@server03 ~]# curl 11.11.11.11
server01 for test
2. Firewall防火墙
- 域(zone)
zone是指规则集,可以预先制定规则集,以后可以随意切换只用。
查看所有的zone:
[root@server03 ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
[root@server03 ~]# firewall-cmd --list-all-zones
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
dmz
target: default
icmp-block-inversion: no
interfaces:
sources:
...
查看当前默认zone:
[root@server03 ~]# firewall-cmd --get-default-zone
public
更改默认zone:
[root@server03 ~]# firewall-cmd --set-default-zone=home
success
[root@server03 ~]# firewall-cmd --get-default-zone
home
- 端口(port)
通过端口来制定防火墙策略
1:查看当前规则集下的策略:
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
2:当前规则集允许tcp80端口通过(删除该端口只需将 --add 改为 --remove 即可)
[root@server03 ~]# firewall-cmd --add-port=80/tcp
success
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 80/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
3:添加多个连续的端口:
[root@server03 ~]# firewall-cmd --add-port=3333-4444/tcp
success
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 80/tcp 3333-4444/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
- 服务(service)
firewall支持通过添加指定的服务来指定防火墙规则,这样例如ftp这样的服务就不用担心端口的问题了。
[root@server03 ~]# firewall-cmd --add-service=http
success
[root@server03 ~]# firewall-cmd --add-service=ftp
success
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client http ftp
ports: 80/tcp 3333-4444/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
- 富规则(rich-rule)
精细化的制定规则策略
1:不允许10.1.1.22访问本机http服务
[root@server03 ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address=10.1.1.22 service name="http" drop'
success
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client http ftp samba
ports: 80/tcp 3333-4444/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="10.1.1.22" service name="http" drop
2: 允许11.11.11.11访问本机http服务,但每分钟只允许有两次连接。
[root@server03 ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address=11.11.11.11 service name="http" limit value=2/m accept'
success
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client http ftp samba
ports: 80/tcp 3333-4444/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="10.1.1.22" service name="http" drop
rule family="ipv4" source address="11.11.11.11" service name="http" accept limit value="2/m"
- runtime模式和permanent模式
runtime模式为默认模式,规则制定后立即生效,重启firewalld服务则规则失效
permanent模式,规则不会立即生效,重启firewalld服务后才生效。
[root@server03 ~]# firewall-cmd --add-service=nfs
success
[root@server03 ~]# firewall-cmd --permanent --add-service=ntp
success
[root@server03 ~]#
[root@server03 ~]# systemctl restart firewalld
[root@server03 ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client ntp
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
一般在写规则的时候不用指定模式,在写完所有规则后执行下面命令即可保存
[root@server03 ~]# firewall-cmd --runtime-to-permanent
success
- 重载
若使用了permanent模式,需要重载firewalld服务。
[root@server03 ~]# firewall-cmd --reload
success
- 禁行模式(panic)
开启该模式后,所有进出的包都将被丢弃。
1:查看是否开启了panic模式
[root@server03 ~]# firewall-cmd --query-panic
no
2:开启panic模式
[root@server03 ~]# firewall-cmd --panic-on
3:关闭panic模式
[root@server03 ~]# firewall-cmd --panic-off
- 开启图形化配置模式
[root@server03 ~]# firewall-config
- firewall实现源地址转换和目标地址转换
开启源地址转换命令(如前文中iptables情景中)
[root@server03 ~]# firewall-cmd --add-masquerade
success
开启目标地址转换命令(如前文iptables情景中)
[root@server03 ~]# firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=10.1.1.20
success