Linux 防火墙:netfilter、iptables、firewalld、firewall-cmd、ufw

1、防火墙 简介

什么是防火墙

防火墙 (Firewall) 也称防护墙,是隔离两个网络的一种 隔离技术,它是位于 "内部网络" 与 "外部网络" 之间的一项信息安全的防护系统。依照特定的规则来控制 "进入、出去" 的网络流量(数据包),即拦截和放行数据包。拦截有害的包,放行正常的包。防火墙可以比喻为 "通信警察",让正常的包通过,有害的包都过滤掉,最大限度地阻止黑客来访问你的网络。

防火墙从诞生开始,已经历了四个发展阶段:

  • 基于路由器的防火墙、
  • 用户化的防火墙工具套、
  • 建立在通用操作系统上的防火墙、
  • 具有安全操作系统的防火墙。

"防火墙" 可以是电脑上运行的软件,也可以是独立的硬件设备。

一个典型的场景:是在一个 "受信任的内网" 和 "不受信任的外网" 之间建立一个屏障。

防火墙 分类

安全性能高的防火墙系统都是组合运用多种类型防火墙,构筑多道防火墙 "防御工事" 

从结构上来分,防火墙有两种:

  • 代理主机结构
  • 路由器 + 过滤器结构

按7层网络结构来划分,防火墙可以分为:

网络层防火墙

网络层防火墙可视为一种 IP 封包过滤器,运作在底层的TCP/IP协议堆栈上。可以以枚举的方式只允许符合特定规则的封包通过,其余的一概禁止穿越防火墙(病毒除外,防火墙不能防止病毒侵入)。这些规则通常可以经由管理员定义或修改,不过某些防火墙设备可能只能套用内置的规则。

应用层防火墙

应用层防火墙是在 TCP/IP 堆栈的 "应用层" 上运作,您使用浏览器时所产生的数据流或是使用 FTP 时的数据流都是属于这一层。应用层防火墙可以拦截进出某应用程序的所有封包,并且封锁其他的封包(通常是直接将封包丢弃)。理论上,这一类的防火墙可以完全阻绝外部的数据流进到受保护的机器里。

数据库防火墙

数据库防火墙是一款基于数据库协议分析与控制技术的数据库安全防护系统。基于主动防御机制,实现数据库的访问行为控制、危险操作阻断、可疑行为审计。数据库防火墙通过SQL协议分析,根据预定义的禁止和许可策略让合法的SQL操作通过,阻断非法违规操作,形成数据库的外围防御圈,实现SQL危险操作的主动预防、实时审计。数据库防火墙面对来自于外部的入侵行为,提供SQL注入禁止和数据库虚拟补丁包功能。

从原理上防火墙可以分成4种类型

  • 特殊设计的硬件防火墙
  • 数据包过滤型
  • 电路层网关
  • 应用级网关

包过滤 防火墙

第一代防火墙技术几乎与路由器同时出现,采用了包过滤(Packet filter)技术。它检查每一个通过的网络包,然后根据规则来决定 数据包 "丢弃、放行",这称为包过滤防火墙。

包过滤型防火墙 工作在 OSI 网络参考模型的 网络层传输层,检查每一个传入包,查看包中可用的基本信息 ,如:数据包头源地址,目的地址、端口号和协议类型等标志,然后将这些信息与设立的规则相比较后在确定是否允许通过。只有满足过滤条件的数据包才被转发到相应的目的地,其余数据包则从数据流中被丢弃。

建立包过滤防火墙规则如下:

  • 对来自专用网络的包,只允许来自内部地址的包通过,因为其他包包含不正确的包头部信息。这条规则可以防止网络内部的任何人通过欺骗性的源地址发起攻击。而且,如果黑客对专用网络内部的机器具有了不知从何得来的访问权,这种过滤方式可以阻止黑客从网络内部发起攻击。
  • 在公共网络,只允许目的地址为80端口的包通过。这条规则只允许传入的连接为Web连接。这条规则也允许与Web连接使用相同端口的连接,所以它并不是十分安全。
  • 丢弃从公共网络传入的包,而这些包都有你的网络内的源地址,从而减少IP欺骗性的攻击。丢弃包含源路由信息的包,以减少源路由攻击。要记住,在源路由攻击中,传入的包包含路由信息,它覆盖了包通过网络应采取得正常路由,可能会绕过已有的安全程序。通过忽略源路由信息,防火墙可以减少这种方式的攻击。

状态 / 动态检测 防火墙

动态包过滤(Dynamic packet filter)技术是第四代防火墙,后来演变为所说的 状态监视(Stateful inspection)技术。状态/动态检测防火墙,试图跟踪通过防火墙的网络连接和包,这样防火墙就可以使用一组附加的标准,以确定是否允许和拒绝通信。它是在使用了基本包过滤防火墙的通信上应用一些技术来做到这点的。检测型防火墙技术与过滤型相类似,可谓是过滤型的加强版,又称为动态过滤型技术。

  • 无状态:当 包过滤防火墙 见到一个网络包,包是孤立存在的。它没有防火墙所关心的历史或未来。允许和拒绝包的决定完全取决于包自身所包含的信息,如源地址、目的地址、端口号等。包中没有包含任何描述它在信息流中的位置的信息,则该包被认为是无状态的,它仅是存在而已。
  • 有状态:一个有状态包检查防火墙跟踪的不仅是包中包含的信息。为了跟踪包的状态,防火墙还记录有用的信息以帮助识别包,例如已有的网络连接、数据的传出请求等。例如,如果传入的包包含视频数据流,而防火墙可能已经记录了有关信息,是关于位于特定IP地址的应用程序最近向发出包的源地址请求视频信号的信息。如果传入的包是要传给发出请求的相同系统,防火墙进行匹配,包就可以被允许通过。

一个状态/动态检测防火墙可截断所有传入的通信,而允许所有传出的通信。因为防火墙跟踪内部出去的请求,所有按要求传入的数据被允许通过,直到连接被关闭为止。只有未被请求的传入通信被截断。

跟踪连接状态的方式取决于包通过防火墙的类型:

  • TCP包。当建立起一个TCP连接时,通过的第一个包被标有包的SYN标志。通常情况下,防火墙丢弃所有外部的连接企图,除非已经建立起某条特定规则来处理它们。对内部的连接试图连到外部主机,防火墙注明连接包,允许响应及随后再两个系统之间的包,直到连接结束为止。在这种方式下,传入的包只有在它是响应一个已建立的连接时,才会被允许通过。
  • UDP包。UDP包比TCP包简单,因为它们不包含任何连接或序列信息。它们只包含源地址、目的地址、校验和携带的数据。这种信息的缺乏使得防火墙确定包的合法性很困难,因为没有打开的连接可利用,以测试传入的包是否应被允许通过。可是,如果防火墙跟踪包的状态,就可以确定。对传入的包,若它所使用的地址和UDP包携带的协议与传出的连接请求匹配,该包就被允许通过。和TCP包一样,没有传入的UDP包会被允许通过,除非它是响应传出的请求或已经建立了指定的规则来处理它。对其他种类的包,情况和UDP包类似。防火墙仔细地跟踪传出的请求,记录下所使用的地址、协议和包的类型,然后对照保存过的信息核对传入的包,以确保这些包是被请求的。

应用程序代理 防火墙

应用代理型防火墙是工作在 OSI 的最高层,即 应用层。其特点是完全 "阻隔" 了网络通信流,通过对每种应用服务编制专门的代理程序,实现监视和控制应用层通信流的作用。应用程序代理防火墙实际上并不允许在它连接的网络之间直接通信。相反,它是接受来自内部网络特定用户应用程序的通信,然后建立于公共网络服务器单独的连接。网络内部的用户不直接与外部的服务器通信,所以外部服务器不能直接访问内部网的任何一部分。

NAT 网络地址转换

防火墙会用到一种路由器技术 NAT(Network Address Translation,网络地址转换)。从技术上讲 NAT 根本不是防火墙。NAT 是将内部网络的多个IP地址转换到一个公共地址发到 Internet 上。众所周知,IPv4的公网IP地址已经枯竭,但是需要接入互联网的设备还在不断增加,这其中NAT就发挥了很大的作用(此处不讨论IPv6)。NAT服务器提供了一组私有的IP地址池(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16),使得连接该NAT服务器的设备能够获得一个私有的IP地址(也称局域网IP/内网IP),当设备需要连接互联网的时候,NAT服务器将该设备的私有IP转换成可以在互联网上路由的公网IP(全球唯一)。NAT的实现方式有很多种,主要有三种:静态NAT动态NAT和网络地址端口转换(NAPT)。

当内部用户与一个公共主机通信时,NAT 追踪是哪一个用户作的请求,修改传出的包,这样包就像是来自单一的公共IP地址,然后再打开连接。一旦建立了连接,在内部计算机和Web站点之间来回流动的通信就都是透明的了。

当从公共网络传来一个未经请求的传入连接时,NAT 有一套规则来决定如何处理它。如果没有事先定义好的规则,NAT 只是简单的丢弃所有未经请求的传入连接,就像包过滤防火墙所做的那样。可以将 NAT 配置为接受某些特定端口传来的传入连接,并将它们送到一个特定的主机地址。

个人防火墙

现在网络上流传着很多的个人防火墙软件,它是应用程序级的。个人防火墙是一种能够保护个人计算机系统安全的软件,它可以直接在用户的计算机上运行,使用与状态/动态检测防火墙相同的方式保护一台计算机免受攻击。通常,这些防火墙是安装在计算机网络接口的较低级别上,使得它们可以监视传入传出网卡的所有网络通信。

一旦安装上个人防火墙,就可以把它设置成 "学习模式",这样的话,对遇到的每一种新的网络通信,个人防火墙都会提示用户一次,询问如何处理那种通信。然后个人防火墙便记住响应方式,并应用于以后遇到的相同那种网络通信。

例如,如果用户已经安装了一台个人Web服务器,个人防火墙可能将第一个传入的Web连接作上标志,并询问用户是否允许它通过。用户可能允许所有的Web连接、来自某些特定IP地址范围的连接等,个人防火墙然后把这条规则应用于所有传入的Web连接。

基本上,你可以将个人防火墙想象成在用户计算机上建立了一个虚拟网络接口。不再是计算机的操作系统直接通过网卡进行通信,而是以操作系统通过和个人防火墙对话,仔细检查网络通信,然后再通过网卡通信。

2、Linux 防火墙

Linux 防火墙在企业应用中非常有用,举例如下:

  • 中小企业与网吧里有 iptables 作为企业的NAT路由器,可以用来代替传统路由器。
  • IDC机房一般没有硬件防火墙,可以用 Linux 防火墙代替硬件防火墙。
  • iptables 可以结合 squid 作为企业内部上网的透明代理。传统代理需要在浏览器里配置代理服务器信息,而 iptables+squid 的透明代理则可以把客户端的请求重定向到代理服务器的端口。客户端不要作任何设置,而感觉不到代理的存在。
  • 将 iptables 作为企业NAT路由器时,可以使用 iptables 的扩展模块屏蔽 P2P 流量,还可以禁止非法网页。
  • iptables 可以用于外网 IP 向内网IP映射。
  • iptables 可以轻松防止轻量级 DOS 攻击,比如 ping 攻击及 SYN 洪水攻击。

netfilter

