1.iptables安装
1.1 iptables和iptables-service的关系
iptables 是基于内核的,和 iptables-services 没有关系,不用安装任何工具包就可以使用 iptable 命令添加的防火墙规则,
但是iptables添加的规则是临时的,基于内存的,在系统重启后会消失,所以需要 iptables.service 服务来对添加的规则进行保存,
这样在系统重启后重载对应的防火墙规则。
1.2 安装iptables和iptables-service
第一步:1、关闭防火墙
[root@localhost ~]# systemctl status firewalld
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld
第二步:查看 iptables 是否安装,安装iptables-services
[root@localhost ~]# rpm -qa iptables
iptables-1.4.21-34.el7.x86_64 # 系统默认装有 iptables
[root@localhost ~]# yum install iptables # 有新版本会安装最新版本
[root@localhost ~]# rpm -qa iptables
iptables-1.4.21-35.el7.x86_64
[root@localhost ~]# yum install iptables-services # 安装 iptables-services
[root@localhost ~]# rpm -qa iptables-services
iptables-services-1.4.21-35.el7.x86_64
第三步:启动iptables
[root@localhost ~]# systemctl enable iptables.service # 设置 iptables 开机启动
[root@localhost ~]# systemctl start iptables # 开启 iptables
[root@localhost ~]# systemctl status iptables # 查看 iptables 状态
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
Active: active (exited) since Fri 2023-10-06 13:05:53 CST; 2s ago
第四步:#防火墙相关模块 加载到内核中,写入到开机自启动.
cat >> /etc/rc.local <<EOF
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
EOF
sysctl -p
2.查看 iptables 的链和规则
查看规则的命令格式为:
iptables [-t tables] [-L] [-nv]
-t :后面接 table ,filter/nat/mangle ,若省略此项目,则使用默认的 filter
-L :列出某个 table 的所有链或某个链的规则
-n :直接显示 IP,速度会快很多
-v :列出更多的信息,包括通过该规则的数据包总位数、相关的网络接口等
列出 filter table INPUT 链的规则:
$ sudo iptables -L INPUT
列出 nat table 三条链的规则:
$ sudo iptables -t nat -L -n
列出 filter table 三条链的规则:
$ sudo iptables -L
红框中的内容为链的名称及其默认策略,filter 表中所有链的默认策略都是 ACCEPT。红框下面的行代表什么呢?
target:代表进行的动作,ACCEPT 是放行,REJECT 是拒绝,DROP 则是丢弃数据包。
port:代表使用的协议,主要有 tcp、udp 和 icmp 三种。
opt:额外的选项说明。
source:规则针对的来源 IP。
destination:规则针对的目标 IP。
因为默认情况下没有添加自定义的规则,所以上图中这些行下面都是空的。
3.清除本机防火墙规则
清除规则的命令格式如下:
iptables [-t tables] [-FXZ]
-F:清除所有已制定的规则
-X:删除所有使用者自定义的 chain(其是 tables)
-Z:将所有的 chain 的计数与流量统计都清零
如果我们要制订一套防火墙规则,一般会先清除现有的规则,然后从头开始创建新的规则。下面让我们清除本机 filter 表中的所有规则:
$ sudo iptables -F
$ sudo iptables -X
$ sudo iptables -Z
4.定义默认策略(policy)
如果一个数据包没有匹配到一个链中的任何一个规则,那么将对该数据包执行这个链的默认策略(default policy),默认策略可以是 ACCEPT 或 DROP。
链中默认策略的存在使得我们在设计防火墙时可以有两种选择:
设置默认策略 DROP 所有的数据包,然后添加规则接受(ACCEPT)来自可信 IP 地址的数据包,或访问我们的服务监听的端口的数据包,比如 bittorrent、FTP 服务器、Web 服务器、Samba 文件服务器等等。
设置默认策略 ACCEPT 所有的数据包,然后添加规则丢弃(DROP)特定的数据包。比如来自一些恶意 IP 的数据包,或访问某些端口的数据包,在这些端口上我们并没有提供公开的服务。
一般情况下,上面的第一个选项用于 INPUT 链,因为我们希望对访问的资源进行权限控制。而第二个选项常用于 OUTPUT 链,因为我们通常信任离开机器的数据包(该数据包来自本机)。
设置默认策略的命令格式如下:
iptables [-t table] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
-P 选项用来定义默认策略(Policy)。注意,这是大写字母 P。ACCEPT 表示接受数据包,DROP 表示丢弃数据包。
一般情况下,我们会把 filter 表的 INPUT 链的默认策略制订的严格一些,比如设为 DROP。而 FORWARD 和 OUTPUT 可以宽松些,设为 ACCEPT。比如我们可以通过下面的命令把 filter 表的 INPUT 链的默认策略设置为 DROP:
$ sudo iptables -P INPUT DROP
5.添加规则
我们可以通过规则来匹配数据包,具体的匹配条件包括 IP、网段、网络接口(interface)和传输协议(tcp、udp 等)。
添加规则的命令格式如下:
iptables [-t tables] [-AI chain] [-io interface] [-p 协议] [-s 来源 IP] [-d 目标 IP] -j [ACCEPT,DROP,REJECT,LOG]
-t :后面接 table ,filter/nat/mangle ,若省略此项目,则使用默认的 filter
-A:针对某个规则链添加一条规则,新添加的规则排在现有规则的后面。
-I:针对某个规则链插入一条规则,可以为新插入的规则指定在链中的序号。如果不指定序号,则新的规则会变成第一条规则。
-i:指定数据包进入的那个网络接口,比如 eth0、lo 等,需要与 INPUT 链配合使用。
-o: 指定传出数据包的那个网络接口,需要与 OUTPUT 链配合使用。
-p: 指定此规则适用于那种网络协议(常用的协议有 tcp、udp、icmp,all 指适用于所有的协议)。
-s:指定数据包的来源 IP/网段,可以指定单个 IP,如 192.168.1.100,也可以指定一个网段,如 192.168.1.0/24。还可以通过 !表示非的意思,如 ! 192.168.1.0/24 表示除了 192.168.1.0/24 之外的数据包。
-d:指定数据包的目标 IP/网段,其它与 -s 选项相同。
--sport:限制来源的端口号,可以是单个端口,也可以是一个范围,如 1024:1050
--dport:限制目标的端口号。
-j:指定匹配成功后的行为,主要有 ACCEPT、DROP、REJECT 和 LOG。
下面我们来看几个例子。
放开本机接口 lo:
$ sudo iptables -A INPUT -i lo -j ACCEPT
只接受来自内网中某个网段的数据包:
$ sudo iptables -A INPUT -i eth2 -s 192.168.10.0/24 -j ACCEPT
接受/丢弃来自指定 IP 的数据包:
$ sudo iptables -A INPUT -i eth3 -s 192.168.100.5 -j ACCEPT
$ sudo iptables -A INPUT -i eth3 -s 192.168.100.6 -j DROP
利用 ! 进行排除,源ip不是172.16.1.0/24的都丢弃
$ sudo iptables -A INPUT ! -s 172.16.1.0/24 -j DROP
注意,因为只有 tcp 协议和 udp 协议使用了端口号,所以在使用 --sport 和 --dport 时,一定要指定协议的类型(-p tcp 或 -p udp)。
$ sudo iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
丢弃所有通过 tcp 协议访问本机 80,443 端口的数据包:
$ sudo iptables -A INPUT -m multiport -p tcp --dport 80,443 -j DROP
丢弃来自 192.168.1.0/24 的 1024:65535 端口的访问本机 ssh 端口的数据包:
$ sudo iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 --sport 1024:65535 --dport ssh -j DROP
禁止192.168.1.9/24 ping本机
$ sudo iptables -A INPUT -s 192.168.1.9/24 -p icmp -j DROP
查看 filter 表的规则:
$ sudo iptables -L -v
iptables-save 命令提供了另外一种风格的输出:
$ sudo iptables-save
6.自定义链
下面是一个抵御洪水攻击的案例:
1.在filter表中建一个名为tcp_packets的链:
iptables -N syn-flood
2.然后可以在自定义链中添加规则:
iptables -A syn-flood -m limit --limit 100/s --limit-burst 150 -j RETURN
iptables -A syn-flood -j DROP
3.然后再把它作为jump的目标,这样我们就会从INPUT链跳入syn-flood链:
#iptables -I INPUT -j syn-flood
7.常见的插件模块
7.1 state模块,匹配网络状态(TCP/IP连接状态)
iptables -A INPUT [-m state] [--state INVALID,ESTABLISHED,NEW,RELATED]
- NEW:已经或将启动新的连接
- ESTABLISHED:已建立的连接
- RELATED:正在启动的新连接
- INVALID:非法或无法识别的
只要是已建立连接或正在启动的新连接接受:
$ sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$ sudo iptables -A OUPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
7.2 limit模块,限制并发及速率
iptables -A INPUT --limit 3/minute --limit-burst 5
意思是开始时有5个通行证,用完之后,1分钟只生成3个令牌,即每20秒生成一个,
这期间没有剩余令牌的时候,到来的封包,无法匹配此条规则,就会继续往下匹配其他规则,
如果有令牌了,则新到的封包就会匹配此条规则
--limit 指定要隔多长时间才能签发一个新的通行证。
--limit-burst 指定刚开始时有多少通行证可用,不指定默认为5
iptables -F iptables -I INPUT -p icmp -m limit --limit 10/minute --limit-burst 5 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -P INPUT DROP
上面代码执行后,其他几台机器同时ping此台机器,刚开始的时候,几台机器加起来有5个ping有回应,后面就每隔6秒才有某一台的ping有回应
8.保存 iptables 的配置
注意,我们通过 iptables 命令设置的规则都保存在内存中,也就是说系统重启的话所有的配置都会丢失。
我们可以通过 iptables-save 命令把 iptables 的配置保存到文件中:
$ sudo iptables-save > /etc/sysconfig/iptables
在需要时再通过 iptables-restore 命令把文件中的配置信息导入:
$sudo iptables-restore < /etc/sysconfig/iptables
9.生产环境中iptables的设置
1.默认策略(policy)应该是DROP(应该先放行远程登录等一系列权限后,再设置默认策略,防止拒绝远程连接)
#清空默认规则(iptables -F命令会把所有规则情况,但是不会修改默认规则,如果默认规则当前是DROP,执行iptables -F会导致立马无法连接机器,因为所有数据包都被拒绝了) iptables -F #1.允许本机回环lo接口数据流量流出与流入 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT #2.允许ssh连接 iptables -A INPUT -p tcp --dport ssh -j ACCEPT #3.允许访问本机80,443端口 iptables -A INPUT -m multiport -p tcp --dport 80,443 -j ACCEPT #4.修改INPUT链默认的规则为拒绝 iptables -P INPUT DROP #5.内存里规则保存到默认的规则文件里 iptables-save > /etc/sysconfig/iptables
10.iptables 实现NAT功能
10.1 NAT实现内部服务器提供上网功能
iptables -t nat -A POSTROUTING -s 172.16.1.7 -j SNAT --to-source 10.0.0.61
1. 指定nat表,配置POSTROUTING链
2. 源ip是172.16.1.7这台主机进行共享上网,如果是多台(-s 172.16.1.0/24)
3. 指定使用SNAT功能,源地址转换.
4. 通过SNAT功能把数据包中的源ip地址改为防火墙公网的ip地址.(10.0.0.61)
5.如果公网ip不固定, -j SNAT --to-source 10.0.0.61 可以写为 -j MASQUERADE 伪装成公网ip.
环境介绍: 172.16.1.7 想要上网的机器,有2个网卡,eth0为外围,eth1为内网 172.16.1.61 实现NAT功能的防火墙机器,eth0为外围,eth1为内网 |
172.16.1.7 操作步骤 1.把机器上能上网的网卡关闭 sed -i 's/ONBOOT=yes/ONBOOT=no/' /etc/sysconfig/network-scripts/ifcfg-eth0 2.把不能上网的这张网卡配一个网关地址,地址为实现NAT的防火墙机器IP vim eth1 GATEWAY=172.16.1.61 3.重启network systemctl restart network |
172.16.1.61操作步骤 1.由于是要把数据从eth1网卡转发到eth1,所以要开启ip_forward功能(内核转发功能) echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf sysctl -p 2.防火墙转发规则配置 iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE |
测试: 172.16.1.7 上ping 8.8.8.8看能不能通 |
10.2 NAT实现外部访问相应的端口转发到内部特定的端口(端口映射)
iptables -t nat -A PREROUTING -p tcp --dport 6666 -j DNAT --to-destination 172.16.1.7:80
只要访问本机的6666端口,就会把请求转发到 172.16.1.7:80端口