且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

iptables基础详解与实例

更新时间:2022-09-06 13:25:15

一、iptables定义

iptables是一个工作于用户空间防火墙应用软件,允许系统管理员可以调整设置X表(Xtables)提供相关的系统表格(目前主要位于iptables/netfilter)以及相关的“链”与“规则”来管理网络数据包的流动与转送的动作。因相关动作上的需要,iptables的操作需要用到超级用户的权限。在大部份的Linux系统上面,iptables是使用/usr/sbin/iptables来操作,文件则放置在手册页(Man page[2])底下,可以通过 man iptables 指令取得。通常iptables都需要内核层级的模块来配合运作,Xtables是主要在内核层级里面iptables API运作功能的模块。

主机防火墙:网络层防火墙可视为一种 IP 数据包过滤器,运作在底层的TCP/IP协议堆栈上

网络防火墙:工作于网络边缘的硬件设备;对于到达网络的数据包根据某种规则进行过滤处理。


二、iptables的四表和五链

四表

raw
设置为raw时不再iptables做数据包连接跟踪处理
mangle 用于对数据包的一些传输特性进行修改(TOS、TTL...)
nat 用于对地址转发功能(端口映射、地址隐射等)
filter 对数据包的过滤功能(最常用的;默认项)


五链

PREROUTING 数据包进入路由之前
INPUT 数据通过路由表后的目标位本机
FORWARD 数据通过路由表后的目标不为本机
OUTPUT 由本机出去的数据包向外发送
POSTROUTING 从网卡接口出去之前


对应关系

FORWARD filter、mangle
INPUT filter、mangle
OUTPUT filter、mangle、nat
PREROUTING mangle、nat
POSTROUTING mangle、nat



filter INPUT、FORWARD、OUTPUT
nat PREROUTING、OUTPUT、POSTROUTING
mangle PREROUTING、INPUT、OUTPUT、FORWARD、POSTROUTING
raw PREROUTING、OUTPUT



三、基本的用法

1、格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[Linux85]#man iptables
IPTABLES(8)                     iptables 1.4.7                     IPTABLES(8)
NAME
       iptables -- administration tool for IPv4 packet filtering and NAT
SYNOPSIS
       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...]
            #-F:清空链中的规则
            #-L:列出表中的所有规则
            #-Z:清空规则计数器
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
       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
        #修改自定义链名称


