📄 0250simple_firewall.htm
字号:
[root@linux ~]# <span class=term_command>iptables -P FORWARD ACCEPT</span>
[root@linux ~]# <span class=term_command>iptables -L -n</span>
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy <span class=term_write>DROP</span>)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
<span class=term_say># 由于 INPUT 设定为 DROP 而又尚未有任何规则,所以上面的输出结果显示∶
# 所有的封包都无法进入你的主机!是不通的防火墙设定!(网路连线是双向的)</span>
</pre></td></tr></table>
看到输出的结果了吧?INPUT 被修改设定了喔!其他的 nat table 三条链的设定也是一样的,例如∶『
<span class=text_import2>iptables -t nat -P PREROUTING ACCEPT</span> 』就设定了 nat table
的 PREROUTING 链为可接受的意思!预设政策设定完毕后,来谈一谈关于封包的基础比对设定吧。<br /><br />
</div>
<a name="netfilter_syntax_comp"></a><hr /><li><span class=text_import1>封包的基础比对 IP/netmask
I/O 装置</span><br />
<div class=block2>
开始来进行封包的比对设定吧!我们先由最基础的 IP 与网域的特徵谈起,再谈装置 (网路卡) 的限制等等。<br />
<table class="term"><tr><td class="term"><pre>
[root@linux ~]# <span class=term_command>iptables [-AI 链] [-io 网路介面] [-p 协定] \</span>
> <span class=term_command>[-s 来源IP/网域] [-d 目标IP/网域] -j [ACCEPT|DROP]</span>
<span class=term_say>参数∶
-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) 及记录 (LOG)</span>
</pre></td></tr></table>
iptables 的基本参数就如同上面所示的,仅只谈到 IP 、网域与装置等等的资讯,
至于 TCP, UDP 封包特有的埠口 (port number) 与状态 (如 SYN 旗标) 则在下小节才会谈到。
好,先让我们来看看最基础的几个规则,例如开放 lo 这个本机的介面以及某个 IP 来源吧!<br />
<table class="term"><tr><td class="term"><pre>
<span class=term_hd>范例一∶所有的来自 lo 这个介面的封包,都予以接受</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i lo -j ACCEPT</span>
<span class=term_say># 仔细看上面并没有列出 -s, -d 等等的规则,这表示∶不论封包来自何处或去到哪里,
# 只要是来自 lo 这个介面,就予以接受!这个观念挺重要的,就是
#『没有设定的规定,则表示该规定完全接受』的意思!例如这个案例当中,
# 关于 -s, -d...等等的参数没有规定时</span>
<span class=term_hd>范例二∶目标来自 192.168.0.1 这个 IP 的封包都予以接受</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -s 192.168.0.1 -j ACCEPT</span>
<span class=term_say># 不管什么封包格式,只要来自 192.168.0.1 就予以接受。</span>
<span class=term_hd>范例三∶目标来自 192.168.1.0/24 可接受,但 192.168.1.10 丢弃</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -s 192.168.1.10 -j DROP</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT</span>
<span class=term_say># 上述这两个范例很重要啊!因为有点关系!要先丢弃 192.168.1.10 才能接受该网域。</span>
[root@linux ~]# <span class=term_command>iptables -L -n</span>
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 192.168.0.1 0.0.0.0/0
DROP all -- 192.168.1.100 0.0.0.0/0
ACCEPT all -- 192.168.1.0/24 0.0.0.0/0
<span class=term_say># 瞧!刚刚的设定在这里已经生效棉!</span>
</pre></td></tr></table>
这就是最单纯、简单的防火墙规则的设定与观察方式。你在设定完毕后,都可以利用 iptables -L -n 或
iptables -L -v 来简单的查阅一下。而如果你想要记录某个规则的纪录怎么办?可以这样做∶<br />
<table class="term"><tr><td class="term"><pre>
[root@linux ~]# <span class=term_command>iptables -A INPUT -s 192.168.2.200 -j LOG</span>
[root@linux ~]# <span class=term_command>iptables -L -n</span>
target prot opt source destination
LOG all -- 192.168.2.200 0.0.0.0/0 LOG flags 0 level 4
</pre></td></tr></table>
看到输出结果的最左边,会出现的是 LOG 喔!只要有封包来自 192.168.2.200 这个 IP 时,
那么该封包的相关资讯就会被写入到核心讯息,亦即是 /var/log/messages 这个档案当中。
<span class=text_import2>然后该封包会继续进行后续的规则比对。</span>所以说,
LOG 这个动作仅在进行记录而已,并不会影响到这个封包的其他规则比对的。
好了,接下来我们分别来看看 TCP,UDP 以及 ICMP 封包的其他规则比对吧!<br /><br />
</div>
<a name="netfilter_syntax_tcp"></a><hr /><li><span class=text_import1>TCP, UDP 的规则比对</span><br />
<div class=block2>
我们在<a href="0110network_basic.php">网路基础</a>谈过各种不同的封包格式,
在谈到 TCP 与 UDP 时,比较特殊的就是那个埠口 (port number),在 TCP 方面则另外有所谓的连线封包状态,
包括最常见的 SYN 主动连线的封包格式。那么如何针对这两种封包格式进行防火墙规则的设定呢?你可以这样看∶<br />
<table class="term"><tr><td class="term"><pre>
[root@linux ~]# <span class=term_command>iptables [-AI 链] [-io 网路介面] [-p tcp,udp] \</span>
> <span class=term_command>[-s 来源IP/网域] [--sport 埠口范围] \</span>
> <span class=term_command>[-d 目标IP/网域] [--dport 埠口范围] -j [ACCEPT|DROP]</span>
<span class=term_say>参数∶
--sport 埠口范围∶限制来源的埠口号码,埠口号码可以是连续的,例如 1024:65535
--dport 埠口范围∶限制目标的埠口号码。</span>
</pre></td></tr></table>
事实上就是多了那个 --sport 及 --dport 这两个玩意儿,重点在那个 port number 上面啦!
底下让我们来进行几个小测试∶<br />
<table class="term"><tr><td class="term"><pre>
<span class=term_hd>范例一∶想要连线进入本机 port 21 的封包都抵挡掉∶</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP</span>
<span class=term_hd>范例二∶想连到我这部主机的网芳 (upd port 137,138 tcp port 139,445) 就放行</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -p udp --dport 137:138 -j ACCEPT</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -p tcp --dport 139 -j ACCEPT</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -p tcp --dport 445 -j ACCEPT</span>
</pre></td></tr></table>
瞧!你可以利用 UDP 与 TCP 协定所拥有的埠口号码来进行某些服务的开放或关闭喔!
你还可以综合处理呢!例如∶只要来自 192.168.1.0/24 的 1024:65535 埠口的封包,
只要想要连线到本机的 ssh port 就予以抵挡,可以这样做∶<br />
<table class="term"><tr><td class="term"><pre>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 \</span>
> <span class=term_command>--sport 1024:65534 --dport ssh -j DROP</span>
</pre></td></tr></table>
注意啊!如果你有使用到 --sport 及 --dport 的参数时,<span class=text_import2>就必须指定 udp 或 tcp
的封包格式才行!</span>否则的话, iptables 的指令就会出现如下的错误∶<br />
<table class="term"><tr><td class="term"><pre>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 --dport 21 -j DROP</span>
iptables v1.2.11: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.
</pre></td></tr></table>
你应该会觉得很奇怪,怎么『 --dport 』会是未知的参数 (arg) 呢?这是因为你没有加上 -p tcp 或 -p udp
的缘故啊!因为 port 是 TCP,UDP 特有的,其他类似 ICMP 则没有这种类的埠口资料啊!
这样说,您可以理解吧! ^_^<br /><br>
除了埠口之外,在 TCP 还有特殊的旗标啊!最常见的就是那个主动连线的 SYN 旗标了。
我们在 iptables 里面还支援『 --syn 』的处理方式,我们以底下的例子来说明好了∶<br />
<table class="term"><tr><td class="term"><pre>
<span class=term_hd>范例∶将来自任何地方来源 port 1:1023 的主动连线到本机端的 1:1023 连线丢弃</span>
[root@linux ~]# <span class=term_command>iptables -A INPUT -i eth0 -p tcp --sport 1:1023 \</span>
> <span class=term_command>--dport 1:1023 --syn -j DROP</span>
</pre></td></tr></table>
一般来说,client 端启用的 port 都是大于 1024 以上的埠口,而 server 端则是启用小于 1023
以下的埠口在监听的。所以我们可以让来自远端的小于 1023 以下的埠口资料的主动连线都给他丢弃!
但不适用在 FTP 的主动连线中!这部份我们未来在 FTP 章节当中再来谈吧!<br /><br />
</div>
<a name="netfilter_syntax_state"></a><hr /><li><span class=text_import1>状态模组∶MAC 与 RELATED</span><br />
<div class=block2>
在早期的 kernel 2.2 以前使用 ipchains 管理防火墙时,通常会让系统管理员相当头痛!
因为 ipchains 没有所谓的封包状态模组,因此我们必须要针对封包的进、出方向进行管控。
举例来说,如果你想要连线到远端主机的 port 22 时,你必须要针对两条规则来设定∶<br />
<ul><li>本机端的 1024:65535 到远端的 port 22 必须要放行 (OUTPUT 链);
<li>远端主机 port 22 到本机的 1024:65535 必须放行 (INPUT 链);</ul>
这会很麻烦!因为如果你要连线到 10 部主机的 port 22 时,假设 OUTPUT 为预设开启 (ACCEPT),
你依旧需要填写十行规则,让那十部远端主机的 port 22 可以连线到你的本地端主机上。
那如果开启全部的 port 22 呢?又担心某些恶意主机会主动以 port 22 连线到你的机器上!
同样的道理,如果你要让本地端主机可以连到外部的 port 80 (WWW 服务),那就更不得了~
这就是网路连线是双向的一个很重要的概念!<br /><br />
好在我们的 iptables 免除了这个困扰!他可以透过一个状态模组来分析
『<span class=text_import2>这个想要进入的封包是否为刚刚我发出去的回应?</span>』
如果是刚刚我发出去的回应,那么就可以予以接受放行!哇!真棒!这样就不用管远端主机是否连线进来的问题了!
那如何达到呢?看看底下的语法∶<br />
<table class="term"><tr><td class="term"><pre>
[root@linux ~]# <span class=term_command>iptables -A INPUT -m state --state 状态</span>
<span class=term_say>参数∶
-m ∶一些 iptables 的模组,主要
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -