最近接触了linux的防火墙,以前不怎么重视,现一看确实博大精深.其主要作用不光是包过滤,如:某个端口,ip,状态的屏蔽等等,更重要的是,主要承担了做网络NAT转换的功能.我们可以通过iptables的NAT表进行DNAT以及SNAT.其实路由器的NAT模式也是如此原理.很多先前觉得神奇的功能都可以再iptables中找到解答.
当数据包到达防火墙时,如果MAC地址符合,就会由内核里相应的驱动程序接收,然后会经过一系列操作,从而决定是发送给本地的程序,还是转发给其他机子,还是其他的什么. 下面是一个包数据流经图..
1.以本地为目标的包的经由路径:
mangle(PREROUTING)—— nat(PREROUTING)-——ROUTING decision(路由判断)——mangle(INPUT)——filter(INPUT)——到达本地程序
2.本地发起的包:
mangle(OUTPUT)——nat(OUTPUT)——filter(OUTPUT)——mangle(POSTROUTING)——nat(POSTROUTING)——离开接口如eth0
3.通过本地转发的包:
mangle(PREROUTING)—— nat(PREROUTING)-——ROUTING decision(路由判断)——mangle(OUTPUT)——nat(OUTPUT)——filter(OUTPUT)——mangle(POSTROUTING)——nat(POSTROUTING)——离开接口如eth0
其中mangle主要做:TOS,TTL,MARK
nat主要做DNAT,SNAT,MASQUERADE
filter主要做过滤
下面是一些经验:
1)当做了snat后,即:-j snat --to--source x.x.x.x.,之后就跳过该链了,如果下面再做就不执行了...
2)当使用一台机器做代理转发的时候,需要将filter表中FORWARD链打开 A FORWARD -j ACCEPT
实验一:举例做一个代理,模型为:在75对36访问ssh,36配置防火墙转发到76上 :
PREROUTING -p tcp -m tcp --dport 22 -j LOG --log-prefix "pre-port-1"PREROUTING -s 192.168.4.75/32 -j DNAT --to-destination 192.168.4.76
POSTROUTING -p tcp -m tcp --dport 22 -j LOG --log-prefix "post-port-1"
POSTROUTING -s 192.168.4.75/32 -j SNAT --to-source 192.168.4.36
此外还需要打开FORWARD,不然会在这里被过滤掉.
FORWARD -j ACCEPT
使用tcpdump抓取日志(tcpdump port 22 -i eth1 -n):
08:27:07.510600 IP 192.168.4.75.37486 > 192.168.4.36.ssh: Flags [.], ack 1, win 46, options [nop,nop,TS val 84817947 ecr 84412689], length 008:27:07.510651 IP 192.168.4.36.37486 > 192.168.4.76.ssh: Flags [.], ack 1, win 46, options [nop,nop,TS val 84817947 ecr 84412689], length 0
08:27:07.516920 IP 192.168.4.76.ssh > 192.168.4.36.37486: Flags [P.], seq 1:22, ack 1, win 46, options [nop,nop,TS val 84412696 ecr 84817947], length 21
08:27:07.516986 IP 192.168.4.36.ssh > 192.168.4.75.37486: Flags [P.], seq 1:22, ack 1, win 46, options [nop,nop,TS val 84412696 ecr 84817947], length 21
08:27:07.517649 IP 192.168.4.75.37486 > 192.168.4.36.ssh:
可见数据传输是:75-》36-》76》36-》75,36做了中转代理.
防火墙日志:
Jun 19 08:28:55 localhost kernel: pre-port-1IN=eth1 OUT= MAC=52:54:00:cf:ce:d8:44:37:e6:5c:c6:f5:08:00 SRC=192.168.4.75 DST=192.168.4.36 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=59497 DF PROTO=TCP SPT=46619 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0Jun 19 08:28:55 localhost kernel: forward-1IN=eth1 OUT=eth1 SRC=192.168.4.75 DST=192.168.4.76 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=59497 DF PROTO=TCP SPT=46619 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Jun 19 08:28:55 localhost kernel: post-port-1IN= OUT=eth1 SRC=192.168.4.75 DST=192.168.4.76 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=59497 DF PROTO=TCP SPT=46619 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Jun 19 08:28:55 localhost kernel: forward-1IN=eth1 OUT=eth1 SRC=192.168.4.75 DST=192.168.4.76 LEN=52 TOS=0x00 PREC=0x00 TTL=62 ID=59498 DF PROTO=TCP SPT=46619 DPT=22 WINDOW=46 RES=0x00 ACK URGP=0Jun 19 08:28:55 localhost kernel: forward-1IN=eth1 OUT=eth1 SRC=192.168.4.75 DST=192.168.4.76 LEN=52 TOS=0x00 PREC=0x00 TTL=62 ID=59499 DF
日志只有包过去,没有过来,先做prerouting,DST地址转化,再经过filter表的FORWARD链,这个时候DST为76,然后经过POSTROUTING,这个时候SRC修改为36.再后面出linux到网络到达76,这个时候不断重复FORWARD日志,因为PREROUTING,POSTROUTING只会经过一次,而回来的包也没这两个日志,也可能是先前经过了,回来不经过了..
实验二:使用42做代理,只代理某个端口到73
-A PREROUTING -p tcp -m tcp --dport 5901 -j DNAT --to-destination 192.168.4.73:5903-A POSTROUTING -p tcp -m tcp --dport 5901 -j SNAT --to-source 192.168.4.42
这里做snat不能写为:-j SNAT --to-source 192.168.4.42:5903,否则会异常,只能连上一次.