iptables教程

iptables

netfilter/iptables(简称iptables)是与2.4.x和2.6.x系列版本Linux内核集成的IP信息包过滤系统。

Iptables Tutorial

1、表和链

1.1、表

iptables会根据不同的数据包处理功能使用不同的规则表。它包括如下五个表:filternatmangle,raw,security

  • filter

    filter是默认的表(如果命令中没有使用-t 指定表,就会使用filter),包含真正的防火墙过滤规则。

​ 内建的规则链包括:INPUT(处理进入的数据包)、OUTPUT(处理本地生成的数据包)和FORWARD(处理转发的数据包)。

​ 在filter表中只允许对数据包进行DROP或ACCEPT操作,而无法对数据包进行更改。

  • nat

    nat表主要用于进行网络地址转换(Network Address Translation, NAT)。包含源地址、目的地址及端口转换使用的规则,当遇到创建新连接的数据包时,会查阅此表。

​ 内建的规则链包括PERROUTINGOUTPUTPOSTROUTING

PREROUTING链的作用是在包刚刚到达防火墙时改变它的目的地址(如果需要的话)。

OUTPUT链改变本地产生的包的目的地址。

POSTROUTING链在包就要离开防火墙之前改变其源地址,此表仅用于NAT,也就是转换包的源或目标地址。实际的操作分为以下几类:

​ (1)DNAT:主要用在这样一种情况,即假设你有一个合法的IP地址,要把对防火墙的访问重定向到其他的机器上(比如DMZ)。也就是说,我们改变的是目的地址,以使包能重路由到某台主机。

​ (2)SNAT:SNAT改变包的源地址,这在极大程度上可以隐藏本地网络或者DMZ等。一个很好的例子是我们知道防火墙的外部地址,但必须用这个地址替换本地网络地址。有了这个操作,防火墙就能自动地对包做SNAT和De-SNAT(就是反向的SNAT),以使LAN能连接到Internet。

  • mangle

    mangle表主要用来定义数据包的操作方式。我们可以改变不同的包及包头的内容,比如TTL、TOS或MARK。这些标志随后被filter表中的规则检查。

    内建的规则链包括:PREROUTINGINPUTFORWARDPOSTROUTINGOUTPUT

raw表设置raw一般是为了不再让iptables做数据包的连接跟踪处理提高新能。内建的规则链包括:PREROUTINGOUTPUT

security表用于强制访问控制 (MAC) 网络规则,例如由 SECMARKCONNSECMARK 目标启用的规则。 强制访问控制由 Linux Security Mod‐ 实现诸如SELinux之类的Ules。

1.2、链

链是数据包传播的路径,一条链就是规则的一个检查清单,每一条链中可以有一条或多条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,查看该数据包是否满足规则所定义的条件,决定是否按预定义的方法处理该数据包,如果包头不符合链中的规则,iptables就会根据该链的默认策略来处理数据包。

表对应的相关规则链的功能如下:

❑ INPUT链:当一个数据包由内核中的路由计算确定为本地的Linux系统后,它会通过INPUT链的检查。

❑ OUTPUT链:保留给系统自身生成的数据包。

❑ FORWARD链:经过Linux系统路由的数据包(即当iptables防火墙用于连接两个网络时,两个网络之间的数据包必须流经该防火墙)。

❑ PREROUTING链:用于修改目的地址(DNAT)。

❑ POSTROUTING链:用于修改源地址(SNAT)。

1.3、iptables五条链的相互关系。

iptables教程_第1张图片

1.4 iptables传输数据包的过程

数据包流经iptables防火墙的路径是经过严格定义的一个处理过程,下图描述了数据包流经iptables防火墙时的传输过程。

iptables教程_第2张图片

(1)流入本机的数据包穿过iptables防火墙的传输过程

官方文档位置

过程1:数据包从网络传入,并由网卡接收。

过程2:随后转入mangle表的PREROUTING链。

过程3:再转入nat表的PRETOUTING链,这个链主要用来做DNAT,即目的地址转发。

过程4:内核对数据包进行路由选择。

过程5:因为数据包是传入本机的,因此转入mangle表的INPUT链。

过程6:然后转入filter表的INPUT链。

过程7:最终到达接收数据包的应用程序。

(2)流出本机的数据包穿过iptables防火墙的传输过程

官方文档位置

过程1:应用程序生成数据包,根据源地址、目的地址、外出接口等信息进行路由判断。

过程2:随后转入mangle表的OUTPUT链。

过程3:再转入nat表的OUTPUT链,这个链可以用来做DNAT。

过程4:进入filter表的OUTPUT链,对该数据包进行选择性过滤。

过程5:然后进入mangle表的POSTROUTING链。

过程6:进入nat表的POSTROUTING链,该链可以做SNAT,即源地址转发,最终进入网络。

(3)流经本机转发的数据包的传输过程

官方文档位置

过程1:数据包从网络传入,并由网卡接收。

过程2:随后转入mangle表的PREROUTING链。

过程3:再转入nat表的PRETOUTING链,这个链主要用来做DNAT,即目的地址转发。

过程4:内核对数据包进行路由选择。该包的目的地址是另一台主机,所以转入mangle表的FORWARD链。

过程5:再转入filter表的FORWARD链,针对这类包的所有过滤操作都在该链进行。

过程6:过滤后转入mangle表的POSTROUTING链。

过程7:最后通过nat表的POSTROUTING链进行SNAT,最终进入网络。

(1)用户可以在各个链定义规则。当数据包到达上图的任意一个链时,iptables就会根据链中定义的规则来处理这个数据包。iptables将数据包的头信息与它所传递到链中的每条规则进行比较,看它是否与某条规则完全匹配。如果数据包与某条规则匹配,iptables就对该数据包执行由该规则指定的操作。如果某条链中的规则决定要丢弃(DROP)数据包,数据包就会在该链中丢弃;如果链中规则接收(ACCEPT)数据包,数据包就可以继续前进。但是,如果数据包和某条规则不匹配,那么它将与链中的下一条规则进行比较。如果该数据包不符合该链中的任意一条规则,那么iptables将根据该链预先定义的默认策略来决定如何处理该数据包。

(2)PREROUTINGPOSTROUTING链只对请求连接的数据包进行操作,对属于该连接的后续数据包,不予比对规则,只按已确定的规则自动进行操作。因此建议不要在此链上作过滤操作;否则将漏掉对后续数据包的过滤。

2、iptables命令格式

iptables命令的基本格式如下:<>括起来的为必设项,[]括起来的为可选项。iptables命令要求严格区分大小写。

iptables [-t table]   [chains] [rule-matcher] [ -j target ]

各选项说明:

  • 表选项(table)

    netfilter的表操作是以-t或–table

    来指定的,未指定时默认为filter表。table选项的参数.

    在这里插入图片描述

  • 常用操作命令选项(COMMAND)

    iptables教程_第3张图片

  • 链选项(chains)

    iptables教程_第4张图片

    ➢filter表有INPUT、OUTPUT、FORWARD和自定义4种链形式。

    ➢nat表有OUTPUT、PREROUTING和POSTROUTING三种链形式。

    ➢mangle表有INPUT、OUTPUT、FORWARD、PREROUTING和POSTROUTING五种链形式。

  • 常用匹配规则选项(rule-matcher)

    匹配规则选项指定数据包与规则匹配所应具备的特征,包括源地址、目的地址、传输协议(如TCP、UDP、ICMP等)和端口号等。

    iptables教程_第5张图片

    “! ”为逻辑非;接口名后跟“+”表示所有以此接口名开头的接口都会被匹配。下图为匹配条件扩展。

    iptables教程_第6张图片

  • 目标动作选项(target)

    当规则匹配一个包时,要执行的目标动作以-j参数标识

    • filter表的目标动作

      在这里插入图片描述

    • nat表的目标动作

      iptables教程_第7张图片


      REDIRECT目标用于将分组和流重定向到计算机本身。这意味着,例如,我们可以将所有发送到HTTP端口的数据包重定向到我们自己主机上的HTTP代理,如squid。本地生成的数据包映射到127.0.0.1地址。换句话说,这将为转发的数据包或类似内容重写到我们自己的主机的目标地址。重定向目标非常适合在我们需要的时候使用,例如,透明代理,局域网主机根本不知道代理。

      DNAT参数--to-destination

      例如:iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

      –to-ports 选项指定要使用的目标端口或端口范围。如果没有 --to-ports 选项,则永远不会更改目标端口。上面的命令就是将tcp端口号为80的数据包重定向到8080端口。

    • mangle表的目标动作

      在这里插入图片描述

    • 扩展的目标动作

      iptables教程_第8张图片

      要使用扩展的目标动作,必须在内核中激活相应选项或装载相应内核模块。

3、 iptables的状态state

iptables防火墙的状态(state):

❑ NEW:如果你的主机向远程机器发出一个连接请求,这个数据包的状态是NEW。

❑ ESTABLISHED:在连接建立之后(完成TCP的三次握手后),远程主机和你的主机通信数据的状态为ESTABLISHED。

❑ RELATED:和现有联机相关的新联机封包。像FTP这样的服务,用21端口传送命令,而用20端口(port模式)或其他端口(PASV模式)传送数据。在已有的21端口上建立好连接后发送命令,用20或其他端口传送的数据(FTP-DATA),其状态是RELATED。

❑ INVALID:无效的数据包,不能被识别属于哪个连接或没有任何状态,通常这种状态的数据包会被丢弃。

如规则iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT表示接受ESTABLISHED,RELATED状态的数据包。

如规则 iptables -A INPUT -m state --state NEW -j DROP这个规则是将所有发送到你机器上的数据包(状态是NEW的包)丢弃,也就是不允许其他的机器主动发起对你的机器的连接,但是你却可以主动连接其他的机器。

4、 iptables的使用

  • 规则 iptables -P INPUT DROP会将进入主机的所有数据全部丢掉。如果你是通过远程shell执行这个命令,那么执行后shell将会断开。

比如我的主机当前的规则,所有的都是策略都是ACCEPT

iptables教程_第9张图片

当执行iptables -P INPUT DROP后,远程shell就会断开,这时通过主机内的shell再次查看当前的规则,就能看到INPUT变成了DROP

iptables教程_第10张图片

再次执行iptables -P INPUT ACCEPTipables恢复。

  • 规则 iptables -A INPUT -m state --state NEW -j DROP

    这个规则是将所有发送到你机器上的数据包(状态是NEW的包)丢弃,也就是不允许其他的机器主动发起对你的机器的连接,但是你却可以主动连接其他的机器,不过仅仅是连接而已,连接之后的数据是ESTABLISHED状态的。

    执行上面的规则后,在查看当前的规则,就能看到下面DROP的一条。

iptables教程_第11张图片

这时,如果你本地再新建一条远程shell去连接主机,就会发现无法连接。而之前已经连接的远程shell是可以正常使用的。

iptables教程_第12张图片

5、保存iptables规则

iptables-save > /opt/iptables_save 将当前的iptables配置保存到 /opt/iptables_save中

iptables-restore < /opt/iptables_save 从/opt/iptables_save中恢复iptables的配置

6、一些常用的命令

