Iptables使用
通过iptables
防火墙,用户可对与Linux
系统进行交互的IP
数据包执行高度的控制,而且这一控制是在Linux
内核中实现。iptables
策略是由一组有序的规则建立,它告诉内核应如何处理某些类别的数据包。iptables
规则应用于一个表中的一个链,一个iptables
链是一个规则集,这些规则按顺序与包含共同特征的数据包进行比较。
iptables
基础介绍
表
表是iptables
构建块,描述了其功能的大类,如包过滤或者网络地址转换(NAT)。iptables
中共有四个表:filter
、nat
、mangle
和raw
,过滤规则应用于filter
表,NAT规则应用于nat
表。
链
每个表都有自己的一组内置链,对我们来说,最重要的内置链是filter
表中的INPUT
、OUTPUT
和FORWARD
链:
INPUT
:当流入的数据包指向本地主机时,将经过INPUT
链的检查。OUTPUT
:OUTPUT
链用于本地主机自身生成的数据包。FORWARD
:FORWARD
链管理经过Linux
系统路由的数据包。
另外两个很重要的链是nat
表中的PREROUTING
和POSTROUTING
链,分别用于IP
路由之前和之后修改数据包的头部。
下图展示了数据包是如何通过nat
和filter
表的不同链:
由图可知,为了实现对Linux
服务器的访问进行控制,主要就是针对filter
表的INPUT
链进行配置管理。
规则匹配
每个iptables
规则都包含一组匹配以及一个目标,后者告诉iptables
对于符合规则的数据包应该采取什么动作。常见的匹配规则如下:
- --source (-s) :匹配源
IP
地址或者网络 - --destination (-d):匹配目标
IP
地址或者网络 - --destination port (-dport): 匹配目标地址的端口号
- --protocol (-p):匹配协议
- --in-interface (-i):流入接口(例如:
eth0
) - --out-interface (-o):流出接口
- --state:匹配一组连接状态
- --string:匹配应用层数据字节序列
目标
最后,iptables
支持一组目标,用于在数据包匹配一个规则时触发一个动作。
- ACCEPT:允许数据包通过
- DROP:丢弃数据包
- LOG:将数据包信息记录到
syslog
- REJECT:丢弃数据包,同时发送适当的响应报文
- RETURN:在调用链中继续处理数据包
在CentOS7中使用
CentOS7
中默认使用的防火墙是firewalld
,为了使用iptables
,需要先禁用firewalld
。
禁用firewalld
首先停止firewalld
服务:
$ sudo systemctl stop firewalld
然后禁止firewalld
服务开机自启动:
$ sudo systemctl disable firewalld
为了防止firewalld
服务被其他服务再次启动:
$ sudo systemctl mask --now firewalld
安装iptables
先检查是否已经安装了iptables
:
$ sudo systemctl status iptables
确认没有安装后通过包管理器进行安装:
$ sudo yum install iptables-services
安装成功后启动服务:
$ sudo systemctl start iptables
设置开机自启动:
$ sudo systemctl enable iptables
查看服务运行状态:
$ sudo systemctl status iptables
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
Active: active (exited) since Thu 2019-12-19 13:31:35 CST; 1min 30s ago
Main PID: 2966 (code=exited, status=0/SUCCESS)
出现以上信息,则表明服务运行正常。接下来可查看当前的iptables
默认规则:
$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
113 6860 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 66 packets, 6232 bytes)
pkts bytes target prot opt in out source destination
定义过滤规则
定义规则的命令格式如下:
$ sudo iptables -t <table> -A <chain> -i <interface> -p <protocol (tcp/udp) > -s <source> --dport <port no.> -j <target>
参数说明可参考上文中的操作选项归纳说明
,这里的-t
指定需定义规则的表,默认为filter
。
开启HTTP(端口80)
、SSH(端口22)
和SSL(443)
三个服务
$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
规则添加后查看如下:
$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
69 4580 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
结果表明,所有访问80
、22
和443
端口的TCP
请求都被允许。
根据源IP
地址限制访问
例如允许IP
为192.168.1.3
访问本机:
$ sudo iptables -A INPUT -s 192.168.1.3 -j ACCEPT
也可以通过DROP
目标限制某一IP
地址访问:
$ sudo iptables -A INPUT -s 192.168.1.3 -j DROP
如果需要限制源地址为IP段
,可通过掩码设定:
$ sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
丢弃所有其他访问请求
定义好允许访问的规则之后,通常需要将其他未授权的访问请求都禁止掉,以达到访问控制的目的:
$ sudo iptables -A INPUT -j DROP
也可以通过定义整个INPUT
链的策略来限制未授权的访问:
$ sudo iptables -P INPUT DROP
如果是远程修改
iptables
规则,在限制全局访问时,一定要先开启远程连接的端口,比如SSH(端口22)
,否则容易造成远程连接中断。
删除规则
如果要删除所有规则,可使用-F
选项(flush):
$ sudo iptables -F
如果需要删除其中某一条规则,首先要查看所有规则的编号:
$ sudo iptables -nvL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 306 18777 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
2 8 563 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
3 9 611 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
4 45 2532 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
在每条规则的开头就是编号,比如删除编号为3
的规则:
$ sudo iptables -D INPUT 3
规则保存
之前对iptables
规则的操作都是保存在内存中,如果系统重启,所有的操作都会丢失,因此在修改规则完成后,需要对其进行保存。
$ sudo service iptables save
典型设置脚本示例
#!/bin/sh
# 先允许所有
iptables -P INPUT ACCEPT
#清空所有默认规则
iptables -F
#清空所有自定义规则
iptables -X
#所有计数器归0
iptables -Z
#允许来自于lo接口的数据包(本地访问)
iptables -A INPUT -i lo -j ACCEPT
#开放22端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#开放21端口(FTP)
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
#开放80端口(HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
#开放443端口(HTTPS)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
#允许ping
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
#其他入站一律丢弃
iptables -P INPUT DROP
#所有出站一律绿灯
iptables -P OUTPUT ACCEPT
#所有转发一律丢弃
iptables -P FORWARD DROP
#保存上述规则
service iptables save
#重启服务
systemctl restart iptables
iptables
操作选项归纳说明
查看选项
简写 | 选项 | 说明 |
---|---|---|
-L | --list chain rulenum | 列出所有链及规则,默认表为filter |
-n | --numeric | IP 地址和端口显示为数字 |
-v | --verbose | 显示详细信息 |
--line-numbers | 显示规则编号 |
链操作选项
简写 | 选项 | 说明 |
---|---|---|
-A | --append chain rule | 向链添加规则 |
-D | --delete chain rulenum | 通过编号删除规则 |
-I | --insert chain rulenum | 插入规则,默认编号为1 |
-R | --replace chain rulenum | 替换规则,默认编号为1 |
-F | --flush chain | 删除指定链所有规则,如未指定,则删除所有链规则 |
-P | --policy chain target | 修改链政策 |
规则选项
简写 | 选项 | 说明 |
---|---|---|
-p | --proto proto | 协议。{tcp, udp, udplite, icmp, esp, ah, sctp}等 |
-s | --source address/mask | 源IP地址 |
-d | --destination address/mask | 目的IP地址 |
目标选项
简写 | 选项 | 说明 |
---|---|---|
-j | --jump target | 调整到目标 |
通用选项
简写 | 选项 | 说明 |
---|---|---|
-t | --table table | 指定表,默认为filter |
-V | --version | 查看版本 |
补充
CentOS 7配置完后发现无法使用YUM包管理器,需添加如下规则:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
如下:
Chain INPUT (policy DROP 58 packets, 6674 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
1309 109K ACCEPT tcp -- * * 10.42.6.0/24 0.0.0.0/0 tcp dpt:22
167 17907 ACCEPT tcp -- * * 10.0.0.0/8 0.0.0.0/0 tcp dpt:80
15809 27M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED