iptables防火墙详解

文章目录

  • 一、iptables概念
    • 1、防火墙基础
      • 1.1 防火墙概念
      • 1.2 Netfilter和iptables的区别
    • 2、Iptables的表、链结构
      • 2.1 规则链
      • 2.2 规则表
      • 2.3 规则表之间的顺序
    • 3、规则
      • 3.1 匹配条件
      • 3.2 处理动作
  • 二、iptables规则管理
    • 1、iptables规则操作
      • 1.1 iptables信息查询
      • 1.2 规则添加
      • 1.3 规则删除
      • 1.4 规则修改
      • 1.5 规则保存
    • 2、iptables匹配条件
      • 2.1 常用基本匹配条件
      • 2.2 扩展匹配条件(基本)
      • 2.3 扩展匹配条件(其他)
      • 2.4 扩展匹配条件tcp-flags
      • 2.5 udp扩展与icmp扩展
      • 2.6 state扩展
      • 2.7 mac扩展
  • 三、iptables进阶与提高
    • 2、iptables自定义链
    • 3、iptables之网络防火墙
      • 3.1 概述
      • 3.2 实战demo
    • 4、iptables动作总结
      • 4.1 常用动作之REJECT
      • 4.2 常用动作之LOG
      • 4.3 NAT相关动作(重要)
  • 四、总结
    • 1、配置应用程序规则举例
      • 1.1 SSH
      • 1.2 HTTP
      • 1.3 NAT规则实战
    • 2、iptables常用套路小结

一、iptables概念

1、防火墙基础

1.1 防火墙概念

从逻辑上讲,防火墙可以大体分为主机防火墙和网络防火墙。网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体), 主机防火墙主内(个人)

  • 主机防火墙:针对于单个主机进行防护
  • 网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网

从物理上讲,防火墙可以分为硬件防火墙和软件防火墙

  • 硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高
  • 软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低

Linux防火墙体系主要工作在网络层,针对TCP/IP数据包实施过滤和限制,属于典型的包过滤防火墙(也称网络层防火墙);Linux防火墙体系基于内核编码实现,具有非常稳定的性能和高效率,因此被广泛的应用

1.2 Netfilter和iptables的区别

Netfilter:指的是Linux内核中实现包过滤防火墙的内部结构,不以程序或文件的形式存在,属于“内核态”(KernelSpace,又称内核空间)的防火墙功能体系(filter是过滤器的意思,netfilter即网络层过滤);Netfilter是Linux操作系统核心层内部的一个数据包处理模块,它具有网络地址转换(Network Address Translate)、数据包内容修改以及数据包过滤的防火墙功能

Iptables:指的是用来管理Linux防火墙的命令程序,通常位于/sbin/iptables,属于“用户态”(UserSpace,又称用户空间)的防火墙管理体系(iptables: IP信息包过滤系统)。虽然我们使用service iptables start启动iptables服务,但是其实准确的来说,iptables并没有一个守护进程,所以并不能算是真正意义上的服务,而应该算是内核提供的功能

2、Iptables的表、链结构

包过滤主要是网络层,针对IP数据包;体现在对包内的IP地址、端口等信息的处理上;而iptables作用是为包过滤机制的实现提供规则(或策略),通过各种不同的规则,告诉netfilter对来自某些源、前往某些目的或具有某些协议特征的数据包应该如何处理。iptables 默认维护着 4 个表和 5 个链,所有的防火墙策略规则都被分别写入这些表与链中

2.1 规则链

规则链上可能不止有一条规则,而是有很多条规则,当我们把这些规则串到一个链条上的时候,就形成了链,ip请求将这条链上的所有规则匹配一遍,如果有符合条件的规则,则执行规则对应的动作。

规则的作用是对数据包进行过滤或处理;链的作用是容纳各种防火墙规则;链的分类依据是处理数据包的不同时机

总共有五种5种规则链,分别是

  • INPUT:处理入站数据包
  • OUTPUT:处理出站数据包
  • FORWARD:处理转发数据包
  • POSTROUTING链:在进行路由选择后处理数据包(对数据链进行源地址修改转换)
  • PREROUTING链:在进行路由选择前处理数据包(做目标地址转换)

INPUT、OUTPUT链主要用在"主机型防火墙"中,即主要针对服务器本机进行保护的防火墙;而FORWARD、PREROUTING、POSTROUTING链多用在"网络型防火墙"中

2.2 规则表

表的作用是容纳各种规则链;表的划分依据是防火墙规则的作用相似,默认包括4个规则表

  • raw表

    确定是否对该数据包进行状态跟踪以及处理异常,表内包含两个链:OUTPUT、PREROUTING

  • mangle表

    为数据包的TOS(服务类型)、TTL(生命周期)值,或者为数据包设置Mark标记,以实现流量整形、策略路由等高级应用。其对应iptable_mangle,表内包含五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD

  • nat表

    修改数据包中的源、目标IP地址或端口;其对应的模块为iptable_nat,表内包括三个链:PREROUTING、POSTROUTING、OUTPUT(centos7中还有INPUT,centos6中没有)

    PREROUTING链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)。POSTROUTING链 – 处理即将离开本机的数据包。它会转换数据包中的源IP地址(source ip address),通常用于SNAT(source NAT)。OUTPUT链 – 处理本机产生的数据包

  • filter表

    确定是否放行该数据包(过滤);其对应的内核模块为iptable_filter,表内包含三个链:INPUT、FORWARD、OUTPUT

    INPUT链 – 处理来自外部的数据。OUTPUT链 – 处理向外发送的数据。FORWARD链 – 将数据转发到本机的其他网卡设备上。

2.3 规则表之间的顺序

  • raw->mangle->nat->filter

  • 规则链之间的顺序

    • 入站:PREROUTING->INPUT
    • 出站:OUTPUT->POSTROUTING
    • 转发:PREROUTING->FORWARD->POSTROUTING
  • 规则链内的匹配顺序

    按顺序依次检查,匹配即停止(LOG策略例外),若找不到相匹配的规则,则按该链的默认策略处理

  • 表和链的关系:表下面是链,表容纳链

3、规则

根据指定的匹配条件来尝试匹配每个流经此处的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理

3.1 匹配条件

基本匹配条件

  • 源地址Source IP,目标地址 Destination IP

扩展匹配条件

  • 除了上述的条件可以用于匹配,还有很多其他的条件可以用于匹配,这些条件泛称为扩展条件,这些扩展条件其实也是netfilter中的一部分,只是以模块的形式存在,如果想要使用这些条件,则需要依赖对应的扩展模块。
  • 源端口Source Port, 目标端口Destination Port

3.2 处理动作

处理动作在iptables中被称为target,动作也可以分为基本动作和扩展动作。此处列出一些常用的动作

ACCEPT:允许数据包通过

DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应

REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息

SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题

MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上

DNAT:目标地址转换

REDIRECT:在本机做端口映射

LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配

二、iptables规则管理

1、iptables规则操作

1.1 iptables信息查询

# filter负责过滤功能,比如允许哪些IP地址访问,拒绝哪些IP地址访问,允许访问哪些端口,禁止访问哪些端口
# filter表会根据我们定义的规则进行过滤,filter表应该是我们最常用到的表了
# 下面两种都可以
# 默认不加-t就是指的filter表
iptables -t filter --list
iptables -t raw -L
iptables -t mangle -L
iptables -t nat -L

