Iptables详解

iptables/netfilter:

Packets Filter Firewall:
	包过滤型防火墙:

Firewall:隔离工具,工作于主机或网络的边缘处,对经由的报文根据预先定义的规则(识别标准)进行检测,对于能够被规则匹配到的报文实行某种预定义的处理机制的一组套件:
	硬件防火墙:CPU级别就可以封包和解包,提供26个字母,硬件逻辑;在硬件级别实现部分功能的防火墙。
	软件防火墙:应用软件逻辑在通用硬件基础上实现。

	主机防火墙:
	网络防火墙:

ipfw --> ipchians -->iptables(ip6tables)

iptables(管控机制,内核中的功能)/netfilter(框架 网络过滤器的规则)
	iptables:规则管理工具
	netfilter: 防火墙框架,承载并生效的规则;

	hook functions(netfilter): 钩子规则
		prerouting:进入/离开本机的外网接口
		input: 数据包从内核流入用户空间的
		forward:从一个网络接口进来,到另一个网络接口去的
		output: 数据包从用户空间流出的
		postrouting:进入/离开本机的内网接口

	iptables:內键链
		PREROUTING
		INPUT
		FORWARD
		OUTPUT
		POSTROUTING

		允许用户自定义规则链:他们需要手动关联至指定的“钩子”;

	钩子和链是有特定对应关系


	netfilter: 功能
		filter防火:包过滤
		NAT: Network Address Translation(网络地址转换)
		mangle: 拆解报文,做出修改,而后重新封装。
		raw : 关闭nat表上启用的连接追踪机制

	功能(表) <--> 钩子
		filter: input, forward, output
		nat: prerouting, input, output, postrouting
		mangle: prerouting, input, forward, output, postrouting
		raw: pretouting, output

		优先级(由高而低): raw --> mangle --> nat --> filter

	iptables规则的组成部分:
		匹配条件:处理机制
			网络层首部(IP):SourceIP , DestinationIP;
			传输层首部(TCP):SourcePort, DestinationPort目标端口, TCP Flags(SYN请求,ACK响应,FIN结束,URG,PSH推送,RST重置)
		跳转目标:target
			內键的处理机制:ACCEPT接受, DROP丢弃, REJECT拒绝,SNAT本地转发, DNAT远程转发,MASQUERADE, MARK, LOG, ...
			用户自定义链: 

		添加规则时需要考量的因素:
			(1)实现的功能:用于判断将规则添加至哪个表;
			(2)报文流经的位置:用于判断规则添加至哪个链;
			(3)报文的流向:判定规则中何为“源”,何为“目标”;
			(4)匹配条件:用于编写正确的匹配规则;
				(a)专用于某种应用的同类规则,匹配范围小的放前面;
				(b)专用于某些应用的不同类规则,匹配到的可能性较多的放前面;同一类别的规则可使用自定义链单独存放;
				(c)用于通用目的的规则放前面;



	filter表:过滤,防火墙意义的核心所在;
		INPUT, FORWARD, OUTPUT

man iptables-extensions
man iptables

安装:
netfilter:位于内核中的tcp/ip协议栈报文处理框架;
iptables:
CentOS 5/6: iptables命令生成规则,可保存于文件中以反复装载生效;
# iptables -t filter -F 先清空规则
# service iptables save 再保存

		man iptables

	CentOS 7: firewalld, firewall-cmd, firewall-config
		# systemctl disable firewall.service  关闭firewall,只使用iptables

		man iptables
		man iptables-extensions

