linux 防火墙管理程序 iptables

2018-08-06 15:22:23

iptables 命令可以过滤外部进来的网络包,可以拒绝,同意或者重定向包。也可以对网络包进行串改,功能非常强大,我们先来看下结构图。

所有的包都会按照这个顺序过滤下来,一般我们只需要关注3个表,filter(默认),nat,mangle。

filter 表命令

-N | --new-chain <chain>  #创建自定义规则连
-F | --flush [<chain>]    #清空当前表规则链中的所有规则,如果没指定,则清空当前表所有链的规则。
-X | --delete-chain [<chain>] #删除当前表自定义链,没有指定则删除当前表所有自定义链

-P | --policy <chain><policy>
#为内建规则链INPUT、OUTPUT、FORWARD设置默认策略比如 ACCEPT、DROP

-L | --list [<chain>]
#列出此规则链中的规则,如果为指定,则列出所有

-Z | --zero    #重置数据包和和字节计数器

-E | rename-chain <old> <new>  #重命名自定义链

-h   #帮助
iptables -j LOG -h

--modprobe=<command>   #加载必要的模块

列出规则链选项

-L -n | --numeric   #以数字形式列出ip地址和端口
-L -v | --verbose   #列出每条规则的额外信息
-L -x | --exact     #列出计数器的精确值,而不是四舍五入的估值
-L --line-numbers   #列出规则在规则链中的位置

对规则的操作

-A | --append <chain>    #将一条规则附加到一个规则链末尾

-I | --insert <chain> [<rule number>]
#插入规则,没指定规则号默认为最前面

-R | --replace <chain><rule number>
#替换规则

-D | --delete <chain><rule number> | <rule specification>
#根据规则号或者匹配删除规则

-C | --check <chain><rule specification>
#检测规则链中是否有匹配的规则

filter 表基本匹配

-i | --in-interface [!][<interface>]
#在INPUT、FORWARD或用户自定义链,对传入数据包指定接口名
#如果未指定,则应用于所有接口

-o | --out-interface [!][<interface>]
#在INPUT、FORWARD或用户自定义链,对传出数据包指定接口名
#如果未指定,则应用于所有接口

-p | --protocol[!][<interface>]
#指定规则的协议,可以是名称或者是数值,在 /etc/protocols 有列出。

-s | --source | --src [!]<address>[</mask>]
#指定ip报头中的主机或者网络源地址

-d | --destination | --dst [!]<address>[</mask>]
#指定ip报头中的主机或者网络目的地址

-j | --jump <target>
#如果数据报匹配规则,则设置此数据报的处置策略。包括
#内建策略、扩展策略、或者用户自定义链

-g | --goto <chain>
#跳转到指定的链处理,不必返回。

-m | --match <match>  #使用扩展来测试是否匹配

-c | --set-counters <packets><bytes>
#初始化数据包和字节计数器
如果匹配的规则没有目标处置,数据报计数器会更新,但规则链遍历会继续。

tcp filter匹配

-p tcp

--source-port | --sport [[!] <port>[:<port>]]
#源端口

--destination-port | --dport [[!] <port>[:<port>]]
#目标端口

--tcp-flags  SYN,!ACK, FIN, RST, URG, PSH, ALL, NONE

udp filter匹配

-p udp

--source-port | --sport [[!] <port>[:<port>]]
#源端口

--destination-port | --dport [[!] <port>[:<port>]]
#目标端口

icmp filter匹配

-p icmp

--icmp-type [!]<type>
#指定 icmp 类型名或类型号

0  echo-reply
3  网络无法到达
4  源断开
5  重定向
8  echo-request
10 超时
11 参数问题


LOG 表目标扩展

-j LOG

--log-level <syslog level>
#日志级别
#alert(1)、crit(2)、err(3)、warn(4)、notice(5)、info(6)、debug(7)

--log-prefix <string>   #日志前缀
-j REJECT

--reject-with <ICMP type 3>
#默认,拒绝后返回 icmp 类型为3

--reject-with tcp-reset
#tcp数据报可以采用tcp的rst消息来拒绝