2、匹配条件

  • 通用匹配

    -s
    匹配源地址;ip或网络地址;! 可以取反。
    -d 匹配目标地址;ip或网络地址;! 可以取反。
    -p 匹配协议{tcp|udp|icmp}
    -i 数据报文流入的接口;通常{INPUT|FORWARD|PREROUTING}
    -o 数据报文流出的接口;通常{OUTPUT|FORWARD|POSTROUTING}
  • 扩展匹配

   隐含扩展:使用-p{tcp|udp|icmp}指定某特定协议后;自动能够对协议进行的扩展

       --dport m[-n]:匹配的目标端口;可以是连续的多个端口

       --sport m[-n]:匹配的目标端口;可以是连续的多个端口

       --tcp-flags:根据tcp的标志位来匹配

       --icmp-type:icmp的状态


   显式扩展:必须要明确指定的扩展模块

    -m:扩展模块名称 --专用选项1 --专用选项2...(/lib64/xtables/*)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Linux85]#ls /lib64/xtables/
libip6t_HL.so          libipt_SET.so         libxt_SECMARK.so      libxt_osf.so
libip6t_LOG.so         libipt_SNAT.so        libxt_TCPMSS.so       libxt_owner.so
libip6t_REJECT.so      libipt_TTL.so         libxt_TCPOPTSTRIP.so  libxt_physdev.so
libip6t_ah.so          libipt_ULOG.so        libxt_TOS.so          libxt_pkttype.so
libip6t_dst.so         libipt_addrtype.so    libxt_TPROXY.so       libxt_policy.so
libip6t_eui64.so       libipt_ah.so          libxt_TRACE.so        libxt_quota.so
libip6t_frag.so        libipt_ecn.so         libxt_cluster.so      libxt_rateest.so
libip6t_hbh.so         libipt_icmp.so        libxt_comment.so      libxt_recent.so
libip6t_hl.so          libipt_realm.so       libxt_connbytes.so    libxt_sctp.so
libip6t_icmp6.so       libipt_set.so         libxt_connlimit.so    libxt_socket.so
libip6t_ipv6header.so  libipt_ttl.so         libxt_connmark.so     libxt_standard.so
libip6t_mh.so          libipt_unclean.so     libxt_conntrack.so    libxt_state.so
libip6t_rt.so          libxt_AUDIT.so        libxt_dccp.so         libxt_statistic.so
libipt_CLUSTERIP.so    libxt_CHECKSUM.so     libxt_dscp.so         libxt_string.so
libipt_DNAT.so         libxt_CLASSIFY.so     libxt_esp.so          libxt_tcp.so
libipt_ECN.so          libxt_CONNMARK.so     libxt_hashlimit.so    libxt_tcpmss.so
libipt_LOG.so          libxt_CONNSECMARK.so  libxt_helper.so       libxt_time.so
libipt_MASQUERADE.so   libxt_DSCP.so         libxt_iprange.so      libxt_tos.so
libipt_MIRROR.so       libxt_MARK.so         libxt_length.so       libxt_u32.so
libipt_NETMAP.so       libxt_NFLOG.so        libxt_limit.so        libxt_udp.so
libipt_REDIRECT.so     libxt_NFQUEUE.so      libxt_mac.so
libipt_REJECT.so       libxt_NOTRACK.so      libxt_mark.so
libipt_SAME.so         libxt_RATEEST.so      libxt_multiport.so
    • multiport:多端口匹配;一次指定多个(15个以内的)离散端口
      [!] --sports port[,port|,port:port] 源端口
      [!] --dports port[,port|,port:port] 目标端口
      [!] --ports port[,port|,port:port] 不区分源与目标端口
    • string:字符串匹配
      --algo {bm|kmp} 字符匹配查找时使用算法;必选
      [!] --string pattern 要查找的字符串;可以取反
      [!] --hex-string pattern 要查找的字符;先编码成16进制的格式
    • iprange:ip地址范围
      [!] --src-range from[-to] 源IP;
      [!] --dst-range from[-to] 目标IP;
    • time:指定时间范围
      --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...] 每周几
    • limit:报文速率控制
      --limit rate[/second|/minute|/hour|/day] number/单位
      --limit-burst number 峰值;最大值
    • connlimit:每IP对指定服务最大并发连接数
      [!] --connlimit-above n 并发超出个数
    • state:状态匹配;根据netfilter内部会话表匹配;能建立连接的都能追踪

      根据ip_conntrack和nf_conntrack来实现对整个系统连接追踪
      INVALID 无法识别的连接;例如:tcp-flags ALL ALL/ALL NONE
      ESTABLISHED 已建立连接的
      NEW 新建立的连接
      RELATED 相关联的;例如命令连接到数据连接
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      [Linux85]#iptables -A INPUT -d 172.16.251.85 -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
      #使用state后;连接追踪模块会自动加载
      [Linux85]#lsmod
      Module                  Size  Used by
      nf_conntrack_ipv4       9506  2
      nf_defrag_ipv4          1483  1 nf_conntrack_ipv4
      xt_state                1492  2
      nf_conntrack           79758  2 nf_conntrack_ipv4,xt_state
      [Linux85]#iptables -L -n -v
      Chain INPUT (policy ACCEPT 1 packets, 40 bytes)
       pkts bytes target     prot opt in     out     source               destination   
         50  3768 ACCEPT     tcp  --  eth0   *       0.0.0.0/0            172.16.251.85       tcp dpt:22 state NEW,ESTABLISHED
      Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination   
      Chain OUTPUT (policy ACCEPT 35 packets, 3252 bytes)
       pkts bytes target     prot opt in     out     source               destination   
      [Linux85]#cat /proc/sys/net/nf_conntrack_max
      15692  #定义了连接追踪的最大值;可以按需调整
      [Linux85]#
      [Linux85]#iptables -L -n -v
      Chain INPUT (policy DROP 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination   
        357 25520 ACCEPT     tcp  --  eth0   *       0.0.0.0/0            172.16.251.85       tcp dpt:22 state NEW,ESTABLISHED
      Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination   
      Chain OUTPUT (policy DROP 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination   
         63  6928 ACCEPT     tcp  --  *      *       172.16.251.85        0.0.0.0/0           tcp spt:22 state ESTABLISHED



四、实例演示

1、自定义一个规则链;过滤非法数据包;并被调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[Linux85]#iptables -N clean_in
#建立一条空规则链
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
[Linux85]#iptables -A clean_in -d 172.16.251.85 -p tcp --tcp-flags ALL ALL -j DROP
#DROP掉tcp-flags值全为1的
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
[Linux85]#iptables -A clean_in -d 172.16.251.85 -p tcp --tcp-flags ALL NONE -j DROP
#DROP掉tcp-flags值全为0的
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
[Linux85]#iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
[Linux85]#iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# 广播包
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
[Linux85]#iptables -A clean_in -d 172.16.251.85 -j RETURN
#检测完无匹配就跳回主链;继续下一条检测
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
[Linux85]#iptables -A INPUT -d 172.16.251.85 -j clean_in
#在INPUT调用
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
[Linux85]#iptables -L -n -v
Chain INPUT (policy ACCEPT 38 packets, 2738 bytes)
 pkts bytes target     prot opt in     out     source               destination   
   35  2504 clean_in   all  --  *      *       0.0.0.0/0            172.16.251.85 
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   
Chain OUTPUT (policy ACCEPT 23 packets, 3260 bytes)
 pkts bytes target     prot opt in     out     source               destination   
Chain clean_in (1 references)
 pkts bytes target     prot opt in     out     source               destination   
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            172.16.251.85       tcp flags:0x3F/0x3F
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            172.16.251.85       tcp flags:0x3F/0x00
    0     0 DROP       icmp --  *      *       0.0.0.0/0            172.16.255.255
    0     0 DROP       icmp --  *      *       0.0.0.0/0            255.255.255.255
   35  2504 RETURN     all  --  *      *       0.0.0.0/0            172.16.251.85


2、放行本机的ssh端口给指定IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Linux85]#iptables -A INPUT -s 172.16.254.28 -d 172.16.251.85 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
#放行新建立和已连接的
[Linux85]#iptables -A OUTPUT -s 172.16.251.85 -m state --state ESTABLISHED -j ACCEPT
#放行已连接的状态
[Linux85]#iptables -P INPUT DROP
[Linux85]#iptables -P OUTPUT DROP
[Linux85]#iptables -L -n -v
Chain INPUT (policy DROP 11 packets, 1378 bytes)
 pkts bytes target     prot opt in     out     source               destination   
  396 29036 ACCEPT     tcp  --  *      *       172.16.254.28        172.16.251.85       tcp dpt:22 state NEW,ESTABLISHED
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   
   91  8328 ACCEPT     all  --  *      *       172.16.251.85        0.0.0.0/0           state ESTABLISHED
[Linux87]#ssh 172.16.251.85
ssh: connect to host 172.16.251.85 port 22: Connection timed out
[Linux87]#测试87这台机器无法连接


3、本机禁ping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Linux86]#ping 172.16.251.87
PING 172.16.251.87 (172.16.251.8756(84) bytes of data.
64 bytes from 172.16.251.87: icmp_seq=1 ttl=64 time=0.848 ms
64 bytes from 172.16.251.87: icmp_seq=2 ttl=64 time=0.401 ms
64 bytes from 172.16.251.87: icmp_seq=3 ttl=64 time=0.412 ms
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[Linux87]#iptables -A INPUT -d 172.16.251.87 -p icmp --icmp-type 8 -j DROP
#禁止任何主机对于本机的icmp的请求
[Linux87]#iptables -L -vn       查看已匹配到包
Chain INPUT (policy ACCEPT 221 packets, 27594 bytes)
 pkts bytes target     prot opt in     out     source               destination    
   71  5964 DROP       icmp --  *      *       0.0.0.0/0            172.16.251.87       icmp type 8
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
Chain OUTPUT (policy ACCEPT 98 packets, 14732 bytes)
 pkts bytes target     prot opt in     out     source               destination
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[Linux86]#ping 172.16.251.87   已经无法ping了
PING 172.16.251.87 (172.16.251.8756(84) bytes of data.


4、放行本机80端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#首先先放行ssh的22号端口
[Linux86]#iptables -A INPUT -d 172.16.251.86 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
[Linux86]#iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
[Linux86]#iptables -P INPUT DROP
[Linux86]#iptables -P OUTPUT DROP
[Linux87]#curl http://172.16.251.86/index.html
curl: (7) couldn't connect to host
[Linux87]#
#测试无法访问
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
[Linux86]#iptables -A INPUT -d 172.16.251.86 -p tcp --dport 80 -m state --state NEW -j ACCEPT
#放行80端口
[Linux87]#curl http://172.16.251.86/index.html
This a test Page!
[Linux87]#测试可以访问了
[Linux86]#iptables -L -nv
Chain INPUT (policy DROP 76 packets, 11352 bytes)
 pkts bytes target     prot opt in     out     source               destination    
  340 27369 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       tcp dpt:22 state NEW
    3   164 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       tcp dpt:80 state NEW
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
  304 34487 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state ESTABLISHED
#上述都可以看到匹配的包


5、放行被动工作的ftp服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
[Linux87]#lftp 172.16.251.86/pub
cd `ftp://172.16.251.86/pub' [Connecting...]
#测试目前无法连接
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
[Linux86]#iptables -A OUTPUT -s 172.16.251.86 -p tcp --sport 21 -j ACCEPT
[Linux86]#iptables -A INPUT -d 172.16.251.86 -p tcp --dport 21 -j ACCEPT
[Linux86]#iptables -A INPUT -d 172.16.251.86 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
[Linux86]#iptables -A OUTPUT -s 172.16.251.86 -p tcp -m state --state ESTABLISHED -j ACCEPT
#上述是放行ftp的端口和相关联的会话连接;还需要装载两个模块才能生效
[Linux86]#modprobe nf_nat_ftp
[Linux86]#modprobe nf_conntrack_ftp
[Linux86]#vi /etc/sysconfig/iptables-config
# Load additional iptables modules (nat helpers)
#   Default: -none-
# Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES="nf_nat_ftp nf_conntrack_ftp"
#写到配置文件;下次开机可以自动装载
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
[Linux87]#lftp 172.16.251.86/pub
cd ok, cwd=/pub
lftp 172.16.251.86:/pub> ls
-rw-r--r--    1 0        0             103 Mar 24 06:23 issue
lftp 172.16.251.86:/pub> #测试可以正常访问了
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
[Linux86]#iptables -L -nv
Chain INPUT (policy DROP 326 packets, 41008 bytes)
 pkts bytes target     prot opt in     out     source               destination    
 1115 80408 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       tcp dpt:22
  174  9245 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       tcp dpt:21
   14   696 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       state RELATED,ESTABLISHED
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
Chain OUTPUT (policy DROP 13 packets, 780 bytes)
 pkts bytes target     prot opt in     out     source               destination    
  671 72480 ACCEPT     tcp  --  *      *       172.16.251.86        0.0.0.0/0           tcp spt:22
  199 13355 ACCEPT     tcp  --  *      *       172.16.251.86        0.0.0.0/0           tcp spt:21
   14   885 ACCEPT     tcp  --  *      *       172.16.251.86        0.0.0.0/0           state ESTABLISHED
匹配到了包;对于上述规则可以进行优化处理;下述进行优化规则
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
[Linux86]#iptables -I INPUT 1 -d 172.26.251.86 -m state --state RELATED,ESTABLISHED -j ACCEPT
[Linux86]#iptables -I INPUT 2 -d 172.26.251.86 -p tcp -m multiport --dports 21,22 -m state --state NEW -j ACCEPT
[Linux86]#iptables -I OUTPUT 1 -s 172.16.251.86 -m state --state ESTABLISHED -j ACCEPT
[Linux86]#iptables -L -nv
Chain INPUT (policy DROP 2 packets, 406 bytes)
 pkts bytes target     prot opt in     out     source               destination    
  380 29174 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       state RELATED,ESTABLISHED
    2   104 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       state NEW multiport dports 22,21
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
   50  6192 ACCEPT     all  --  *      *       172.16.251.86        0.0.0.0/0           state ESTABLISHED
#优化后;测试ftp正常;且还可以放行例如80等端口


6、屏蔽指定字符串的网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Linux87]#curl http://172.16.251.86/admin.html
This a admin page!
[Linux87]#curl http://172.16.251.86/index.html
This a test Page!
[Linux87]#
上述访问正常;下面来写规则进行屏蔽admin字符的页面
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[Linux86]#iptables -I INPUT 1 -d 172.16.251.86 -p tcp -m string --algo bm --string "admin" -j DROP
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[Linux87]#curl http://172.16.251.86/index.html
This a test Page!
[Linux87]#curl http://172.16.251.86/admin.html
curl: (52) Empty reply from server
[Linux87]#
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
[Linux86]#iptables -L -nv
Chain INPUT (policy DROP 13 packets, 1264 bytes)
 pkts bytes target     prot opt in     out     source               destination    
   13  5510 DROP       tcp  --  *      *       0.0.0.0/0            172.16.251.86       STRING match "admin" ALGO name bm TO 65535
  931 79380 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       state RELATED,ESTABLISHED
   12   672 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.251.86       multiport dports 22,21,80 state NEW
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination    
  416 47643 ACCEPT     all  --  *      *       172.16.251.86        0.0.0.0/0           state ESTABLISHED


五、配置nat转发在不同网络放行web等服务

NAT:网络地址转换;iptables基于SNAT和DNAT这两个目标实现地址转换技术。

SNAT:源地址转换;用于让内网主机访问互联网。在POSTROUTING或OUTPUT上写规则。

DNAT:目标地址转换;让互联网上主机访问本地内网中的某服务器上的服务。在PREROUTING上写规则。


大致规划:

配置三台虚拟机:

linux87:172.16.251.87(内网)/192.168.111.11(外网)

linux86:172.16.251.86    网关指向:172.16.251.87

linux12:192.168.111.12  

假设由192.168.111.12充当外网提供ftp和web等服务;

linux87:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Linux87]#ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:5E:1E:4F
          inet addr:172.16.251.87  Bcast:172.16.255.255  Mask:255.255.0.0
          inet6 addr: fe80::20c:29ff:fe5e:1e4f/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:44356 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8569 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:5091283 (4.8 MiB)  TX bytes:4238794 (4.0 MiB)
          Interrupt:19 Base address:0x2000
eth1      Link encap:Ethernet  HWaddr 00:0C:29:5E:1E:59
          inet addr:192.168.111.11  Bcast:192.168.111.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe5e:1e59/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:122 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:11513 (11.2 KiB)  TX bytes:2615 (2.5 KiB)
                                                                                                                                                                                                                                                                                                                                             
#配置好IP地址后开启转发功能;
[Linux87]#sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
[Linux87]#

linux86:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Linux86]#ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:DF:70:B6
          inet addr:172.16.251.86  Bcast:172.16.255.255  Mask:255.255.0.0
          inet6 addr: fe80::20c:29ff:fedf:70b6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:21060 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5558 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1984222 (1.8 MiB)  TX bytes:707372 (690.7 KiB)
#配置网关
[Linux86]#route add default gw 172.16.251.87
[Linux86]#route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.16.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0
0.0.0.0         172.16.251.87   0.0.0.0         UG    0      0        0 eth0


为了演示方便;这里先把192.168.111.12的网关指向111.11;后续操作时在删除这个网关

linux12:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Linux12]#ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:4D:AE:B9
          inet addr:192.168.111.12  Bcast:192.168.111.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe4d:aeb9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:268 errors:0 dropped:0 overruns:0 frame:0
          TX packets:180 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:23231 (22.6 KiB)  TX byte
                                                                                                                                                                                                                                                                                                                               
#提供ftp和web等服务
[Linux12]#ss -tunl | grep 80
tcp    LISTEN     0      128                   :::80                   :::* 
[Linux12]#ss -tunl | grep 21
udp    UNCONN     0      0                      *:35216                 *:* 
tcp    LISTEN     0      32                     *:21                    *:* 
[Linux12]#
[Linux12]#vi /var/www/html/index.html
This is 192.168.111.12 page!
[Linux12]#cd /var/ftp/pub/
[Linux12]#touch 192.168.111.12.txt
[Linux12]#ls
192.168.111.12.txt
[Linux12]#


上述配置完成后内部网络其实已经可以访问了;因为转发功能已开启;且网关都以指向251.87这台机器;所以这里可以看下效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Linux87]#curl http://192.168.111.12
This is 192.168.111.12 page!
[Linux87]#
[Linux86]#curl http://192.168.111.12
This is 192.168.111.12 page!
[Linux86]#
[Linux86]#lftp 192.168.111.12/pub
cd ok, cwd=/pub
lftp 192.168.111.12:/pub> ls
-rw-r--r--    1 0        0               0 Mar 28 08:39 192.168.111.12.txt
#测试访问都是正常的
[Linux12]#tail -3 /var/log/httpd/access_log
192.168.111.11 - - [28/Mar/2014:16:42:39 +0800"GET / HTTP/1.1" 200 29 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" #这台是中间路由机器
172.16.251.86 - - [28/Mar/2014:16:45:26 +0800"GET / HTTP/1.1" 200 29 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" #这台是linux86
172.16.254.28 - - [28/Mar/2014:16:45:45 +0800"GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36" #这台是宿主机的IP
[Linux12]#


下面先把192.168.111.12上的网关删除;而后做SNAT转发后在查看下日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Linux86]#curl http://192.168.111.12
curl: (7) couldn't connect to host
[Linux86]#
下面写入规则
[Linux87]#iptables -t nat -A POSTROUTING -s 172.16.251.86 -j SNAT --to-source 192.168.111.11
[Linux86]#curl http://192.168.111.12
This is 192.168.111.12 page!
[Linux86]#再次测试;访问正常
加入网关;来查看下日志
[Linux12]# tail -4 /var/log/httpd/access_log
172.16.254.28 - - [28/Mar/2014:16:45:45 +0800"GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36"
192.168.111.11 - - [28/Mar/2014:16:52:33 +0800"GET / HTTP/1.1" 200 29 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
192.168.111.11 - - [28/Mar/2014:16:54:31 +0800"GET / HTTP/1.1" 200 29 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
192.168.111.11 - - [28/Mar/2014:16:54:32 +0800"GET / HTTP/1.1" 200 29 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
[Linux12]# 上面的访问地址都已变成linux87这台外网IP了


上面的SNAT转换以成功;下面进行DNAT地址转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Linux87]#ss -tunl | grep 80
[Linux87]#
#linux87主机上不提供web服务
[Linux86]#curl http://172.16.251.87
curl: (7) couldn't connect to host
[Linux86]#测试也无法访问;现在把目标地址转换到192.168.111.12上。此时192.168.111.12不是作为外网提供;可以想象是作为内网的;与SNAT相互调换即可
[Linux87]#iptables -t nat -A PREROUTING  -d 172.16.251.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.111.12
DNAT转换需要在PREROUTING上添加规则
[Linux86]#curl http://172.16.251.87
This is 192.168.111.12 page!
[Linux86]#
#测试访问成功;宿主机上也是可以正常访问的;因为源地址是开放给所有主机的;如需要屏蔽;可以在FORWARD上DROP需要屏蔽的IP即可
                                     
                                     
#支持端口映射;例如
[Linux87]#iptables -t nat -A PREROUTING  -d 172.16.251.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.111.12:8080
可以转换到8080端口的。

至此;基本的iptables已结束;iptables规则除了要写出合适的规则;更重要的是要优化好规则才能更能提高效率。



本文转自Mr_陈 51CTO博客,原文链接:http://blog.51cto.com/chenpipi/1386184,如需转载请自行联系原作者