iptables命令:
iptables [-t table] {-A|-C|-D} chain rule-specification
-A: append
-C: check
-D: delete

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]

    COMMANDS:	
   	    链管理:
   	    	-N: --new-chain chain: 新建一个自定义规则链
   	    		iptables -N input-http
   	    		iptables -nL
   	    	-X: --delete-chain [chain] :删除用户自定义的被应用为0的空链,
   	    	-F: --flush [chain] :清空指定的规则链上的规则,不指定链就清空所有链上的规则;
   	    	-E: --rename-chain old-chain new-chain: 重命名自定义链;
   	    	-Z: --zero [chain [rulenum]]: 置零计数器;
   	    		注意:每个规则都有两个计数器
   	    			packets:被本规则所匹配到的所有报文的个数;
   	    			bytes:被本规则所匹配到的所有报文的大小之和;
   	    	-P: --policy chain target: 更改默认策略,
   	    		示例:
	   	    		iptables -t filter -P DROP
	   	    		iptables -t filter -P ACCEPT
   	    		注意,一般生产中不设置默认策略,一般是自定义策略;
   	    规则管理:
   	    	-A :--append chain rule-specification: 追加新规则于指定链的尾部;
   	    	-I: --insert chain [rulennum] rule-specification :插入新规则于指定连的指定位置,默认为首部;
   	    	-R:--replace chain rulenum rule-specification: 替换指定的规则为新的规则;
   	    	-D: --delete chain rulenum: 根据规则编号删除规则;
   	    		rulenum:表示第几条规则
   	    	-D:--delete chain rule-specification: 根据规则本身删除规则;
   	    规则显示:
   	    	-L:--list [chain]: 列出规则;
   	    		-v, --verbose: 详细信息;
   	    		-vv:更详细;
   	    		-n, --numeric: 以数字显示主机地址和端口号;
   	    		-x, --exact: 显示计数器的精确数值,而非圆整后的数据;
   	    		--line-numbers: 列出规则时,显示其在链上的响应的规则编号;
   	    			示例:iptables -vnL
   	    			iptables -vnxL --line-numbers
   	    	-S, --list-rules [chain]: 显示指定链的所有规则;
   	    		示例:iptables -S

   	rule-specification = [matches...] [target]
   		matches: 匹配条件
   		target: 跳转目标;

   		匹配条件:match = -m matchname [per-match-options]
   			-m matchname [per-match-options]

   			通用匹配(PARAMETERS)参数,大写字母是target跳转目标扩展,小写字母是match扩展
   				[!] -s, --source address[/mask][,...]:检查报文的源IP地址是否符合此处指定的范围,或是否等于此处给定的地址;如果有多个地址,需要用逗号","隔开;
				[!] -d, --destination address[/mask][,...]:检查报文的目标IP地址是否符合此处指定的范围,或是否等此处给定的地址;	如果有多个地址,需要用逗号","隔开;
					示例:
						iptables -A INPUT -s 172.16.0.0/16,127.0.0.0/8 -d172.16.73.101,127.0.0.1 -j ACCEPT
						iptables -A OUTPUT -s 172.16.73.101 -d 172.16.0.0/16 -j ACCEPT
				[!] -p, --protocol protocol:匹配报文中的协议,可用值:tcp, udp, udplite, icmp, esp, ah, sctp or all,也可以使用数字表示:
				示例:
					iptables -R INPUT 1 -s 172.16.0.0/16 -d 172.16.73.101 -p tcp  -j ACCEPT
					iptables -R OUTPUT 1 -s 172.16.73.101 -d 172.16.0.0/16 -p tcp -j ACCEPT

				[!] -i, --in-interface name:限定报文仅能从指定接口流入,only  for packets  entering the INPUT, FORWARD and PREROUTING chains  只能用于这三个链:INPUT, FORWARD and PREROUTING
				[!] -o, --out-interface name:限定报文仅能从指定接口流出,for packets entering the  FORWARD,  OUTPUT  and  POSTROUTING  chains  ,只能用于这三个链:FORWARD,  OUTPUT  and  POSTROUTING
				-m,--match match:调用指定的扩展匹配模块来扩展匹配条件检查机制;  			
   			扩展匹配(MATCH EXTENSIONS)

   		跳转目标:target = -j targetname [per-target-options]
   			-j targetname [per-target-options]
	   			ACCEPT:接受
	   			DROP:丢弃
	   			PREJECT:拒绝

回顾:
iptables/netfilter:
netfilter: 防火墙框架
iptables: 管理规则的工具;

	四表:filter, nat, mangle, raw
	五链:PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING

iptables命令:
	iptables [-t table] COMMAND [chain] [PARAMETERS] [-m matchname] [per-match-options] [-j targetname [per-target-options]]

	PARAMETERS:
		-s, -d, -p {tcp|dup|icmp|sctp|udplite|...}, -i, -o

	COMMAND:
		连管理:-P, -X, -N, -E, -F, -Z, 
		规则管理:-A, -I, -R, -D, 
		查看:-L, -S
			-L: -n, -v,-x , --line-numbers

	-j targetname
		ACCEPT, DROP, REJECT

iptables(2)
iptables [-t table] COMMAND [chain] [PARAMETERS] [-m matchname] [per-match-options] [-j targetname [per-target-options]]

	匹配条件:
		基本匹配条件:PARAMETERS
		扩展匹配条件:-m matchname
			隐式扩展:由协议本身生成的扩展条件由 -p引出,在使用-p选项指明了特定的协议时,无需再用-m选项指明扩展模块的扩展机制;

			显式扩展:必须使用-m选项指明要调用的扩展模块的扩展机制;

	隐式扩展:
		-p tcp: 可直接使用tcp扩展模块的专用选项:
			[!] --source-port:--sport port[:port]:匹配报文源端口;可以给出多个端口,但只能是连续的端口范围;

			示例:iptables -t filter -A INPUT -s 192.168.199.0/24 -d 192.168.199.152 -p tcp --dport 22 -j ACCEPT  允许199这个网段的主机访问本机

			iptables -I INPUT -s 192.168.199.151 -d 192.168.199.152 -p tcp --dport 22 -j ACCEPT -I插入这条记录

			iptables -R INPUT 1 -s 192.168.199.151 -d 192.168.199.152 -p tcp --dport 22 -j REJECT  拒绝151主机使用22端口访问本机,-R表示修改这条记录,

			[!] --destination-port:--dport port[:port]:匹配报文目标端口;可以给出多个端口,但只能是连续的端口范围;

			示例:iptables -t filter -A OUTPUT -s 192.168.199.152 -d 192.168.199.0/24 -p tcp --sport 22 -j ACCEPT

			[!] --tcp-flags mask comp:匹配报文中的tcp协议的标志位;Flags are标志位: SYN ACK FIN RST URG PSH ALL  NONE.
				mask:要检查的FLAGS LIST,以逗号分隔:
				comp: 在mask给定的诸多FLAGS中,其值必须为1的FLAGS列表,余下的其值必须为0;
				    --tcp-flags SYN,ACK,FUB,RST SYN 三次握手的第一次请求;SYN为1,其他为0,;
				    --tcp-flags ALL ALL  所有标识位都为1
				    --tcp-flags ALL NONE 所有标识位都为0

			示例:
				iptables -N clean_invalid_packets  使用-N添加一条自定义链

				iptables -A clean_invalid_packets -p tcp --tcp-flags ALL ALL -j DROP  在自定义链上添加拒绝所有TCP标识位为1的包;

				iptables -A clean_invalid_packets -p tcp --tcp-flags ALL NONE -j DROP  添加拒绝所有标识位为0的包,

				说明:以上这三条记录是为了拒绝恶意攻击;并且添加自定义链,必须在调用时才生效,调用方法:
					iptables -I INPUT -d 192.168.199.152 -j clean_invalid_packets

				不使用自定义链,删除方法:
					iptables -X clean_invalid_packets  执行这条命令后
						iptables: Too many links.  这表示自定义链有引用。,需要先拆除引用。
					iptables -D INPUT  表示拆除引用,然后再执行上一条命令

					iptables -X clean_invalid_packets
						iptables: Directory not empty.  提示链非空,需要先清空这条自定义链
					iptables -F clean_invalid_packets, 清空以后,在执行一次上面的命令
					iptables -X clean_invalid_packets  这样就删除了这条自定义链。



			[!] --syn: --tcp-flags SYN,ACK,FUB,RST SYN  开放三次握手的第一次,生产中会用到。



		-p udp:可直接只用udp协议扩展模块的专用选项:
			[!] --source-port:--sport port[:port]
			[!] --destination-port:--dport port[:port]

			示例:yum安装samba服务,mkdir -p /samba/data
			配置:vim /etc/samba/smb.conf
					[files]
						comment = Files
						path = /samba/data
						public = yes
				语法检查:testparm
				创建用户:useradd centos
				设定密码:smbpasswd -a centos
				启动服务:systemctl start smb
						  systemctl start nmb
				查看端口是否启动:ss -tunl

			在另外一台主机上访问这台主机的共享目录
			smbclient -L //192.168.199.152 -U centos
				Enter centos's password: 
				Connection to 192.168.199.152 failed (Error NT_STATUS_UNSUCCESSFUL) 提示出现错误
			再开启这台主机的samba服务的端口:
				先将这台主机的防火墙默认规则改为接受
					iptables -P INPUT ACCEPT  修改默认规则
					iptables -P OUTPUT ACCEPT
			另外的主机上再次访问共享目录
				smbclient -L //192.168.199.152 -U centos
					Enter centos's password: 
					Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]

						Sharename       Type      Comment
						---------       ----      -------
						print$          Disk      Printer Drivers
						files           Disk      Files
						IPC$            IPC       IPC Service (Samba 4.4.4)
						centos          Disk      Home Directories
					Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]

						Server               Comment
						---------            -------
						LUFEI                Samba 4.4.4

						Workgroup            Master
						---------            -------
					表示访问成功
			这时,可以添加自定义的访问规则
				iptables -A INPUT  -d 192.168.199.152 -j REJECT 自定义修改默认规则为拒绝,
				iptables -A OUTPUT  -s 192.168.199.152 -j REJECT

				再次访问这台主机的共享目录:
					smbclient -L //192.168.199.152 -U centos
						Enter centos's password: 
						Connection to 192.168.199.152 failed (Error NT_STATUS_UNSUCCESSFUL)

				定义这种默认规则的好处:1、如果失误将规则清空的话,默认规则依然是ACCEPT ,不会影响访问。	2、本机对本机的通信并未阻止。使用ping 127.0.0.1可以测试;

			现在开放本机的udp的137,138端口和tcp的139,445端口
				iptables -I INPUT -d 192.168.199.152 -p udp --dport 137:138 -j ACCEPT
				iptables -I OUTPUT -s 192.168.199.152 -p udp --sport 137:138 -j ACCEPT
				iptables -I INPUT 2 -d 192.168.199.152 -p tcp --dport 139 -j ACCEPT
				iptables -I INPUT 2 -d 192.168.199.152 -p tcp --dport 445 -j ACCEPT
				iptables -I OUTPUT 2 -s 192.168.199.152 -p tcp --sport 445 -j ACCEPT
				iptables -I OUTPUT 2 -s 192.168.199.152 -p tcp --sport 139 -j ACCEPT
			再次使用另外的主机访问这台主机的共享目录
				smbclient -L //192.168.199.152 -U centos
					Enter centos's password: 
					Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]

						Sharename       Type      Comment
						---------       ----      -------
						print$          Disk      Printer Drivers
						files           Disk      Files
						IPC$            IPC       IPC Service (Samba 4.4.4)
						centos          Disk      Home Directories
					Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]

						Server               Comment
						---------            -------
						LUFEI                Samba 4.4.4

						Workgroup            Master
						---------            -------

					这时可以成功访问。

			添加访问httpd 的控制规则:

		[!] --icmp-type {type[/code]|typename} 互联网报文控制选项,比如ping命令  ICMP Types and Codes
			0/0:echo reply
			8/0: echo request
		示例:如何开发ping请求
			iptables -I INPUT 3 -d 192.168.199.152 -p icmp --icmp-type 8 -j ACCEPT 这时ping 的入栈规则,请求要设为8
			iptables -I OUTPUT 2 -s 192.168.199.152 -p icmp --icmp-type 0 -j ACCEPT  响应要设为0

			tcpdump -i eth1 -nn icmp 使用抓包工具可以查看请求和响应过程

	tcpdump -i eno16777736 -nn 抓包命令
	tcpdump -i eno16777736 -nn tcp port 22

	显示扩展:必须使用-m选项指明要调用的扩展模块的扩展机制;
		1、multiport
			以离散或连续的方式定义多端口匹配条件,最多15个;
			protocols:  tcp,  udp,  udplite, dhcp and sctp. 支持的协议类型

			[!] --source-ports:--sports port[,port|,port:port].. :指定多个源端口,port:port这种情况是只记录两个端口
			[!] --destination-ports:--dports port[,port|,port:port]...:指定多个目标端口;port:port这种情况是只记录两个端口
			[!] --ports port[,port|,port:port]...:当源端口和目标端口相同时,使用;

			示例:
			iptables -I INPUT -d 192.168.199.152 -p tcp -m multiport --dports 22,80,139,445,3306 -j ACCEPT
			iptables -I OUTPUT -s 192.168.199.152 -p tcp -m multiport --sports 22,80,139,445,3306 -j ACCEPT
			iptables -I INPUT 2 -d 192.168.199.152 -j REJECT
			iptables -I OUTPUT 2 -s 192.168.199.152 -j REJECT

		2、iprange
			以连续地址块的方式来指明多个IP地址匹配条件;
			[!] --src-range from [-to]   源地址范围
			[!] --dst-range from [-to]	 目标地址范围,本机有多个IP时,容易演示。

			示例:iptables -I INPUT -d 192.168.199.152 -p tcp -m multiport --dports 22,80,139,445,3306 -m iprange --src-range 192.168.199.180-192.168.199.254 -j REJECT  表示拒绝180-254之间的地址访问152的主机的22,80,139,445,3306端口的服务。


		3、time
			This  matches  if  the  packet  arrival  time/date is within a given range. 控制时间

			--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]  日期时间范围
			--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
			--timestart hh:mm[:ss]  时间的开始,不指定日期是每天的这个时间
			--timestop hh:mm[:ss] 时间的结束。
			[!] --monthdays day[,day...]  指定每月的几号
			[!] --weekdays day[,day...] 指定周几,
			--kerneltz: 使用内核配置时区而非默认UTC时间

		示例:iptables -I INPUT -d 192.168.199.152 -p tcp --dport 80 -m time --timestart 09:00 --timestop 18:00 --weekdays 6,7 -j REJECT

		4、string
			This modules matches a given string by using some pattern matching strategy. 基于给定的匹配策略来检查模式,

			--algo {bm|kmp}
				bm = Boyer-Moore, kmp = Knuth-Pratt-Morris
			[!] --string pattern
			[!] --hex-string pattern 直接给定16进制格式
			--from offset  偏移量,from不指定,表示检查整个报文
			--to offset

			示例:iptables  -A  INPUT  -p tcp --dport 80 -m string --algo bm --string 'GET/index.html' -j LOG
			iptables  -p  udp  --dport  53  -m  string  --algo  bm --from 40 --to 57 --hex-string '|03|www|09|netfilter|03|org|00|'

			示例:iptables -I OUTPUT -m string --algo bm --string "gay" -j REJECT

		5、connlimit:限制单客户端最大并发连接数,

			--connlimit-upto n: 限制的上限,小于等于n
			--connlimit-above n: 限制的至少为n,大于n

			示例:
			allow 2 telnet connections per client host
          		iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT  仅检查新连接

   			you can also match the other way around:
          		iptables  -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT

          	iptables -I INPUT -d 192.168.199.152 -p tcp  --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT 最多允许两个ssh客户端同时连接本机  ,仅检查新连接。




		6、limit: 限定速率,This module matches at a limited rate using a  token  bucket  filter.令牌桶过滤器机制来完成过滤,
			--limit rate[/second|/minute|/hour|/day]
			--limit-burst number  空闲桶,limit峰值,最大容纳量,

			iptables -I INPUT -d 192.168.199.152 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 5 -j ACCEPT

			iptables -I OUTPUT -s 192.168.199.152 -p icmp --icmp-type 0 -j ACCEPT
		7、state 状态检测,运行检查内部状态,状态追踪功能机制:

			The "state" extension is a subset of the "conntrack"  module.
			conntrack:探查内部连接状态
			[!] --state state: 
				recognized: INVALID,  ESTABLISHED, NEW, RELATED or UNTRACKED 五种状态

				NEW:新连接请求;一般在入栈中放行,
				ESTABLISHED:已建立的连接; 一般在入栈和出栈中放行。
				INVALID: 无法识别的连接;
				RELATED:相关联的连接,当前连接是一个新请求,但附属于某个已存在的连接;
				UNTRACKED: 未追踪的连接;

			state: conntrack
				/proc/net/nf_ocnntrack
				/proc/sys/net/nf_conntrack_max

			示例:万能的匹配策略
				iptables -A INPUT -d 192.168.199.152 -j REJECT
				iptables -A OUTPUT -s 192.168.199.152 -j REJECT
				iptables -I INPUT -d 192.168.199.152 -p tcp -m multiport --dports 22,80,139,445,3306 -m state --state NEW -j ACCEPT
				iptables -I INPUT  -m state --state ESTABLISHED -j ACCEPT
				iptables -I OUTPUT  -m state --state ESTABLISHED -j ACCEPT
				iptables -I INPUT 2 -d 192.168.199.152 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT  开放禁ping的策略

				以上示例就可更优化之前设置的限制策略。


			iptables -vnL
				Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
				 pkts bytes target     prot opt in     out     source               destination         
				  330 24472 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state ESTABLISHED
				    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.199.152      multiport dports 22,80,139,445,3306 state NEW
				    5   420 REJECT     all  --  *      *       0.0.0.0/0            192.168.199.152      reject-with icmp-port-unreachable

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

				Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
				 pkts bytes target     prot opt in     out     source               destination         
				  127 11680 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state ESTABLISHED
				   14  1176 ACCEPT     icmp --  *      *       192.168.199.152      0.0.0.0/0            icmptype 0
				    5   560 REJECT     all  --  *      *       192.168.199.152      0.0.0.0/0            reject-with icmp-port-unreachable
	规则调用逻辑:
		当报文入栈以后,正常是在主链上检查报文的,如果主链上某条规则匹配到,跳转至其他链上的规则,则由其他链上的规则,自上而下进行检查,若在这条链上匹配到规则以后就会直接处理报文,若在这条链上没有匹配到规则,则会返回主链上再次自上而下匹配其他规则;

