防火墙:硬件、软件:一套安全规则

Linux防火墙:netfilter-FrameWork

hook function:钩子函数
	prerouting
	input
	output
	forward
	postrouting

	规则链:
	PREROUTING
	INPUT
	OUTPUT
	FORWARD
	POSTROUTING

filter(过滤)表:
	INPUT
	OUTPUT
	FORWARD

nat(地址转换)表:
	PREROUTING
	OUTPUT
	POSTROUTING

mangle(拆开、修改、再封装报文首部)表:
	修改TTL
	打上标记
	改服务类型
	PREROUTING
	INPUT
	FORWARD
	OUTPUT
	POSTROUTING

raw(原始格式):
	PREROUTING
	OUTPUT

iptables

能否使用自定义链?
	可以使用自定链,但只在被调用时才能发挥作用,而且如果没有自定义链中的任何规则匹配,还应该有返回机制;

	用可以删除自定义的空链
	默认链无法删除

每个规则都有两个内置的计数器:
	被匹配的报文个数
	被匹配的报文大小之和

匹配标准:
	通用匹配
		-s, --src: 指定源地址
		-d, --dst:指定目标地址
		-p {tcp|udp|icmp}:指定协议
		-i INTERFACE: 指定数据报文流入的接口
			可用于定义标准的链:PREROUTING,INPUT,FORWARD
		-o INTERFACE: 指定数据报文流出的接口
			可用于标准定义的链:OUTPUT,POSTROUTING,FORWARD
	扩展匹配
		隐含扩展:不用特别指明由哪个模块进行的扩展,因为此时使用
				-p tcp
						--sport  PORT[-PORT]:源端口,或者连续端口范围
						--dport  PORT[-PORT]:目标端口
						--tcp-flags mask comp: 只检查mask指定的标志位,是逗号分隔的标志位列表;comp:此列表中出现的标记位必须为1,comp中没出现,而mask中出现的,必须为0;
						--tcp-flags SYN,FIN,ACK,RST SYN = --syn
				--syn   专门匹配TCP三次握手的第一次


			-p icmp
				--icmp-type
					0: echo-reply
					8: echo-request

			-p udp
				--sport
				--dport

		显式扩展:必须指明由哪个模块进行的扩展,在iptables项可完成此功能
					-m EXTENDSION_NAME --specific-opt

			state: 状态扩展
				结合ip_conntrack追踪会话的状态
					NEW: 新连接请求
					ESTABLISHED:已建立的连接
					INVALID:非法连接
					RELATED:相关联的,为FTP被动模式设计的
				-m state --state NEW,ESTABLISHED -j ACCEPT

				首先要装载ip_conntrack_ftp和ip_nat_ftp模块

				iptables -A INPUT -d 172.16.100.7 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

			multiport: 离散的多端口匹配扩展
				--source-ports
				--destination-ports
				--ports

			-m multiport --destination-ports 21,22,80 -j ACCEPT

						-m state --state
				ip_conntrack: 连接追踪
					udp, tcp, icmp
						/proc/net/ip_conntrack
						/proc/sys/net/ipv4/ip_conntrack_max
						/proc/sys/net/ipv4/netfilter/
				NEW, ESTABLISHED, RELATED, INVALID

			-m multiport : 使用离散端口
				--source-ports
				--destination-ports
				--ports

			-m iprange
				--src-range
				--dst-range

				普通:
				-s, -d
				-s IP, NET
					172.16.0.0/16, 172.16.100.3-172.16.100.100

				拓展:
				iptables -A INPUT -p tcp -m iprange --src-range 172.16.100.3-172.16.100.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

				iptables -A INPUT -p tcp -m iprange ! --src-range 172.16.100.3-172.16.100.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

			-m connlimit: 连接数限制
				! --connlimit-above num 连接数目小于num个
				  --connlimit-above num 连接数目大于等于num个

					iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m connlimit !--connlimit-above 2 -j ACCEPT
					//低于两个就允许
					iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m connlimit !--connlimit-above 2 -j ACCEPT
					//

			-m limit
				--limit RATE
				--limit-burst 7  :慢慢放行,最多7个数据报文

				iptables -I INPUT -d 172.16.100.7 -p tcp --dport 22 -m limit --limit

			-m string
				--algo {bm|kmp}
				--string "STRING"

iptables [-t TABLE] COMMOND CHAIN [num] 匹配条件 -j 处理动作