注意这里没有使用-t参数指定表名,默认显示的就是filter表,如果要显示其他的表,需要使用-t后加表名。如-t nat

  • 查看iptables规则

    iptables -L
    

    -L参数可以后跟--line-numbers 参数打印出行号。

    iptables -L --line-numbers 。后面命令中指定插入行号,替换行号等等都可以参照--line-numbers输出的行号

  • 将IP地址和端口号以数字格式显示列出所有链的规则。

    iptables -nL
    
  • 详细列出所有链的规则

    iptables -vL
    #不能使用 iptables -Lv
    
  • 列出INPUT链的规则

    iptables -L INPUT
    
  • 列出INPUT链的1号规则

    iptables -L INPUT 1
    
  • 显示所有链的规则

    iptables -S
    
  • 详细显示所有链的规则

    iptables -vS
    #不能使用iptables -Sv
    
  • 显示INPUT链的规则

    iptables -S INPUT
    
  • 显示INPUT链的1号规则

    iptables -S INPUT 1
    

    清除指定链和表中的所有规则

  • 清除所有链的规则(默认为filter表)

    iptables -F
    
  • 清楚INPUT链的所有规则

    iptables -F INPUT
    
  • 将所有链中的规则的包字节计数器清零。

    iptables -Z
    
  • 将INPUT链中的规则的包字节计数器清零

    iptables -Z INPUT
    
  • 在INPUT、OUTPUT和FORWARD链上设置默认规则策略为DROP(拒绝所有数据包)

    iptables -P INPUT ACCEPT
    iptables -P OUTPUT ACCEPT
    iptables -P FORWARD ACCEPT
    
  • 在INPUT链上添加规则,协议为tcp,目标端口号是21

    iptables -A INPUT -p tcp --dport 21
    

    这里没有指定动作,所以就按照INPUT的默认动作进行处理。

    执行完上面的命令再次查看,就会看到INPUT中多了一个对应的条目

    iptables教程_第13张图片

  • 在INPUT链上插入规则,协议为tcp,目标端口号是22

iptables -I INPUT 1 -p tcp --dport 23

​ 从下图也能看到多了一条dpt:telnet的条目,原来的dpt:ftp的行号已经变成了2

iptables教程_第14张图片

  • 在INPUT链上替换规则号1的iptables规则,将目标端口号更改为24

     iptables -R INPUT 1 -p tcp --dport 24
    

iptables教程_第15张图片

  • 删除规则

    首先找到规则对应的行号。使用-L --line-numbers参数。

    比如要删除上面INPUT中的tcp端口是24的规则。通过iptables -L --line-numbers看到对应行号是1。

    执行iptables -D INPUT 1就可以删除。

  • 创建用户自定义链

    iptables -N WWW   #创建用户自定义链WWW
    

    iptables教程_第16张图片

  • 指定协议

    iptables -A INPUT -p tcp -j ACCEPT
    iptables -A INPUT -p udp -j ACCEPT
    
  • 指定ICMP类型

    iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
    iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
    iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
    
  • 指定IP地址

    iptables -A INPUT -s 192.168.0.5   -j ACCEPT
    iptables -A INPUT -s 192.168.1.0/24   -j ACCEPT  #允许192.168.1.0这个子网的所有主机访问
    
  • 指定接口

    iptables -A INPUT -i eth0 -j ACCEPT
    iptables -A FORWARD -o eth0 -j ACCEPT
    iptables -A FORWARD -o ppp+ -j ACCEPT
    
  • 指定端口号

    iptables -A INPUT -p tcp --sport www -j ACCEPT
    iptables -A INPUT -p tcp --sport 80-j ACCEPT
    iptables -A INPUT -p tcp --dport 53-j ACCEPT
    iptables -A INPUT -p tcp --sport 22:80-j ACCEPT
    

7、NAT案例:

使用NAT功能,首先需要将文件“/proc/sys/net/ipv4/ip_forward”设置为1(默认是0),才能打开内核的路由功能。

具体命令如下:

echo "1">/proc/sys/net/ipv4/ip_forward

iptables教程_第17张图片

上面有A、B、C三个服务。它们都在同一局域网内。A服务器有公网 ip 10.x.x.x。B、C都没有公网ip。B、C两个服务器连接公网都需要通过A服务器进行转发。外部网路无法直接访问B、C服务器。A服务器也就是充当了路由器。

