今天搞了个网络转发,将服务器中的一个虚拟机通过网络转发的方式让其他网络的主机访问虚拟机。
iptables传输数据包过程:
1.首先进入PREROUTING链,内核根据数据包目的ip判断是否转出。
2.数据包如果是本机数据包,则进入INPUT链,此时本机任何进程都可以收到数据包。同时,本机上的程序都可以发送数据包,并进入OUTPUT链,最后进入POSTROUTING链输出。
3.若是非本机数据包,并且内核判断允许转出,则进入FORWARD链,最后进入POSTROUTING链输出。
iptable有四个表,filter,nat,mangle和raw,用于实现包过滤,网络地址转换,包重构和数据跟踪处理。
filter表有三个链:INPUT,FORWARD和OUTPUT
nat表有三个链:PREROUTING,POSTROUTING和OUTPUT
managle表有五个链:PREROUTING,POSTROUTING,INPUT,OUTPUT和FORWARD
raw表有两个链:OUTPUT和PREROUTING
语法:
iptables -t [表名] 命令控制选项 [链名] [条件匹配规则] -j [处理方式]
表名:filter,nat,mangle,raw
命令控制选项:
-A 在指定链末尾添加一条新规则
-D 删除指定链中的一条规则,可按照规则序号和内容删除
-I 在指定链中插入一条新的规则,默认添加在第一行
-R 修改,替换指定链中的一条规则,可按照规则序号和内容替换
-L 列出指定链中所有规则
-E 重命名用户定义的链,不改变链本身
-F 清空
-N 新建一条用户自定义的规则链
-X 删除指定表中用户自定义的规则链
-P 设置指定链的默认策略
-Z 将所有表的所有链的字节和数据包计数器清零
-n 使用数字形式显示输出结果
-v 查看规则表详细信息
-V 查看版本
-h 帮助
处理方式有四种:
ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给任何返回信息
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应信息
LOG 在/var/log/messages文件中记录日志信息,并将数据包传递给下一条规则
网络转发shell脚本:
dest_ip=192.168.122.50
dest_port=8000
gatewat_public_ip=192.168.1.250
gateway_port=10050
gatewaty_private_ip=192.168.122.1
iptables -t nat -A PREROUTING -d $gateway_public_ip/32 -p tcp -m tcp --dport $gateway_port -j DNAT --to-destination $dest_ip:$dest_port
iptables -t nat -A POSTROUTING -d $dest_ip/32 -p tcp -m tcp --dport $dest_port -j SNAT --to-source $gateway_private_ip
获取nat表信息shell脚本:
#!/bin/bash
iptables -t nat -nL --line-number
删除nat表规则shell脚本:
#!/bin/bash
prerouting_num=$1
postrouting_num=$2
iptables -t nat -D PREROUTING $prerouting_num
iptables -t nat -D POSTROUTING $postrouting_num
ps:
添加网络转发遇到的一个小问题
在添加一条POSTROUTING规则时:
num pkts bytes target prot opt in out source destination
1 0 0 MASQUERADE tcp -- × × 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
iptables -t nat -A POSTROUTING -p tcp -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE --to-posts 1024-65535
要设置destination为!192.168.122.0/24时,取反符号!放在-d前面。