3 分钟了解 iptables

Oct 23, 2019 22:30 · 1481 words · 3 minute read Linux Network

Linux 内核提供了这样的接口,使用规则表来过滤进入和出去的流量。iptables 是一个用来创建、维护和检查这些规则表的命令行应用程序。定义多个规则表,每个表包含多个链(关卡)。而链串着一组规则,每条规则指定了如果数据包匹配将执行的操作。当数据包匹配时,它会被给与一个 TARGET,TARGET 可以是另一条链也可以是下面的值:

  • ACCEPT 表示数据包可以通过
  • DROP 表示数据包不能通过
  • RETURN 表示跳过当前链,并从调用它的链中返回到下一个规则。

过滤规则表有三种链:

  • INPUT 这条链被用来控制进入服务器的数据包。你可以根据端口、协议或者源 IP 拦截/放行连接。
  • FORWARD 被用来过滤准入但是即将被递交给别处的数据包
  • OUTPUT 过滤从服务器出去的数据包

第一步 安装 iptables

  1. Ubuntu
$ sudo apt-get update
$ sudo apt-get install iptables
  1. CentOS
$ sudo yum update
$ sudo yum install iptables

iptables 语法规则

格式:iptables [-t table] command

\[chain\]

\[match\]

\[target\]

查看当前 iptables 状态

$ sudo iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     udp  --  virbr0 any     anywhere             anywhere             udp dpt:domain
    0     0 ACCEPT     tcp  --  virbr0 any     anywhere             anywhere             tcp dpt:domain
    0     0 ACCEPT     udp  --  virbr0 any     anywhere             anywhere             udp dpt:bootps
    0     0 ACCEPT     tcp  --  virbr0 any     anywhere             anywhere             tcp dpt:bootps
  7528 9529K ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
    11   646 ACCEPT     all  --  lo     any     anywhere             anywhere
  135 27309 INPUT_direct  all  --  any    any     anywhere             anywhere
  135 27309 INPUT_ZONES_SOURCE  all  --  any    any     anywhere             anywhere
  135 27309 INPUT_ZONES  all  --  any    any     anywhere             anywhere
    0     0 DROP       all  --  any    any     anywhere             anywhere             ctstate INVALID
  134 27245 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  any    virbr0  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  virbr0 any     192.168.122.0/24     anywhere
    0     0 ACCEPT     all  --  virbr0 virbr0  anywhere             anywhere
    0     0 REJECT     all  --  any    virbr0  anywhere             anywhere             reject-with icmp-port-unreachable
    0     0 REJECT     all  --  virbr0 any     anywhere             anywhere             reject-with icmp-port-unreachable
    0     0 ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere
    0     0 FORWARD_direct  all  --  any    any     anywhere             anywhere
    0     0 FORWARD_IN_ZONES_SOURCE  all  --  any    any     anywhere             anywhere
    0     0 FORWARD_IN_ZONES  all  --  any    any     anywhere             anywhere
    0     0 FORWARD_OUT_ZONES_SOURCE  all  --  any    any     anywhere             anywhere
    0     0 FORWARD_OUT_ZONES  all  --  any    any     anywhere             anywhere
    0     0 DROP       all  --  any    any     anywhere             anywhere             ctstate INVALID
    0     0 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 3370 packets, 282K bytes)
  pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     udp  --  any    virbr0  anywhere             anywhere             udp dpt:bootpc
    22  1600 ACCEPT     all  --  any    lo      anywhere             anywhere
  3370  282K OUTPUT_direct  all  --  any    any     anywhere             anywhere
  • -L 列出所有规则
  • -v 查看详情

第二步 定义链规则

定义一条规则表示向列表追加一条记录。

sudo iptables -A  -i <interface> -p <protocol (tcp/udp) > -s <source> --dport <port no.>  -j <target>

-A 表示追加,interface 是想要过滤流量的网卡,protocol 指想要过滤的数据包协议。还可以指定端口。

1. 准入来自 localhost 的流量

$ sudo iptables -A INPUT -i lo -j ACCEPT

-A 选项用来向 INPUT 链追加规则,接受来自 lo 网卡的所有连接。lo 表示回环网卡,用来本地通讯。

2. 接受 HTTP、SSH、SSL 标准端口的连接

$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
  • -p 协议
  • dport 目标端口(destination port)

3. 基于源 IP 过滤

如果想要基于源 IP 或地址段准入或拦截数据包,通过 -s 选项指定。

接受来自 192.168.1.3 的数据包:

$ sudo iptables -A INPUT -s 192.168.1.3 -j ACCEPT

类似的,利用 DROP 选项来丢弃某个源 IP 的数据包:

$ sudo iptables -A INPUT -s 192.168.1.3 -j DROP

如果要丢弃来自某个 IP 段的数据包,带上 -m 使用 Iprange 模块并 –src-range 指定 IP 段

$ sudo iptables -A INPUT -m iprange --src-range 192.168.1.100-192.168.1.200 -j DROP

4. 丢弃所有其他包

在定义好自己的规则后丢弃所有除此之前的包,可以阻止非法访问。

$ sudo iptables -A INPUT -j DROP

5. 删除规则

全删并恢复到初始状态,使用 flush 命令。

$ sudo iptables -F

上面的命令删掉所有规则,要是只想删特定的规则,通过 -D 选项带上行号。首先列出所有规则

$ sudo iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
2    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
3    ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
4    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps
5    ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
6    ACCEPT     all  --  anywhere             anywhere
7    INPUT_direct  all  --  anywhere             anywhere
8    INPUT_ZONES_SOURCE  all  --  anywhere             anywhere
9    INPUT_ZONES  all  --  anywhere             anywhere
10   DROP       all  --  anywhere             anywhere             ctstate INVALID
11   REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited
12   ACCEPT     all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
2    ACCEPT     all  --  192.168.122.0/24     anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
5    REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
6    ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
7    ACCEPT     all  --  anywhere             anywhere
8    FORWARD_direct  all  --  anywhere             anywhere
9    FORWARD_IN_ZONES_SOURCE  all  --  anywhere             anywhere
10   FORWARD_IN_ZONES  all  --  anywhere             anywhere
11   FORWARD_OUT_ZONES_SOURCE  all  --  anywhere             anywhere
12   FORWARD_OUT_ZONES  all  --  anywhere             anywhere
13   DROP       all  --  anywhere             anywhere             ctstate INVALID
14   REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc
2    ACCEPT     all  --  anywhere             anywhere
3    OUTPUT_direct  all  --  anywhere             anywhere

指定行号删除规则

sudo iptables -D INPUT 3

第三步 存档

以上追加的规则都只暂存在内存中,重启后还得重新定义。使用下面的命令来持久化:

sudo iptables-save