回顾:iptables规则
iptables [-t table] SUBCOMMAND [CHAIN] [PARAMETERS] [-m matchname [per-match-options]] [-j targetname [per-target-options]]

	match:
		multiport, iprange, time, connlimit, limit, string, 

	state:
		conntrack:一般在服务器很繁忙的情况下不要开启这一项。

		五中状态:NEW, ESTABLISHED, RELATED, INVALID, UNTRACKED

		能追踪到的最大连接数量定义在:/proc/sys/net/nf_conntrack_max
		追踪到的连接:/proc/net/nf_conntrack

iptables(3)
state扩展:
centos7:内核模块的装载,以下两个是可以调用state模块
nf_conntrack
nf_conntrack_ipv4

	手动装载:
		modprobe nf_conntrack_ftp

	centos6:如何装载nf_conntrack模块

处理动作(跳转目标)
	-j targetname [per-target-options]
		简单target:
			ACCEPT, DROP

		扩展target:
			REJECT
				--reject-with type
				icmp-net-unreachable,  icmp-host-unreachable,
          icmp-port-unreachable,   icmp-proto-unreachable,    icmp-net-prohibited,
          icmp-host-prohibited,  or  icmp-admin-prohibited 
			

			LOG
				turn on kernel

				--log-level
				--log-prefix