Netfilter 是由 Rusty Russell 提出的 Linux 2.4 内核防火墙通用架构,工作于内核空间。该框架既简洁又灵活,可实现安全策略应用中的许多功能,如:数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换(Network Address Translation,NAT),以及基于用户及媒体访问控制(Media Access Control,MAC)地址的过滤和基于状态的过滤、包速率限制等。Iptables / Netfilter 的这些规则可以通过灵活组合,形成非常多的功能、涵盖各个方面,这一切都得益于它的优秀设计思想。

  • netfilter 是内核的模块实现是 Linux 的2.4版内核引入了一种全新的包过滤引擎。属于 " 内核态 " 的防火墙框架。这个框架里面包含了 4个表5个链,这些链又包含了很多的规则。而数据包执行的动作就是这个链中所定义的规则。
  • iptables 是一个应用层(Ring3)的应用程序,用来管理 Linux 防火墙。它通过 Netfilter 放出的接口来对存放在内核内存中的 XXtables(Netfilter的配置表)进行修改,这个XXtables由表tables、链chains、规则rules组成,iptables在应用层负责修改这个规则文件。

如果不严格的区分,在Linux 中 netfilter 和 iptables 都可以认为是指 Linux 防火墙,在下述的内容中就以 iptables 来称呼 Linux 防火墙了。

防火墙 管理 工具

iptables

iptables 是控制 netfilter 的工具,用来管理内核包的过滤,属于 "用户态" 的防火墙管理体系。真正实现防火墙功能的是 netfilter。通过 iptables 可以编写某些规则,并将规则保存在 netfilter 的某些表的某些链中,进而才起到防火墙的功能。 

Netfilter / Iptables 数据包过滤系统可以当成一个整体 

Iptables 有两种应用模式:主机防火墙NAT路由器

firewalld

firewalld 和 iptables 一样,也是一个防火墙管理工具firewalld管理火墙相对简单。iptables复杂但功能强大。firewalld 是一个动态的、可定制而无需重新启动防火墙守护程序或服务。在CentOS 8中,nftables 取代 iptables 成为默认的Linux 网络包过滤框架。

firewalld 相比 iptables 的 2 个好处:

  • firewalld 可以动态修改单条规则,而不需要像 iptables 那样,在修改了规则后必须得全部刷新才可以生效;
  • firewalld 在使用上要比 iptables 人性化很多,即使不明白 “五张表五条链” ,而且对 TCP/IP协议也不理解也可以实现大部分功能。

firewall-cmd

firewall-cmd 是 iptables/nftable 的前端,是 firewalld的字符界面管理工具

基本语法:firewall-cmd --zone=zone-name --add-service=service-name --permanent

命令参数

  • --zone:指定要添加服务的区域名称。
  • --add-service:指定要添加的服务名称。
  • --permanent:指定该规则永久生效。

除此之外,还有其他可选参数:

  • --list-all:列出所有规则。
  • --reload:重新加载防火墙规则。
  • --permanent:将规则保存到永久配置中,以便系统重启后仍然有效。
  • --delete-service:删除服务。
  • --list-services:列出当前系统中所有可用服务。
  • --add-source:添加一个 IP 或 IP 段。
  • --remove-source:删除一个 IP 或 IP 段。
  • --list-sources:列出所有已添加的 IP 或 IP 段。
  • --add-port:添加端口。
  • --remove-port:删除端口。
  • --list-ports:列出所有已添加的端口。
  • --add-rich-rule:添加一个更加复杂的规则。
  • --query-service:查询服务是否可用。
  • --get-zones:列出所有可用的区域。
  • --zone=zone-name:指定一个区域。

示例

在修改防火墙规则时,建议使用 --permanent 选项,以便该规则在系统重启后仍然有效。

添加端口:firewall-cmd --zone=public --add-port=80/tcp --permanent
删除端口:firewall-cmd --zone=public --remove-port=80/tcp --permanent
添加服务:firewall-cmd --zone=public --add-service=http --permanent
删除服务:firewall-cmd --zone=public --remove-service=http --permanent
列出所有规则:firewall-cmd --list-all
重新加载防火墙规则:firewall-cmd --reload
列出所有可用的服务:firewall-cmd --list-services

Netfilter 的基本组件

Netfilter 的组成

  • Netfilter 由  4个表 (tables) 组成。表(tables)提供特定的功能,iptables有4个表:"raw表、filter表 (实现包过滤)、nat表 (网络地址转换)、mangle表 (对数据包进行高级修改)"。
  • 每个表由若干个链(chains)组成。表中的规则写在链上
  • 每条链可以由一条或若干条规则(rules)组成,其规则由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。

iptables 的 的示意图如下:

在 iptables 规则表中,filter表 nat表 用的比较多,而其他两个表用的相对来说比较少。

在这些表当中,raw表的优先级最高,其次是mangle表,接着是nat表,最后才是filter表

因此,表的优先级顺序由高到低是:raw > mangle > nat > filter。

  • 当一个数据包进入到防火墙时,它会依次根据这些表中的相关链中的规则对数据包进行匹配,允许则通过,拒绝则丢弃。
  • 出防火墙时,也是根据这个顺序进行规则匹配的,允许则通过,拒绝则丢弃。

4 表 ( raw、Mangle、nat、filter )

  • raw (表):主要用来决定是否对数据包进行状态跟踪。包含OUTPUT、PREROUTING两个规则链。raw表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在系统进行ip_conntrack(连接跟踪)前进行处理。一但用户使用了raw表,在某个链上,raw表处理完后,将跳过NAT表和ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了。RAW表可以应用在那些不需要做nat的情况下,以提高性能。
  • Mangle (表) :这个表主要用来 mangle 数据包,用来修改数据包的TOS,TTL值,或者为数据包设置Mark标记。注意 MARK 并没有真正地改动数据包,它只是在内核空间为包设了一个标记。防火墙内的其他的规则或程序(如tc)可以使用这种标记对包进行过滤或高级路由。注意,mangle表不能做任何NAT,它只是改变数据包的TTL,TOS或MARK,而不是其源目地址。NAT 必须在nat表中操作的。

    PREROUTING(链)在包进入防火墙之后、路由判断之前改变包
    INPUT(链) 在包被路由到本地之后,但在用户空间的程序看到它之前改变包
    FORWARD(链) 在最初的路由判断之后、最后一次更改包的目的之前mangle包
    OUTPUT(链) 在确定包的目的之前更改数据包
    POSTROUTING(链)是在所有路由判断之后

  • nat (表):Nat (Network Address Translation) 表的主要用处是网络地址转换。主要用来修改数据包IP地址、端口号等信息。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包(因为包的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作。也就是说,余下的包不会再通过这个表
    PREROUTING(链)的作用是在包刚刚到达防火墙时改变它的目的地址
    POSTROUTING (链)
    OUTPUT(链)改变本地产生的包的目的地址

  • filter (表):filter表主要用来对数据包进行过滤,根据具体的规则要求决定如何处理一个数据包。内建三个链,可以无条件地对包进行 DROP、LOG、ACCEPT 和 REJECT 等操作。
    INPUT(链) 是针对那些目的地是本地的包
    FORWARD(链) 是过滤所有不是本地产生的并且目的地不是本地(即本机只是负责转发)的包
    OUTPUT(链) 是用来过滤所有本地生成的包 

5 链

chain 的本质是 Netfilter 定义的不同过滤点。总共定义了 5个过滤点 (5个链) 。Netfilter 在五个链上,使用 HOOK 技术做规则检查。iptables 的 5个链是 prerouting,input,forward,output,postrouting,每个链上都有默认的规则。

  • PREROUTING:在进行路由选择前处理数据包。即数据包进入本机,进入路由器之前。可以用于目标地址转换(DNAT)。
  • INPUT 链:处理入站数据包。
  • FORWARD 链: 处理转发数据包。
  • OUTOPUT 链:处理出站数据包。由本机产生,向外转发。
  • POSTROUTIONG:在进行路由选择后处理数据包。即通过路由表后,发送到网卡接口之前。可以用于转发数据(SNAT,MASQUERADE)

规则链 的作用是容纳各种防火墙规则,规则链 分为5种,分别在不同的时机处理数据包。

Linux 防火墙的原理主要是对数据包的控制。看下图:netfilter 五条链相互关系,即 iptables 数据包转发流程图。

其中 INPUT 和 OUTPUT链主要用在 "主机型防火墙" 中,而 FORWARD、POSTROUTING 和PREROUTING 链主要用在 "网关防火墙" 中。

详细的数据包流程

(图片引用 https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg

  • (1)数据包进入网卡时,先进入PREROUTING(路由前)链,之后做路由判断数据包应发往何处,本机或其他机器。
  • (2)若数据包原目标地址是本机的,数据包会前往INPUT链。到达INPUT链后,任何进程都会收到它。
  • (3)本机程序发送出数据包,数据包会经过OUTPUT链,然后到达POSTROUTING链输出。
  • (4)若数据包原目标地址非本机,则需要转发出去的,且内核允许转发,数据包前往 FORWARD链,然后到达POSTROUTING(路由后)链输出。

链(chains)是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。

规则

规则(rules)是管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。

规则执行流程梳理:

iptables 执行规则时,是从规则表中从上至下顺序执行的。

1. 若没遇到匹配的规则,就一条一条往下匹配;

2. 若完全没有匹配的规则,则执行该链上的默认规则;

3. 若遇到匹配的规则,则执行规则,执行后根据本规则的动作(accept,reject,log,drop等),决定下一步执行的情况,后续执行一般有三种情况:

  • 继续执行当前规则队列内的下一条规则。比如执行过Filter队列内的LOG后,还会执行Filter队列内的下一条规则。
  • 中止当前规则队列的执行,转到下一条规则队列。比如从执行过accept后就中断Filter队列内其它规则,跳到nat队列规则去执行。
  • 中止所有规则队列的执行。

image

过这种机制可以进行复杂、多重的封包过滤,简单的说,iptables可以进行纵横交错式的过滤(tables)而非链状过滤(chains)。

从上图中,我们可以总结出以下规律:

  • 当一个数据包进入网卡时,数据包首先进入PREROUTING链,在PREROUTING链中我们有机会修改数据包的DestIP(目的IP),然后内核的"路由模块"根据"数据包目的IP"以及"内核中的路由表"判断是否需要转送出去(注意,这个时候数据包的DestIP有可能已经被我们修改过了)
  • 如果数据包就是进入本机的(即数据包的目的IP是本机的网口IP),数据包就会沿着图向下移动,到达INPUT链。数据包到达INPUT链后,任何进程都会-收到它
  • 本机上运行的程序也可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROTING链输出(注意,这个时候数据包的SrcIP有可能已经被我们修改过了)
  • 如果数据包是要转发出去的(即目的IP地址不再当前子网中),且内核允许转发,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出(选择对应子网的网口发送出去)

在写iptables规则的时候,要时刻牢记这张路由次序图,根据所在Hook点的不同,灵活配置规则

使用 Iptables 是一个非常灵活的过程,我们在写规则的时候,一定要时刻牢记上面的这张 "数据包路由图",明白在5个Hook点,3种"表"分别所处的位置,以及结合在这个5个Hook点可以实现的功能,来理解规则。理解规则的原理比强记规则本身效果要好得多

编写 防火墙 规则

重点:规则顺序非常重要,规则顺序非常重要,规则顺序非常重要

iptables 命令 帮助

iptables 的基本语法命令格式:iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 控制类型]

  • 表名链名:指定iptables命令所操作的,未指定表名时将默认使用filter表;
  • 管理选项:表示iptables规则的操作方式,比如:插入增加删除查看等;
  • 匹配条件:指定要处理的数据包的特征,不符合指定条件的数据包不处理;
  • 控制类型:指数据包的处理方式,比如:允许accept拒绝reject丢弃drop日志LOG等;

1.  [-t 表名]:该规则所操作的哪个表,可以使用 filter、nat 等,如果没有指定则默认为 filter

iptables 命令的常用管理选项
        -A:在指定链的末尾添加一条新的规则
        -D:删除指定链中的某一条规则,可删除指定序号或具体内容
        -I:在指定链中插入一条新规则,未指定序号时默认作为第一条规则
        -R:修改、替换指定链中的某一条规则,可指定规则序号或具体内容
        -L:列出指定链中所有的规则,未指定链名,则列出表中的所有链。或者 -nL
        -F:清空指定链中所有的规则,未指定链名,则清空表中的所有链
        -P:设置指定链的默认策略
        -n:使用数字形式显示输出结果
        -v:查看规则列表时显示详细的信息
        -h:查看命令帮助信息
        --line-numbers:查看规则列表时,同时显示规则在链中的顺序号

2.  chain名:指定规则表的哪个链,如INPUT、OUPUT、FORWARD、PREROUTING等

[规则编号]:插入、删除、替换规则时用,--line-numbers显示号码
[-i|o 网卡名称]:i 是指定数据包从哪块网卡进入,o是指定数据包从哪块网卡输出
[-p 协议类型]:可以指定规则应用的协议,包含tcp、udp和icmp等
[-s 源IP地址]:源主机的IP地址或子网地址
[--sport 源端口号]:数据包的IP的源端口号
[-d目标IP地址]:目标主机的IP地址或子网地址
[--dport目标端口号]:数据包的IP的目标端口号

3. -m:extend matches,这个选项用于提供更多的匹配参数,如:

-m state --state ESTABLISHED,RELATED
-m tcp --dport 22
-m multiport --dports 80,8080
-m icmp --icmp-type 8

4. <-j 动作>:处理数据包的动作,包括 accept、drop、reject、log、mirror、queue、redirect、return 和 ulog。

  • ACCEPT:允许数据包通过。
  • DROP:直接丢弃数据包,不给出任何回应信息。
  • REJECT:DROP 和 REJECT 都会把它们的包丢弃。DROP是默默地丢弃,而 REJECT如果必要时会返回一则 ICMP 错误消息。
  • LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则。
  • SNAT:源地址转换。在进入路由层面的route之后,出本地的网络栈之前,改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机。解决内网用户用同一个公网地址上网的问题。MASQUERADE,是SNAT的一种特殊形式,适用于像 adsl 这种临时会变的ip上
  • DNAT:目标地址转换。和SNAT相反,IP包经过route之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。可以隐藏后端服务器的真实地址。(感谢网友提出之前这个地方与SNAT写反了)
  • REDIRECT:是 DNAT 的一种特殊形式,将网络包转发到本地 host 上(不管IP头部指定的目标地址是啥),方便在本机做端口转发。例如:用这个功能来使站点上的所有Web流量都通过一个Web高速缓存,比如Squid。
  • RETURN:终结用户定义的链,类似于子例程调用中的return语句。
  • MIRROR:目标在发送包之前交换IP源和目的地址。
  • QUEUE:通过一个内核模块把包交给本地用户程序。

iptables 服务操作
    检查:# service --status-all
    启动:# service iptables start    // 开启 iptables 服务,默认加载/etc/sysconfig/iptables中的规则
    停止:# service iptables stop    // 关闭 iptables 服务,默认将会清空所有的iptables规则。
    重启:# service iptables restart
使用 systemctl 管理防火墙
    systemctl start firewalld   开启
    systemctl status firewalld  查看防火墙状态
    systemctl enable firewalld  设置开机自启
    systemctl disable firewalld 开机自动关闭防火墙
    systemctl stop firewalld    关闭防火墙

使用命令配置防火墙
        firewall-cmd --state  查看防火墙状态
        firewall-cmd --get-active-zones 查看防火墙正在使用的域
        firewall-cmd --get-default-zone 查看防火墙默认域
        firewall-cmd --get-zones    查看防火墙的域
        firewall-cmd --zone=public --list-all 列出public域的所有设置
        firewall-cmd --get-services    查看防火墙的服务
        firewall-cmd --list-all-zones  列出所有域的详细信息
        firewall-cmd --set-default-zone=*** 设置***为默认域
        firewall-cmd --reload  重新加载防火墙设置

清除所有 iptables 规则并保存更改。下面命令分别清除过滤器、网络地址转换(NAT)和数据包修改(MANGLE)表中的所有规则,并将默认策略设置为接受所有传入、转发和输出流量。

sudo iptables -F
sudo iptables-save > /etc/sysconfig/iptables
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

保存更改:sudo service iptables save

将当前的 iptables 规则保存到 /etc/sysconfig/iptables 文件中,以便在下次启动时重新加载。

查看:sudo iptables -L

防火墙规则的批量备份,还原,需要用到两个命令:iptables-save、iptables-restore

  • iptables-save 命令用来批量导出 iptables防火墙规则,直接执行iptables-save时,将显示出当前启用的所有规则,按照raw、mangle、nat、filter表的顺序依次列出;若只希望显示出某一个表,应添加 "-t 表名" 作为命令选项,然后结合重定向输入 ">" 将输出内容重定向到某个文件中。
  • iptables-retore 命令用来批量导入Linux防火墙规则,如果已经有使用iptable-save命令导出的备份文件,则恢复规则的过程也就是一瞬间的事。与iptables-save命令相对的,iptables-restore命令应结合重定向输入来指定备份文件的位置。

sudo iptables -F 清除所有的 iptables 过滤器规则。
这个命令将会删除所有的过滤器链(如 INPUT、FORWARD 和 OUTPUT)中的规则,并将默认策略设置为接受所有的流量。请注意,这不会清除 NAT 或 MANGLE 表中的规则。
运行 sudo iptables -L 来检查 iptables 的规则是否已被清除。

1、备份保存 iptables 规则

示例:备份所有表的规则。

执行命令:iptables-save > /opt/iprules_all.txt 
或者 service iptables save  默认将所有规则保存到 "/etc/sysconfig/iptables" 文件中。

2、恢复 iptables 规则

示例:将上所备份的规则恢复到 iptables 中。
[root@localhost /]#iptables-restore < /opt/iprules_all.txt
或者
[root@localhost /]#service iptables start
后者默认将 "/etc/sysconfig/iptables" 文件中的内容加载到 iptables 中。如果备份使用的是 "service iptables save" 那么恢复的时候就应该使用 "service iptables start"。

iptables 规则的匹配条件

1、通用匹配

通用匹配也称常规匹配,这种匹配方式可以独立使用,不依赖其他条件或扩展模块,常见的通用匹配包括协议匹配,地址匹配,网络接口匹配。

  • 协议pipe:编写iptables规则时使用“-p 协议名”的形式指定,用来检查数据包所使用的网络协议,如:tcp、udp、icmp等。
    示例:编写iptables拒绝通过icmp的数据包。
    [root@localhost /]#iptables -A INPUT -p icmp -j DROP
  • 地址匹配:编写iptables规则时使用“-s源地址”或“-d目标地址”的形式指定,用来检查数据包的源地址或目标地址。
    示例:编写iptables拒绝转发192.168.1.0/24到202.106.123.0/24的数据包。
    [root@localhost /]#iptables -A FORWARD -s 192.168.1.0/24 -d 202.106.123.0/24 -j DROP
  • 网络接口匹配:编写iptables规则时使用“-i 接口名”和“-o 接口名”的形式,用于检查数据包从防火墙的哪一个接口进入或发出,分别对应入站网卡(--in-interface),出站网卡(--out-interface)。
    示例:拒绝从防火墙的eth1网卡接口ping防火墙主机。
    [root@localhost /]#iptables -A INPUT -i eth1 -p icmp -j DROP

2、隐含匹配

这种匹配方式要求以指定的协议匹配作为前提条件,相当于子条件,因此无法独立使用,其对应的功能由iptables在需要时自动隐含载入内核。常见的隐含匹配包括端口匹配,TCP标记匹配,ICMP类型匹配。

  • 端口匹配:编写iptable规则时使用“--sport 源端口”或“--dport”的形式,针对的协议为TCP或UDP,用来检查数据包的源端口或目标端口。单个端口或者以“:”分隔的端口范围都是可以接受的,但不支持多个不连续的端口号。
    示例:编写iptables规则允许FTP数据包通过,则需要允许20,21和用于被动模式的24500-24600的端口范围。
    [root@localhost /]#iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT
    [root@localhost /]#iptables -A INPUT -p tcp --dport 24500:24600 -j ACCEPT
  • TCP标记匹配:编写iptables规则时使用“--tcp-flags 检查范围 被设置的标记”的形式,针对的协议为TCP,用来检查数据包的标记位。其中“检查范围”指出需要检查数据包的那几个标记位,“被设置的标记”则明确匹配对应值为1的标记,多个标记之间以逗号进行分隔。
    示例:若要拒绝外网卡接口(eth1)直接访问防火墙本机的TCP请求,但其他主机发给防火墙的TCP响应等数据包应允许,可执行如下操作。
    [root@localhost /]#iptables -A INPUT -i eth1 -p tcp --tcp-flags SYN,RST,ACK SYN -j DROP
  • ICMP类型匹配:编写iptables规则时使用“--icmp-type ICMP类型”的形式,针对的协议为ICMP,用来检查ICMP数据包的类型。ICMP类型使用字符串或数字代码表示,如“Echo-quest”(代码为8),“Echo-Reply”(代码为0),“Destination-Unreachable”(代码为3),分别对应ICMP协议的请求,回显,目标不可达。
    示例:若要禁止从其他主机ping防火墙本机,但允许防火墙本机ping其他主机,可执行以下操作。
    [root@localhost /]#iptables -A INPUT -p icmp --icmp-type 8 -j DROP
    [root@localhost /]#iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
    [root@localhost /]#iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT

3、显示匹配

这种匹配方式要求有额外的内核模块提供支持,必须手动以“-m 模块名称”的形式调用相应的模块。然后方可设置匹配条件。常见的显示匹配包括多端口匹配,IP范围匹配,MAC地址匹配,状态匹配。

  • 多端口匹配:编写iptables规则时使用“-m multiport --dport 端口列表”或“-m multiport --sport 端口列表”的形式,用来检查数据包的源端口,目标端口,多端口之间以逗号进行分隔。
    示例:若允许本机开放25,80,110,143等端口,以便提供电子邮件服务,可执行如下操作。
    [root@localhost /]#iptables -A INPUT -p tcp -m multiport --dport 25,80,110,143 -j ACCEPT
  • IP地址范围匹配:编写iptables规则时使用“-m iprange --src-range IP范围”,“-m -iprange --dst-range IP地址范围”的形式,用来检查数据包的源地址,目标地址,其中IP范围采用“起始地址-结束地址”的形式表示。
    示例:若要允许转发源地址IP位于192.168.4.21与192.168.4.28之间的TCP数据包,可执行如下操作。
    [root@localhost /]#iptables -A FORWARD -p tcp -m iprange --src-range 192.168.4.21-192.168.4.28 -j ACCEPT
  • MAC地址匹配:编写iptables规则时使用“-m mac --mac-source MAC地址”的形式,用来检查数据包的源MAC地址。由于MAC地址本身的局限性,此类匹配条件一般只适用于内部网络。
    示例:若要根据MAC地址封锁主机,禁止其访问本机的任何应用,可以执行如下操作。
    [root@localhost /]#iptables -A INPUT -m mac --mac-source 00:0c:29:c0:55:3f -j DROP
  • 状态匹配:编写iptables规则时使用“-m state --state 连接状态”的形式,基于iptables的状态跟踪机制用来检查数据包的连接状态。常见的连接状态包括NEW(如任何连接无关的),ESTABLISHED(相应请求或者一建立连接的),RELATED(与已有连接有相关性的,如FTP数据连接)。
    示例:编写iptables规则,只开放本机的80端口服务,对于发送给本机的TCP应答数据包给予放行,其他入站数据包均拒绝,可执行如下操作。
    [root@localhost /]#iptables -A INPUT -p tcp -m multiport --dport 80 -j ACCEPT
    [root@localhost /]#iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT

示例:

提出需求

1. 网口at0(10.0.0.1)是一个伪AP的网口,目标客户端连接到伪AP网口at0之后会发
   起DHCPDISCOVER过程,监听在at0上的DHCPD会进行回应,
   为客户端分配10.0.0.100的IP地址,并设置客户端的默认网关为10.0.0.1(即at0的IP地址)、
   默认DNS服务器为10.0.0.1(即at0的IP地址)
2. 需要将网口at0(10.0.0.1)的入口流量牵引到真正连接外网的网卡接口
   eth0(192.168.159.254)上,做一个NAT服务
3. 对网口at0(10.0.0.1)的DHCP流量(目的端口67的广播数据包)予以放行,
   因为我们需要在伪AP所在的服务器上假设DHCP服务器
4. 对网口at0(10.0.0.1)的DNS流量(目的端口53)予以放行,
   因为我们需要在伪AP所在的服务器上假设DNS服务器

逐步抽象化我们的需求

我们根据我们的需求进行抽象化,即用规则来抽象化描述我们的目的,在编写的过程中要注意不同的Hook点所能做的修改是不同的

// 开启Linux路由转发开关,由于本机对数据包进行转发
echo "1" > /proc/sys/net/ipv4/ip_forward

// 将客户端的HTTP流量进行NAT,改变数据包的SrcIP,
// 注意,是在POSTROUTING(数据包即将发送出去之前进行修改)
iptables -t nat -A POSTROUTING -p tcp -s 10.0.0.0/24 --dport 80 -j SNAT --to-source 192.168.159.254

// 将远程WEB服务器返回来的HTTP流量进行NAT,回引回客户端,
// 注意,是在PREROUTING(数据包刚进入协议栈之后马上就修改)
iptables -t nat -A PREROUTING -p tcp -d 192.168.159.254 -j DNAT --to 10.0.0.100

我们在DHCP服务器中指定客户端的默认DNS服务器是10.0.0.1(本机),即伪DNS,但我目前还没有在本机架设DNS,所以目前还需要将53号端口的DNS数据包NAT出去,牵引到谷歌的DNS: 8.8.8.8上去

iptables -t nat -A PREROUTING -p udp -s 10.0.0.0/24 --dport 53 -j DNAT --to 8.8.8.8
iptables -t nat -A POSTROUTING -p udp -s 10.0.0.0/24 --dport 53 -j SNAT --to-source 192.168.159.254

iptables -t nat -A PREROUTING -p udp -d 192.168.159.254 --sport 53 -j DNAT --to 10.0.0.100
iptables -t nat -A POSTROUTING -p udp -s 8.8.8.8 --sport 53 -j SNAT --to-source 10.0.0.1

命令:  -A, --append
范例:  iptables -A INPUT ...
说明:  新增规则到某个规则链中,该规则将会成为规则链中的最后一条规则。

命令:  -D, --delete
范例:  iptables -D INPUT --dport 80 -j DROP
       iptables -D INPUT 1
说明:  从某个规则链中删除一条规则,可以输入完整规则,或直接指定规则编号加以删除。

命令:  -R, --replace
范例:  iptables -R INPUT 1 -s 192.168.0.1 -j DROP
说明:  取代现行规则,规则被取代后并不会改变顺序。

命令:  -I, --insert
范例:  iptables -I INPUT 1 --dport 80 -j ACCEPT
说明:  插入一条规则,原本该位置上的规则将会往后移动一个顺位。

命令:  -L, --list
范例1: iptables -L INPUT
说明:  列出某规则链中的所有规则。
范例2: iptables -t nat -L
说明:  列出nat 表所有链中的所有规则。

命令:  -F, --flush
范例:  iptables -F INPUT
说明:  删除filter 表中INPUT 链的所有规则。

命令:  -Z, --zero
范例:  iptables -Z INPUT
说明:  将封包计数器归零。封包计数器是用来计算同一封包出现次数,是过滤阻断式攻击不可或缺的工具。

命令:  -N, --new-chain
范例:  iptables -N allowed
说明:  定义新的规则链。

命令:  -X, --delete-chain
范例:  iptables -X allowed
说明:  删除某个规则链。

命令:  -P, --policy
范例:  iptables -P INPUT DROP
说明:  定义过滤政策。也就是未符合过滤条件之封包, 默认的处理方式。

命令:  -E, --rename-chain
范例:  iptables -E allowed disallowed
说明:  修改某自定义规则链的名称。

3. [match] 常用封包匹配参数
参数:  -p, --protocol
范例:  iptables -A INPUT -p tcp
说明:  匹配通讯协议类型是否相符,可以使用! 运算符进行反向匹配,例如:
           -p !tcp
       意思是指除tcp 以外的其它类型,如udp、icmp ...等。
       如果要匹配所有类型,则可以使用all 关键词,例如:
           -p all

参数:  -s, --src, --source
范例:  iptables -A INPUT -s 192.168.1.1
说明:  用来匹配封包的来源IP,可以匹配单机或网络,匹配网络时请用数字来表示子网掩码,
例如:
       -s 192.168.0.0/24
       匹配IP 时可以使用! 运算符进行反向匹配,例如:
       -s! 192.168.0.0/24。

参数:  -d, --dst, --destination
范例:  iptables -A INPUT -d 192.168.1.1
说明:  用来匹配封包的目的地IP,设定方式同上。

参数:  -i, --in-interface
范例:  iptables -A INPUT -i eth0
说明:  用来匹配封包是从哪块网卡进入,可以使用通配字符+ 来做大范围匹配,例如:
         -i eth+
      表示所有的ethernet 网卡
      也可以使用! 运算符进行反向匹配,例如:
         -i !eth0

参数:  -o, --out-interface
范例:  iptables -A FORWARD -o eth0
说明:  用来匹配封包要从哪块网卡送出,设定方式同上。

参数:  --sport, --source-port
范例:  iptables -A INPUT -p tcp --sport 22
说明:  用来匹配封包的源端口,可以匹配单一端口,或是一个范围,例如:
          --sport 22:80
       表示从22 到80 端口之间都算是符合条件,如果要匹配不连续的多个端口,则必须使用
          --multiport 参数,详见后文。匹配端口号时,可以使用! 运算符进行反向匹配。

参数:  --dport, --destination-port
范例:  iptables -A INPUT -p tcp --dport 22
说明:  用来匹配封包的目的地端口号,设定方式同上

参数:  --tcp-flags
范例:  iptables -p tcp --tcp-flags SYN,FIN,ACK SYN
说明:  匹配TCP 封包的状态标志;
       参数分为两个部分,
         第一个部分列举出想匹配的标志,
         第二部分则列举前述标志中哪些有被设置,未被列举的标志必须是空的。
       TCP 状态标志包括:
          SYN(同步)、ACK(应答)、FIN(结束)、RST(重设)、URG(紧急) 、PSH(强迫推送) 
       等均可使用于参数中,
       除此之外还可以使用关键词ALL 和NONE 进行匹配。
       匹配标志时,可以使用! 运算符行反向匹配。

参数:  --syn
范例:  iptables -p tcp --syn
说明:  用来表示TCP 通信协议中,SYN 位被打开,而ACK 与FIN 位关闭的分组,即TCP 的初始连接,
       与iptables -p tcp --tcp-flags SYN,FIN,ACK SYN 的作用完全相同,
       如果使用!运算符,可用来匹配非要求连接封包。

参数:  -m multiport --source-port
范例:  iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
说明:  用来匹配不连续的多个源端口,一次最多可以匹配15 个端口,
       可以使用! 运算符进行反向匹配。

参数:  -m multiport --destination-port
范例:  iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
说明:  用来匹配不连续的多个目的地端口号,设定方式同上

参数:  -m multiport --port
范例:  iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
说明:  这个参数比较特殊,用来匹配源端口和目的端口号相同的封包,设定方式同上。
       注意:在本范例中,如果来源端口号为80目的地端口号为110,这种封包并不算符合条件。

参数:  --icmp-type
范例:  iptables -A INPUT -p icmp --icmp-type 8
说明:  用来匹配ICMP 的类型编号,可以使用代码或数字编号来进行匹配。
       请打iptables -p icmp--help 来查看有哪些代码可用。

参数:  -m limit --limit
范例:  iptables -A INPUT -m limit --limit 3/hour
说明:  用来匹配某段时间内封包的平均流量,
       上面的例子是用来匹配:每小时平均流量是否超过一次3 个封包。
       除了每小时平均次外,也可以每秒钟、每分钟或每天平均一次,默认值为每小时平均一次,参数如后:
           /second、/minute、/day
       除了进行封包数量的匹配外,设定这个参数也会在条件达成时,暂停封包的匹配动作,
       以避免因骇客使用洪水攻击法,导致服务被阻断。

参数:  --limit-burst
范例:  iptables -A INPUT -m limit --limit-burst 5
说明:  用来匹配瞬间大量封包的数量,
       上面的例子是用来匹配一次同时涌入的封包是否超过5个(这是默认值),超过此上限的封包将被直接丢弃。
       使用效果同上。

参数:  -m mac --mac-source
范例:  iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
说明:  用来匹配封包来源网络接口的硬件地址,
       这个参数不能用在OUTPUT 和POSTROUTING 规则链上,
       这是因为封包要送到网卡后,才能由网卡驱动程序透过ARP 通讯协议查出目的地的MAC 地址,
       所以iptables 在进行封包匹配时,并不知道封包会送到哪个网络接口去。

参数:  --mark
范例:  iptables -t mangle -A INPUT -m mark --mark 1
说明:  用来匹配封包是否被表示某个号码,
       当封包被匹配成功时,我们可以透过MARK 处理动作,将该封包标示一个号码,号码最大不可以超过4294967296。

参数:  -m owner --uid-owner
范例:  iptables -A OUTPUT -m owner --uid-owner 500
说明:  用来匹配来自本机的封包,是否为某特定使用者所产生的,
       这样可以避免服务器使用root或其它身分将敏感数据传送出,可以降低系统被骇的损失。
       可惜这个功能无法匹配出来自其它主机的封包。

参数:  -m owner --gid-owner
范例:  iptables -A OUTPUT -m owner --gid-owner 0
说明:  用来匹配来自本机的封包,是否为某特定使用者群组所产生的,使用时机同上。

参数:  -m owner --pid-owner
范例:  iptables -A OUTPUT -m owner --pid-owner 78
说明:  用来匹配来自本机的封包,是否为某特定进程所产生的,使用时机同上。

参数:  -m owner --sid-owner
范例:  iptables -A OUTPUT -m owner --sid-owner 100
说明:  用来匹配来自本机的封包,是否为某特定连接(Session ID)的响应封包,使用时机同上。

参数:  -m state --state
范例:  iptables -A INPUT -m state --state RELATED,ESTABLISHED
说明:  用来匹配连接状态, 
       连接状态共有四种:
          INVALID、ESTABLISHED、NEW 和RELATED。
       INVALID     表示该封包的连接编号(Session ID)无法辨识或编号不正确。
       ESTABLISHED 表示该封包属于某个已经建立的连接。
       NEW         表示该封包想要起始一个连接(重设连接或将连接重导向)。
       RELATED     表示该封包是属于某个已经建立的连接,所建立的新连接。
       例如:FTP-DATA 连接必定是源自某个FTP 连接。

4. [-j target/jump] 常用的处理动作
-j 参数用来指定要进行的处理动作,常用的处理动作包括:
   ACCEPT、REJECT、DROP、REDIRECT、MASQUERADE、LOG、DNAT、SNAT、MIRROR、QUEUE、RETURN、MARK,

分别说明如下:
动作:  ACCEPT 
说明:  将封包放行,
       进行完此处理动作后,将不再匹配其它规则,直接跳往下一个规则链(natostrouting)。

动作:  REJECT 
说明:  拦阻该封包,并传送封包通知对方,
       可以传送的封包有几个选择:
           ICMP port-unreachable、
           ICMP echo-reply 或是
           tcp-reset(这个封包会要求对方关闭连接),
         进行完此处理动作后,将不再匹配其它规则,直接中断过滤程序。
范例:  iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset

动作:  DROP
说明:  丢弃封包不予处理,进行完此处理动作后,将不再匹配其它规则,直接中断过滤程序。

动作:  REDIRECT
说明:  将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续匹配其它规则。
       这个功能可以用来实现透明代理或用来保护web 服务器。
范例:  iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

动作:  MASQUERADE
说明:  改写封包来源IP 为防火墙NIC IP,可以指定port 对应的范围,
       进行完此处理动作后,直接跳往下一个规则链(manglepostrouting)。
       这个功能与SNAT 略有不同,当进行IP 伪装时,不需指定要伪装成哪个IP,IP 会从网卡直接读取,
       当使用拨号接连时,IP通常是由ISP 公司的DHCP 服务器指派的,这个时候MASQUERADE 特别有用。
范例:  iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000

动作:  LOG
说明:  将封包相关讯息纪录在/var/log 中,详细位置请查阅/etc/syslog.conf 配置文件,
       进行完此处理动作后,将会继续匹配其规则。
范例:  iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"

动作:  SNAT
说明:  改写封包来源IP 为某特定IP 或IP 范围,可以指定port 对应的范围,
       进行完此处理动作后,将直接跳往下一个规则(mangleostrouting)。
范例:  iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source?194.236.50.155-194.236.50.160:1024-32000

动作:  DNAT
说明:  改写封包目的地IP 为某特定IP 或IP 范围,可以指定port 对应的范围,
       进行完此处理动作后,将会直接跳往下一个规则链(filter:input 或filter:forward)。
范例:  iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10:80-100

动作:  MIRROR
说明:  镜射封包,也就是将来源IP 与目的地IP 对调后,将封包送回,
       进行完此处理动作后,将会中断过滤程序。

动作:  QUEUE
说明:  中断过滤程序,将封包放入队列,交给其它程序处理。
       通过自行开发的处理程序,可以进行其它应用,例如:计算连接费用等。

动作:  RETURN
说明:  结束在目前规则链中的过滤程序,返回主规则链继续过滤,
       如果把自定义规则链看成是一个子程序,那么这个动作,就相当于提前结束子程序并返回到主程序中。

动作:  MARK
说明:  将封包标上某个代号,以便提供作为后续过滤的条件判断依据,
       进行完此处理动作后,将会继续匹配其它规则。
范例:  iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2

iptables -F chain-name    把之前所有的规则都从链中清除掉。
iptables -P chain-name target    给链设置一条默认策略(也就是target)。建议使用DROP作为链默认的目标(target)。
iptables -A chain-name -i interface -j target    -A把当前的说明追加到链上。

iptables -I INPUT -s 0/0 -d 192.168.42.153 -p tcp -m multiport --dports 22,80,3306 -j ACCEPT
iptables -t filter -I INPUT -d 192.168.42.153 -p tcp --dport 80 -j ACCEPT 

示例:常用示例

iptables常用实例备查:https://segmentfault.com/a/1190000002547344
25个iptables常用示例:https://www.cnblogs.com/bill1015/p/6847841.html​​​​​​​

示例:通过 shell 批量添加规则

在生产环境中,很少会一条一条的去编写 iptables 规则,最普遍的做法就是,将其写到 shell 脚本,进行一次性处理。常见的防火墙脚本中,通常包括变量定义、模块加载、/proc调整、规则设置等多个部分,某些简单的防火墙脚本可能只包括规则设置部分。

下面我们通过一个 "网络型" 防火墙脚本实例来了解如何编写防火墙脚本。

[root@loaclhost /]#vim /opt/myipfw.sh

#!/bin/bash
# 1.定义基本变量
INET_IF="eth0" //外网接口
INET_IP="218.29.30.31" //外网接口地址
LAN_IF="eth1" //内网接口
LAN_IP="192.168.1.1" //内网接口地址
LAN_NET="192.168.1.0/24" //内网网段
LAN_WWW_IP="192.168.1.7" //网站服务器的内部地址
IPT="/sbin/iptables" //iptables命令的路径
MOD="/sbin/modprobe" //modprode命令的路径
CTL="/sbin/sysctl" //sysctl命令的路径

# 2.加载内核模块
$MOD ip_tables //iptables基本模块
$MOD ip_conntrack //连接跟踪模块
$MOD ipt_REJECT //拒绝操作模块
$MOD ipt_LOG //日志记录模块
$MOD ipt_iprange //支持IP范围匹配
$MOD xt_tcpudp //支持tcp、udp协议
$MOD xt_state //支持状态匹配
$MOD xt_multiport //支持多端口匹配
$MOD xt_mac //支持MAC地址匹配
$MOD ip_nat_ftp //支持TFP地址转换
$MOD ip_conntrack_ftp //支持TFP连接跟踪 

# 3.调整/porc参数
$CTL -w net.ipv4.ip_forward=1 //打开路由转发功能
$CTL -w net.ipv4.ip_default_ttl=128 //修改ICMP响应超时
$CTL -w net.ipv4.icmp_echo_ignore_all=1 //拒绝响应ICMP请求
$CTL -w net.ipv4.icmp_echo_ignore_broadcasts //拒绝响应ICMP广播
$CTL -w net.ipv4.tcp_syncookies=1 //启用SYN Cookie机制
$CTL -w net.ipv4.tcp_syn_retries=3 //最大SYN请求重试次数
$CTL -w net.ipv4.tcp_synack_retries=3 //最大ACK确认重试次数
$CTL -w net.ipv4.tcp_fin_timeout=60 //TCP连接等待超时
$CTL -w net.ipv4.tcp_max_syn_backlog=3200 //SYN请求的队列长度

# 4.设置具体的防火墙规则
# 4.1删除自定义链、清空已有规则
$IPT -t filter -X //清空各表中定义的链
$IPT -t nat -X
$IPT -t mangel -X
$IPT -t raw -X
$IPT -t filter -F //清空各表中已有的规则
$IPT -t nat -F
$IPT -t mangel -F
$IPT -t raw -F

# 4.2定义默认规则
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCETP

# 4.3设置nat表中的各种策略
$IPT -t nat -A POSTROUTING -s $LAN_NAT -o $INET_IF -j SNAT --to-source $INET_IP
$IPT -t nat -A PREROUTING -i $INET_IF -d $INET_IP -p tcp --dport 80 -j DNAT --to-destination $LAN_WWW_IP

# 4.4设置filter表中的各种规则
$IPT -A INPUT -m state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -s $LAN_NET -o $INET_IF -p udp --dport 53 -j ACCEPT
$IPT -A FORWARD -s $LAN_NET -o $INET_IF -p tcp -m multiport --dport 20,21,25,80,110,143,443 -j ACCEPT
$IPT -A FORWARD -d $LAN_NET -i $INET_IF -m state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -d $LAN_WWW_IP -p tcp --dport 80 -j ACCEPT
$IPT -A FORWARD -d $LAN_WWW_IP -p tcp --sport 80 -j ACCEPT

上述防火墙脚本实例中,仅列出其中最基础的一些规则。更多具体的规则设置取决于实际的应用需求,还有待大家在生产环境中慢慢去体会,逐渐融会贯通。

示例:剖析一个完整的例子

我们假定接口ppp0通往Internet,接口eth0通往内部网络。
ppp0的IP地址是128.138.101.4,eth0的IP地址是10.1.1.1,两个接口的子网掩码都是255.255.255.0。
这个例子使用无状态包过滤机制来保护IP地址为10.1.1.2的Web服务器,这是保护Internet服务器的标准方法。
在这个例子的后面部分,我们将展示如何使用有状态的过滤机制来保护桌面用户。

在您使用iptables之前,必须启用IP forwarding(IP转发)功能,并且确保内核里已经加载了各个iptables模块。
要了解启用IP forwarding功能的更多知识,参见28.4节或者12.11.8节。
带有iptables的所有发行版本也都有能够完成启用和加载的启动脚本。

1. 第一组规则是对filter表进行初始化。
首先,冲洗掉表中所有的链,
然后将INPUT和FORWARD链的默认目标设为DROP。
和其他任何网络防火墙一样,最安全的策略就是丢弃您没有明确允许的任何包。
# iptables -F
# iptables -P INPUT DROP       // 如果是用SSH连接进行设置,不要用这条命令,会导致SSH断开;
# iptables -P FORWARD DROP

2. 规则是按照它们出现在链中的顺序来进行匹配的,所以我们将用得最多的规则放在最前面 。
FORWARD链中的前3条规则让去往10.1.1.2上网络服务的连接通过防火墙。
确切地说,我们允许SSH(端口22)、HTTP(端口80)和HTTPS(端口443)能够连到我们的Web服务器。
第一条规则允许来自可信网络的所有连接通过防火墙。
# iptables -A FORWARD -i eth0 -p ANY -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 22  -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 80  -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 443 -j ACCEPT

3. 我们允许流到防火墙主机(10.1.1.1)的唯一TCP流量是SSH,它用于管理防火墙。
下面列出的第二条规则允许环回(loopback)流量,它留在防火墙主机的本地。
我们的系统管理员在他们不能ping到默认路由时会感到紧张,
所以这里的第三条规则允许从内部IP地址来的ICMP ECHO_REQUEST包。
# iptables -A INPUT -i eth0 -d 10.1.1.1  -p tcp --dport 22     -j ACCEPT
# iptables -A INPUT -i lo   -d 127.0.0.1 -p ANY                -j ACCEPT
# iptables -A INPUT -i eth0 -d 10.1.1.1  -p icmp --icmp-type 8 -j ACCEPT 

4. 为了能让任何TCP/IP主机在Internet正常工作,必须允许某些类型的ICMP包通过防火墙。
下面的8条规则就是让ICMP包既能送到防火墙主机,也能送到在它之后的网络的最小集合。
# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
# iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
# iptables -A INPUT -p icmp --icmp-type 5 -j ACCEPT
# iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 0 -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 3 -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 5 -j ACCEPT
# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 11 -j ACCEPT

5. 接下来向NAT表的PREROUTING链加入规则。虽然NAT表的目的并不是做包过滤,
但是它的PREROUTING链对于反IP欺骗的过滤来说特别有用。
如果我们在PREROUTING链中加入DROP项,它们就不需要出现在INPUT和FORWARD链里了,
因为PREROUTING链会应用到所有进入防火墙主机的包上。
将控制项放到一个地方比重复放置它们的做法条理性要好得多。
# iptables -t nat -A PREROUTING -i ppp0 -s 10.0.0.0/8 -j DROP
# iptables -t nat -A PREROUTING -i ppp0 -s 172.16.0.0/12 -j DROP
# iptables -t nat -A PREROUTING -i ppp0 -s 192.168.0.0/16 -j DROP
# iptables -t nat -A PREROUTING -i ppp0 -s 127.0.0.0/8 -j DROP
# iptables -t nat -A PREROUTING -i ppp0 -s 224.0.0.0/8 -j DROP
 
6. 最后,我们用一条禁止所有没有得到明确许可的包的规则来结束INPUT和FORWARD链。
虽然我们在前面已经用iptables -P命令实施过这个做法,但是LOG目标(target)能让我们看到谁正在从Internet上敲我们的大门。
# iptables -A INPUT -i ppp0 -j LOG
# iptables -A FORWARD -i ppp0 -j LOG

7. 我们还可以设置IP NAT来伪装在内部网络里使用的私用地址空间。
参见12.12节了解更多有关NAT的知识。

8. Netfilter带给Linux防火墙最强大的功能之一就是有状态包过滤机制。
针对连到Internet的客户机的防火墙不是允许特定的传入服务,而是允许根据客户机的请求而传入的响应。
下面这条简单的有状态FORWARD链允许离开我们网络的所有流量通过,但只允许和我们的主机发起的连接有关的入流量通过。
# iptables -A FORWARD -i eth0 -p ANY -j ACCEPT
# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

要跟踪复杂的网络会话,比如FTP和IRC,必须加载某些内核模块来启动iptables。
如果没有加载这些模块,iptables就会简单地禁止那些连接。虽然有状态包过滤器能够提高站点的安全性,
但是它们也增加了网络的复杂性。所以在防火墙上实现它之前,要确信您的确需要有状态功能。


五、调试iptables规则集
调试iptables规则集最好的办法或许就是用命令:
  iptables -L -v 

这些选项会告诉您链里面的每条规则匹配了多少个包。
我们经常在想了解有关匹配包的更多信息时,增加带有LOG目标(target)的临时iptables规则。
您可以经常通过使用像tcpdump这样的包探测器解决更棘手的问题。

六、应用实例
1. 禁止端口的实例
1). 禁止ssh 端口
只允许在192.168.62.1上使用ssh 远程登录,从其它计算机上禁止使用ssh
# iptables -A INPUT -s 192.168.62.1 -p tcp --dport 22 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j DROP

