Linux网络学习笔记-防火墙与NAT

前言

Linux防火墙作为安全屏障,需要认真设置。

认识防火墙

概述

防火墙就是透过订定一些有顺序的规则,并管制进入到我们网域内的主机 (或者可以说是网域)
数据封包的一种机制,更广义的来说,只要能够分析与过滤进出我们管理之网域的封包数据,
就可以称为防火墙。

防火墙分类:

  • 硬件防火墙

    是由厂商设计好的主机硬件,这部硬件防火墙内的操作系统主要以提供封包数据的过滤机制为主,并将其他不必要的功能拿掉。因为单纯作为防火墙功能而已,因此封包过滤的效率较佳。

  • 软件防火墙

    它是最常用的防火墙,通常作为计算机系统上的程序运行。它是可定制的,允许用户控制其功能。

防火墙的作用

防火墙最大的功能就是帮助你限制某些服务的存取来源。最主要的任务如下:

  • 切割被信任(如子域)与不被信任(如 Internet)的网段;
  • 划分出可提供 Internet 的服务与必须受保护的服务;
  • 分析出可接受与不可接受的封包状态;

Linux系统上防火墙的类别

依据防火墙管理的范围,将防火墙区分为网域型与单一主机型的控管。

在单一主机型的控管方面,主要的防火墙有封包过滤型的 Netfilter 与依据服务软件程序作为分析的 TCP Wrappers 两种。

若以区域型的防火墙而言,由于此类防火墙都是当作路由器角色,因此防火墙类型主要则有封包过滤的 Netfilter 与利用代理服务器 (proxy server)进行存取代理的方式了。

  • Netfilter–数据包过滤机制

    所谓的数据包过滤,就是分析进入主机的数据包,分析头部信息来决定是否放行。主要是用iptables这个软件作为防火墙数据包过滤的命令。因为Netfilter是内核内建的功能,所以效率非常高。

  • TCP Wrappers–程序管理

    通过服务器的外挂来处理。这种机制主要是分析谁对某程序进行访问,然后通过规则去分析该服务器程序谁能够连接、谁不能连接。

  • Proxy–代理服务器

    QmMZhF.png

    其实代理服务器是一种网络服务,代理用户的需求。由proxy来分析用户的IP来源是否合法,用户想去的IP是否合法

防火墙的一般网络布线图

单一网络,单个路由器

QmM8AK.png

  • 内外网分开,安全维护在内网可以放开的权限较大
  • 安全机制的设置可以针对Linux防火墙主机来维护即可
  • 对外只看到Linux防火墙主机,所以对内部有安全防护

内部包含更安全的子网,内部防火墙切开子网

QmMsN8.png

如果公司内部有安全保密需要非常严格的部门,需要在子网上重新架设防火墙。

在防火墙后面架设网络服务器主机

QmMIEV.png

将DMZ隔离于internet和LAN之外,无论是LAN还是DMZ被攻破时,都不会影响彼此。

防火墙的使用限制

  1. 拒绝让Internet的数据包进入主机的某些端口
  2. 拒绝让某些来源IP的数据包进入
  3. 拒绝让带有某些特殊标志位的数据包进入
  4. 分析MAC地址来决定连接与否

不能抵挡的攻击:

  1. 不能有效阻挡病毒或者木马
  2. 对内部的LAN的攻击无能为力

TCP Wrappers

这就是由/etc/hosts.allow/etc/hosts.deny两个文件来管理的一个类似防火墙的机制,只有下面的软件才能通过这两个文件来管理防火墙规则

  • xinetd管理的服务
  • 支持libwrap.so模块的服务

两个文件的设置方式

1
2
<service(program_name)> : <IP, domain, hostname> 
<服务 (亦即程序名称)> : <IP 或领域 或主机名>
  • 先以 /etc/hosts.allow 为优先比对,该规则符合就予以放行;
  • 再以 /etc/hosts.deny 比对,规则符合就予以抵挡;
  • 若不在这两个档案内,亦即规则都不符合,最终则予以放行。

Linux数据包过滤软件iptables

数据包进入流程

防火墙将会如何分析到来的数据包?

QmXbHP.png

当网络封包进入 Rule 1 的比对时,如果比对结果符合 Rule 1 ,此时这个网络封包就会进行 Action 1 的动作,而不会理会后续的 Rule 2, Rule 3…. 等规则的分析了。如果都不符合就会执行最下面的预设封包动作,当你的规则顺序排列错误时,就会产生很严重的错误了。

iptables的表格和链

防火墙软件里有许多的表格,表格里都定义出自己的默认规则和政策,且每个表格的用途都不一样。

Qmj62Q.png