保存和载入规则:
	保存:iptables-save
		centos7的方法:iptables-save >/PATH/TO/somefile  直接从定向到文件。

		centos6的方法:service iptables save = iptables-save >/etc/sysconfig/iptables  每次都是覆盖保存。

	载入:iptables-restore < /etc/sysconfig/iptables  使用输入重定向。
		-n, --noflush: 不清除原有规则,就是和已有的合并。
		-t, --test:仅分析生成规则集,但不提交。

		centos6: service iptables resttart
		默认重载/etc/sysconfig/iptables文件中的规则。

		配置文件:/etc/sysconfig/iptables-config
			IPTABLES_MODULES="nf_conntrack_ftp"   开机加载ftp模块。


		centos7开机自动载入:
			1,自定义Unit File,进行iptables-restore;
			2, firewalld服务;
			3, 自定义脚本。

		lsmod查看加载的模块

规则优化的思路:
	1,使用自定义链管理特定应用的相关规则。
	2,优先放行双方向状态为ESTABLEISHED的报文。
	3,服务于不同类别的功能的规则,匹配到报文的可能性更大的放前面。
	4,服务于同一类别的功能的规则,匹配条件较严格的放在前面。
	5,设置默认策略,白名单机制:
		iptables -P,不建议。
		建议在规则的最后定义规则作为默认策略。

iptables/netfilter网络防火墙:
1,网关;
2,filter表的FORWARD链;

要注意的问题:
	1, 请求-响应报文均会经由FORWARD链,要注意规则的方向性。
	2,如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接报文。
	目标地址时私网地址不能被互联网转发。


NAT:Network Address Translation  网络地址转换
	请求报文:由管理员定义
	响应报文:由NAT的conntrack机制自动实现

	请求报文:
		改原地址:SNAT  本地内网地址是客户端,访问远端的服务器端,只能发生在POSTROUTING,本机内部的私有地址发生在OUTPUT
		改目标地址:DNAT  内网是服务端,远端是客户端,只能发生在PREROUTING,要指定某服务。

		PNAT:port nat 端口地址转换。

iptables/netfilter:
	
	NAT定义在nat表;
		PREROUTING, INPUT, OUTPUT, POSTROUTING四个链上。

nat表的target分类:
	SNAT:
		This  target  is  only  valid  in  the  nat table, in the POSTROUTING and INPUT chains, and user-defined chains which are only called from  those  chains.
		
		--to-source [ipaddr[-ipaddr]] [:port[-port]]  多地址多端口转换。

	DNAT:
		This target is only valid in the  nat  table,  in  the  PREROUTING  and  OUTPUT chains,  and  user-defined  chains which are only called from those chains.
		--to-destination [ipaddr[-ipaddr]][:port[-port]]  多地址多端口转换

	MASQUERADE  :地址伪装,拨号上网时,IP地址不固定,动态地址获取的,也是原地址转换的。可直行判断要转换为的地址。
		This target is only valid in the nat  table,  in  the  POSTROUTING  chain. 

		--to-ports [:port[-port]]

		SNAT场景中应用于POSTROUTING链上的规则实现源地址转换,但外网地址不固定时,使用此target.

	REDIRECT:端口重定向。
		This  target  is  only  valid  in  the  nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from  those  chains.

		--to-ports port[-port]

测试实例:利用iptables 做路由转发实验,并做防火墙策略。
转发服务并且是网络防火墙,6.8的两个地址分别为:内网IP:192.168.199.153,外网IP:172.16.73.135
内网的两台服务器7.2地址分别为:192.168.199.152;192.168.199.101
外网的服务器6.7地址为:172.16.73.120

1,首先设置路由服务器6.8,添加两块网卡;内网配置IP配置为192.168.199.153,外网地址配置为:172.16.73.135
	ip addr add 172.16.73.153/16 dev eth0
	ip addr add 192.168.199.135/24 dev eth1
2、配置6.7主机的网关为6.8的外网IP
   配置7.2的两台主机的网关为6.8的内网IP。
	7.2的两台主机使用vmnet1的网卡,
	6.8主机的内网网卡使用vmnet1的网卡
	6.7主机的网卡使用桥接,
	6.8主机的外网网卡也使用桥接。

	nmtui是centos7的图形界面网卡配置。

	7.2主机配置网IP后,重启网卡就可以,不要重启网络。
		ip link set eno16777736 down
		ip link set eno16777736 up
		或者添加默认路由:route add default gw 192.168.199.153

	6.7主机添加网关
		route add default gw 172.16.73.135
		route del -net 0.0.0.0 gw 172.16.0.1

	测试一下:
	7.2主机使用ping命令:
		ping 172.16.73.135  看是否能通
		ping 192.168.199.153
	6.7主机使用ping命令测试:
		ping 192.168.199.153  看是否能通
	经过测试可以通。

	ip route show  查看网关指向。