2). 禁止代理端口
# iptables -A INPUT -p tcp --dport 3128 -j REJECT

3). 禁止icmp 端口
除192.168.62.1外,禁止其它人ping 我的主机
# iptables -A INPUT -i eth0 -s 192.168.62.1/32 -p icmp -m icmp --icmp-type echo-request -j ACCEPT
# iptables -A INPUT -i eth0 -p icmp --icmp-type echo-request –j DROP

# iptables -A INPUT -i eth0 -s 192.168.62.1/32 -p icmp -m icmp --icmp-type 8 -j ACCEPT
# iptables -A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j DROP
注:可以用iptables --protocol icmp --help 查看ICMP 类型

4). 禁止QQ 端口
# iptables -D FORWARD -p udp --dport 8000 -j REJECT

2. 强制访问指定的站点
要使192.168.52.0/24网络内的计算机(这此计算机的网关应设为192.168.52.10)强制访问指定的站点,
在做为防火墙的计算机(192.168.52.10)上应添加以下规则:
1). 打开ip 包转发功能
# echo 1 > /proc/sys/net/ipv4/ip_forward

2). 在NAT/防火墙计算机上的NAT 表中添加目的地址转换规则:
# iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 202.96.134.130:80
# iptables -t nat -I PREROUTING -i eth0 -p udp --dport 80 -j DNAT --to-destination 202.96.134.130:80