现在B服务器部署了一个nginx服务,想让公网上的用户访问需要怎么做呢。

  1. 外部公网服务器访问nginx服务器

因为公网只能访问到A服务器,所以我们可以在A服务器上进行DNAT处理,将访问A服务器80端口的请求全部转发到B服务器。由于DNAT只会修改目标ip,不会修改源ip。所以在B 服务器处理完请求,还会把响应继续发送到A服务器,A服务器这时会对B服务器返回的响应继续执行unDNAT操作,将响应返回对应的公网服务器。

具体的命令如下:

#这个命令需要在A服务器上执行,将访问自己公网ip:80的请求转发到B服务器80端口
iptables -t nat -A PREROUTING --dst 10.x.x.x  -p tcp --dport 80 -j DNAT --to-destination 192.168.1.102:80

iptables教程_第18张图片

如上图,我们在A服务器上面标注1的地方将目标ip修改成了B服务器的ip 192.168.1.102,在标注2的地方路由选择的时候,发现目的ip不是本机,就直接进行转发。

进行路线就是图上红色箭头标注的路线,可以看到数据包压根就不会流转到INPUT mangleOUTPUT filter这一段。

这样设置之后公网服务器是可以正常访问,没有任何问题。

  1. 局域网内部访问nginx服务器

C服务器通过请求10.x.x.x:80去访问的时候,发现无法访问。

具体的原因是由于B服务器处理完请求写回的时候发现ip是192.168.1.101,不需要经过A服务器就能直接访问。因此B直接将响应发送回C服务器。但是由于C服务器只是给A服务器10.x.x.x发送了请求,并没有给B服务器192.168.1.102发送请求,所以收到B服务器192.168.1.102的响应后,就直接丢弃了。

所以我们还需要B服务器处理完请求后,依旧能返回到A服务器,由A服务器将请求再转发回C服务器。当前B服务器将响应发送回C,没有发送回A的原因是发送给B的请求的源ip是C的ip。所以我只需要把B服务器收到的请求中的源ip修改成A服务器的ip,那B服务器处理完后,就会将响应发送回A服务器。A服务器收到响应后,就会继续向回转发。

具体命令如下:

# 在A服务器上执行,将发送给B服务器80端口的消息,将源ip修改成自己的ip地址
iptables -t nat -A POSTROUTING -p tcp --dst 192.168.68.102 --dport 80 -j SNAT --to-source 10.x.x.x

iptables教程_第19张图片

如上图,我们在标注3的地方修改了源ip地址,改成了A服务器的地址,这样B服务器处理完请求返回响应的时候回根据源ip地址,将请求发送到A服务器。A服务器收到请求后回原路返回。

  1. A服务器访问nginx服务器

    A服务器自己请求10.x.x.x:80去访问,还是无法访问。

    对照着图其实也是很好理解的,我们将请求转发到B服务器是在PREOUTING nat执行的,如果的本机的话,压根就不会流转到PREOUTING nat,也就是在PREOUTING nat进行的设置对本机发出的请求都是无效的。

    这时,我们就可以在OUTPUT nat这个阶段进行处理,将本机发出的请求目的ip地址是10.x.x.x:80的,将它的目的ip地址修改成B服务器的ip地址。这样本机也就可以正常访问了。

    具体命令如下:

    #还是在A服务器执行,将A服务器发出的请求目的ip修改成192.168.1.102
    iptables -t nat -A OUTPUT --dst 10.x.x.x -p tcp --dport 80 -j DNAT --to-destination 192.168.1.102:80
    

iptables教程_第20张图片

如上图,本机发出的请求,起点位置在应用程序这里,所以PREROUTING nat不会生效,OUTPUT natPOSTROUTING nat这两个地方的设置才会生效。

你可能感兴趣的:(网络,服务器,linux,缓存,iptables)