iptables介绍与用法

相关术语

防火墙

从逻辑上讲,防火墙可以大体分为主机防火墙和网络防火墙。

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

网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体), 主机防火墙主内(个人)。

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

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

iptables

iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的”安全框架”中,这个”安全框架”才是真正的防火墙,这个框架的名字叫netfilter

netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。

netfilter/iptables(下文中简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。

netfilter

netfilter是Linux操作系统核心层内部的一个数据包处理模块,它具有如下功能:

  1. 网络地址转换(Network Address Translate)
  2. 数据包内容修改
  3. 数据包过滤的防火墙功能

所以说,虽然我们使用 service iptables start 启动 iptables“服务”,但是其实准确的来说,iptables并没有一个守护进程,所以并不能算是真正意义上的服务,而应该算是内核提供的功能。

组成结构

iptables是按照规则来办事的,我们就来说说规则(rules),规则其实就是网络管理员预定义的条件,规则一般的定义为 “如果数据包头符合这样的条件,就这样处理这个数据包”。

规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。

当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。

五链

image

  • PREROUTING 数据包刚进入网络层 , 路由之前
  • INPUT 路由判断,流入用户空间
  • OUTPUT 用户空间发出,后接路由判断出口的网络接口
  • FORWARD 路由判断不进入用户空间,只进行转发
  • POSTROUTING 数据包通过网络接口出去

打个比方:
到本机某进程的报文:PREROUTING –> INPUT
由本机转发的报文:PREROUTING –> FORWARD –> POSTROUTING
由本机的某进程发出报文(通常为响应报文):OUTPUT –> POSTROUTING

四表

我们把具有相同功能的规则的集合叫做 “表”,所以说,不同功能的规则,我们可以放置在不同的表中进行管理,而iptables已经为我们定义了4种表,每种表对应了不同的功能,而我们定义的规则也都逃脱不了这4种功能的范围,所以,学习iptables之前,我们必须先搞明白每种表的作用。

  • filter表:负责过滤功能,防火墙;内核模块:iptables_filter
  • nat表:network address translation,网络地址转换功能;内核模块:iptable_nat
  • mangle表:拆解报文,做出修改,并重新封装 的功能;iptable_mangle
  • raw表:关闭nat表上启用的连接追踪机制;iptable_raw

也就是说,我们自定义的所有规则,都是这四种分类中的规则,或者说,所有规则都存在于这4张”表”中。

表链关系

四表/五链 PREROUTING INPUT FORWARD OUTPUT POSTROUTING
filter
nat √(centos7)
mangle
raw

表的优先级关系: raw –> mangle –> nat –> filter , raw 最高

image

image

规则

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

匹配条件

匹配条件分为基本匹配条件与扩展匹配条件

  • 基本匹配条件:
    源地址Source IP,目标地址 Destination IP
    上述内容都可以作为基本匹配条件。

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

处理动作

处理动作在iptables中被称为target(这样说并不准确,我们暂且这样称呼),动作也可以分为基本动作和扩展动作。
此处列出一些常用的动作,之后的文章会对它们进行详细的示例与总结:

  • ACCEPT:允许数据包通过。
  • DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。
  • REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。
  • SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
  • MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
  • DNAT:目标地址转换。
  • REDIRECT:在本机做端口映射。
  • LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。

补充一下DROP和REJECT的区别。DROP是直接把匹配到的报文丢弃,REJECT除了把报文丢弃还会给该报文中的源IP发一个ICMP报文说明目的不可达(直接回复不可达, 更强硬)。前者报文发送方只能等超时,而后者发送方因为收到了ICMP不可达所以马上就给出了提示。

filter过滤规则

filter负责过滤功能,比如允许哪些IP地址访问,拒绝哪些IP地址访问,允许访问哪些端口,禁止访问哪些端口,filter表会根据我们定义的规则进行过滤,filter表应该是我们最常用到的表了。

查看规则

怎样查看filter表中的规则呢?使用如下命令即可查看。

iptables -t filter -L

刚才提到,我们可以使用 iptables -t filter -L 命令列出filter表中的所有规则,那么举一反三,我们也可以查看其它表中的规则,示例如下

iptables -t raw -L
iptables -t mangle -L
iptables -t nat -L

其实,我们可以省略 -t filter,当没有使用 -t 选项指定表时,默认为操作filter表,即 iptables -L 表示列出filter表中的所有规则。

详细信息

我们还可以只查看指定表中的指定链的规则,比如,我们只查看filter表中INPUT链的规则,示例如下(注意大小写)。

iptables --line-numbers  -nvL INPUT
Chain INPUT (policy ACCEPT 14M packets, 2062M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1    2697K  114M KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate NEW /* kubernetes service portals */
2    2697K  114M KUBE-EXTERNAL-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate NEW /* kubernetes externally-visible service portals */
3     906M  477G KUBE-FIREWALL  all  --  *      *       0.0.0.0/0            0.0.0.0/0
  • 头含义
    示例中 INPUT链 后面的括号中包含 policy ACCEPT ,0 packets,0bytes 三部分:

    • policy: 表示当前链的默认策略,policy ACCEPT表示上图中INPUT的链的默认动作为ACCEPT
    • packets: 表示当前链(上例为INPUT链)默认策略匹配到的包的数量,0 packets表示默认策略匹配到0个包。
    • bytes: 表示当前链默认策略匹配到的所有包的大小总和。

    其实,我们可以把packets与bytes称作”计数器”,示例中的计数器记录了默认策略匹配到的报文数量与总大小,”计数器”只会在使用 -v 选项时,才会显示出来。

  • 字段含义

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

增加规则

为了准备一个从零开始的环境,使用 iptables -F INPUT 命令清空 filter表 INPUT链 中的规则。

root@localhost:~# iptables -nvL INPUT # 重新检测
Chain INPUT (policy ACCEPT 215 packets, 16538 bytes)
 pkts bytes target     prot opt in     out     source               destination

清空INPUT链以后,filter表中的INPUT链已经不存在任何的规则,但是可以看出,INPUT链的默认策略是ACCEPT,也就是说,INPUT链默认”放行”所有发往本机的报文,当没有任何规则时,会接受所有报文,当报文没有被任何规则匹配到时,也会默认放行报文。

增加

iptables -t filter -I INPUT -s 192.168.1.101 -j DROP

在目标服务器增加一条本地的 ip(即示例中的 12.168.1.101), 发现已经 ping不通了.

使用 -t选项 指定了要操作的表,此处指定了操作filter表,与之前的查看命令一样,不使用 -t选项 指定表时,默认为操作filter表。

使用 -I选项,指明将 “规则” 插入至哪个链中,-I表示insert,即插入的意思,所以 -I INPUT 表示将规则插入于INPUT链中,即添加规则之意。

使用 -s选项,指明 “匹配条件” 中的 “源地址”,即如果报文的源地址属于-s对应的地址,那么报文则满足匹配条件,-s为source之意,表示源地址。

使用 -j选项,指明当 “匹配条件” 被满足时,所对应的动作,示例中指定的动作为DROP,在示例中,当报文的源地址为192.168.1.101 时,报文则被DROP(丢弃)。

查看

再次查看 filter表 中的 INPUT链,发现规则已经被添加了,在iptables中,动作被称之为 “target”,所以,上个示例中taget字段对应的动作为DROP。

root@localhost:~# iptables -vL INPUT
Chain INPUT (policy ACCEPT 2043 packets, 135K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   66  9796 DROP       all  --  any    any     192.168.1.101       anywhere

注意看, 可以看到 bytes 的字节数, 说明已经匹配上了。

顺序

规则的顺序很重要。

如果报文已经被前面的规则匹配到,iptables则会对报文执行对应的动作,即使后面的规则也能匹配到当前报文,很有可能也没有机会再对报文执行相应的动作。

删除规则

此刻,如果我们想要删除 filter表 中INPUT中的一条规则,该怎么做呢?有两种办法
方法一:根据规则的编号去删除规则
方法二:根据具体的匹配条件与动作删除规则

# 添加两种
iptables -t filter -A INPUT -s 1.1.1.1 -j DROP
iptables -t filter -A INPUT -s 1.1.1.2 -j DROP


iptables --line -nvL INPUT
3        0     0 DROP       all  --  *      *       1.1.1.1              0.0.0.0/0           
4        0     0 DROP       all  --  *      *       1.1.1.2              0.0.0.0/0  


# 两种删除方式
iptables -D INPUT 3
iptables -D INPUT -s 1.1.1.2 -j DROP

删除所有

而删除指定表中某条链中的所有规则的命令,我们在一开始就使用到了,就是 iptables -t 表名 -F 链名
-F选项 为flush之意,表示冲刷指定的链,即删除指定链中的所有规则,但是注意,此操作相当于删除操作,在没有保存iptables规则的情况下,请慎用。

修改规则

建议删除后再新增

修改默认策略

使用 -t 指定要操作的表,使用 -P选项 指定要修改的链,下例中,-P FORWARD ACCEPT 表示将表中 FORWRD链 的默认策略改为ACCEPT。

iptables --line -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)

# 执行修改默认
iptables -P FORWARD ACCEPT

iptables --line -nvL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

保存规则

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

centos

entos6中,使用”service iptables save”命令即可保存规则,规则默认保存在 /etc/sysconfig/iptables 文件中。

service iptables save

centos7中,使用 firewall 替代了原来的 iptables service。

firewall-cmd --zone=public --add-port=3000/tcp --permanent
firewall-cmd --reload

# 也可以安装 iptables-service
yum install -y iptables-services
systemctl disable firewalld
systemctl enable iptables
service iptables save

还可以使用另一种方法保存iptables规则,就是使用iptables-save命令
使用 iptables-save 并不能保存当前的iptables规则,但是可以将当前的iptables规则以”保存后的格式”输出到屏幕上。可以使用iptables-save命令,再配合重定向。

iptables-save > /etc/sysconfig/iptables
iptables-restore < /etc/sysconfig/iptables

ubuntu

sudo apt-get install iptables-persistent

sudo /etc/init.d/iptables-persistent save 
sudo /etc/init.d/iptables-persistent reload

# Ubuntu 16.04 Server
sudo netfilter-persistent save
sudo netfilter-persistent reload

匹配条件

匹配方式

# 单个匹配
iptables -I INPUT -s 1.1.1.2 -j DROP

# 多个匹配
iptables -I INPUT -s 1.1.1.3,1.1.1.4 -j DROP

# 网段匹配
iptables -I INPUT -s 1.1.1.5/23 -j DROP

# 取反匹配
iptables -I INPUT ! -s 1.1.1.6 -j ACCEPT

取反注意点

使用 “!” 取反后则表示,报文源地址IP只要不为1.1.1.6即满足条件,那么,上例中规则表达的意思就是,只要发往本机的报文的源地址不是1.1.1.6,就接受报文。

只要报文的源IP不是1.1.1.6,那么就接受此报文,但是,某些小伙伴可能会误会,把上例中的规则理解成如下含义,

只要报文的源IP是1.1.1.6,那么就不接受此报文,这种理解与上述理解看似差别不大,其实完全不一样,这样理解是错误的,上述理解才是正确的。

换句话说就是,报文的源IP不是1.1.1.6时,会被接收,并不能代表,报文的源IP是1.1.1.6时,会被拒绝。

匹配IP地址

如果我们不指定任何目标地址,则目标地址默认为0.0.0.0/0,同理,如果我们不指定源地址,源地址默认为0.0.0.0/0,0.0.0.0/0表示所有IP,示例如下

# 只丢弃从 1.1.1.7 发往 1.1.1.8 这个IP的报文
iptables -I INPUT -s 1.1.1.7 -d 1.1.1.8 -j DROP

与-s选项一样,-d选项也可以使用 “叹号” 进行取反,也能够同时指定多个IP地址,使用 “逗号” 隔开即可。

但是请注意,不管是-s选项还是-d选项,取反操作与同时指定多个IP的操作不能同时使用。

需要明确的一点就是:当一条规则中有多个匹配条件时,这多个匹配条件之间,默认存在”与”的关系。也就是取其交集的意思。

匹配协议类型

我们可以使用 -p选项,指定需要匹配的报文的协议类型。

拒绝来自 1.1.1.2的tcp类型的请求

iptables -I INPUT -s 1.1.1.2 -p tcp -j DROP

root@localhost:~# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  1.1.1.2              anywhere

centos6中,-p选项支持如下协议类型。
tcp, udp, udplite, icmp, esp, ah, sctp

centos7中,-p选项支持如下协议类型。
tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh

当不使用-p指定协议类型时,默认表示所有类型的协议都会被匹配到,与使用-p all的效果相同。

ping 49.234.15.70 # 服务器可以通

ps -ef | grep sshd #  获取登录者 root@pts/1
who -a | grep pts/0 # 获取登录者ip 20816 (223.70.253.1)

iptables -I INPUT -s 223.70.253.1 -p icmp -j DROP # 服务器禁ping

ping 49.234.15.70 # 服务器不通了

匹配网卡接口

入口

iptables -I INPUT -s 223.70.253.1 -i eth0 -p icmp -j DROP

使用 -i选项,指定网卡名称, 表示丢弃由eth0网卡流入的icmp类型的报文。

-i选项 是用于匹配报文流入的网卡的,也就是说,从本机发出的报文是不可能会使用到-i选项的,因为这些由本机发出的报文压根不是从网卡流入的,而是要通过网卡发出的,从这个角度考虑,-i选项的使用是有限制的。

所以 -i选项 只能用于前面示例中的PREROUTING链、INPUT链、FORWARD链,这是 -i选项 的特殊性。

出口

当主机有多块网卡时,可以使用-o选项,匹配报文将由哪块网卡流出,没错,-o选项 与 -i选项 是相对的,-i选项 用于匹配报文从哪个网卡流入,-o选项 用于匹配报文将从哪个网卡流出。

-o选项 只能用于FORWARD链、OUTPUT链、POSTROUTING链。

匹配端口

匹配端口属于扩展匹配条件, 需要依赖一些扩展模块。

端口 -m tcp

选项–dport 可以匹配报文的目标端口,–dport意为destination-port,即表示目标端口。与之前的选项不同,–dport前有两条 “横杠”,而且,使用–dport选项时,必须事先指定了使用哪种协议,即必须先使用-p选项

iptables -I INPUT -s 1.1.1.2 -p tcp -m tcp --dport 22 -j DROP

root@localhost:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 1631 packets, 1525K bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       tcp  --  *      *       1.1.1.2              0.0.0.0/0            tcp dpt:22

在使用–dport之前,我们使用-m选项,指定了对应的扩展模块为tcp,也就是说,如果想要使用–dport这个扩展匹配条件,则必须依靠某个扩展模块完成,上例中,这个扩展模块就是tcp扩展模块,最终,我们使用的是tcp扩展模块中的dport扩展匹配条件。

  • -m tcp 表示使用tcp扩展模块,–dport表示tcp扩展模块中的一个扩展匹配条件,可用于匹配报文的目标端口。
  • -p tcp 与 -m tcp 并不冲突,-p用于匹配报文的协议,-m 用于指定扩展模块的名称,正好,这个扩展模块也叫tcp。

扩展匹配条件是可以取反的,同样是使用 “!” 进行取反,比如 “! –dport 22”,表示目标端口不是22的报文将会被匹配到。

代表 “源端口” 的扩展匹配条件为–sport, 不管是–sport还是–dsport,都能够指定一个端口范围,比如,–dport 22:25表示目标端口为22到25之间的所有端口,即22端口、23端口、24端口、25端口。

多个端口 -m multiport

如果想要同时指定多个离散的端口,需要借助另一个扩展模块,multiport模块。

iptables -I INPUT -s 1.1.1.2 -p tcp -m multiport --dports 22,36,80 -j DROP

root@tencent:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 184 packets, 109K bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       tcp  --  *      *       1.1.1.2              0.0.0.0/0            multiport dports 22,36,80
posted @ 2024-03-09 17:36  505donkey  阅读(65)  评论(0编辑  收藏  举报