# -v是显示详细的信息,列出INPUT链的详细信息
iptables -vL INPUT
# 不让IP进行反解
iptables -nvL INPUT
# 显示规则的序号,--line-numbers选项表示显示规则的序号,注意,此选项为长选项,不能与其他短选项合并,不过此选项可以简写为--line
iptables --line-numbers -t 表名 -L
# 表示查看表中的所有规则,并且显示更详细的信息(-v选项),不过,计数器中的信息显示为精确的计数值,而不是显示为经过可读优化的计数值,-x选项表示显示计数器的精确值
iptables -t 表名 -v -x -L
# 可以合起来,不过-L在最后
iptables --line -t filter -nvxL INPUT

# -----------------------显示界面解释-----------------------
# Chain INPUT (policy ACCEPT 170M packets, 33G bytes)
# policy表示当前链的默认策略,policy ACCEPT表示INPUT的链的默认动作为ACCEPT,换句话说就是,默认接受通过INPUT关卡的所有请求,所以我们在配置INPUT链的具体规则时,应该将需要拒绝的请求配置到规则中
# 说白了就是”黑名单”机制,默认所有人都能通过,只有指定的人不能通过,当我们把INPUT链默认动作设置为接受(ACCEPT),就表示所有人都能通过这个关卡,此时就应该在具体的规则中指定需要拒绝的请求,就表示只有指定的人不能通过这个关卡,这就是黑名单机制
# packets表示当前链(上例为INPUT链)默认策略匹配到的包的数量,0 packets表示默认策略匹配到0个包。
# bytes表示当前链默认策略匹配到的所有包的大小总和。
# 其实,我们可以把packets与bytes称作”计数器”,上图中的计数器记录了默认策略匹配到的报文数量与总大小,”计数器”只会在使用-v选项时,才会显示出来

# pkts:对应规则匹配到的报文的个数。
# bytes:对应匹配到的报文包的大小总和。
# target:规则对应的target,往往表示规则对应的”动作”,即规则匹配成功后需要采取的措施。
# prot:表示规则对应的协议,是否只针对某些协议应用此规则。
# opt:表示规则对应的选项。
# in:表示数据包由哪个接口(网卡)流入,即从哪个网卡来。
# out:表示数据包将由哪个接口(网卡)流出,即到哪个网卡去。
# source:表示规则对应的源头地址,可以是一个IP,也可以是一个网段。
# destination:表示规则对应的目标地址。可以是一个IP,也可以是一个网段

1.2 规则添加

注意:添加规则时,规则的顺序非常重要,哪个先匹配就执行哪个,后面就算有一模一样的也不会执行

# 在指定表的指定链的尾部添加一条规则,-A选项表示在对应链的末尾添加规则,省略-t选项时,表示默认操作filter表中的规则
iptables -t 表名 -A 链名 匹配条件 -j 动作
# 举例,表示丢弃来自192.168.1.146的数据包
# 使用-s选项,指明”匹配条件”中的”源地址”,即如果报文的源地址属于-s对应的地址,那么报文则满足匹配条件,-s为source之意,表示源地址
iptables -t filter -A INPUT -s 192.168.1.146 -j DROP

# 在指定表的指定链的首部添加一条规则,-I选型表示在对应链的开头添加规则
iptables -t 表名 -I 链名 匹配条件 -j 动作
# 举例
iptables -t filter -I INPUT -s 192.168.1.146 -j ACCEPT

# 在指定表的指定链的指定位置添加一条规则
iptables -t 表名 -I 链名 规则序号 匹配条件 -j 动作
iptables -t filter -I INPUT 5 -s 192.168.1.146 -j REJECT

# 设置指定表的指定链的默认策略(默认动作),并非添加规则。
iptables -t 表名 -P 链名 动作
# 表示将filter表中FORWARD链的默认策略设置为ACCEPT
iptables -t filter -P FORWARD ACCEPT

1.3 规则删除

注意:如果没有保存规则,删除规则时请慎重

# 按照规则序号删除规则,删除指定表的指定链的指定规则,-D选项表示删除对应链中的规则
iptables -nvL --line-numbers
iptables -t 表名 -D 链名 规则序号
# 表示删除filter表中INPUT链中序号为3的规则
iptables -t filter -D INPUT 3

# 按照具体的匹配条件与动作删除规则,删除指定表的指定链的指定规则
iptables -t 表名 -D 链名 匹配条件 -j 动作
# 表示删除filter表中INPUT链中源地址为192.168.1.146并且动作为DROP的规则
iptables -t filter -D INPUT -s 192.168.1.146 -j DROP

# 删除指定表的指定链中的所有规则,-F选项表示清空对应链中的规则,执行时需三思
iptables -t 表名 -F 链名
iptables -t filter -F INPUT

# 删除指定表中的所有规则,执行时需三思
iptables -t 表名 -F
iptables -t filter -F

1.4 规则修改

注意:如果使用-R选项修改规则中的动作,那么必须指明原规则中的原匹配条件,例如源IP,目标IP等,如果不写明会变成默认,建议直接新增后删除

# 修改指定表中指定链的指定规则,-R选项表示修改对应链中的规则,使用-R选项时要同时指定对应的链以及规则对应的序号,并且规则中原本的匹配条件不可省略
iptables -t 表名 -R 链名 规则序号 规则原本的匹配条件 -j 动作
# 修改filter表中INPUT链的第3条规则,将这条规则的动作修改为ACCEPT, -s 192.168.1.146为这条规则中原本的匹配条件,如果省略此匹配条件,修改后的规则中的源地址可能会变为0.0.0.0/0
iptables -t filter -R INPUT 3 -s 192.168.1.146 -j ACCEPT
# 其他修改规则的方法:先通过编号删除规则,再在原编号位置添加一条规则

# 修改指定表的指定链的默认策略(默认动作),并非修改规则,可以使用如下命令
iptables -t 表名 -P 链名 动作
# 将filter表中FORWARD链的默认策略修改为ACCEPT
iptables -t filter -P FORWARD ACCEPT

1.5 规则保存

在默认的情况下,我们对"防火墙"所做出的修改都是"临时的",换句话说就是,当重启iptables服务或者重启服务器以后,我们平常添加的规则或者对规则所做出的修改都将消失,为了防止这种情况的发生,我们需要将规则"保存"

# centos6中,使用"service iptables save"命令即可保存规则,规则默认保存在/etc/sysconfig/iptables文件中
service iptables save
# 如果误操作了规则,但是并没有保存,那么使用service iptables restart命令重启iptables以后,规则会再次回到上次保存/etc/sysconfig/iptables文件时的模样
service iptables restart

# centos7中,已经不再使用init风格的脚本启动服务,而是使用unit文件
# 使用firewall替代了原来的iptables service,不过不用担心,我们只要通过yum源安装iptables与iptables-services即可(iptables一般会被默认安装,但是iptables-services在centos7中一般不会被默认安装)
#配置好yum源以后安装iptables-service
yum install -y iptables-services
#停止firewalld
systemctl stop firewalld
#禁止firewalld自动启动
systemctl disable firewalld
#启动iptables
systemctl start iptables
#将iptables设置为开机自动启动,以后即可通过iptables-service控制iptables服务
systemctl enable iptables
# 上述配置过程只需一次,以后即可在centos7中愉快的使用service iptables save命令保存iptables规则了


# 然后是ubuntu的安装
# 首先安装iptables-persistent工具
sudo apt install iptables-persistent
# 每当设置了新的iptables规则后,使用如下命令保存规则即可,规则会根据ipv4和ipv6分别保存在了/etc/iptables/rules.v4和/etc/iptables/rules.v6文件中
netfilter-persistent  save
# 由于 ipt­a­bles-per­sis­tent 在安装时已经把它作为一个服务设置为开机启动了,它在开机后会自动加载已经保存的规则,所以也就达到了永久保存的目的