ULOG 表目标扩展

与 LOG 目标相关的是 ULOG 目标,在幕后,数据包会被内核通过您选择的 netlink 套接字(默认为 socket 1)组播。用户空间的程序将从套接字读取消息并做响应的处理,提供了相比标准的 LOG 目标更具扩展性的日志记录功能。

-j ULOG

--ulog-nlgroup <group>
#定义接受数据包的 netlink 组,默认为1

--ulog-prefix <prefix>
#作为消息的前缀,最大长度 32

--ulog-cprange <size>
#发送给 netlink 套接字的字节数。默认为0,即整个数据包

--ulog-qthreshold <size>
#内核队列数据包的数目,默认为1,意味着队列中每到一个数据报
#就发送一个消息到 netlink 套接字


multiport filter 表匹配扩展

每个列表最多只能包含 15 个端口。端口不能为空白,逗号和端口号之间不能有空格。列表中不能使用端口范围。而且 -m multiport 命令必须紧跟在 -p <protocol> 后。

-m multiport

--source-port <port>[,<port>]   #源端口

--destination-port <port>[,<port>]
#目的端口

--port<port>[,<port>]
#同时匹配源端口、目的端口
iptables -A OUTPUT -o eth0 -p tcp -m multiport --destination-port 22,33,44 --syn -j REJECT

limit filter 表匹配扩展

主要是用来限制数据包频率,有了它可以避免日志数量记录泛洪。

--limit <rate>
#指定单位时间内通过的次数,默认为 3/hour,可选单位为
#/sec /minute /hour /day

--limit-burst <n>
#根据上面的单位,设置峰值,默认为5
iptables -A INPUT -p icmp -m limit --limit 10/m --limit-burst 3 -j ACCEPT
iptables -P INPUT DROP

上面的意思是,当在一分钟内到达3个 icmp 包,那么则触发限制,每分钟最多允许10个包通过。

当我们 ping 这台主机时,前3个正常,当到第四个时,每6s通过一个。

iptables -A INPUT -i eth0 -p icmp -m limit --limit 1/second -j LOG

1秒内接受到5个 icmp,则触发限速,接下来每秒只记录一次日志。

state filter 表匹配扩展

维护一个状态表可以绕过防火墙的检查路径。如果 tcp 数据包被识别为已允许的、正在进行连接的一部分,那么剩下的防火墙过滤器可以直接跳过。

缺点是当连接数很多时会消耗很多内存来记录,而且表的创建、查询、删除都会花费时间。

状态维护对于正在进行的如 ftp 传输或 udp 多媒体会话流来说是有益的。但是对于简单的 dns 或 ntp 客户端/服务器交换来说状态维护并不是防火墙的性能收益。对于数据包来说,状态的建立和销毁相对于简单的过滤器规则遍历,很容易需要大量的运算和内存。

-m state

--state <state>[,<state>]
#相关值为NEW、ESTABLISHED、RELATED、INVALID

NEW  初始 tcp syn 或者第一个 udp 数据包。
ESTABLISHED  指的是连接初始化后进行中的 tcp ack 消息,以及接下来发生在同一主机和端口间的 udp 数据包交换,以及对之前 echo 请求回应的 icmp echo 响应消息。
RELATED  目前指的仅仅是 icmp 错误消息。ftp 的二级连接由额外的 ftp 连接追踪支持模块进行管理。通过此模块,RELATED 的意义被扩展包括 FTP 的二级连接。
INVALID  数据包的例子是:一个并不响应当前会话的传入的 icmp 错误消息,或并不回应之前 echo 请求的 echo 响应。

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

允许传出的 NEW 请求,传入的(ESTABLISHED)响应和任何(RELATED) icmp 错误消息。


nat 表目标扩展

nat 即网络地址和端口转换,iptables 支持常见的四种nat。SNAT(源)、DNAT(目标)、MASQUERADE(伪装)、REDIRECT(端口重定向)。

SNAT

#echo 1 > /proc/sys/net/ipv4/ip_forward 开启不同接口间的包转发