命令:
	管理规则
		-A:附加一条规则,添加在链的尾部
		-I CHAIN [num]:插入一条规则,插入为对应CHAIN上的第num条,省略num则插入为第一条
		-D CHAIN [num]:删除指定链中的第num条规则
		-R CHAIN [num]:替换指定的规则
	管理链:
		-F [CHAIN]:flush用于清空指定规则链,如果CHAIN省略,则可以实现删除对应表中的所有链
		-P CHAIN:设定指定链的默认策略
		-N:自定义一个新的空链
		-X:删除一个自定义的空链
		-Z:清空(置0)指定链中的所有规则的计数器
		-E:重命名自定义的链
	查看类:
		-L:list显示指定表中的所有规则
			-n:以数字格式显示主机地址和端口号
			-v: 显示链及规则详细信息
			-vv:
			-vvv:更详细
			-x:不做单位换算,显示精确值
			--line-nums:显示规则号码

	保存规则:
	# service iptables save
		默认保存在/etc/sysconfig/iptables
	# iptables-save > /etc/sysconfig/iptables.20170616
		导出规则
	# iptables-restore < /etc/sysconfig/iptables.20170616

-j TARGET
	ACCEPT:放行
	DROP:丢弃
	REJECT:拒绝
	REDIRECT:端口重定向
	MARK:打标机
	LOG:日志,一定要放在规则的前面,如被放行,则不能打LOG了
	DNAT:目的地址转换
	SNAT: 源地址转换
	MASQUERADE:地址伪装


例子:放行ssh服务
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -p tcp --dport 22 -j ACCEPT
# iptables -t filter -A INPUT -s 172.16.100.7 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT

例子:修改默认策略
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -P FORWARD  DROP

例子:禁止ping(默认策略为DROP的情况,8--request,0--reply )
# iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 0 -j DROP
# iptables -A OUTPUT -s 172.16.100.7  -p icmp --icmp-type 8 -j ACCEPT