3、测试一下7.2主机是否能ping通6.7主机
	ping 172,16,73,120  结果是不通,
	可以在6.7上使用抓包功能看一下是否有7.2主机的包
	tcpdump -i eth1 -nn  结果没有。
4,在6.8主机上开通路由转发功能
	cat /proc/sys/net/ipv4/ip_forward 的内容是1还是0, 0表示没开启路由转发,1表示已经开启路由转发功能。

	echo 1 >  /proc/sys/net/ipv4/ip_forward 表示开启了路由转发功能。
	或使用:sysctl -w net.ipv4.ip_forward=1
	tcpdump -i eth1 -nn icmp 再抓包查看。
		-X 显示16进制格式内容。

以上的配置为路由功能,路由转发的过程。

5、在6.7服务器上配置一个httpd服务 yum -y install httpd vsftpd
	并编辑一个网页内容
	vim /var/www/html/index.html
		<h1>www.lufei.com</h1>

	service httpd start  启动服务
	并在浏览器查看内容。或使用curl命令查看。
	curl http://172.16.73.120
	service vsftpd start

6、在6.8主机上设置防火墙的forword链,来控制6.7主机上的哪些服务允许7.2访问,哪些不允许访问。
	centos6系统需要配置的地方
		配置文件:/etc/sysconfig/iptables-config
			IPTABLES_MODULES="nf_conntrack_ftp"   开机加载ftp模块。

	如果是centos7的系统,需要关闭firewalld的服务。systemctl stop firewalld。

	01、先在6.8上设置默认拒绝所有服务的规则
		iptables -P INPUT DROP
		iptables -P OUTPUT DROP
		iptables -P FORWARD DROP
	02、开放7.2可以访问6.7的web服务
		在6.8主机上添加请求转发的规则:iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp --dport 80 -j ACCEPT  添加请求的入链规则,这里只知道目标端口是80,所以使用--dport 80.

		7.2主机curl http://172.16.73,120 测试是否有响应。
		6.7主机tcpdump -i eth1 -nn tcp port 80 抓包测试一下 
			tail /var/log/httpd/access_log 也可以查看httpd的日志 
		在6.8添加响应转发的规则:
			ptables -A FORWARD -s 172.16.0.0/16 -d 192.168.199.0/24 -p tcp --sport 80 -j ACCEPT  将源地址和目标地址改一些,修改成源端口 --sport ,这里只知道源端口是80,目标端口不知道,所有只设定源端口就可以。
		测试:
			7.2主机curl http://172.16.73,120 测试是否有响应。
			6.7主机tcpdump -i eth1 -nn tcp port 80 抓包测试一下

	03、添加其他服务访问,例如ftp, mysql, ssh等
		iptables -I FORWARD 1 -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp -m multiport --dports 80,22,3306,20,21 -j ACCEPT

		iptables -I FORWARD 2 -s 172.16.0.0/16 -d 192.168.199.0/24 -p tcp -m multiport --sports 80,22,3306,20,21 -j ACCEPT

		再次测试:方法同02步骤
	04、添加ping 请求
		iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p icmp --icmp-type 8 -j ACCEPT
		iptables -A FORWARD -s 172.16.0.0/16 -d 192.168.199.0/24 -p icmp --icmp-type 0 -j ACCEPT
		以上两条实现7.2主机可以ping通6.7主机的规则。
	05、添加ftp服务规则:
		iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp  -m state --state RELATED,ESTABLISHED -j ACCEPT  这里要去掉端口。以上两条是ftp入栈的规则。
		
		iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp  -m state --state ESTABLISHED -j ACCEPT 这一条是响应的规则

	06、查看链接记录:
		cat /proc/net/nf_conntrack

	07、保存iptables 规则记录
		iptables-save > /tmp/iptables.rules.1
	然后清空iptables -F
7、重新写一个规则,使用-m state,为了简化规则条数。
	01、添加默认规则
	iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT  保持现状的默认规则,也就是都不放行。
	iptables -A FORWARD -s 192.168.199.0/24 -d 172.16.0.0/16 -p tcp -m multiport --dports 22,21,80,3306 -m state --state NEW -j ACCEPT  放行这些服务。
	iptables -A FORWARD -p icmp -m state --state NEW -j ACCEPT
	 放行ping操作。

8、添加本机的ssh服务
	iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
	iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
	iptables -A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
	iptables -A OUTPUT -p tcp --sport 22 -m state --state NEW -j ACCEPT
	私网地址不能直接被公网地址访问,必须通过网关转发才能实现。

