iptables的四表五链

时间:2023-02-03 11:18:47

四表五链

四表(table):raw、mangle、nat、filter

五链(chain):PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING

每个表存在几个或全部链,详情如下:

raw

PREROUTING、OUTPUT

mangle

PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING

nat

PREROUTING、INPUT、OUTPUT、POSTROUTING

filter

INPUT、FORWARD、OUTPUT

请求是先按照链的顺序再以表的顺序进行判定的,如下!

iptables的四表五链

注:此为整体的顺序,通常请求只经历其中某几个阶段;

理想的初始状态下表和链全是空的,但有默认规则,比如INPUT默认是ACCEPT,当然可以修改,如果改成DROP那全部请求包括远程ssh就都连不上了;

我们要做的就是添加规则来满足自己的需求,每条规则一定属于某个表的某个链;

防火墙

# 下文代名词:table(表),chain(链),rulenum(规则序号)
# 加中括号[]表示可带可不带,不加则必须带
iptables -L   
# 以链分类来列出规则, 显示内容中的policy表示默认规则;
加-n参数可以把解读为域名和程序名的IP和端口号显示出来;加-v显示更新详细的内容;
iptables -L [chain [rulenum]] [-t table] [--line-numbers]  
# 可以指定chain/rulenum(不指定为all),可以指定table(不指定为filter),
--line-numbers是把rulenum显示出来(就是链内从1开始的序号,可以自己数)
iptables -S [chain [rulenum]] [-t table] [--line-numbers]  
# 直接列出规则,显示内容中的-p表示默认规则
iptables -F [chain] [-t table]  
# 清空指定表和链的规则,不指定chain则为all,不指定table则为filter
([-t table]这个选项基本上所有命令都可用,且都是这个意思,下文不再重复)
iptables -D chain rulenum  
# 删除指定的一条规则

iptables -A chain  # 在chain的末尾加一条规则
iptables -I chain [rulenum]  
# 在rulenum前(不指定则为首位)插入一条规则
iptables -A INPUT -s 172.18.27.8 -j DROP  
# 拒绝来自172.18.27.8的请求, -s表示source,-j表示jump
iptables -A INPUT -s 172.18.0.0/16 -p tcp --dport 22 -j DROP  
# 拒绝来自IP段172.18.0.0/16的ssh连接
# 注:除了-I可以指定rulenum外,-I和-A基本上可以互相替换;由于在一个表的某个链范围内,
规则按顺序依次判定,一旦匹配那么后续的规则将跳过,所以要活用这俩参数
将新规则放到合适的位置;
# 规则相关的参数解析:
-s IP/IP段    源地址
-d IP/IP段    目标地址
-p tcp/udp/...  协议
--sport 端口   源端口,要先指定协议
--dport 端口   目标端口,要先指定协议
-i 网卡      进入的网卡
-o 网卡      发出的网卡
-j 动作      可选ACCEPT(允许)、DROP(丢弃)、REJECT(拒绝)、RETURN(返回)
# accept与reject的区别:以来电为例,前者相当于静音后不予理会,
发起者不清楚状况只能等待超时;
后者相当于直接挂断,发起者立刻就收到了反馈;
# return就是结束该链的判定,跳过后续规则;若在自定义链中就返回到引用它的链,
#若在主链中则使用默认规则;
# 要注意的是,INPUT时本机为目标地址和目标端口,OUTPUT时本机为源地址和源端口

地址转换

| `REDIRECT`   | `本机重定向`       |
| ------------ | ------------------ |
| `NAT` | `网络地址转换` |
| `DNAT` | `目标网络地址转换` |
| `SNAT` | `源网络地址转换` |
| `MASQUERADE` | `网络地址伪装` |




# 地址转换的规则当然是要放到nat表

# 将数据转发到本机的另一个端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

# 下面是将80端口的数据转发到172.18.27.8的8080端口,需要两条规则
# 先在路由前(PREROUTING)修改目标网络地址(目标地址若不加端口则表示端口不修改)
iptables -t nat -A PREROUTING -p tcp --dport 80
-j DNAT --to-destination 172.18.27.8:8080
# 然后在发出时(POSTROUTING)将源地址改为本机,
这个可以通过SNAT或MASQUERADE两种方式实现:
iptables -t nat -A POSTROUTING -p tcp --dport 8080 -j SNAT --to-source [本机IP]
# 或
iptables -t nat -A POSTROUTING -p tcp --dport 8080
-j MASQUERADE
# 效果就是访问[本机IP:80]则相当于访问[172.18.27.8:8080]
# MASQUERADE相比于SNAT是动态获取本机地址后自动伪装,在本机IP会动态变化时尤其有用

# 端口可以范围映射
iptables -t nat -A PREROUTING -p tcp --dport 8080:8081
-j DNAT --to-destination 172.18.27.38:8080-8081
iptables -t nat -A POSTROUTING -p tcp --dport 8080:8081 -j MASQUERADE

自定义链

# 自定义链在规则较多时使用,方便管理,必须在主链中引用才能生效,
引用后就相当于在引用处插入了链内所有规则
# 自定义链的信息同样通过-L查看
iptables -N MY_CHAIN [-t table] 
# 新建一个名为MY_CHAIN的链,不指定table则默认为filter
iptables -E MY_CHAIN YOUR_CHAIN  # 重命名
iptables -A MY_CHAIN -s 172.18.27.8 -j DROP  # 向链中添加规则
iptables -A INPUT -j MY_CHAIN  #在INPUT链中引用
# 删除自定义链需要它没有引用,也没有规则
iptables -D INPUT -j MY_CHAIN  # 删除引用
iptables -F MY_CHAIN  # 清空
iptables -X MY_CHAIN  # 删除

场景问题

# 禁ping
iptables -A INPUT -p icmp -j DROP

相关文章链接

kvm使用之virsh:​​​​​​​​https://blog.51cto.com/u_12040959/5075900​

快速搭建kvm:​​​​https://blog.51cto.com/u_12040959/5023797​

虚拟机内部ping不通百度:​​https://blog.51cto.com/u_12040959/5115691​