# iptables - Linux上常用的防火墙软件

iptables命令 是Linux上常用的防火墙软件,是netfilter项目的一部分。可以直接配置,也可以通过许多前端和图形界面配置。

iptables指令用来设置Linux内核的ip过滤规则以及管理nat功能。iptables用于在Linux内核中设置、维护和检查IPv4数据包过滤规则表。可以定义几个不同的表。每个表包含许多内置链,也可能包含用户定义的链。每个链都是一个规则列表,可以匹配一组数据包。每条规则都指定如何处理匹配的数据包。这被称为“目标”,它可能是跳转到同一表中的用户定义链。

# 适用范围

RedHat
RHEL
Ubuntu
CentOS
Debian
Deepin
SUSE
openSUSE
Fedora
Linux Mint
Alpine Linux
Arch Linux

# 语法

iptables  [-t table]  {-A|-D}  chain  rule-specification
iptables  [-t table]  -I  chain  [rulenum]  rule-specification
iptables  [-t table]  -R  chain  rulenum  rule-specification
iptables  [-t table]  -D  chain  rulenum
iptables  [-t table]  -S  [chain [rulenum]]
iptables  [-t table]  {-F|-L|-Z}  [chain [rulenum]]  [options...]
iptables  [-t table]  -N  chain
iptables  [-t table]  -X  [chain]
iptables  [-t table]  -P  chain  target
iptables  [-t table]  -E  old-chain-name  new-chain-name  rule-specification = [matches...] [target]
match = -m matchname [per-match-options]  target = -j targetname [per-target-options]

目前Linux内核支持3个相互独立的表:filter,过滤ip数据包;nat,配置nat功能;mangle,修改ip数据包。

filter是默认表,包含INPUT(发送给本机) 、OUTPUT(本机向外发送)、FORWARD(被路由出去)三个链。

nat表包含PREROUTING(修改刚收到的数据包) 、OUTPUT(在路由之前处理本机产生的数据包) 、POSTROUTING(修改将要发送的数据包)三个链。

mangle表包含PREROUTING(路由之前,修改收到的包) 、OUTPUT(路由之前,修改本机产生的包) 、INPUT(修改发送到本机的包) 、FORWARD (修改路由之后的包) 、POSTROUTING(修改将被本机发送的包)五个链。

Linux系统中的内置目标包括:ACCEPT(允许数据包通过) DROP(丢弃数据包) QUEUE(传递包到用户空间) RETURN(停止向后检测其他的规则,返回之前的条用规则处)

# 选项

# 基本参数

-P	             # 设置默认策略:iptables -P INPUT (DROP
-F	             # 清空规则链
-L	             # 查看规则链
-A	             # 在规则链的末尾加入新规则
-I	             # num 在规则链的头部加入新规则
-D	             # num 删除某一条规则
-s	             # 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。
-d	             # 匹配目标地址
-i	             # 网卡名称 匹配从这块网卡流入的数据
-o	             # 网卡名称 匹配从这块网卡流出的数据
-p	             # 匹配协议,如tcp,udp,icmp
--dport num	     # 匹配目标端口号
--sport num	     # 匹配来源端口号

# 命令

-t table                                         # 指定要管理的表
-A, --append chain rule-specification            # 追加记录
-D, --delete chain rule-specification            # 删除记录
-I, --insert chain [rulenum] rule-specification  # 插入记录
-R, --replace chain [rulenum] rule-specification # 替换记录
-L, --list [chain]                               # 列出记录
-S, --list-rules [chain]                         # 列出已选择链的所有规则。如果没有选择任何链,则所有链都打印
-F, --flush [chain]                              # 删除指定的记录
-Z, --zero [chain [rulenum]]                     # 将数据计数和字节计数清零
-N, --new-chain chain                            # 用户自定义新链
-X, --delete-chain [chain]                       # 删除用户自定义链
-P, --policy chain target                        # 为指定的链设置策略
-E, --rename-chain old new                       # 重命名链
-h                                               # 显示帮助信息

# 参数

