网络七层协议:

  • 应用层
  • 表示层
  • 会话层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层

iptable 是一个配置 Linux 内核防火墙的命令行工具, 工作在网络层和传输层.

ip packets

/wiki/wiki/ip-datagram.jpg

Example:

                                  
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Ver= 4 |IHL= 5 |Type of Service|       Total Length = 472      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Identification = 111      |Flg=0|     Fragment Offset = 0 |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Time = 123  | Protocol = 6  |        header checksum        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         source address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                      destination address                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   \                                                               \
   \                                                               \
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |             data              |                                
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                

常用协议号:

Protocol Number Protocol
1 ICMP
6 TCP
17 UDP

所有的协议对照表可以查看文件: /etc/protocols .

iptables

iptables 包含几个概念: 表, 链, 规则, 允许用户定义 链和规则.

Tables 表

  • filter : 默认表
  • nat : 用于网络地址转换, 如端口转发
  • mangle : 用于特定数据包的修改
  • security : 用于强制访问控制的网络规则, 如 SELinux
  • raw : 用于配置数据包, raw 中的数据不会被系统跟踪

Chains 链

表由链组成, 链是一些按顺序排列的规则的列表.

filter table: INPUT, OUTPUT, FORWARD

nat table: PREROUTING, POSTROUTING, OUTPUT

mangle table: PREROUTING, INPUT, OUTPUT, POSTROUTING, FORWARD

用户可以向链中添加自定义规则, 默认规则总在链的最后生效.

Rules 规则

数据包的过滤基于规则.

经过防火墙的数据包(转发)


PREROUTING(mangle/nat) => FORWARD(mangle/filter) => POSTROUTING(mangle/nat)

发给防火墙的流量(给本机)


PREROUTING(mangle/nat)=>                                => POSTROUTING(mangle/nat)
                       |                               |
                       |                               |
                INPUT(mangle/filter)       OUTPUT(mangle/nat/filter)       
                       |                               |
                       |                               |
                       +------>>----- local ----->>----+                       

匹配顺序

raw > mangle > nat > filter

入站数据: PREROUTING => INPUT

出站数据: OUTPUT => POSTROUTING

转发数据: PREROUTING => FORWARD => POSTROUTING

链内从上到下, 找到匹配立即停止, 找不到则使用默认规则.

manipulation

iptables 操作即时生效, 重启服务即失效, 除非输出配置并保存到指定配置文件.

service iptables save

或者

iptables-save > /etc/sysconfig/iptables
命令 命令简写 解释
–append -A chain 将规则添加到链
–check -C chain 检查该规则是否在该链上
–delete -D chain 从链中删除匹配的规则
–delete -D chain rulenum 从链中删除指定规则号位置的规则
–insert -I chain [rulenum] 在链中指定规则号的位置, 插入规则
–replace -R chain rulenum 在链中指定规则号的位置, 替换规则
–list -L [chain [rulenum]] 列出所有规则
–list-rules -S [chain [rulenum]] 打印所有规则
–flush -F [chain] 删除所有规则
–zero -Z [chain [rulenum]] 归零
–new -N chain 新建用户自定义链
–delete-chain -X [chain] 删除用户自定链
–policy -P chain target 修改链的策略
–rename-chain -E old-chain new-chain 修改链名(移除依赖)

注意: 规则号从1开始, 每次操作完规则号刷新

选项 解释
–ipv4 -4 Nothing
–ipv6 -6 Error
[!] –protocol -p proto 指定协议名或协议号
[!] –source -s address[/mask][…] 指定来源
[!] –destination -d address[/mask][…] 指定目的
[!] –in-interface -i input name[+] 入口名 ([+] for wildcard)
–jump -j target 跳转到目标, 执行完return (may load target extension)
–goto -g chain 跳转到目标, 执行完不return
–match -m match 延伸匹配 (may load extension)
–numeric -n 数字格式的输出地址和端口
[!] –out-interface -o output name[+] 网络接口名 ([+] for wildcard)
–table -t table 指定要操作的表, 默认为 filter
–verbose -v 详情模式
–wait -w [seconds] 等待 xtables 锁
–line-numbers 打印规则号
–exact -x expand numbers (display exact values)
[!] –fragment -f match second or further fragments only
–modprobe= try to insert modules using this command
–set-counters PKTS BYTES set the counter during insert/append
[!] –version -V print package version.

