理解iptables

iptables 初解

防火墙只是一个规则机器与外部有交互时的一个过滤规则,依赖netfilter注册各种hooks实现。iptables以表(table)->链(chain)->规则(rule)的逻辑来对流量的逻辑控制。有4个表:raw,mangle,filter,nat

  • Filter:此表对应3个链,INPUT、FORWARD、OUTPUT。从字面意思也能理解,入站、出站、路由。
  • NAT:全名Network Address Traslation,即网络地址转换。也对应3个链PREROUTING,OUTPUT,POSTROUTING。其中PREROUTING在路由前修改目的地址(实现DNAT),OUTPUT主要为本机发出的包实现DNAT,相应的最后的作用修改源地址,实现SNAT。
  • Mangle: 修改数据包。
  • Raw:连接跟踪设置。

iptables实验及常用命令

# 规则保存和加载
iptables-save
iptables-restore

# 查看iptables的默认规则,没有特别指明,一般默认操作filter
iptables -L

#清空服务器上所有的规则
iptables -F

# 列出规则
iptables -S
iptables -L INPUT
iptables -nvL

示例 环境

  • 虚拟机Centos node1 ip: 192.168.99.110
  • 虚拟机Centos node2 ip: 192.168.99.111

现在,两台机器都能相互ping通。在node1上运行命令启动8000端口:

python -m SimpleHTTPServer #python2
python -m http.server # python3

在node2上访问:curl 192.168.99.110:8000,正常返回没问题,下面尝试关闭node1上的8080入站。在node1上执行:

iptables -t filter -I INPUT -p tcp --dport 8000 -j REJECT

再到node2上访问:

[root@node2 ~]# curl http://192.168.99.110:8000
curl: (7) Failed connect to 192.168.99.110:8000; Connection refused

结果正如预期,如果想放开8000,可以有如下:

也可以执行iptables -F清理所有filter表。这儿需要说明的是,firewalld只是封装iptables的一个服务,底层还是iptables。如果启动firewalled,会有一些默认的规则,前面的8000端口是访问不通的,可以单独对8000放行。

iptables -t filter -I INPUT -p tcp --dport 8000 -j ACCEPT

命令简单解释上面这条指令:

  • -t filter: -t 指定table, 不写默认filter。
  • -I INPUT: -I (INSERT) 指定链。-D表示删除,
  • -p tcp --dport 8000 : 协议、端口
  • -j ACCEPT: 动作(ACCEPT,DROP,REJECT,RETURN)

对链的操作主要有下表选项:

选项 意义
-s 匹配源地址
-d 匹配目的地址
-p 协议匹配
-i 入接口匹配
-o 出接口匹配
–sport,–dport 源和目的端口匹配
-j 跳转,也就是包的方向
! 取反

语法: iptables [-t table] 操作 chain RULE 图片来源: 玩转Linux防火墙命令iptables

实验2代理

还是上面两台机器,这次在node2上启动8000端口python -m SimpleHTTPServer,在node1上执行下列命令:

iptables -t nat -I PREROUTING -p tcp --dport 8080 -j DNAT --to 192.168.99.111:8000
# 回路
iptables -t nat -I POSTROUTING -p tcp --dport 8000 -j MASQUERADE

从第三台机器访问node1

✔ curl 192.168.99.110:8080
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
<li><a href=".bash_logout">.bash_logout</a>
<li><a href=".bash_profile">.bash_profile</a>
<li><a href=".bashrc">.bashrc</a>
<li><a href=".cshrc">.cshrc</a>
<li><a href=".pki/">.pki/</a>
<li><a href=".tcshrc">.tcshrc</a>
<li><a href="anaconda-ks.cfg">anaconda-ks.cfg</a>
<li><a href="post_install.log">post_install.log</a>
</ul>
<hr>
</body>
</html>
CONTENTS