Linux 的 iptables 至少就有三个表格,包括管理本机进出的 filter 、管理后端主机 (防火墙内部的其他计算机) 的 nat 、管理特殊旗标使用的 mangle (较少使用)

  • filter:主要跟进入 Linux 本机的封包有关,这个是预设的 table 喔!
    • INPUT:主要与想要进入我们 Linux 本机的封包有关;
    • OUTPUT:主要与我们 Linux 本机所要送出的封包有关;
    • FORWARD:这个咚咚与 Linux 本机比较没有关系,他可以『转递封包』到后端的计算机中,与下列 nat table 相关性较高。
  • nat (地址转换):是 Network Address Translation 的缩写,这个表格主要在进行来源与目的之 IP 或 port 的转换,与 Linux 本机较无关,主要与 Linux主机后的局域网络内计算机较有相关。

    • PREROUTING:在进行路由判断之前所要进行的规则(DNAT/REDIRECT)
    • POSTROUTING:在进行路由判断之后所要进行的规则(SNAT/MASQUERADE)
    • OUTPUT:与发送出去的封包有关
  • mangle (破坏者):这个表格主要是与特殊的封包的路由旗标有关,早期仅有 PREROUTING 及 OUTPUT 链,不过从 kernel 2.4.18 之后加入了 INPUT 及 FORWARD 链。由于这个表格与特殊旗标相关性较高,所以像咱们这种单纯的环境当中,较少使用 mangle 这个表格。

封包传递流程

因为mangle用的比较少,就暂时省略…

1575250748268

  • A:封包进入Linux主机使用资源

    在路由判断后确定是向 Linux 主机要求数据的封包,主要就会透过 filter 的 INPUT 链来进行控管

  • B:封包经过Linux主机传递到后端主机,并未使用Linux主机资源

    主要经过的链是 filter 的 FORWARD 以及 nat 的 POSTROUTING, PREROUTING

  • C:封包由Linux主机发送出去

    例如响应客户端的要求,或者是 Linux 本机主动送出的封包,都是透过路径 C 来跑的。先是透过路由判断,
    决定了输出的路径后,再透过 filter 的 OUTPUT 链来传送的!当然,最终还是会经过 nat 的 POSTROUTING 链

iptables设置

正常使用的查看表格和链的命令:

1
2
3
4
5
6
[root@www ~]# iptables [-t tables] [-L] [-nv]
选项与参数:
-t :后面接 table ,例如 nat 或 filter ,若省略此项目,则使用默认的 filter
-L :列出目前的 table 的规则
-n :不进行 IP 与 HOSTNAME 的反查,显示讯息的速度会快很多!
-v :列出更多的信息,包括通过该规则的封包总位数、相关的网络接口等

建议使用 iptables-save 这个指令来观察防火墙规则,上面会列出接口:

1
2
3
[root@www ~]# iptables-save [-t table]
选项与参数:
-t :可以仅针对某些表格来输出,例如仅针对 nat 或 filter 等等

清除防火墙规则:

1
2
3
4
5
[root@www ~]# iptables [-t tables] [-FXZ]
选项与参数:
-F :清除所有的已订定的规则;
-X :杀掉所有使用者 "自定义" 的 chain (应该说的是 tables )啰;
-Z :将所有的 chain 的计数与流量统计都归零

定义预设政策:

就是最基础的最底层的限制规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@www ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
选项与参数:
-P :定义政策( Policy )。注意,这个 P 为大写啊!
ACCEPT :该封包可接受
DROP :该封包直接丢弃,不会让 client 端知道为何被丢弃。

范例:将本机的 INPUT 设定为 DROP ,其他设定为 ACCEPT
[root@www ~]# iptables -P INPUT DROP
[root@www ~]# iptables -P OUTPUT ACCEPT
[root@www ~]# iptables -P FORWARD ACCEPT
[root@www ~]# iptables-save
# Generated by iptables-save v1.4.7 on Fri Jul 22 15:56:34 2011
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Fri Jul 22 15:56:34 2011

nat table 三条链的预设政策设定也是一样的方式,例如:『iptables -t nat -P PREROUTING ACCEPT 』就设定了 nat table的 PREROUTING 链为可接受的意思

IP、网域及接口设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@www ~]# iptables [-AI 链名] [-io 网络接口] [-p 协议] \
> [-s 来源IP/网域] [-d 目标IP/网域] -j [ACCEPT|DROP|REJECT|LOG]
选项与参数:
-AI 链名:针对某的链进行规则的 "插入" 或 "累加"
-A :新增加一条规则,该规则增加在原本规则的最后面。例如原本已经有四条规则,
使用 -A 就可以加上第五条规则!
-I :插入一条规则。如果没有指定此规则的顺序,默认是插入变成第一条规则。
例如原本有四条规则,使用 -I 则该规则变成第一条,而原本四条变成 2~5 号
链 :有 INPUT, OUTPUT, FORWARD 等,此链名称又与 -io 有关,请看底下。