[!] –p, --protocol protocol               # 指定协议类型tcp、udp、icmp、all,协议前加!标识否定
[!] –s, --source address[/mask][,…        # 源地址
[!] –d, --destination address[/mask][,…   # 目标
-j, --jump                                # 指定跳转的目标
-g, --goto chain                          # 这指定应在用户指定的链中继续处理。与“--jump”选项不同,返回将不再在此链中继续处理,而是在通过“--jump”调用我们的链中继续处理。
[!] –i, --in-interface name               # 接收数据包的接口名称(仅用于输入、转发和PREROUTING链的数据包)。当“!”参数在接口名称之前使用,意义被倒置。如果接口名以“+”结尾,则以此名称开头的任何接口都将匹配。如果省略此选项,则任何接口名称都将匹配。
-o, --out-interface name                  # 指定数据包离开的网络接口
[!] –f, --fragment                        # 这意味着该规则仅指分段数据包的第二段和更多的片段。
-c, --set-counters packets bytes          # 这使管理员能够初始化规则的数据包和字节计数器(在插入、追加、替换操作期间)。

# 其他选项

-v, --verbose                             # 冗长的输出,该选项使List命令显示接口名称、规则选项(如果有的话)和TOS掩码。还列出了数据包计数器和字节计数器
-n, --numeric                             # 数字输出IP地址和端口号将以数字格式打印。默认情况下,程序将尝试将它们显示为主机名、网络名称或服务(只要适用)。
-x, --exact                               # 扩大数字。显示数据包和字节计数器的确切值,而不是只显示K‘s(1000倍)M’s(1000 K倍数)或G‘s(1000 m倍数)中的四舍五入数。此选项仅与-L命令相关。
--line-numbers                            # 当列出规则时,将行号添加到每条规则的开头,对应于该规则在链中的位置。
--modprobe=command                        # 在向链中添加或插入规则时,使用命令加载任何必要的模块(目标、匹配扩展等)

# 举例

# 清空当前的所有规则和计数

iptables -F  # 清空所有的防火墙规则
iptables -X  # 删除用户自定义的空链
iptables -Z  # 清空计数

# 配置允许ssh端口连接

iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
# 22为你的ssh端口, -s 192.168.1.0/24表示允许这个网段的机器来连接,其它网段的ip地址是登陆不了你的机器的。 -j ACCEPT表示接受这样的请求

# 允许本地回环地址可以正常使用

iptables -A INPUT -i lo -j ACCEPT
#本地圆环地址就是那个127.0.0.1,是本机上使用的,它进与出都设置为允许
iptables -A OUTPUT -o lo -j ACCEPT

# 设置默认的规则

iptables -P INPUT DROP # 配置默认的不让进
iptables -P FORWARD DROP # 默认的不允许转发
iptables -P OUTPUT ACCEPT # 默认的可以出去

# 配置白名单

iptables -A INPUT -p all -s 192.168.1.0/24 -j ACCEPT  # 允许机房内网机器可以访问
iptables -A INPUT -p all -s 192.168.140.0/24 -j ACCEPT  # 允许机房内网机器可以访问
iptables -A INPUT -p tcp -s 183.121.3.7 --dport 3380 -j ACCEPT # 允许183.121.3.7访问本机的3380端口

# 开启相应的服务端口

iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 开启80端口,因为web对外都是这个端口
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # 允许被ping
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 已经建立的连接得让它进来

# 保存规则到配置文件中

cp /etc/sysconfig/iptables /etc/sysconfig/iptables.bak # 任何改动之前先备份,请保持这一优秀的习惯
iptables-save > /etc/sysconfig/iptables
cat /etc/sysconfig/iptables

# 列出已设置的规则

iptables -L [-t 表名] [链名]

  • 四个表名 rawnatfiltermangle
  • 五个规则链名 INPUTOUTPUTFORWARDPREROUTINGPOSTROUTING
  • filter表包含INPUTOUTPUTFORWARD三个规则链
iptables -L -t nat                  # 列出 nat 上面的所有规则
#            ^ -t 参数指定,必须是 raw, nat,filter,mangle 中的一个
iptables -L -t nat  --line-numbers  # 规则带编号
iptables -L INPUT

iptables -L -nv  # 查看,这个列表看起来更详细

# 清除已有规则

iptables -F INPUT  # 清空指定链 INPUT 上面的所有规则
iptables -X INPUT  # 删除指定的链,这个链必须没有被其它任何规则引用,而且这条上必须没有任何规则。
                   # 如果没有指定链名,则会删除该表中所有非内置的链。
iptables -Z INPUT  # 把指定链,或者表中的所有链上的所有计数器清零。

# 删除已添加的规则

# 添加一条规则
iptables -A INPUT -s 192.168.1.5 -j DROP

将所有iptables以序号标记显示,执行:

iptables -L -n --line-numbers

比如要删除INPUT里序号为8的规则,执行:

iptables -D INPUT 8

# 开放指定的端口

iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT               #允许本地回环接口(即运行本机访问本机)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    #允许已建立的或相关连的通行
iptables -A OUTPUT -j ACCEPT         #允许所有本机向外的访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT    #允许访问22端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT    #允许访问80端口
iptables -A INPUT -p tcp --dport 21 -j ACCEPT    #允许ftp服务的21端口
iptables -A INPUT -p tcp --dport 20 -j ACCEPT    #允许FTP服务的20端口
iptables -A INPUT -j reject       #禁止其他未允许的规则访问
iptables -A FORWARD -j REJECT     #禁止其他未允许的规则访问

# 屏蔽IP

iptables -A INPUT -p tcp -m tcp -s 192.168.0.8 -j DROP  # 屏蔽恶意主机(比如,192.168.0.8
iptables -I INPUT -s 123.45.6.7 -j DROP       #屏蔽单个IP的命令
iptables -I INPUT -s 123.0.0.0/8 -j DROP      #封整个段即从123.0.0.1到123.255.255.254的命令
iptables -I INPUT -s 124.45.0.0/16 -j DROP    #封IP段即从123.45.0.1到123.45.255.254的命令
iptables -I INPUT -s 123.45.6.0/24 -j DROP    #封IP段即从123.45.6.1到123.45.6.254的命令是

# 指定数据包出去的网络接口

只对 OUTPUT,FORWARD,POSTROUTING 三个链起作用。

iptables -A FORWARD -o eth0

# 查看已添加的规则

iptables -L -n -v
Chain INPUT (policy DROP 48106 packets, 2690K bytes)
 pkts bytes target     prot opt in     out     source               destination
 5075  589K ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
 191K   90M ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:22
1499K  133M ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80
4364K 6351M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
 6256  327K ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 3382K packets, 1819M bytes)
 pkts bytes target     prot opt in     out     source               destination
 5075  589K ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0

# 启动网络转发规则

公网210.14.67.7让内网192.168.188.0/24上网

iptables -t nat -A POSTROUTING -s 192.168.188.0/24 -j SNAT --to-source 210.14.67.127

# 端口映射

本机的 2222 端口映射到内网 虚拟机的22 端口

iptables -t nat -A PREROUTING -d 210.14.67.127 -p tcp --dport 2222  -j DNAT --to-dest 192.168.188.115:22

# 字符串匹配

比如,我们要过滤所有TCP连接中的字符串test,一旦出现它我们就终止这个连接,我们可以这么做:

iptables -A INPUT -p tcp -m string --algo kmp --string "test" -j REJECT --reject-with tcp-reset
iptables -L

# Chain INPUT (policy ACCEPT)
# target     prot opt source               destination
# REJECT     tcp  --  anywhere             anywhere            STRING match "test" ALGO name kmp TO 65535 reject-with tcp-reset
#
# Chain FORWARD (policy ACCEPT)
# target     prot opt source               destination
#
# Chain OUTPUT (policy ACCEPT)
# target     prot opt source               destination

# 阻止Windows蠕虫的攻击

iptables -I INPUT -j DROP -p tcp -s 0.0.0.0/0 -m string --algo kmp --string "cmd.exe"

# 防止SYN洪水攻击

iptables -A INPUT -p tcp --syn -m limit --limit 5/second -j ACCEPT

# 添加SECMARK记录

iptables -t mangle -A INPUT -p tcp --src 192.168.1.2 --dport 443 -j SECMARK --selctx system_u:object_r:myauth_packet_t
# 向从 192.168.1.2:443 以TCP方式发出到本机的包添加MAC安全上下文 system_u:object_r:myauth_packet_t

显示filter表的记录

[root@localhost ~]$ iptables -t filter –L    #显示指定表的记录
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere                  
…
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere           
…
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

禁止端口135的tcp数据包

[root@localhost ~]$ iptables -t filter -A INPUT -p tcp --dport 135 -j DROP  #添加记录,忽略135端口的tcp数据包 

[root@localhost ~]$ iptables –L      #查看表,已经加入规则
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
DROP       tcp  --  anywhere             anywhere            tcp dpt:epmap

禁止目标地址访问本机

[root@localhost ~]$ iptables -A INPUT -s 192.168.1.110 -j DROP   #禁止110地址访问本机
[root@localhost ~]$ iptables -L |grep DROP                       #查看filter表,已经添加记录
DROP       tcp  --  anywhere             anywhere            tcp dpt:epmap
DROP       all  --  192.168.1.110        anywhere