3). 在NAT/防火墙计算机上的NAT 表中添加源地址转换规则:
# iptables -t nat -I POSTROUTING -o eth1 -p tcp --dport 80 -s 192.168.52.0/24 -j SNAT --to-source 202.96.134.10:20000-30000
# iptables -t nat -I POSTROUTING -o eth1 -p udp --dport 80 -s 192.168.52.0/24 -j SNAT --to-source 202.96.134.10:20000-30000

4). 测试:在内部网的任一台计算机上打开浏览器,输入任一非本网络的IP,都将指向IP 为202.96.134.130的网站.

3. 发布内部网络服务器
图4

要使因特网上的计算机访问到内部网的FTP 服务器、WEB 服务器,在做为防火墙的计算机上应
添加以下规则:
1).
# echo 1 > /proc/sys/net/ipv4/ip_forward

2). 发布内部网web 服务器
# iptables -t nat -I PREROUTING -p tcp -i eth1 -s 202.96.134.0/24 --dport 80 -j DNAT --to-destination 192.168.52.15:80
# iptables -t nat -I POSTROUTING -p tcp -i eth0 -s 192.168.52.15 --sport 80 -j SNAT --to-source 202.96.134.10:20000-30000

3). 发布内部网ftp 服务器
# iptables -t nat -I PREROUTING -p tcp -i eth1 -s 202.96.134.0/24 --dport 21 -j DNAT --to-destination 192.168.52.14:21
# iptables -t nat -I POSTROUTING -p tcp -i eth0 -s 192.168.52.14 --sport 21 -j SNAT --to-source 202.96.134.10:40000-50000

