iptables Basic
网络七层协议:
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
iptable 是一个配置 Linux 内核防火墙的命令行工具, 工作在网络层和传输层.
ip packets
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 基础配置:
-
放行环回口
-
放行http, https
-
放行ssh
-
放行icmp
-
放行相关连接, 放行已建立连接
-
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