例子:放行httpd,ssh
# iptables -A INPUT -d 172.16.100.7 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -s 172.16.100.7 -p tcp --dport 22 -m state --state ESTABLISHED -j ACCEPT
# iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A INPUT -s 172.16.100.7 -p tcp --dport 22 -m state --state ESTABLISHED -j ACCEPT
//可以使用ipstate查看连接状态,lsmod查看ip_conntrack模块,modprobe卸载模块
//可以修改ipstate中的一些参数,临时修改,命令为:#sysctl -w net.ipv4.ip_conntrack_max=65536
//想永久有效,需要修改#vim /etc/sysctl.conf
将OUTPUT链合并:# iptables -I OUTPUT -s 172.16.100.7 -m state --state ESTABLISHED -j ACCEPT
查看:# iptables -L -n --line-nums -v
删除原来的:# iptables -D OUTPUT 2
替换:# iptables -R INPUT 6 -d 172.16.100.7 -片tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
(RELATED在ftp服务下要使用,必须加载模块:#vim /etc/sysconfig/iptables-config中找到IPTABELS_MODULES="ip_nat_ftp ip_conntrack_ftp")

例子:限制每分钟ping 5下
# iptables -R INPUT 3 -d 172.16.100.7 -p icmp --icmp-type 9 -m limit --limit 5/minute -j ACCEPT
# iptables -R INPUT 3 -d 172.16.100.7 -p icmp --icmp-type 9 -m limit --limit 5/minute --limit-burst 6 -j ACCEPT

例子:限制网页连接包含特定字符的数据包(入方向,如www.XXX.com/h7n9.html)
# iptables -I INPUT -d 172.16.100.7 -m string --algo kmp --string "h7n9" -j REJECT

例子:限制网页内容中包含特定字符的数据包(出方向)
# iptables -I OUTPUT -s 172.16.100.7 -m string --algo kmp --string "h7n9" -j REJECT

例子:将ping的包,记录log
# iptables -I INPUT 4 -d 172.16.100.7 -icmp --icmp-type 8 -j LOG --log-prefix "--firewall log for icmp--"

例子:自定义链
# iptables -N clean_in(重命名-E)
# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# iptables -A clean_in -p tcp ! --syn -m state --state NEW  -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A clean_in -d 172.16.100.7 -j RETURN (如果之前规则都不匹配, 返回到主链)

加入主链:iptables -I INPUT -j clean_in

几个例子:
# iptables -A INPUT  -i lo -j ACCEPT
# iptables -A OUTPUT -o lo -j ACCEPT

# iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP
# iptables -A INPUT  -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP
# iptables -A INPUT  -i eth0 -p udp --dport 1026 -j DROP
# iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP

# iptables -A INPUT  -p icmp -m limit --limit 10/second -j ACCEPT

利用iptables的recent模块来抵御DOS攻击

ssh: 远程连接,

iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

1.利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值;

2.利用recent和state模块限制单IP在300s内只能与本机建立3个新连接。被限制五分钟后即可恢复访问。

下面对最后两句做一个说明:

1.第二句是记录访问tcp 22端口的新连接,记录名称为SSH
--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目

2.第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
--update 是指每次建立连接都更新列表;
--seconds必须与--rcheck或者--update同时使用
--hitcount必须与--rcheck或者--update同时使用

3.iptables的记录:/proc/net/ipt_recent/SSH

也可以使用下面的这句记录日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"

Network Address Translate
一。SNAT:源地址转换(对于网关在POSTROUTING上做,OUTPUT)
NAT环境下首先需要开启模块/proc/sys/net/ipv4/ip_forward置为1
两种方法:
① # cat /proc/sys/net/ipv4/ip_forward
   # echo 1 > /proc/sys/net/ipv4/ip_forward
② # vim /etc/sysctl.conf
	编辑 net.ipv4.ip_forward = 1
   # sysctl -p

LAN								WAN
172.16.100.1---172.16.100.7     192.168.10.6---192.168.10.7

例子:对192.168.10.0/24网段进行源地址转换
# iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.7
# iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.7-172.16.100.10
# iptables -A FORWARD -s 192.168.10.9/24 -p icmp -j REJECT

例子:服务器默认政策为DROP
# iptables -P FORWARD  DROP
# iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
# iptables -A FORWARD -s 192.168.10.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
# iptables -A FORWARD -s 192.168.10.0/24 -p icmp --icmp-type -m state --state NEW -j ACCEPT

二。DNAT: 目标地址转换(必须明确服务,即端口)
# iptables -t nat -A PREROUTING -d 172.16.100.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.22
# iptables -t nat -R PREROUTING 1 -d 172.16.100.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.22:8080
# iptables -A FORWARD  -m string --algo kmp --string "h7n9" -j DROP

==================================================================================
多对一
            -----------Router------------Internet
                    LAN      WAN
         192.168.0.0/24      192.168.1.155
iptables -t nat -A POSTROUTING -o ethx -s 192.168.0.0/24 -j SNAT --to 192.168.1.155

多对一
            -----------Router------------Internet
                    LAN      ADSL
         192.168.0.0/24
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j MASQUERADE

多对多
iptables -t nat -A POSTROUTING -o ethx -s 192.168.0.0/24 -j SNAT --to 192.168.1.155-192.168.1.157

一对一
pc1-------------------------(eth0)pc2(eth1)------------------------pc3
19.168.0.18         192.168.0.230     10.10.10.1          10.10.10.10
使用ifconfig eth1 add 10.10.10.2 netmask 255.255.255.0
iptables -t nat -A PREROUTING -i eth1 -d 10.10.10.2 -j DNAT --to 192.168.0.18
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.18 -j SNAT --to 10.10.10.2

NAPT(基于端口的NAT)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.0.18:80

==================================================================================
layer7 -- l7

应用:xunlei, qq, netfilter<--patch

-m layer7 --l7proto xunlei -j DROP

1、给内核打补丁,并重新编译内核
2、给iptables源码打补丁,并重新编译iptables
3、安装l7proto

kernel, patch

iptables, patch

Kernel Patch
# tar zxvf  linux-2.6.28.10.tar.gz  -C  /usr/src
# tar zxvf  netfilter-layer7-v2.22.tar.gz  -C  /usr/src
# cd /usr/src
# ln –s  linux-2.6.28.10  linux
# cd /usr/src/linux/
# patch -p1  <  ../netfilter-layer7-v2.22/kernel-2.6.25-2.6.28-layer7-2.22.patch

# cp /boot/config-2.6.18-164.el5  /usr/src/linux/.config
# make  menuconfig

Networking support → Networking Options →Network packet filtering framework →Core Netfilter Configuration
<M>  Netfilter connection tracking support
<M>  “layer7” match support
<M>  “string” match support
<M>  “time”  match support
<M>  “iprange”  match support
<M>  “connlimit”  match support
<M>  “state”  match support
<M>  “conntrack”  connection  match support
<M>  “mac”  address  match support
<M>   "multiport" Multiple port match support

Networking support → Networking Options →Network packet filtering framework → IP: Netfilter Configuration
<M> IPv4 connection tracking support (required for NAT)
<M>   Full NAT
	<M>     MASQUERADE target support
	<M>     NETMAP target support
	<M>     REDIRECT target support

# make
# make modules_install
# make install

Compiles iptables :

# cp /etc/init.d/iptables ~/iptables
# cp /etc/sysconfig/iptables-config ~/
# rpm  -e  iptables-ipv6  iptables  iptstate  --nodeps
# tar jxvf iptables-1.4.6.tar.bz2 –C  /usr/src
# cd /usr/src/iptables-1.4.6
# cp ../netfilter-layer7-v2.22/iptables-1.4.3forward-for-kernel-2.6.20forward/libxt_layer7.*   ./extensions/

# ./configure  --prefix=/usr  --with-ksource=/usr/src/linux
# make
# make install

# tar zxvf l7-protocols-2009-05-28.tar.gz
# cd l7-protocols-2009-05-28
# make install

# mv ~/iptables  /etc/rc.d/init.d/

# service iptables start

l7-filter uses the standard iptables extension syntax
# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]


#练习

定义自定义链clean_in,清除非法连接
# iptables -N clean_in
# iptables -A clean_in -p tcp ! --syn  -m state --state NEW -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A clean_in -d XXX.XXX.XXX.XXX -j RETURN

# iptables -t filter -I INPUT -j clean_in

抵制DDOS
# iptables -N clean_ddos
# iptables -A clean_ddos -p tcp --dport 80 -m connlimit --connlimit-above 5 -j DROP
# iptables -A clean_ddos -p tcp --dport 80 -m state --state NEW -m recent --set --name DDOS
# iptables -A clean_ddos -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name DDOS -j DROP

# iptables -t filter -I INPUT 2 -j clean_ddos

测试2:
xiaoxiaomaoqiu。cn
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT  --to-destination XXX.XXX.XXX.XXX


# Generated by iptables-save v1.4.21 on Tue Oct  3 11:26:56 2017
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [103128:15995486]
:clean_ddos - [0:0]
:clean_in - [0:0]
-A INPUT -j clean_in
-A INPUT -j clean_ddos
-A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 3306 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A OUTPUT -o lo -j ACCEPT
-A clean_ddos -p tcp -m tcp --dport 80 -m connlimit --connlimit-above 3 --connlimit-mask 32 --connlimit-saddr -j DROP
-A clean_ddos -p tcp -m tcp --dport 80 -m state --state NEW -m recent --set --name DDOS --mask 255.255.255.255 --rsource
-A clean_ddos -p tcp -m tcp --dport 80 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name DDOS --mask 255.255.255.255 --rsource -j DROP
-A clean_in -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A clean_in -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
-A clean_in -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A clean_in -d 123.206.89.221/32 -j RETURN
COMMIT
# Completed on Tue Oct  3 11:26:56 2017
# Generated by iptables-save v1.4.21 on Tue Oct  3 11:26:56 2017
*nat
:PREROUTING ACCEPT [127095:8064248]
:INPUT ACCEPT [661:31504]
:OUTPUT ACCEPT [21471:1455133]
:POSTROUTING ACCEPT [21471:1455133]
COMMIT
# Completed on Tue Oct  3 11:26:56 2017

# frps
# Generated by iptables-save v1.4.21 on Tue Jan 18 17:59:41 2022
*mangle
:PREROUTING ACCEPT [645485602:52047125706]
:INPUT ACCEPT [645485487:52047086227]
:FORWARD ACCEPT [109:39179]
:OUTPUT ACCEPT [679485310:80446769417]
:POSTROUTING ACCEPT [679485419:80446808596]
-A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
COMMIT
# Completed on Tue Jan 18 17:59:41 2022
# Generated by iptables-save v1.4.21 on Tue Jan 18 17:59:41 2022
*nat
:PREROUTING ACCEPT [40273334:1519850755]
:INPUT ACCEPT [40130175:1511261161]
:OUTPUT ACCEPT [20750740:1272633054]
:POSTROUTING ACCEPT [20750740:1272633054]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
COMMIT
# Completed on Tue Jan 18 17:59:41 2022
# Generated by iptables-save v1.4.21 on Tue Jan 18 17:59:41 2022
*filter
:INPUT ACCEPT [7304:1025569]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [7178:1443467]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
:clean_ddos - [0:0]
-A INPUT -j clean_ddos
-A clean_ddos -p tcp -m tcp --dport 6000 -m connlimit --connlimit-above 20 --connlimit-mask 32 --connlimit-saddr -j DROP
-A clean_ddos -p tcp -m tcp --dport 6000 -m state --state NEW -m recent --set --name DDOS --mask 255.255.255.255 --rsource
-A clean_ddos -p tcp -m tcp --dport 6000 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 --name DDOS --mask 255.255.255.255 --rsource -j DROP
COMMIT
# Completed on Tue Jan 18 17:59:41 2022


备份地址: 【Iptables 使用总结