4). 注意:内部网的计算机网关要设置为防火墙的ip(192.168.52.1)
5). 测试:
     用一台IP 地址为202.96.134.0段的计算机虚拟因特网访问,
     当在其浏览器中访问http://202.96.134.10时, 实际应看到的是192.168.52.15的的web 服务;
     当访问ftp://202.96.134.10时,实际应看到的是192.168.52.14上的的ftp 服务

4. 智能DNS
图5

1).
# echo 1 > /proc/sys/net/ipv4/ip_forward

2). 在NAT 服务器上添加以下规则:
在PREROUTING 链中添加目的地址转换规则:
# iptables -t nat -I PREROUTING -i eth0 -p tcp --dpor 53 -j DNAT --to-destination 202.96.134.130
# iptables -t nat -I PREROUTING -i eth0 -p udp --dpor 53 -j DNAT --to-destination 202.96.134.130

在POSTROUTING 链中添加源地址转换规则:
# iptables -t nat -I POSTROUTING -o eth1 -s 192.168.52.0/24 -p tcp --dpor 53 -j SNAT --to-source 202.96.134.10:40000-50000
# iptables -t nat -I POSTROUTING -o eth1 -s 192.168.52.0/24 -p udp --dpor 53 -j SNAT --to-source 202.96.134.10:40000-50000

3). 测试
在内部网任一台计算机上,将DNS 设置为任意的外网IP,就可以使用DNS 
测试工具如nslookup来解析DNS 服务器202.96.134.130上的名称.

5. 端口映射
见上节透明代理设置
# iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.62.0/24 --dport 80 -j REDIRECT --to-ports 3128

6. 典型NAT 上网
一般做为NAT 的计算机同时也是局域网的网关,
假定该机有两块网卡eth0、eth1,
eth0连接外网,  IP 为202.96.134.134;
eth1连接局域网,IP 为192.168.62.10

1). 先在内核里打开ip 转发功能
# echo 1 > /proc/sys/net/ipv4/ip_forward

2). 使局域网用户能访问internet 所要做的nat
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to?202.96.134.134


如果上网的IP 是动态IP,则使用以下规则:
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.62.0/24 -j MASQUERADE

如果是通过ADSL 上网,且公网IP 是动态IP,则使用以下规则:
# iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.62.0/24 -j MASQUERADE

3). 使internet 用户可以访问局域网内web 主机所要做的nat
# iptables -t nat -A PREROUTING -p tcp -d 202.96.134.134 --dport 80 -j DNAT --to-destination 192.168.62.10
注:局域网内的客户端需将默认网关、DNS 设为防火墙的IP

7. 在我们的网络机房实现NAT 共享上网
工作环境:上层代理192.168.60.6(4480),只授予教师机(192.168.62.111)使用该代理的权限
目标:不使用squid 代理上网,而是使用NAT 的方式上网
方法:
1). 确保停止教师机(192.168.62.111)的squid 或其它代理服务
2). 客户端网关、DNS 均指向192.168.62.111,浏览器代理设置为192.168.60.6(4480)。
    测试在当前情况下能否上网
3). 在教师机(192.168.62.111)上添加如下iptables 规则:
# iptables -t nat -A POSTROUTING -p tcp -d 192.168.60.6/32 --dport 4480 -j SNAT --to-source 192.168.62.111:10000-30000
解释:对于目的地为192.168.60.6、目的端口为4480的TCP 包,
      在经过防火墙路由后,将其源地址转换为192.168.62.111,端口转换为10000-30000间的某个端口。
4). 客户端测试能否上网

8. 对流媒体服务器的服务做IP 限制
1). 清空规则并放开SSH
# iptables -F
# iptables -A INPUT -s 10.1.1.11 -p tcp --dport 22 -j ACCEPT

2). 对指定IP放开,可以推送流到这台服务器, 其余的IP都禁止
A. 只对单个IP放开
# iptables -A INPUT -s 10.2.1.54 -j ACCEPT
# iptables -A INPUT -s! 10.2.1.54 -j REJECT

# iptables -A INPUT -s 10.2.1.54 -j ACCEPT
# iptables -A INPUT   -i eth0 -j REJECT

B. 对多个IP放开,即将要放开的IP插入到最后一条拒绝的规则之前
# iptables -A INPUT -s 10.2.1.54 -j ACCEPT
# iptables -A INPUT   -i eth0 -j REJECT
# iptables -I INPUT 2 -s 10.2.1.13 -j ACCEPT

3). 对指定IP段 放开,可以推送流到这台服务器,其余的IP都禁止
A. 对单个IP段放开
# iptables -I INPUT 2 -s 10.2.1.0/24 -j ACCEPT
# iptables -A INPUT   -i eth0 -j REJECT

B. 对多个IP段放开
# iptables -I INPUT 2 -s 10.2.1.0/24 -j ACCEPT
# iptables -A INPUT   -i eth0 -j REJECT
# iptables -I INPUT 2 -s 10.2.2.0/24 -j ACCEPT

其中:
10.2.1.0/24 表示: A类地址主机为8位,表示10.2.1固定,后面是可变
前面是IP地址10.2.1.0,是表示局域网地址。
后而的24是指掩码,因为IP地址和掩码用二进制表示的话都是32位的。
所以掩码的24表示那掩码前24位是1,后8位是0,转换成10进制就是表示掩码是255.255.255.0
即, 255.255.255.0=11111111.11111111.11111111.0=24个1
192.168.0.0/16 代表B类地址 主机为16,表示192.168固定,后面是可用.