最后是通用的方法,使用另一种方法保存iptables规则,就是使用iptables-save命令

# 使用iptables-save并不能保存当前的iptables规则,但是可以将当前的iptables规则以”保存后的格式”输出到屏幕上
# 我们可以使用iptables-save命令,再配合重定向,将规则重定向到/etc/sysconfig/iptables文件中即可
iptables-save > /etc/sysconfig/iptables

# 可以将/etc/sysconfig/iptables中的规则重新载入为当前的iptables规则,但是注意,未保存入/etc/sysconfig/iptables文件中的修改将会丢失或者被覆盖
# 使用iptables-restore命令可以从指定文件中重载规则
iptables-restore < /etc/sysconfig/iptables

2、iptables匹配条件

2.1 常用基本匹配条件

当规则中同时存在多个匹配条件时,多个条件之间默认存在"与"的关系,即报文必须同时满足所有条件,才能被规则匹配

# --------------------匹配条件:目标IP地址
# -s用于匹配报文的源地址,可以同时指定多个源地址,每个IP之间用逗号隔开,也可以指定为一个网段
# 逗号两侧均不能包含空格,多个IP之间必须与逗号相连
iptables -t filter -I INPUT -s 192.168.1.111,192.168.1.118 -j DROP
iptables -t filter -I INPUT -s 192.168.1.0/24 -j ACCEPT
# 只要发往本机的报文的源地址不是192.168.1.146,就接受报文
iptables -t filter -I INPUT ! -s 192.168.1.0/24 -j ACCEPT

# -d用于匹配报文的目标地址,可以同时指定多个目标地址,每个IP之间用逗号隔开,也可以指定为一个网段
# 所有IP发送往111,118的报文都将被丢弃
iptables -t filter -I OUTPUT -d 192.168.1.111,192.168.1.118 -j DROP
iptables -t filter -I INPUT -d 192.168.1.0/24 -j ACCEPT
# 不管是-s选项还是-d选项,取反操作与同时指定多个IP的操作不能同时使用
iptables -t filter -I INPUT ! -d 192.168.1.0/24 -j ACCEPT

# -------------------匹配条件:协议类型
# -p用于匹配报文的协议类型,可以匹配的协议类型tcp、udp、udplite、icmp、esp、ah、sctp等(centos7中还支持icmpv6、mh)
iptables -t filter -I INPUT -p tcp -s 192.168.1.146 -j ACCEPT
iptables -t filter -I INPUT ! -p udp -s 192.168.1.146 -j ACCEPT

# ---------------匹配条件:网卡接口
# -i用于匹配报文是从哪个网卡接口流入本机的,由于匹配条件只是用于匹配报文流入的网卡
# 所以在OUTPUT链与POSTROUTING链中不能使用此选项
# 拒绝由网卡eth4流入的ping请求报文
iptables -t filter -I INPUT -p icmp -i eth4 -j DROP
iptables -t filter -I INPUT -p icmp ! -i eth4 -j DROP

# -o用于匹配报文将要从哪个网卡接口流出本机,于匹配条件只是用于匹配报文流出的网卡,所以在INPUT链与PREROUTING链中不能使用此选项。
iptables -t filter -I OUTPUT -p icmp -o eth4 -j DROP
iptables -t filter -I OUTPUT -p icmp ! -o eth4 -j DROP

2.2 扩展匹配条件(基本)

基本匹配条件我们可以直接使用,而如果想要使用扩展匹配条件,则需要依赖一些扩展模块,或者说在使用扩展匹配条件之前,需要指定相应的扩展模块,使用-m 来选择扩展模块

# 常用的扩展匹配条件,tcp扩展模块
# -m tcp表示使用tcp扩展模块,–dport表示tcp扩展模块中的一个扩展匹配条件,可用于匹配报文的目标端口。
# 注意,-p tcp与 -m tcp并不冲突,-p用于匹配报文的协议,-m 用于指定扩展模块的名称,正好,这个扩展模块也叫tcp,那就可以省略
# 如果-p对应的值为udp,那么默认调用的扩展模块就为-m udp
# -p tcp -m tcp –sport 用于匹配tcp协议报文的源端口,可以使用冒号指定一个连续的端口范围
# -p tcp -m tcp –dport 用于匹配tcp协议报文的目标端口,可以使用冒号指定一个连续的端口范围
#示例如下
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport :22 -j REJECT
# 匹配80号端口以及其以后的所有端口(直到65535)
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp --dport 80: -j REJECT
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp ! --sport 22 -j ACCEPT


# multiport扩展模块
# -m multiport –dports 22,36,80表示使用了multiport扩展模块的–dports扩展条件,以同时指定了多个离散的端口,每个端口之间用逗号隔开
# -m multiport是不能省略的,如果你省略了-m multiport,就相当于在没有指定扩展模块的情况下,使用了扩展条件(”–dports”),那么上例中,iptables会默认调用”-m tcp”,但是,”–dports扩展条件”并不属于”tcp扩展模块”,而是属于”multiport扩展模块”,所以,这时就会报错
# -p tcp -m multiport –sports 用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用”逗号”隔开
# -p udp -m multiport –dports 用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用”逗号”隔开
#示例如下
iptables -t filter -I OUTPUT -d 192.168.1.146 -p udp -m multiport --sports 137,138 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport ! --dports 22,80 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 80:88 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80:88 -j REJECT

2.3 扩展匹配条件(其他)

  • iprange模块

-s选项与-d选项并不能一次性的指定一段连续的IP地址范围,如果我们需要指定一段连续的IP地址范围,可以使用iprange扩展模块。使用iprange扩展模块可以指定"一段连续的IP地址范围",用于匹配报文的源地址或者目标地址

—src-range:指定连续的源地址范围

—dst-range:指定连续的目标地址范围

#示例
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROP
iptables -t filter -I OUTPUT -m iprange --dst-range 192.168.1.127-192.168.1.146 -j DROP
iptables -t filter -I INPUT -m iprange ! --src-range 192.168.1.127-192.168.1.146 -j DROP
  • string模块

使用string扩展模块,可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件,比如,如果报文中包含字符”OOXX”,我们就丢弃当前报文

—algo:指定对应的匹配算法,可用算法为bm、kmp,此选项为必需选项。

—string:指定需要匹配的字符串

# -m string表示使用string模块,–algo bm表示使用bm算法去匹配指定的字符串,–string"OOXX"则表示我们想要匹配的字符串为"OOXX"
iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT
iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT
  • time模块

我们可以通过time扩展模块,根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件

—timestart:用于指定时间范围的开始时间,不可取反

—timestop:用于指定时间范围的结束时间,不可取反

—weekdays:用于指定”星期几”,可取反

—monthdays:用于指定”几号”,可取反

—datestart:用于指定日期范围的开始日期,不可取反

—datestop:用于指定日期范围的结束时间,不可取反

# "-m time"表示使用time扩展模块,–timestart选项用于指定起始时间,–timestop选项用于指定结束时间
# 每天早上9点到下午6点不能看网页
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 443 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT
# 只有周六日不能看网页
# 使用–weekdays选项可以指定每个星期的具体哪一天,可以同时指定多个,用逗号隔开,除了能够数字表示”星期几”,还能用缩写表示,例如:Mon, Tue, Wed, Thu, Fri, Sat, Sun
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --weekdays 6,7 -j REJECT
# 具体指定的每个月的哪一天
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --monthdays 22,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time ! --monthdays 22,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --weekdays 5 --monthdays 22,23,24,25,26,27,28 -j REJECT
# 可以使用–datestart 选项与-datestop选项,指定具体的日期范围
iptables -t filter -I OUTPUT -p tcp --dport 80  -m time --datestart 2017-12-24 --datestop 2017-12-27 -j REJECT
  • connlimit 模块