-io 网络接口:设定封包进出的接口规范
-i :封包所进入的那个网络接口,例如 eth0, lo 等接口。需与 INPUT 链配合;
-o :封包所传出的那个网络接口,需与 OUTPUT 链配合;

-p 协定:设定此规则适用于哪种封包格式
主要的封包格式有: tcp, udp, icmp 及 all 。

-s 来源 IP/网域:设定此规则之封包的来源项目,可指定单纯的 IP 或包括网域,例如:
IP :192.168.0.100
网域:192.168.0.0/24, 192.168.0.0/255.255.255.0 均可。
若规范为『不许』时,则加上 ! 即可,例如:
-s ! 192.168.100.0/24 表示不许 192.168.100.0/24 之封包来源;

-d 目标 IP/网域:同 -s ,只不过这里指的是目标的 IP 或网域。

-j :后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG)

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@www ~]# iptables -A INPUT -i lo -j ACCEPT

[root@www ~]# iptables -A INPUT -i eth1 -s 192.168.100.0/24 -j ACCEPT
# 由于是内网就接受,因此也可以称之为『信任网域』。

范例:只要是来自 192.168.100.10 就接受,但 192.168.100.230 这个恶意来源就丢弃
[root@www ~]# iptables -A INPUT -i eth1 -s 192.168.100.10 -j ACCEPT
[root@www ~]# iptables -A INPUT -i eth1 -s 192.168.100.230 -j DROP
# 针对单一 IP 来源,可视为信任主机或者是不信任的恶意来源喔!

[root@www ~]# iptables-save
# Generated by iptables-save v1.4.7 on Fri Jul 22 16:00:43 2011
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [17:1724]
-A INPUT -i lo -j ACCEPT
-A INPUT -s 192.168.100.0/24 -i eth1 -j ACCEPT
-A INPUT -s 192.168.100.10/32 -i eth1 -j ACCEPT
-A INPUT -s 192.168.100.230/32 -i eth1 -j DROP
COMMIT
# Completed on Fri Jul 22 16:00:43 2011

notes:

如果设置为LOG的处理方式,就会将该数据包的相关信息写入日志文件/var/log/messages,然后继续进行后续规则的对比。

针对端口的设置:

1
2
3
4
5
6
[root@www ~]# iptables [-AI 链] [-io 网络接口] [-p tcp,udp] \
> [-s 来源IP/网域] [--sport 埠口范围] \
> [-d 目标IP/网域] [--dport 埠口范围] -j [ACCEPT|DROP|REJECT]
选项与参数:
--sport 埠口范围:限制来源的端口号码,端口号码可以是连续的,例如 1024:65535
--dport 埠口范围:限制目标的端口号码。

其实就是多了两个端口的范围,一个是目的端口,一个是来源端口,因为只有TCP和UDP数据包具有端口,所以需要-p加上协议类型

1
2
[root@www ~]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 \
> --sport 1024:65534 --dport ssh -j DROP

SYN标志位处理:

加上–syn即可

1
2
3
范例:将来自任何地方来源 port 1:1023 的主动联机到本机端的 1:1023 联机丢弃
[root@www ~]# iptables -A INPUT -i eth0 -p tcp --sport 1:1023 \
> --dport 1:1023 --syn -j DROP

外挂模块:mac和state

state可以针对想要进入主机的数据包是否为刚刚发出去的数据包的响应来判断是否需要拦截数据包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@www ~]# iptables -A INPUT [-m state] [--state 状态]
选项与参数:
-m :一些 iptables 的外挂模块,主要常见的有:
state :状态模块
mac :网络卡硬件地址 (hardware address)
--state :一些封包的状态,主要有:
INVALID :无效的封包,例如数据破损的封包状态
ESTABLISHED:已经联机成功的联机状态;
NEW :想要新建立联机的封包状态;
RELATED :这个最常用!表示这个封包是与我们主机发送出去的封包有关

范例:只要已建立或相关封包就予以通过,只要是不合法封包就丢弃
[root@www ~]# iptables -A INPUT -m state \
> --state RELATED,ESTABLISHED -j ACCEPT
[root@www ~]# iptables -A INPUT -m state --state INVALID -j DROP

另一个mac就是针对MAC地址来进行放行和防御:

1
2
3
4
5
范例:针对局域网络内的 aa:bb:cc:dd:ee:ff 主机开放其联机
[root@www ~]# iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff \
> -j ACCEPT
选项与参数:
--mac-source :就是来源主机的 MAC 啦!

ICMP数据包规则:

通常ICMP数据包用来检测网络连接是否正常,所以最好不要将所有的ICMP包都丢弃,如果主机不是路由器,一般会将ICMP type8(echo request)拿掉,这样远程主机就不知道我们是否存在,不会接受ping的响应,这样处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@www ~]# iptables -A INPUT [-p icmp] [--icmp-type 类型] -j ACCEPT
选项与参数:
--icmp-type :后面必须要接 ICMP 的封包类型,也可以使用代号,
例如 8 代表 echo request 的意思。

范例:让 0,3,4,11,12,14,16,18 的 ICMP type 可以进入本机:
[root@www ~]# vi somefile
#!/bin/bash
icmp_type="0 3 4 11 12 14 16 18"
for typeicmp in $icmp_type
do
iptables -A INPUT -i eth0 -p icmp --icmp-type $typeicmp -j ACCEPT
done

[root@www ~]# sh somefile

NAT服务器的设置

NAT 的全名是Network Address Translation,字面上的意思是『网络地址的转换』,iptables指令可以修改数据包的表头数据,来源和目的地址,端口都可以修改,nat就运用了这些功能。

内部LAN想传送数据包出去的步骤:

  1. 先经过 NAT table 的 PREROUTING 链;
  2. 经由路由判断确定这个封包是要进入本机与否,若不进入本机,则下一步;
  3. 再经过 Filter table 的 FORWARD 链;
  4. 通过 NAT table 的 POSTROUTING 链,最后传送出去。

NAT table 的两条重要的链:PREROUTING 与 POSTROUTING。POSTROUTING 在修改来源 IP ,PREROUTING 则在修改目标 IP 。由于修改的 IP 不一样,所以就称为来源 NAT (Source NAT, SNAT) 及目标 NAT(Destination NAT, DNAT)

SNAT

Qnelyq.png

  1. 客户端所发出的封包表头中,来源会是 192.168.1.100 ,然后传送到 NAT 这部主机;
  2. NAT 这部主机的内部接口 (192.168.1.2) 接收到这个封包后,会主动分析表头数据,因为表头数据显示目的并非 Linux 本机,所以开始经过路由,将此封包转到可以连接到 Internet 的 Public IP 处;
  3. 由于 private IP 与 public IP 不能互通,所以 Linux 主机透过 iptables 的 NAT table 内的 Postrouting 链将封包表头的来源伪装成为 Linux 的 Public IP ,并且将两个不同来源 (192.168.1.100 及 public IP) 的封包对应写入暂存内存当中,然后将此封包传送出去了;

Qnejcn.png

  1. 在 Internet 上面的主机接到这个封包时,会将响应数据传送给那个 Public IP 的主机;
  2. 当 Linux NAT 服务器收到来自 Internet 的回应封包后,会分析该封包的序号,并比对刚刚记录到内存当中的数据,由于发现该封包为后端主机之前传送出去的,因此在 NAT Prerouting 链中,会将目标 IP 修改成为后端主机,亦即那部 192.168.1.100,然后发现目标已经不是本机 (public IP),所以开始透过路由分析封包流向;
  3. 封包会传送到 192.168.1.2 这个内部接口,然后再传送到最终目标 192.168.1.100 机器上去!

DNAT

QnmaE8.png

其实就是和SNAT反向的操作…

设置

1
2
3
4
5
6
7
8
9
10
iptables -A INPUT -i $INIF -j ACCEPT
# 这一行为非必要的,主要的目的是让内网 LAN 能够完全的使用 NAT 服务器资源。
# 其中 $INIF 在本例中为 eth1 接口

echo "1" > /proc/sys/net/ipv4/ip_forward
# 上头这一行则是在让你的 Linux 具有 router 的能力

iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
# 这一行最关键!就是加入 nat table 封包伪装!本例中 $innet 是 192.168.100.0/24
# 而 $EXTIF 则是对外界面,本例中为 eth0

重点在那个『 MASQUERADE 』!这个设定值就是『 IP 伪装成为封包出去 (-o) 的那块装置上的 IP 』

1
2
iptables -t nat -A POSTROUTING -o eth0 -j SNAT \
--to-source 192.168.1.210-192.168.1.220

上述为对外IP轮流使用…

1
2
3
4
5
6
7
8
9
 4. NAT 服务器后端的 LAN 内对外之服务器设定
# iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 80 \
# -j DNAT --to-destination 192.168.1.210:80 # WWW

# 5. 特殊的功能,包括 Windows 远程桌面所产生的规则,假设桌面主机为 1.2.3.4
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4 --dport 6000 \
# -j DNAT --to-destination 192.168.100.10
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4 --sport 3389 \
# -j DNAT --to-destination 192.168.100.20

总结

也算是对Linux的防火墙有了一个初步的认识,更多的学习需要以后更加努力…

Author: Gard3nia
Link: https://gardenia30.top/2019/11/28/Linux网络学习笔记-防火墙与NAT/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.