4). 对指定IP拒绝,
A. 对单个IP拒绝
# iptables -A INPUT -s 10.2.1.11 -p tcp --dport 1935 -j REJECT

防火墙 的 网关功能

通过上面知道了 Linux 防火墙的表、链结构,并学会了编写简单的防火墙规则。Linux防火墙在很多时候承担着连接企业内、外网的重任,除了提供数据包过滤功能以外,有时还需要提供一些基本的网关应用。在配置 SNAT 和 DNAT 之前,需要开启 Linux 系统中的地址转发功能,否则数据无法通过防火墙转发出去。

修改 /etc/sysctl.conf 配置文件件,将 ip_forward 的值设置为1即可。
vim /etc/sysctl.conf
......//省略部分内容
net.ipv4.ip_forwaed=1 //将此行中的0改为1
[root@localhost /]#sysctl -p //重新读取修改后的配置
也可以开启临时的路由转发,可以执行以下操作。
[root@localhost /]#echo 1> /proc/sys/net/ipv4/ip_forward
或者
[root@localhost /]#sysctl -w net.ipv4.ip_forward=1

SNAT 策略及应用

SNAT:源地址转换,是Linux防火墙的一种地址转换操作,也是 iptables 命令中的一种数据包控制类型,其作用是根据指定条件修改数据包的源IP地址。
SNAT 策略只能用在nat表的POSTROUTING链中,使用iptables命令编写SNAT策略时,需要结合“--to-source IP地址”选项来指定修改后的源IP地址。

列如:Linux网关服务器通过eth0和eth1分别连接Internet和局域网,其中eth0的IP地址为218.29.30.31,eth1的IP地址为192.168.1.1。现在要求在Linux网关服务器上配置规则,使用局域网内的所有用户可以通过共享的方式访问互联网。可执行以下操作。

1)开启路由转发,上面已经讲过,这里不在详述了。
2)在iptables的POSTROUTING中编写SNAT规则。
[root@localhost /]#iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 218.29.30.31
3)在某些情况下,网关的外网IP地址可能不是固定的,列如使用ADSL宽带接入时,针对这这种需求,iptables提供了一个名为MASQUERASE(伪装)的数据包控制类型,MASQUERADE相当于SNAT的一个特列,同样同来修改数据包的源IP地址只过过它能过自动获取外网接口的IP地址。
参照上一个SNAT案例,若要使用MASQUERADE伪装策略,只需要去掉SNAT策略中的“--to-source IP地址”。然而改为“-j MASQUERADE”指定数据包的控制类型。对于ADSL宽带连接来说,连接名称通常为ppp0,ppp1等。操作如下
[root@localhost /]#iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE
4)测试SNAT共享接入的结果
同过上面的配置,这时内部局域网访问互联网所使用的IP地址是网关服务器的外网接口地址了。我们可以在往外客户端执行“tcpdump -i eth0”监听访问本机的数据流,然后在内网ping外网客户端,然后查看外网客户端监听的状态,会发现,访问外网客户机的IP地址是网关服务器的外网接口地址,而不是内部局域网的地址。

DNAT 策略及应用

DNAT:目标地址转换,是Linux防火墙的另一种地址转换操作,同样也是iptables命令中的一种数据包控制类型,其作用是根据指定条件修改数据包的目标IP地址,目标端口。

DNAT策略与SNAT策略非常相似,只不过应用方向反过来了。

SNAT用来修改源地址IP,而DNAT用来修改目标IP地址,目标端口;

SNAT只能用在nat表的POSTROUTING链,而DNAT只能用在nat表的PREROUTING链和OUTPUT链中。

列如:借助上述网络环境,公司内部局域网内搭建了一台web服务器,IP地址为192.168.1.7,现在需要将其发布到互联网上,希望通过互联网访问web服务器。那么我们可以执行如下操作。
1)在iptables的PREROUTING中编写DNAT规则。
[root@localhost /]#iptables -t nat -A PREROUTING -i eth0 -d 218.29.30.31 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.7:80
2)再列如:公司的web服务器192.168.1.7需要通过互联网远程管理,由于考虑到安全问题,管理员不希望使用默认端口进行访问,这时我们可以使用DNAT修改服务的默认端口。操作如下:
[root@localhost /]#iptables -t nat -A PREROUTING -i eth0 -d 218.29.30.31 -p tcp --dport 2346 -j DNAT --to-destination 192.168.1.7:22
3)在外网客户端浏览器中访问网关服务器的外网接口,可以发现访问的居然是内网192.168.1.7的web服务器的网页。而在使用sshd连接2346端口时,居然可以远程连接到192.168.1.7服务器上。

3、Ubuntu 防火墙 ufw

UbuntuHelp:UFW :http://wiki.ubuntu.org.cn/UbuntuHelp:UFW
ufw使用指南:http://wiki.ubuntu.org.cn/Ufw使用指南
ubuntu ufw防火墙:http://wap.dongnanshan.com/fn.php?s=ubuntu ufw防火墙
UFW要领:通用防火墙规则和命令:https://www.howtoing.com/ufw-essentials-common-firewall-rules-and-commands/

ufw 简介

由于 iptables 操作起来比较复杂,依赖关系比较多,所以 Ubuntu 自带了一个 UFW 工具,可以简化 iptables 的操作。当然 Debian 同样适用。无论是桌面版还是服务器版,UFW 的命令行用法是一样的。ufw 防火墙uncomplicated firewall(不复杂的防火墙)iptables 的接口,旨在简化配置防火墙的过程。 但是繁琐的部分还是需要使用 iptables进行设置

由于 Ubuntu 系统的不断更新迭代,配置工具也发生了变化:iptables ---> firewall ---> ufw

安装 UFW ( Gufw )

Gufw 是带界面的 UFW,操作起来更方便。Ubuntu 的防火墙默认已安装,如果没有安装,执行以下命令安装

安装 UFW:sudo apt install ufw
安装 Gufw :sudo apt install gufw

sudo ufw status           查看防火墙状态
sudo ufw status numbered  按编号显示
sudo ufw version          防火墙版本

ufw 命令参数说明

ufw 帮助:sudo ufw --help
更详细说明:man ufw 或者 info ufw

$ sudo ufw --help

用法: ufw COMMAND
相关命令:
    enable                          启用防火墙
    disable                         禁用防火墙
    default ARG                     设置默认策略
    logging LEVEL                   设置日子级别
    allow ARGS                      添加 allow 规则
    deny ARGS      deny直接丢弃访问数据,访问者不知道是访问被拒绝还是不存在该主机。
    reject ARGS     reject 让访问者知道数据被拒绝(回馈拒绝信息)。
    limit ARGS                      添加 limit 规则
    delete RULE|NUM                 删除 RULE
    insert NUM RULE                 插入 RULE at NUM
    route RULE                      添加 route RULE
    route delete RULE|NUM           删除 route RULE
    route insert NUM RULE           插入 route RULE at NUM
    reload                          重新载入 firewall
    reset                           重置 firewall
    status                          显示 firewall 状态
    status numbered                 显示 firewall status as numbered list of RULES
    status verbose                  显示 防火墙详细状态信息
    show ARG                        显示 firewall report
    version                         显示版本信息

Application profile commands:
    app list                        列出 application profiles
    app info PROFILE                显示 PROFILE
    app update PROFILE              更新 PROFILE
    app default ARG                 设置默认 application policy

参数
–version    显示程序版本号
-h , –help  显示帮助信息
–dry-run    不实际运行,只是把涉及的更改显示出来。
enable      激活防火墙,开机时自动启动
disable     关闭防火墙,开机时不启动
reload      重新载入防火墙

启动、禁用、重置 UFW

sudo apt install ufw     # 安装 ufw
sudo ufw enable|disable  # 设置开机 开启/关闭防火墙 (默认设置是 disable)

sudo ufw deny            # 关闭所有外部对本机的访问,但本机访问外部正常。 
sudo ufw default deny    # 设置 ufw 默认为拒绝
sudo ufw reset           # 重置防火墙

以上三条命令已经足够安全了

如果需要开放某些服务,再使用 sudo ufw allow 开启相应服务即可。

编辑 UFW 的配置文件

虽然可以通过命令行添加简单的规则,但仍有可能需要添加或删除更高级或特定的规则。

  • 在通过终端输入的规则之前 UFW 将运行一个文件 before.rules,它允许回环接口、ping 和 DHCP 等服务。要添加或改变这些规则,编辑 /etc/ufw/before.rules 这个文件。 同一目录中的 before6.rules 文件用于 IPv6 。
  • 还存在一个 after.ruleafter6.rule 文件,用于添加在 UFW 运行你通过命令行输入的规则之后需要添加的任何规则。
  • 还有一个配置文件位于 /etc/default/ufw。 从此处可以禁用或启用 IPv6,可以设置默认规则,并可以设置 UFW 以管理内置防火墙链。    

启用 IPv6 支持

如果你的云服务器启用了 IPv6,则需要配置 UFW 以启用支持,编辑 UFW 配置文件:
sudo nano /etc/default/ufw
在配置文件中将 IPV6 设置为 yes :
IPV6=yes
保存并退出编辑器,重启 UFW:
sudo ufw disable
sudo ufw enable
这样,UFW 就同时支持 IPv4 和 IPv6 两种协议了。

规则

[] 是代表可选内容。可能需要root权限。

ufw [--dry-run] enable|disable|reload    # 命令[–试运行]激活|关闭|重新载入
# 命令[–试运行]默认 允许|阻止|拒绝 [访问本机的规则|向外访问的规则]
ufw [--dry-run] default allow|deny|reject [incoming|outgoing]  
ufw [--dry-run] logging on|off|LEVEL       # 命令[–试运行]日志 开启|关闭|“级别”
ufw [--dry-run] reset                      # 命令[–试运行]复位
ufw [--dry-run] status [verbose|numbered]  # 命令[–试运行]状态 [详细|被编号的规则]
ufw [--dry-run] show REPORT                # 命令[–试运行]显示 “报告类型”
ufw [--dry-run] [delete] [insert NUM] allow|deny|reject|limit [in|out][log|log-all] PORT[/protocol]
命令[–试运行][删除] [插到x号规则之前] 允许|阻止|拒绝|限制 [进|出] [记录新连接|记录所有数据包] “端口” [/“协议”]
ufw [--dry-run] [delete] [insert NUM] allow|deny|reject|limit [in|out on INTERFACE] [log|log-all] [proto protocol] [from ADDRESS [port PORT]] [to ADDRESS [port PORT]]
命令 [–试运行][删除][插到x号规则之前] 允许|阻止|拒绝|限制 [进|出 基于“什么网络设备”] [协议 “协议”] [来源 “地址” [端口 “端口”]] [目标 “地址” [端口 “端口”]]
ufw [--dry-run] delete NUM                      # 命令[–试运行] 删除 “第X号规则”
ufw [--dry-run] app list|info|default|update    # 命令 [–试运行] 程序 清单|信息|默认|更新

default allow|deny|reject 方向
方向是指:向内(incoming)|向外(outgoing)。如果更改了默认策略,一些已经存在的规则可能需要手动修改。更多内容看“规则示例”一节。
logging on|off|“级别”  # 切换日志状态。日志记录包使用的是系统日志。“级别”有好几个,默认是低级(low)。详细内容看“日志”一节。
reset [--force]  # 关闭防火墙,并复位至初始安装状态。如果使用–force选项,则忽略确认提示。
status    # 显示防火墙的状态和已经设定的规则。使用status verbose显示更详细的信息。‘anywhere’与‘any’、‘0.0.0.0/0’一个意思。
show “报告类型”  # 显示防火墙运行信息。详细内容看“报告类型”
limit “规则”     # 此命令目前只能用于IPv4。还不支持IPv6.

删除规则

有两种删除防火墙规则的方法,最直接的方法是:
sudo ufw delete allow ssh
如上,我们在 delete 指令后面输入要删除的规则即可。还可以这样:
sudo ufw delete allow 80/tcp

sudo ufw delete allow 1000:2000/tcp

如果规则又长又复杂,问题就比较棘手了。这里有一个更简单的方法,需要分成两个步骤:        
sudo ufw status numbered    # 按规则来编号防火墙规则。命令会将所有防火墙规则以数字列表形式列出来
# 请将 [number] 替换成规则列表对应的数字序号。
sudo ufw delete 1           # 按规则编号删除防火墙规则 sudo ufw delete [number]
sudo ufw delete 4           # 删除编号为4的规则

示例

用法sudo ufw allow|deny [service]

reject 让访问者知道数据被拒绝(回馈拒绝信息)。deny则直接丢弃访问数据,访问者不知道是访问被拒绝还是不存在该主机。

# 设置默认策略(默认策略即为拒绝所有传入连接,允许所有传出链接)
sudo ufw default deny incoming
sudo ufw default allow outgoing


# 基于端口的允许/阻止
# 允许 SSH 连接。以下两条命令效果是一样的
sudo ufw allow ssh  # 允许外部到本机的 ssh
sudo ufw allow 22   # 允许外部连接到本机的 22 端口


# 基于 IP地址/子网/端口 的组合来 允许/阻止。
# 用法:ufw deny from {ip-address-here} to any port {port-number-here}

# 阻断或拒绝IP地址 202.54.1.5 访问 80 端口的请求
sudo ufw deny from 202.54.1.5 to any port 80    


# 拦截特定 IP、端口以及协议
# 用法:sudo ufw deny proto {tcp|udp} from {ip-address-here} to any port {port-number-here}
# 例如,阻断 IP地址 202.54.1.1 访问 tcp 22 端口(FTP协议),可以输入:
sudo ufw deny proto tcp from 202.54.1.1 to any port 22
sudo ufw status numbered


# UFW 拦截子网
# 用法:
    sudo ufw deny proto tcp from sub/net to any port 22
    sudo ufw deny proto tcp from 202.54.1.0/24 to any port 22

sudo ufw deny from 192.168.1.5 to any    # 拦截或拒绝来自192.168.1.5的所有数据包
sudo ufw allow from 123.45.67.89         # 允许从一个 IP 地址连接:
sudo ufw allow from 123.45.67.89/24      # 允许特定子网的连接:


# 允许特定 IP/端口 的组合:
sudo ufw allow from 123.45.67.89 to any port 22 proto tcp
# proto tcp 可以删除或者根据你的需求改成 proto udp,所有例子的 allow 都可以根据需要变成 deny。


sudo ufw allow www    或   sudo ufw allow 80/tcp
sudo ufw allow ftp    或   sudo ufw allow 21/tcp
sudo ufw allow 22/tcp             # 允许所有的外部IP访问本机的22/tcp (ssh)端口
sudo ufw allow 53                 # 允许外部访问53端口(tcp/udp)
sudo ufw allow 80                 # 允许外部访问80端口 等价 sudo ufw allow http
sudo ufw delete allow 80          # 禁止外部访问80 端口
sudo ufw allow from 192.168.1.1   # 允许此IP访问所有的本机端口    
sudo ufw allow from 111.111.111.111 to any port 22    # 允许特定IP特定端口的连接
sudo ufw allow proto udp 192.168.0.1 port 53 to 192.168.0.2 port 53
sudo ufw deny smtp                # 禁止外部访问smtp服务
sudo ufw allow smtp               # 允许所有的外部IP访问本机的25/tcp (smtp)端口
sudo ufw delete allow smtp        # 删除上面建立的某条规则

sudo ufw deny http                    # 拒绝http连接
sudo ufw deny from 111.111.111.111    # 拒绝特定IP连接

# 允许特定端口范围连接
sudo ufw allow 1000:2000/tcp
sudo ufw allow 2001:3000/udp

# 拒绝所有的TCP流量从10.0.0.0/8 到192.168.0.1地址的22端口
sudo ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port 22

# 可以允许所有RFC1918网络(局域网/无线局域网的)访问这个主机(/8,/16,/12是一种网络分级):
sudo ufw allow from 10.0.0.0/8
sudo ufw allow from 172.16.0.0/12
sudo ufw allow from 192.168.0.0/16
# 这样设置已经很安全,如果有特殊需要,可以使用sudo ufw allow开启相应服务

* 规则可以简写也可以完整表达。简写的规则只能指定端口和(或)协议被允许或阻止。默认是访问本机的规则(incoming)。
示例:ufw allow 53        允许其它机子访问本机53端口,协议包含tcp和udp。

* 如果要控制协议,只要加入“/协议”在端口后面就行了。
示例:ufw allow 25/tcp        允许其它机子使用tcp协议访问25端口。

* UFW 也可以检查 /etc/services文件,明白服务的名字及对应的端口和协议。
示例:ufw allow smtp

* UFW 同时支持出入口过滤。使用in或out来指定向内还是向外。如果未指定,默认是in。

例如:
ufw allow in http
ufw reject out smtp
ufw deny out to 192.168.1.1        阻止向192.168.1.1发送信息

* 也可使用完整的规则来指定来源、目的地,端口。书写规则基于OpenBSD PF。

示例:ufw deny proto tcp to any port 80        阻止本机用tcp协议在80端口发数据
示例:ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port 25

* ufw 也可以使用IPv6协议。但要事先在/etc/default/ufw 中设定IPv6为启动状态。

示例:ufw deny proto tcp from 2001:db8::/32 to any port 25
          阻止IPv6为2001:db8::/32类型的地址,连接本机25端口

* ufw 可以连续例举端口号。端口号间必须使用逗号或分号,不能使用空格。"输入端口号" 字符数最多不能超过15过(8080:8090算两个字符)。

示例:允许80,443,8080~8090这几个端口接受tcp传入连接。
ufw allow proto tcp from any to any port 80,443,8080:8090
此例,"输入端口号" 字符数为4个。

* ufw 可以对连接数率进行限制,以防范暴力登录攻击。如果同一个IP地址在30秒之内进行了6次及6次以上的连接,ufw将阻止(deny)该连接。可以查看更多信息。
ufw limit ssh/tcp

想让访问者知道他的访问被拒绝了,而不是保持沉默让他不知道哪出了问题。就使用 reject 代替 deny。ufw reject auth

* 默认情况下ufw 的所有规则针对所有网络设备(比如网卡1,网卡2,无线网卡1,虚拟网卡1……)。但是我们可以特别指定,某规则在什么网络设备上生效。注意只能使用设备号,不能用别名。比如有线网卡:eth0(你可以使用ifconfig命令查看你现有的网络设备)
ufw allow in on eth0 to any port 80 proto tcp

* 要删除规则,只要在命令中加入delete就行了。

比如:ufw deny 80/tcp
要删除条命令建立的规则,使用:ufw delete deny 80/tcp
当然,也可以使用规则号来进行删除。比如要第3号规则:ufw delete 3
注意,如果你开启IPv6功能。要同时删除IPv4和IPv6的规则(比如:ufw allow 22/tcp),如果用规则号的方式删除可能只删除了一个。

* 显示第几号规则,可以使用这样的命令
ufw status numbered(也就是规则号)

* 日志功能。如果使用 log 将记录所有符合规则的新连接,如果使用 log-all 将记录所有符合规则的数据包。

例如,要允许并记录 ssh(22/tcp)上的新连接:ufw allow log 22/tcp
特殊例子: 允许RFC1918网络结构访问本机:
ufw allow from 10.0.0.0/8
ufw allow from 172.16.0.0/12
ufw allow from 192.168.0.0/16

端口转发

ufw 可以通过端口转发来将来自外部网络连接的流量重定向到内部网络中的特定主机或端口。

以下是一个简单的示例,演示如何使用 ufw 进行端口转发:

假设内部网络中的 Web 服务器 IP 是 192.168.1.100,并且正在监听端口 80。现在想要将外部网络中来自 Internet 的流量重定向到该服务器上。

打开终端(Terminal)。
运行以下命令打开 ufw 的配置文件:
sudo nano /etc/ufw/sysctl.conf
找到以下行,并取消注释:
net.ipv4.ip_forward=1
如果没有该行,请添加该行并保存文件。
运行以下命令以重新加载 ufw:
sudo ufw reload
现在你可以为 Web 服务器设置端口转发了。运行以下命令:
sudo ufw route allow proto tcp from any to any port 80 redirect to 192.168.1.100
将所有来自 Internet 的 TCP 流量重定向到 192.168.1.100 端口为 80 的 Web 服务器上。
完成后,你可以运行以下命令检查 ufw 的规则是否正确设置:
sudo ufw status
现在,当外部网络中的用户访问你的公共 IP 地址和端口 80 时,ufw 会将流量重定向到内部网络中的 Web 服务器。

重定向 ssh 端口:sudo ufw route allow proto tcp from any to any port 22 redirect to 192.168.1.100 port 2222

将所有来自 Internet 的 TCP 流量重定向到内网 IP 地址为 192.168.1.100,端口为 2222 的 SSH 服务器上。

* ufw能从 /etc/ufw/applications.d. 中读取应用程序清单。你可以使用命令查看:
ufw app list
* 大家可以使用应用程序名字来增加规则。比如
ufw allow <程序名字>
ufw allow CUPS
ufw allow from 192.168.0.0/16 to any app <程序名字>
注意,端口号已经被程序名所对应的策略所包括,不要再重新列举端口号。
* 查看程序名所对应的策略内容,命令:
ufw app into <程序名字>
注意:程序名字是清单上有的才行。程序名字改用用all,可以看全部策略。
* 如果你编辑或者增加了程序清单,你可使用此命令更新防火墙:
ufw app update <程序名字>
程序名字改用用all,则更新整个清单。
* 更新清单同时增加规则可以使用如下命令:
ufw app update –add-new <程序名字>
注意:update –add-new参数的行为由此命令配置:
ufw app default skip|allow|deny
默认是skip,也就是没有设定。
警告:如果程序规则设定为default allow ,将会引起很大的风险。请三思而后行!
日志
ufw支持许多日志级别。默认是低级(low),用户也可以自己指定:
ufw logging on|off|low|medium|high|full
  * off 就是关闭日志
  * low 记录与默认策略冲突的封装数据包(记录速度被限制)。记录与规则符合的数据包(没有要求关闭记录的)
  * medium 记录与默认策略冲突的数据包(包括被规则允许的)、无效数据包、所有新连接。记录速度被限制。
  * high 同medium,只是没有记录速度限制。附加记录所有数据包(有记录速度限制)。
  * full 与high等同,只是取消记录限制。
medium 级别及更上级会记录许多内容,有可能短时间内撑爆你的硬盘。特别是用在服务器一类的机器上。

  • 10
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值