使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:我们不用指定IP,其默认就是针对"每个客户端IP",即对单IP的并发连接数限制

—connlimit-above:单独使用此选项时,表示限制每个IP的链接数量。

—connlimit-mask:此选项不能单独使用,在使用–connlimit-above选项时,配合此选项,则可以针对"某类IP段内的一定数量的IP"进行连接数量的限制,如果不明白可以参考上文的详细解释。

# 限制每个IP地址最多只能占用两个ssh链接远程到server端
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
# –connlimit-mask 24表示某个C类网段,没错,mask为掩码之意,所以将24转换成点分十进制就表示255.255.255.0
# 一个最多包含254个IP的C类网络中,同时最多只能有20个ssh客户端连接到当前服务器
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT
# –connlimit-mask 27表示某个C类网段,通过计算后可以得知,这个网段中最多只能有30台机器(30个IP),这30个IP地址最多只能有10个ssh连接同时连接到服务器端,当然,这样并不能避免某个IP占用所有连接的情况发生
# 假设,报文来自192.168.1.40这个IP,按照掩码为27进行计算,这个IP属于192.168.1.32/27网段,如果192.168.1.40同时占用了10个ssh连接,那么当192.168.1.51这个IP向服务端发起ssh连接请求时,同样会被拒绝,因为192.168.1.51这个IP按照掩码为27进行计算,也是属于192.168.1.32/27网段,所以他们共享这10个连接名额
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT
# 在不使用–connlimit-mask的情况下,连接数量的限制是针对”每个IP”而言的,当使用了–connlimit-mask选项以后,则可以针对”某类IP段内的一定数量的IP”进行连接数量的限制
  • limit模块

connlimit模块是对连接数量进行限制的,limit模块是对"报文到达速率"进行限制的。用大白话说就是,如果我想要限制单位时间内流入的包的数量,就能用limit模块,我们可以以秒为单位进行限制,也可以以分钟、小时、天作为单位进行限制,比如,限制每秒中最多流入3个包,或者限制每分钟最多流入30个包都可以

—limit-burst:类比”令牌桶”算法,此选项用于指定令牌桶中令牌的最大数量,上文中已经详细的描述了”令牌桶”的概念,方便回顾

—limit:类比”令牌桶”算法,此选项用于指定令牌桶中生成新令牌的频率,可用时间单位有second、minute 、hour、day

#示例 #注意,如下两条规则需配合使用,具体原因上文已经解释过,忘记了可以回顾
# ”–limit-burst”可以指定”空闲时可放行的包的数量”,用了令牌桶的方法,所以前几个都会接收,后面满了才会按照指定速率
# 3/second表示每秒生成3个”令牌”,30/minute表示每分钟生成30个”令牌”
# 外部主机对本机进行ping操作时,本机最多每6秒中放行一个ping包
iptables -t filter -I INPUT -p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT
iptables -t filter -A INPUT -p icmp -j REJECT

2.4 扩展匹配条件tcp-flags

—tcp-flags指的就是tcp头中的标志位,看来,在使用iptables时,我们可以通过此扩展匹配条件,去匹配tcp报文的头部的标识位,然后根据标识位的实际情况实现访问控制的功能

# 复习之前的内容,这个也是tcp模块里的
# --sport用于匹配tcp协议报文的源端口,可以使用冒号指定一个连续的端口范围
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECT
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22:25 -j REJECT
iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp ! --sport 22 -j ACCEPT

# --dport 用于匹配tcp协议报文的目标端口,可以使用冒号指定一个连续的端口范围
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport :22 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 80: -j REJECT

# --tcp-flags,用于匹配报文的tcp头的标志位
# 匹配到”第一次握手”的报文
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
# 匹配tcp头中的第二次握手时的标志位
iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT
# 上两条命令的简写
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT
iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags ALL SYN,ACK -j REJECT

# --syn 用于匹配tcp新建连接的请求报文,相当于使用”–tcp-flags SYN,RST,ACK,FIN  SYN”
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --syn -j REJECT

2.5 udp扩展与icmp扩展

udp扩展模块,这个扩展模块中能用的匹配条件比较少,只有两个,就是–sport与–dport,即匹配报文的源端口与目标端口。

# 放行samba服务的137与138这两个UDP端口
iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPT
iptables -t filter -I INPUT -p udp -m udp --dport 137:157 -j ACCEPT
#可以结合multiport模块指定多个离散的端口
# 但是udp中的–sport与–dport也只能指定连续的端口范围,并不能一次性指定多个离散的端口,使用之前总结过的multiport扩展模块,即可指定多个离散的UDP端口

ICMP协议的全称为Internet Control Message Protocol,翻译为互联网控制报文协议,它主要用于探测网络上的主机是否可用,目标是否可达,网络是否通畅,路由是否可用等。—icmp-type:匹配icmp报文的具体类型

我们平常使用ping命令ping某主机时,如果主机可达,对应主机会对我们的ping请求做出回应(此处不考虑禁ping等情况),也就是说,我们发出ping请求,对方回应ping请求,虽然ping请求报文与ping回应报文都属于ICMP类型的报文,但是如果在概念上细分的话,它们所属的类型还是不同的,我们发出的ping请求属于类型8的icmp报文,而对方主机的ping回应报文则属于类型0的icmp报文

# 要禁止所有icmp类型的报文进入本机
# 我们只想要ping通别人,但是不想让别人ping通我们
# –icmp-type 8/0表示icmp报文的type为8,code为0才会被匹配到,也就是只有ping请求类型的报文才能被匹配到
# 别人对我们发起的ping请求将会被拒绝通过防火墙,而我们之所以能够ping通别人,是因为别人回应我们的报文的icmp type为0,code也为0,所以无法被上述规则匹配到,所以我们可以看到别人回应我们的信息
iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECT
# 因为type为8的类型下只有一个code为0的类型,所以我们可以省略对应的code
iptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECT
iptables -t filter -I OUTPUT -p icmp -m icmp --icmp-type 0/0 -j REJECT
iptables -t filter -I OUTPUT -p icmp --icmp-type 0 -j REJECT
# 除了能够使用对应type/code匹配到具体类型的icmp报文以外,我们还能用icmp报文的描述名称去匹配对应类型的报文
iptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j REJECT

2.6 state扩展

state模块可以让iptables实现"连接追踪"机制,对于state模块而言的"连接"并不能与tcp的"连接"画等号,在TCP/IP协议簇中,UDP和ICMP是没有所谓的连接的,但是对于state模块来说,tcp报文、udp报文、icmp报文都是有连接状态的,我们可以这样认为,对于state模块而言,只要两台机器在"你来我往"的通信,就算建立起了连接,其中的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED

  • NEW:连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。
  • ESTABLISHED:我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接已建立。
  • RELATED:从字面上理解RELATED译为关系,但是这样仍然不容易理解,我们举个例子,比如FTP服务,FTP服务端会建立两个进程,一个命令进程,一个数据进程。命令进程负责服务端与客户端之间的命令传输(我们可以把这个传输过程理解成state中所谓的一个"连接",暂称为"命令连接")。数据进程负责服务端与客户端之间的数据传输 ( 我们把这个过程暂称为"数据连接" )。但是具体传输哪些数据,是由命令去控制的,所以,"数据连接"中的报文与"命令连接"是有关系的。那么,"数据连接"中的报文可能就是RELATED状态,因为这些报文与"命令连接"中的报文有关系。(注:如果想要对ftp进行连接追踪,需要单独加载对应的内核模块nf_conntrack_ftp,如果想要自动加载,可以配置/etc/sysconfig/iptables-config文件)
  • INVALID:如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是INVALID,我们可以主动屏蔽状态为INVALID的报文。
  • UNTRACKED:报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找到相关的连接。