实例

iptables -L -nv --line-numbers

查看默认表的配置, 并显示详细信息, 显示数字端口号, 显示规则行号.

iptables -t nat -L POSTROUTING -nv --line-numbers

查看 nat 表中 POSTROUTING 链的规则详情.

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

不写 -t 时, 默认是 filter 表. -A, 追加规则到 filter 表的 INPUT 链的最后.

iptables -D INPUT -p tcp --dport 80 -j ACCEPT

-D, 根据规则删除一条.

iptables -P INPUT DROP

修改INPUT链的默认动作为 DROP .

iptables -F

flush 掉filter表的所有链的所有规则(不会清除其他表的规则).

注意: 它不会修改链的默认动作!

所以如果之前开放了某些端口, 又把默认动作设置为 DROP, -F 之后就只剩了所有都DROP的规则, SSH 都上不去了…

iptables -t filter -F FORWARD

flush 掉filter table中 FORWARD链中的所有规则.


iptables -t filter -I INPUT 4 -p tcp --dport 9999:10001 -j ACCEPT

在 filter table 的 INPUT 链的第4行, 插入规则: 放行 tcp 协议的9999端口到10001的数据流入.

-p 匹配协议类型

  • -p udp

  • -p tcp

  • -p icmp

–sport 匹配来源端口号, –dport 匹配目的端口号. 可以指定单个端口, 也可以指定端口范围. 指定端口前必须先指定协议.

  • -p tcp --sport 1000 == 1000

  • -p tcp --sport 1000: >= 1000

  • -p tcp --sport :10000 <= 10000

iptables -t filter -I INPUT 1 -p tcp -s 117.136.8.114 --dport 10000 -j ACCEPT

向 filter table 的 INPUT 链, 第一行位置插入规则: 放行 TCP协议来源IP是117.136.8.114, 目的端口是10000的数据包.

iptables -t filter -A FORWARD -s 192.168.80.39 -j DROP

阻止源IP是 192.168.80.39 的数据流经本机(禁止转发).

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 180.165.190.1-180.165.190.10

将来源IP网段为 192.168.0.0/24 的数据包, 应用源地址转发到 180.165.190.1-180.165.190.10 这个地址池 .

此规则用于内网NAT转发, 让隐藏在内网后的终端可以访问外网, 将源地址由内网IP转化为公网IP.

注意SNAT应用在 nat 表, 动作作用在 POSTROUTING 链上.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.1:8080

将访问本机eth0网卡的80端口的TCP协议转发到 192.168.0.1:8080 .

此规则用于服务的端口转发, 网卡可选.

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

动态原地址转换: 将来源为 192.168.0.0/24 网段内的数据包, 伪装为从本机 eth0 网卡上的发出的.

好处是不用明确指定出口地址, 解决了家庭IP不固定的问题.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

对相关连接的包和已建立连接的包放行.

-m 代表”延伸匹配”, 可以是:

  • -m state --state NEW,ESTABLISHED

  • -m mac --mac-source aa:aa:00:12:0c:2a

  • -m limit --limit 50/s 匹配每秒50个包以内的

  • -p tcp -m multiport --dports 80,443

state description
NEW 新建的连接的包
ESTABLISHED 已建立连接的后续包
RELATED 相关连接的包, 如FTP控制和数据
INVALID 没识别出来, 或者没有状态, 一般DROP此类的包

注意: 多个state逗号连接, 之间不能留空格.

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A INPUT -p tcp --dport ${SSH_CLIENT##* } -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -P INPUT DROP

Nginx Server 基础配置:

  1. 放行环回口

  2. 放行http, https

  3. 放行ssh

  4. 放行icmp

  5. 放行相关连接, 放行已建立连接

  6. DROP 其他所有

iptables -I OUTPUT 1 -p tcp --sport 10000 -j ACCEPT

OUTPUT 链本来都是放行的, 加规则主要是为了统计流量.

清空所有规则和链

shell script cat > clear-iptables <<EOF *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT EOF iptables-restore < clear-iptables iptables -L -nv --line-numbers

延伸阅读

https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html

/wiki/wiki/tuna.png