目标地址转换实验,源端口和目标端口转换实验。解决安全问题,还有解决公网地址不够用的问题。
6.7主机是远程互联网主机,7.2是本机的内网主机,6.8是路由主机且是网络防火墙服务器
6.7 IP:172.16.73.120
7.2 IP:192.168.199.152
7.2 IP:192.168.199.101
6.8 IP内网:192.168.199.153
6.8 IP内网:172.16.73.135

1、iptables -F 清空所有规则
	iptables -A INPUT -j ACCEPT
	iptables -A OUTPUT -j ACCEPT
	iptables -A FORWARD -j ACCEPT
	以上是设置默认规则都允许的。
	iptables -t filter -vnL
	iptables -t nat -vnL 
	查看filter和nat 表的规则。

2、使用7.2主机访问6.7主机。让显示的IP结果为6.8的外网地址,实现源地址转换。
	01、先测试一下不做源地址转换时,6.7服务器查看来访IP是什么
		curl http://172.16.73.120
		tail /var/log/httpd/access_log
	02、在6.8上做源地址转换,在6.8主机上操作
		iptables -t nat -A POSTROUTING -s 192.168.199.9/24 -j SNAT --to-source 172.16.73.135

		回应时是自动做的转换。不需要再添加规则。
	03,只允许7.2访问6.7的web服务,实现方式:白名单(先将默认规则设置为DROP)或黑名单(先将默认规则设置为ACCEPT)。

	A、白名单实现方式:
		iptables -P FORWARD DROP :设置FORWARD链为全部拒绝。
		iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT  允许所有已建立的连接
		iptables -A FORWARD -s 192.168.199.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT  允许第一次访问web的新建的连接。

	iptables -t filter -F 
	iptables -t nat -F
	iptables -P FORWARD ACCEPT
3、使用MASQUERADE做源地址转换,在静态场景中不建议使用。
	01、默认规则不变
	02、iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -j MASQUERADE

4,DNAT示例:目标地址转换
	iptables -t nat -A PREROUTING -d 172.16.73.135 -p tcp --dport 22 -j DNAT --to-destination 192.168.199.152
	iptables -A FORWARD -s 172.16.249.12 -j DROP 拒绝这台主机访问。

5、
7.2主机是内网段IP,需要安装软件,但yum厂库在外网,需要在6.8的路由服务上做源地址转换来实现
	iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -j SNAT --to-source 172.16.73.135

6、7.2的两台主机是一台内网的web服务,一台ssh服务,其中一台199.152的web服务的监听端口是8080,一台199.101的ssh端口是22,但是外网用户访问这个web服务器时,访问的是192.168.199.152:8080端口,但是这时是内网IP,互联网无法访问,所以就需要让外网6.7直接访问6.8这台连接外网的服务器,但是这台服务器是没有web服务的,所以就需要做目标地址转换和接口映射,所以6.7就是访问172.16.73.135:80地址时,就会直接映射到192.168.199.152:8080 。同理:6.7的外网要连接101主机的ssh服务,也需要在6.8上做目标地址转换和端口映射。

实现方案:
	01、
	修改两台web服务器的监听端口后重启web服务
	vim /etc/httpd/conf/httpd.conf
		Listen 8080
		Listen 808
	service httpd restart
	systemctl restart httpd.service 
	02、
	iptables -t nat -A PREROUTING -d 172.16.73.135 -p tcp --dport 80 -j DNAT --to-destination 192.168.199.152:8080  将目标地址135转换为152的地址,并将135的80端口映射为152的8080端口
	iptables -t nat -A PREROUTING -d 172.16.73.135 -p tcp --dport 22012 -j DNAT --to-destination 192.168.199.101:22 将135的ssh的端口映射为101主机的22端口,并将其目标地址转换为101地址
	03、测试
	在6.7主机使用curl http://172.16.73.137:80(默认端口可以省略)
	然后就直接返回了192.168.199.152的主页,这就实现了目标地址转换和端口映射的功能。
	ssh -p 22012 root@172.16.73.135 会直接映射到192.168.199.101的ssh的22端口

补充:利用iptables 的recent模块来抵御DOS攻击:22,建立一个列表,保存有所有访问过指定的服务的客户端IP
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 LOG --log-prefix "SSH Attach: "

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内只能与本机建立2个新连接,被限制五分钟后即可恢复访问。

下面对最后两句做一个说明:
1,第二句是记录访问TCP 22端口的新连接,记录名为SSH
--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目。
2, 第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
--update: 是指每次建立连接都更新列表。
--seconds 必须与--rcheck或者--update同事使用。
--hitcount 必须与--rcheck或者--update同时使用。
3.iptables的记录: /proc/net/xt_recent/SSH

也可以使用下面的这句记录日志:
	iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lufei0920

你的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值