# 只要放行状态为ESTABLISHED的报文即可,因为如果报文的状态为ESTABLISHED,那么报文肯定是之前发出的报文的回应
# 如果你还不放心,可以将状态为RELATED或ESTABLISHED的报文都放行,这样,就表示只有回应我们的报文能够通过防火墙,如果是别人主动发送过来的新的报文,则无法通过防火墙
# 这样就可以保证主机安全
iptables -F
iptables -t filter -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A INPUT -j REJECT
# 当前主机IP为104,当放行ESTABLISHED与RELATED状态的包以后,并没有影响通过本机远程ssh到IP为77的主机上,但是无法从77上使用22端口主动连接到104上
# 对于其他端口与IP来说,也是相同的,可以从104主动发送报文,并且能够收到响应报文,但是其他主机并不能主动向104发起请求。

# 现在更推荐conntrack代替state的,不过两者都能使用,区别不大
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 22 -j ACCEPT

2.7 mac扩展

# mac扩展用来匹配某个mac地址
# 用法 -m mac --mac-source MAC
# 阻断来自某MAC地址的数据包通过本机
iptables -A FORWARD -m mac --mac-source xx:xx:xx:xx -j DROP
# 注意
# 报文经过路由后,数据包中原有的mac信息会被替换,所以在路由后的iptables中使用mac模块是没有意义的

三、iptables进阶与提高

1、iptables的黑白名单机制

报文在经过iptables的链时,会匹配链中的规则,遇到匹配的规则时,就执行对应的动作,如果链中的规则都无法匹配到当前报文,则使用链的默认策略(默认动作),链的默认策略通常设置为ACCEPT或者DROP

那么,当链的默认策略设置为ACCEPT时,如果对应的链中没有配置任何规则,就表示接受所有的报文,如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被接受。同理,当链的默认策略设置为DROP时,如果对应的链中没有配置任何规则,就表示拒绝所有报文,如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被拒绝。

  • 黑名单机制:当链的默认策略为ACCEPT时,链中的规则对应的动作应该为DROP或者REJECT,表示只有匹配到规则的报文才会被拒绝,没有被规则匹配到的报文都会被默认接受
  • 白名单机制:当链的默认策略为DROP时,链中的规则对应的动作应该为ACCEPT,表示只有匹配到规则的报文才会被放行,没有被规则匹配到的报文都会被默认拒绝
# 白名单机制
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
# 将INPUT链的默认策略改为DROP
iptables -nvL INPUT
iptables -P INPUT DROP


# 如果此时iptables -F清空了的话,那么将拒绝所有请求
# 这就是默认策略设置为DROP的缺点,在对应的链中没有设置任何规则时,这样使用默认策略为DROP是非常不明智的,因为管理员也会把自己拒之门外
# 所以,我们如果想要使用”白名单”的机制,最好将链的默认策略保持为”ACCEPT”,然后将”拒绝所有请求”这条规则放在链的尾部,将”放行规则”放在前面
# 这样做,既能实现”白名单”机制,又能保证在规则被清空时,管理员还有机会连接到主机
iptables -P INPUT ACCEPT
# 当所有放行规则设置完成后,在INPUT链的尾部,设置一条拒绝所有请求的规则
iptables -A INPUT -j REJECT

2、iptables自定义链

自定义链可以方便的管理不同的规则,方便后期规则的修改,但是需要注意的是,自定义链并不能直接使用,而是需要被默认链引用才能够使用

# 创建自定义链
#示例:在filter表中创建IN_WEB自定义链,省略-t选项时,缺省操作的就是filter表
iptables -t filter -N IN_WEB
# 可以看到,这条自定义链的引用计数为0 (0 references),就是说,这条自定义链还没有被任何默认链所引用
iptables -nvL

# 自定义链中配置规则,和其他一样
iptables -t filter -I IN_WEB -s 192.168.1.139 -j REJECT
iptables -I IN_WEB -s 192.168.1.188 -j REJECT
iptables -t filter --line -nvL IN_WEB


# 引用自定义链
#示例:在INPUT链中引用刚才创建的自定义链
iptables -t filter -I INPUT -p tcp --dport 80 -j IN_WEB

# 重命名自定义链
#示例:将IN_WEB自定义链重命名为WEB
iptables -E IN_WEB WEB

# 删除自定义链
# 删除自定义链需要满足两个条件:自定义链没有被引用;自定义链中没有任何规则
#示例:删除引用计数为0并且不包含任何规则的WEB链
iptables -D INPUT 1
iptables -t filter -F WEB
# 使用”-X”选项可以删除一个引用计数为0的、空的自定义链
iptables -X WEB

3、iptables之网络防火墙

3.1 概述

网络防火墙: 往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网(有点类似路由器),网络防火墙往往处于网络的入口或者边缘,那么,如果想要使用iptables充当网络防火墙,iptables所在的主机则需要处于网络入口处。

不管是由外部主机发往内部主机的报文,还是由内部主机发往外部主机的报文,都需要经过iptables所在的主机,由iptables所在的主机进行"过滤并转发",所以,防火墙主机的主要工作就是"过滤并转发"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOPMRPW4-1680865857920)(http://qnypic.shawncoding.top/blog/%E8%BD%AC%E5%8F%91%E5%9B%BE_ziB0kUlrCp.png)]

前文中,iptables都是作为**“主机防火墙”**的角色出现的,所以我们举例时,只用到了上图中的INPUT链与OUTPUT链,因为拥有"过滤功能"的链只有3条,INPUT、OUTPUT、FORWARD,当报文发往本机时,如果想要过滤,只能在INPUT链与OUTPUT链中实现,而此时,iptables的角色发生了转变,我们想要将iptables所在的主机打造成"网络防火墙",而刚才已经说过,网络防火墙的职责就是"过滤并转发",要想"过滤",只能在INPUT、OUTPUT、FORWARD三条链中实现,要想"转发",报文则只会经过FORWARD链(发往本机的报文才会经过INPUT链),所以,综上所述,iptables的角色变为"网络防火墙"时,规则只能定义在FORWARD链中。

3.2 实战demo

此处所描述的内网、外网与我们平常所说的公网、私网不同。此处描述的内外部网络你可以理解成两个网段,A网络与B网络,为了方便描述,我们把圆形内的主机称为内部主机,把上图中圆形所表示的网络称为内部网络,把圆形外的网络称为外部网络。

ifconfig | awk '/inet/{print $1,$2}'
# route命令配置的路由条目在网络重启后将会失效
# 现在A主机通往10.1网络的网关已经指向了B主机
# 因为A发往内网的网关是默认的,所以再加一个从内网到A的默认网关即可
route add -net 10.1.0.0/16 gw 192.168.1.146
route -n
# 如果A ping 10.1.0.3会有反应,因为这两个网卡都是它自己,故会反应
# 但ping内网中的其他机器就不会有回应了,因为还没配置规则

# -----------------------开启转发----------------------------

#如果想要iptables作为网络防火墙,iptables所在主机开启核心转发功能,以便能够转发报文。
#使用如下命令查看当前主机是否已经开启了核心转发,0表示未开启,1表示已开启
cat /proc/sys/net/ipv4/ip_forward
#使用如下两种方法均可临时开启核心转发,立即生效,但是重启网络配置后会失效。
方法一:echo 1 > /proc/sys/net/ipv4/ip_forward
方法二:sysctl -w net.ipv4.ip_forward=1

#使用如下方法开启核心转发功能,重启网络服务后永久生效。
# 配置/etc/sysctl.conf文件(centos7中配置/usr/lib/sysctl.d/00-system.conf文件),在配置文件中将 net.ipv4.ip_forward设置为1
# ubuntu中
# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
# sysctl -p
# 总之原理就是把net.ipv4.ip_forward = 1开启
# 这样内外网都可以ping通了

# -------------------------转发规则------------------------------
#由于iptables此时的角色为"网络防火墙",所以需要在filter表中的FORWARD链中设置规则。
#可以使用"白名单机制",先添加一条默认拒绝的规则,然后再为需要放行的报文设置规则。
#配置规则时需要考虑"方向问题",针对请求报文与回应报文,考虑报文的源地址与目标地址,源端口与目标端口等。
#示例为允许网络内主机访问网络外主机的web服务与sshd服务
# 白名单机制,先添加最后一个为拒绝
iptables -A FORWARD -j REJECT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -d 10.1.0.0/16 -p tcp --sport 80 -j ACCEPT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -d 10.1.0.0/16 -p tcp --sport 22 -j ACCEPT
 
#可以使用state扩展模块,对上述规则进行优化,使用如下配置可以省略许多"回应报文放行规则"。
iptables -A FORWARD -j REJECT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

4、iptables动作总结

4.1 常用动作之REJECT

之前用到了一些常用动作,比如ACCEPT、DROP、REJECT等。"动作"与"匹配条件"一样,也有"基础"与"扩展"之分。同样,使用扩展动作也需要借助扩展模块,但是,扩展动作可以直接使用,不用像使用"扩展匹配条件"那样指定特定的模块。之前用到的ACCEPT与DROP都属于基础动作;而REJECT则属于扩展动作。

# -----------------------------动作REJECT----------------
# REJECT动作的常用选项为--reject-with,使用--reject-with选项,可以设置提示信息,当对方被拒绝时,会提示对方为什么被拒绝
# 可用值如下
# icmp-net-unreachable
# icmp-host-unreachable
# icmp-port-unreachable
# icmp-proto-unreachable
# icmp-net-prohibited
# icmp-host-pro-hibited
# icmp-admin-prohibited
# 当不设置任何值时,默认值为icmp-port-unreachable

iptables -F
iptables -t filter -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j REJECT
iptables -nvL INPUT
# 当没有明确设置–reject-with的值时,默认提示信息为icmp-port-unreachable,即端口不可达之意

# 修改拒绝报文,发ping就会显示主机不可达
iptables -I INPUT 2 -j REJECT --reject-with icmp-host-unreachable

4.2 常用动作之LOG

使用LOG动作,可以将符合条件的报文的相关信息记录到日志中,但当前报文具体是被"接受",还是被"拒绝",都由后面的规则控制,换句话说,LOG动作只负责记录匹配到的报文的相关信息,不负责对报文的其他处理,如果想要对报文进行进一步的处理,可以在之后设置具体规则,进行进一步的处理。

# 举例
iptables -F
# 将发往22号端口的报文相关信息记录在日志中
iptables -I INPUT -p tcp --dport 22 -j LOG
# 都会被记录到日志中,查看/var/log/messages即可看到对应报文的相关信息
tail -f /var/log/messages
# 但匹配条件过于宽泛,所以在使用LOG动作时,匹配条件应该尽量写的精确一些,先删除这条

# 当然,我们也可以将相关信息记录在指定的文件中,以防止iptables的相关信息与其他日志信息相混淆
# 修改/etc/rsyslog.conf文件(或者/etc/syslog.conf),在rsyslog配置文件中添加如下配置即可
vim /etc/rsyslog.conf
# 末尾添加
kern.warning /var/log/iptables.log
# 加入上述配置后,报文的相关信息将会被记录到/var/log/iptables.log文件中
# 完成上述配置后,重启rsyslog服务(或者syslogd)
service rsyslog restart


# LOG动作也有自己的选项,常用选项如下
# --log-level选项可以指定记录日志的日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug
# –-log-prefix选项可以给记录到的相关信息添加”标签”之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤
# 注:-–log-prefix对应的值不能超过29个字符
# 举例将主动连接22号端口的报文的相关信息都记录到日志中,并且把这类记录命名为want-in-from-port-22
iptables -F INPUT
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix "want-in-from-port-22"

# 可以连接ssh进行测试,查看iptables.log日志,发现日志中有标签,还有网卡信息,时间等

4.3 NAT相关动作(重要)

图中圆形所示的逻辑区域表示公司内网,网段为10.1.0.0/16,主机B、C、D都属于内网主机,主机B比较特殊,同时扮演了网关与防火墙,主机B持有公司唯一的公网IP(我们用了一个假的公网IP),局域网内主机如果想与公网主机通讯,需要共享此公网IP,由B主机进行NAT,所以,我们为主机B准备了两块网卡,公网IP与私网IP分别配置到这两块网卡中

# 如果想要NAT功能能够正常使用,需要开启Linux主机的核心转发功能。
# -----------------------开启转发----------------------------
#使用如下命令查看当前主机是否已经开启了核心转发,0表示未开启,1表示已开启
cat /proc/sys/net/ipv4/ip_forward
#使用如下两种方法均可临时开启核心转发,立即生效,但是重启网络配置后会失效。
方法一:echo 1 > /proc/sys/net/ipv4/ip_forward
方法二:sysctl -w net.ipv4.ip_forward=1
#使用如下方法开启核心转发功能,重启网络服务后永久生效。
# 配置/etc/sysctl.conf文件(centos7中配置/usr/lib/sysctl.d/00-system.conf文件),在配置文件中将 net.ipv4.ip_forward设置为1
# ubuntu中
# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
# sysctl -p

# -------------------SNAT相关操作----------------------
# 网络内部的主机可以借助SNAT隐藏自己的IP地址,同时还能够共享合法的公网IP,让局域网内的多台主机共享公网IP访问互联网
# 而此时的主机B就扮演了拥有NAT功能的设备,我们使用iptables的SNAT动作达到刚才所说的目的
# 我们将来自于10.1.0.0/16网段的报文的源地址改为公司的公网IP地址
# -t nat表示操作nat表,我们之前一直在灌输一个概念,就是不同的表有不同的功能,filter表的功能是过滤,nat表的功能就是地址转换,所以我们需要在nat表中定义nat规则。
# -A POSTROUTING表示将SNAT规则添加到POSTROUTING链的末尾,在centos7中,SNAT规则只能存在于POSTROUTING链与INPUT链中,在centos6中,SNAT规则只能存在于POSTROUTING链中
# -s 10.1.0.0/16表示报文来自于10.1.0.0/16网段
# -j SNAT表示使用SNAT动作,对匹配到的报文进行处理,对匹配到的报文进行源地址转换
# –to-source 192.168.1.146表示将匹配到的报文的源IP修改为192.168.1.146,我们已经总结过,某些动作会有自己的选项,–to-source就是SNAT动作的常用选项,用于指定SNAT需要将报文的源IP修改为哪个IP地址
# 只是用于配置SNAT的话,我们并不用 手动的进行DNAT设置,iptables会自动维护NAT表,并将响应报文的目标地址转换回来
# 内外网可以相互ping通,iptables自动维护转换表

# 配置SNAT,可以隐藏网内主机的IP地址,也可以共享公网IP,访问互联网,如果只是共享IP的话,只配置如下SNAT规则即可
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP

# ---------------------------------动作MASQUERADE-----------------------------
# MASQUERADE和SNAT类似,也就是源地址转换
# MASQUERADE会动态的将源地址转换为可用的IP地址,其实与SNAT实现的功能完全一致,都是修改源地址
# 只不过SNAT需要指明将报文的源地址改为哪个IP,而MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址
# 通过外网网卡出去的报文在经过POSTROUTING链时,会自动将报文的源地址修改为外网网卡上可用的IP地址,这时,即使外网网卡中的公网IP地址发生了改变,也能够正常的、动态的将内部主机的报文的源IP映射为对应的公网IP
# 可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效

# 如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作,如下命令表示将10.1网段的报文的源IP修改为eth0网卡中可用的地址
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE

# ------------------------------DNAT相关操作---------------------------
# 配置DNAT,可以通过公网IP访问局域网内的服务
# -t nat -I PREROUTING表示在nat表中的PREROUTING链中配置DNAT规则,DNAT规则只配置在PREROUTING链与OUTPUT链中。
# 注:理论上来说,只要配置DNAT规则,不需要对应的SNAT规则即可达到DNAT效果
# 但是在测试DNAT时,对应SNAT规则也需要配置,才能正常DNAT,可以先尝试只配置DNAT规则
# 如果无法正常DNAT,再尝试添加对应的SNAT规则,SNAT规则配置一条即可,DNAT规则需要根据实际情况配置不同的DNAT规则
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.1.0.1:80
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP

# -------------------------------动作REDIRECT--------------------
# 使用REDIRECT动作可以在本机上进行端口映射
# REDIRECT规则只能定义在PREROUTING链或者OUTPUT链中
# 在本机进行目标端口映射时可以使用REDIRECT动作
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
# 配置完成上述规则后,其他机器访问本机的80端口时,会被映射到8080端口

四、总结

1、配置应用程序规则举例

1.1 SSH

#-m state: 启用状态匹配模块(state matching module)
#–-state: 状态匹配模块的参数。当SSH客户端第一个数据包到达服务器时,状态字段为NEW;建立连接后数据包的状态字段都是ESTABLISHED
#–sport 22: sshd监听22端口,同时也通过该端口和客户端建立连接、传送数据。因此对于SSH服务器而言,源端口就是22
#–dport 22: ssh客户端程序可以从本机的随机端口与SSH服务器的22端口建立连接。因此对于SSH客户端而言,目的端口就是22
# 1.允许接收远程主机的SSH请求
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# 2.允许发送本地主机的SSH响应
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 如果服务器也需要使用SSH连接其他远程主机,则还需要增加以下配置

# 1.送出的数据包目的端口为22
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# 2.接收的数据包源端口为22
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

1.2 HTTP

# 1.删除现有规则
iptables -F

# 2.配置默认链策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# 3.允许远程主机进行SSH连接
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# 4.允许本地主机进行SSH连接
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# 5.允许HTTP请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

# 配置转发端口示例
iptables -t nat -I PREROUTING -p tcp --dport 3389 -j DNAT --to 38.X25.X.X02 
iptables -t nat -I POSTROUTING -p tcp --dport 3389 -j MASQUERADE

1.3 NAT规则实战

# 把本地的mysql 3306端口映射出去变成63306,外面连接的语句是
# 注:当访问63306的时候,会自动去请求3306,然后返回数据
mysql -uroot -p'password' -h xxxxx -P 63306

# 先允许数据包转发
echo 1 >/proc/sys/net/ipv4/ip_forward
# 注:这是允许所有外来的IP访问,慎用
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 63306 -j DNAT --to-destination 127.0.0.1:3306
# 修改规则(4代表编号, --line-number可查看对应编号, -s 指定来源IP)
iptables -t nat -R PREROUTING 4 -s 192.168.40.154 -p tcp -m tcp --dport 63306 -j DNAT --to-destination 127.0.0.1:3306
# 查看nat规则
iptables -L -t nat --line-number

2、iptables常用套路小结

  • 规则的顺序非常重要

    如果报文已经被前面的规则匹配到,IPTABLES则会对报文执行对应的动作,通常是ACCEPT或者REJECT,报文被放行或拒绝以后,即使后面的规则也能匹配到刚才放行或拒绝的报文,也没有机会再对报文执行相应的动作了(前面规则的动作为LOG时除外),所以,针对相同服务的规则,更严格的规则应该放在前面

  • 当规则中有多个匹配条件时,条件之间默认存在"与"的关系

    如果一条规则中包含了多个匹配条件,那么报文必须同时满足这个规则中的所有匹配条件,报文才能被这条规则匹配到。

  • 在不考虑1的情况下,应该将更容易被匹配到的规则放置在前面

    比如,你写了两条规则,一条针对sshd服务,一条针对web服务。假设,一天之内,有20000个请求访问web服务,有200个请求访问sshd服务,那么,应该将针对web服务的规则放在前面,针对sshd的规则放在后面,因为访问web服务的请求频率更高。如果将sshd的规则放在前面,当报文是访问web服务时,sshd的规则也要白白的验证一遍,由于访问web服务的频率更高,白白耗费的资源就更多;如果web服务的规则放在前面,由于访问web服务的频率更高,所以无用功会比较少。换句话说就是,在没有顺序要求的情况下,不同类别的规则,被匹配次数多的、匹配频率高的规则应该放在前面。

  • 当IPTABLES所在主机作为网络防火墙时,在配置规则时,应着重考虑方向性,双向都要考虑,从外到内,从内到外。

  • 在配置IPTABLES白名单时,往往会将链的默认策略设置为ACCEPT,通过在链的最后设置REJECT规则实现白名单机制,而不是将链的默认策略设置为DROP,如果将链的默认策略设置为DROP,当链中的规则被清空时,管理员的请求也将会被DROP掉。


参考文章:

https://www.zsythink.net/archives/tag/iptables/

https://zhuanlan.zhihu.com/p/279919870

https://zhuanlan.zhihu.com/p/465319846

https://www.cnblogs.com/hellowangbucuo/p/9617282.html
服务时,sshd的规则也要白白的验证一遍,由于访问web服务的频率更高,白白耗费的资源就更多;如果web服务的规则放在前面,由于访问web服务的频率更高,所以无用功会比较少。换句话说就是,在没有顺序要求的情况下,不同类别的规则,被匹配次数多的、匹配频率高的规则应该放在前面。

  • 当IPTABLES所在主机作为网络防火墙时,在配置规则时,应着重考虑方向性,双向都要考虑,从外到内,从内到外。
  • 在配置IPTABLES白名单时,往往会将链的默认策略设置为ACCEPT,通过在链的最后设置REJECT规则实现白名单机制,而不是将链的默认策略设置为DROP,如果将链的默认策略设置为DROP,当链中的规则被清空时,管理员的请求也将会被DROP掉。

参考文章:

https://www.zsythink.net/archives/tag/iptables/

https://zhuanlan.zhihu.com/p/279919870

https://zhuanlan.zhihu.com/p/465319846

https://www.cnblogs.com/hellowangbucuo/p/9617282.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/7077.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ant Design Vue的汉化

Ant Design Vue的汉化 1. 引入依赖 import zhCN from "ant-design-vue/lib/locale-provider/zh_CN"; // 汉化 export default {data () {zhCN,} }2. 标签包裹需要汉化的组件 <a-config-provider :locale"zhCN"><a-table :row-selection"ro…

C++IO流

文章目录一、CIO流体系二、C标准IO流三、C文件IO流1.ifstream2.ofstream一、CIO流体系 C流是指信息从外部输入设备向计算机内部输入&#xff0c;从内存向外部输出设备输出的过程&#xff0c;这种输入输出的过程非常形象地被称为流的概念。IO流指的就是输入输出流。 我们平时对…

PerfEnforce Demonstration: Data Analytics with Performance Guarantees

PerfEnforce Demonstration: Data Analytics with Performance Guarantees Created by: ctur Date: April 2, 2023 2:54 PM Status: ready to start 实时响应式的扩展算法 实时响应式的扩展算法分为 1. 比例积分控制 2. 强化学习 比例积分控制方法 “We use a proportiona…

现在的年轻人真会玩,开发界面都这么时尚,不服老都不行了

文章目录一、你还在用传统的开发界面吗二、年轻人的界面1.动漫型2.偶像型3.提神型三、更换背景的操作第一步第二步第三步一、你还在用传统的开发界面吗 不比不知道&#xff0c;一比吓一跳&#xff0c;都2023年了&#xff0c;你还在用Pycharm的默认背景写代码吗&#xff1f;已经…

不同版本的JDK新特性

1.JDK9&#xff1a;模块化开发 模块化功能用的不是很多 2.JDK10&#xff1a;var局部变量推导 使用var的两个基本要求&#xff1a; 也用得不是很多 3.JDK11 (1)单文件程序 就是能够直接用java命令编译.java文件了&#xff0c;跳过了使用javac命令的步骤&#xff0c;对新人…

4年功能测试月薪9.5K,3个月时间成功进阶自动化,跳槽涨薪6k后我的路还很长...

前言 其实最开始我并不是互联网从业者&#xff0c;是经历了一场六个月的培训才入的行&#xff0c;这个经历仿佛就是一个遮羞布&#xff0c;不能让任何人知道&#xff0c;就算有面试的时候被问到你是不是被培训的&#xff0c;我还是不能承认这段历史。我是为了生存&#xff0c;…

AD14安装步骤

首先 得需要科学安软件&#xff0c;我相信你可以找到的。 第一步&#xff1a;解压完成之后哦&#xff0c;双击打开AltiumDesignerSetup14_3_15.exe 第二步&#xff1a;点击next 第三步&#xff1a;先点击我同意&#xff0c;在点击next 第四步&#xff1a;点击next 第五步&…

路径 Dijkstra 蓝桥杯 JAVA

目录题目描述&#xff1a;Dijkstra 算法 (朴素版)&#xff1a;用Dijkstra解决本题&#xff1a;题目描述&#xff1a; 小蓝学习了最短路径之后特别高兴&#xff0c;他定义了一个特别的图&#xff0c;希望找到图中的最短路径。 小蓝的图由2021 个结点组成&#xff0c;依次编号1 至…

TypeScript由浅到深(上篇)

目录 一、什么是TypeScript有什么特点&#xff1a; 二、TypeScript的编译环境&#xff1a; 三、TypeScript数据类型&#xff1a; 01_标识符的类型推导&#xff1a; 02_JS中的类型Array&#xff1a; 03_JS 中的类型Object&#xff1a; 04_函数的类型&#xff1a; 05_匿名…

C++游戏分析与破解方法介绍

1、C游戏简介 目前手机游戏直接用C开发的已经不多&#xff0c;使用C开发的多是早期的基于cocos2dx的游戏&#xff0c;因此我们这里就以cocos2d-x为例讲解C游戏的分析与破解方法。 Cocos2d-x是一个移动端游戏开发框架&#xff0c;可以使用C或者lua进行开发&#xff0c;也可以混…

SpringBoot事件的选取原理

有四个事件启动监听器&#xff1a; 事件1会被监听吗&#xff1f;答案不会 容器发布一个正在启动的事件 org.springframework.context.event.AbstractApplicationEventMulticaster#retrieveApplicationListeners 遍历我们注册的监听器&#xff0c;但这里有个判断条件&#xff…

众人围剿,GPT-5招惹了谁

目录千人呼吁暂停AI训练代表人物分析反对原因分析信息安全人身安全失业利益总结GPT-4 火爆全球&#xff0c;引发了人工智能大浪潮。过去的一个月&#xff0c;OpenAI、微软、谷歌加上百度不断释放王炸&#xff0c;所有人都相信&#xff0c;AI 的就是未来的生产力。俗话说&#x…

Android动画进阶

在Android中&#xff0c;实现动画的方式通常有两种&#xff1a;视图动画和属性动画。然而这两种方式只能实现一些较为简单动画&#xff0c;仅仅通过改变这些控件属性的方式实现一些复杂的动画效果是比较有难度的&#xff0c;那么我们该如何实现复杂的动画。这里介绍两种实现方式…

Android配置Jetpack-Compose环境

Android 配置 Jetpack Compose 环境 记录配置Jetpack Compose环境的一些坑~ 本文同步更新于博客&#xff1a; 链接 直接创建kotlin项目或创建java项目后再配置均可 根目录 build.gradle 配置kotlin环境构建脚本 buildscript {ext.kotlin_version 1.4.32dependencies {clas…

大模型时代,AI模型开源还能这么玩?模型空间内测邀请(含重磅福利)

‍人工智能学习与实训社区飞桨 AI Studio自2019年以来&#xff0c;持续吸纳众多开发者于平台内开源贡献、实训提升&#xff0c;分享项目经验、共享自研模型等。 随着 AI Studio 开发者规模的增长、开发者开发能力的提升&#xff0c;我们收到许多期待与建议&#xff0c;经过一段…

企业OA管理系统需具备哪些功能?

OA也就是办公自动化&#xff0c;是通过将计算机、通信等现代化技术运用到传统办公方式而形成的一种新型办公方式。OA办公管理系统能够更加高效优质的处理办公事务以及进行企业管理业务&#xff0c;实现对资源的高效利用&#xff0c;进而达到提高生产力&#xff0c;提升管理水平…

详解vue各种权限控制与管理的实现思路

一、 菜单权限 菜单权限&#xff1a;控制用户在系统中能够看到哪些菜单项菜单权限指的就是后台系统中的左侧的菜单栏&#xff0c;前端可以根据后端接口返回的权限数据结合element-ui菜单组件循环拼接而成即可&#xff0c;有什么权限就展示什么菜单通过vuex持久化插件(本地存储…

Linux系统【centos7】常用基础命令教程

今天我来介绍一下Linux系统的基础知识。 首先&#xff0c;我们需要了解Linux是什么。Linux是一种免费且开放源代码的操作系统&#xff0c;它被广泛用于服务器、移动设备和嵌入式系统。 接下来&#xff0c;我们需要了解基本的Linux命令。其中一些基本命令包括&#xff1a; 1.…

项目 TO 的自我修养

最近作为项目 TO 在公司内完成了一个涉及面比较广的项目&#xff0c;对于如何推动项目上线有一些经验和大家分享。希望刚毕业几年、没有参与过大型项目的同学&#xff0c;从中能学到一些方法&#xff0c;为今后担任项目主力做一些准备。所谓的 TO&#xff0c;是 Technical Owne…

java和mysql进行排序和排名

目录 一、基于java排序和排名 1、数值相同,排名相同,排名连续 2、数值相同,排名相同,排名不连续 3、数值相同,排名不相同,排名连续 二、基于mysql排序和排名 1、准备一张表 2、插入数据 3、设置临时变量,方便后续查询 4、数值相同,排名相同,排名连续 5、数值相同,排名…