#出包的时候把发送原地址改成192.168.1.242,充当路由器
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 192.168.1.242

#把tcp包的源地址随机改成194.236.50.155-194.236.50.160一个,端口取1024-32000一个
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000

MASQUERADE

#用来补充SNAT当服务器地址是动态,它会自动SNAT当前服务器地址,
#--to-ports指定出包时候开的端口范围(范围一定要够大,要不然会很慢)
iptables -t nat -A POSTROUTING  -s 192.168.1.0/24 -j MASQUERADE --to-ports 1024-31000

DNAT

#把去向15.45.23.67:80的包改成去向192.168.1.1-192.168.1.10中的随机一个
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT \
         --to-destination 192.168.1.1-192.168.1.10

iptables -t nat -A PREROUTING -p tcp --dport 80  -j DNAT --to-destination 192.168.1.245

REDIRECT

iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80-81

把发到 8080端口的数据包转到 80 或者 81 端口。


mangle 表命令

-t mangle

-j MARK --set-mark <value>
#为数据包设置 netfilter 标记值

-j TOS --set-tos <value>
#设置 ip 报头中的 TOS 值
iptables -t mangle -A PREROUTING -p tcp -j MARK --set-mark 0x00010070
iptables -t mangle -A OUTPUT -p tcp -j TOS --set-tos <tos>


简单的配置实例

#配置默认策略
iptables -P INPUT DROP/ACCEPT

iptables -t nat -F POSTROUTING				#清空nat下的POSTROUTING链下规则
iptables -t nat -F							#清空nat下的所有规则

iptables -t nat -Z							#nat下包数,字节数归零

iptables -t nat -N new-chain					#nat下新增new-chain链
iptables -t nat -X new-chain					#nat下删除new-chain链(new-chain链必须为空)
iptables -t nat -E new-chain new-chain-1	#nat下重命名链

[-j DROP,REJECT,ACCEPT]
iptables -t filter -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
#替换1号规则
iptables -t filter -R INPUT 1 -s 192.168.1.0/24 -p udp --dport 22 -j ACCEPT

iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j DROP


#允许自己ping别人,不允许别人ping自己
iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT	

#-m state RELATED,ESTABLISHED,INVALID,NEW
iptables -A INPUT -m state --state ESTABLISHED, NEW --dport 22 -j ACCEPT

#本地端口转发
[-j REDIRECT]
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080-8090

#自定义链返回
[-j RETURN]
iptables -t nat -A new-chain -s 192.168.1.0/24 -j RETURN

#路由转发
[-j SNAT]
#出包的时候把发送原地址改成192.168.1.242
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 192.168.1.242
#把tcp包的源地址随机改成194.236.50.155-194.236.50.160一个,端口取1024-32000一个
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000

#用来补充SNAT当服务器地址是动态,它会自动SNAT当前服务器地址,--to-ports指定出包时候开的端口范围(范围一定要够大,要不然会很慢)
[-j MASQUERADE]
iptables -t nat -A POSTROUTING  -s 192.168.1.0/24 -j MASQUERADE --to-ports 1024-31000

[-j DNAT]
#把去向15.45.23.67:80的包改成去向192.168.1.1-192.168.1.10中的随机一个
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10
#例子
iptables -t nat -A PREROUTING -p tcp --dport 80  -j DNAT --to-destination 192.168.1.245
iptables -t nat -A POSTROUTING -d 192.168.1.245 -j SNAT --to 192.168.1.242


[-j LOG]
#日志记录到/var/log/message以--log-prefix开头
#很多tcp连接很慢有可能是dns返回的包被阻止了
iptables -I INPUT -s 192.168.1.0/24 -j LOG --log-prefix "ddddddd-"

#如果本地INPUT默认为DROP一定要加
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


备注:
1.本系列命令都在centos7里测试,其他发行版如ubuntu、debian、fedora、opensuse等可能略微不同
2.本文只讲解常用用法,详细用法请自行利用 man 命令查看
3.原文地址http://www.freecls.com/a/2712/fb

 

©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。