From c42821590deab2c527e3f037c1a889eeaa5d675e Mon Sep 17 00:00:00 2001 From: wizardforcel <562826179@qq.com> Date: Sun, 27 Aug 2017 17:39:33 +0800 Subject: [PATCH] ex26 --- ex26.md | 622 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 622 insertions(+) create mode 100644 ex26.md diff --git a/ex26.md b/ex26.md new file mode 100644 index 0000000..b2324bd --- /dev/null +++ b/ex26.md @@ -0,0 +1,622 @@ +# 练习 26:网络:封包过滤配置,`iptables` + +> 原文:[Exercise 26. Networking: packet filter configuration, iptables](https://archive.fo/D3zbt) + +> 译者:[飞龙](https://github.com/wizardforcel) + +> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) + +> 自豪地采用[谷歌翻译](https://translate.google.cn/) + +让我以引用维基百科上的[`iptables`](http://en.wikipedia.org/wiki/Iptables)来开始: + +> `iptables`是一个用户态应用程序,允许系统管理员配置由 Linux 内核防火墙(实现为不同的 Netfilter 模块)提供的表,以及它存储的链和规则。不同的内核模块和程序目前用于不同的协议;`iptables`适用于 IPv4,`ip6tables`适用于 IPv6,`arptables`适用于 ARP,`ebtables`适用于以太网帧。 + +为了使用它,你必须了解以下概念: + ++ [`LINKTYPE_LINUX_SLL`](http://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html) - `tcpdump`伪链路层协议。 ++ [以太网帧头部](http://en.wikipedia.org/wiki/Ethernet_frame%23Header) - 以太网链路上的数据包称为以太网帧。帧以前缀和起始分隔符开始。接下来,每个以太网帧都有一个头部,其特征为源和目标 MAC 地址。帧的中间部分是载荷数据,包含帧中携带的其他协议(例如,互联网协议)的任何头部。该帧以 32 位循环冗余校验(CRC)结束,用于检测传输中数据的任何损坏。 ++ [IPv4 头部](http://en.wikipedia.org/wiki/IPv4_header%23IPv4%20header) - IP 封包包括头部部分和数据部分。IPv4 封包头部由 14 个字段组成,其中 13 个是必需的。第十四个字段是可选的,适当地命名为:`options`。 ++ [TCP 段结构](http://en.wikipedia.org/wiki/Transmission_Control_Protocol%23TCP_segment_structure) - 传输控制协议接受来自数据流的数据,将其分割成块,并添加 TCP 头部来创建 TCP 段。TCP 段然后被封装成互联网协议(IP)数据报。TCP 段是“信息封包,TCP 用于与对方交换数据”。 + +我会提醒你,让你获取一些指南: + ++ 阅读相应的维基百科文章,直到你至少表面上理解了它(但是深入研究当然更好)。 + + 展开站点左侧的 IP 地址树节点,并通过它来以你的方式实现。 + + 展开 TCP 树节点并执行相同操作。 ++ 阅读 [Linux 网络概念介绍](http://www.iptables.org/documentation/HOWTO//networking-concepts-HOWTO-3.html%23ss3.1)。这本指南很好,因为它甚至承认 互联网是为情欲而生的。 + +比起 [Peter Harrison 的优秀指南](http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables),我没办法更好地描述`iptables`了。如果你从未使用过它,请先阅读本指南。 + +但是,我将会将理论付诸实践,并 在数据交换的一个非常简单的情况下,逐步展示出`iptalbes`内部的内容。第一件事情是主要概念: + +`iptables` - 用于在 Linux 内核中设置,维护和检查 IPv4 包过滤规则表的程序。可以定义几个不同的表。每个表包含多个内置链,并且还可以包含用户定义的链。 +`ip6tables` - 用于 IPv6 的相同东西。 +链 - 可以匹配一组数据包的规则列表。每个规则规定了,如何处理匹配的数据包。这被称为目标,它可能是相同表中的,用户定义的链的跳转。 +目标 - 防火墙规则为封包和目标指定了判别标准。如果数据包不匹配,就会检查的链中的下一个规则;如果它匹配,则下一个规则由目标的值指定,该值可以是用户定义链的名称或特殊值之一: + +`ACCEPT` - 让包通过。 +`DROP` - 将数据包丢弃。 +`QUEUE` - 将数据包传递给用户空间。 +`RETURN` - 停止遍历此链,并在上一个(调用)链中的下一个规则处恢复。如果达到了内置链的结尾,或者内置链中的一个带有`RETURN`的规则匹配它,链策略指定的目标决定了数据包的命运。 + +现在让我们看看有什么默认的表和内置的链: + +| 表名 | 内置链 | 描述 | +| --- | --- | --- | +| `raw` | | 该表主要用于配置与`NOTRACK`目标结合的连接跟踪的免除。它以较高的优先级在`netfilter`钩子中注册,因此在`ip_conntrack`或任何其他 IP 表之前调用。 | +| | PREROUTING | 用于经过任何网络接口到达的封包。 | +| | OUTPUT | 用于本地进程生成的封包。 | +| `mangle` | | 该表用于专门的数据包更改。 | +| | PREROUTING | 用于在路由之前更改传入的数据包。 | +| | OUTPUT | 用于在路由之前更改本地生成的数据包。 | +| | INPUT | 用于进入本机的数据包。 | +| | FORWARD | 用于经过本机的数据包。 | +| | POSTROUTING | 用于当数据包打算出去时,更改它们。 | +| `nat` | | 当遇到创建新连接的数据包时,将查看此表。 | +| | PREROUTING | 用于一旦数据包进来,就更改它们。 | +| | OUTPUT | 用于在路由之前更改本地生成的数据包。 | +| | POSTROUTING | 用于当数据包打算出去时,更改它们。 | +| `filter` | | 这是默认表(如果没有传入`-t`选项)。 | +| | INPUT | 用于发往本地套接字的数据包。 | +| | FORWARD | 用于经过本机的数据包。 | +| | OUTPUT | 用于本地生成的数据包。 | + +好的,我们准备看看它实际如何运作。我会从我的家用计算机,使用 TCP 协议和`netcat`向`vm1`发送一个字符串`Hello world!`,`netcat`就像`cat`一样,但是通过网络。起步: + +1\. 我将另一个端口,80,转发到我运行 Linux 的家用 PC,所以我能象这样连接它: + +``` +(My home PC) --> vm1:80 +``` + +2\. 我将这个规则添加到`iptables`,来记录`iptables`内部的数据包发生了什么。 + +``` +sudo iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 -j TRACE +sudo iptables -t raw -A INPUT -p tcp -m tcp --sport 80 -j TRACE +``` + +这是我的`vm1`上的`iptables`规则集: + +``` +root@vm1:/home/user1# for i in raw mangle nat filter ; do echo -e "\n-----" TABLE: $i '-----' ; iptables -t $i -L ; done + +----- TABLE: raw ----- +Chain PREROUTING (policy ACCEPT) target prot opt source destination + TRACE tcp -- anywhere anywhere tcp dpt:www +Chain OUTPUT (policy ACCEPT) target prot opt source destination + TRACE tcp -- anywhere anywhere tcp spt:www +----- TABLE: mangle ----- +Chain PREROUTING (policy ACCEPT) target prot opt source destination +Chain INPUT (policy ACCEPT) target prot opt source destination +Chain FORWARD (policy ACCEPT) target prot opt source destination +Chain OUTPUT (policy ACCEPT) target prot opt source destination +Chain POSTROUTING (policy ACCEPT) target prot opt source destination + +----- TABLE: nat ----- +Chain PREROUTING (policy ACCEPT) target prot opt source destination +Chain POSTROUTING (policy ACCEPT) target prot opt source destination +Chain OUTPUT (policy ACCEPT) target prot opt source destination + +----- TABLE: filter ----- +Chain INPUT (policy ACCEPT) target prot opt source destination +Chain FORWARD (policy ACCEPT) target prot opt source destination +Chain OUTPUT (policy ACCEPT) target prot opt source destination +``` + +你可以看到,没有其它规则了。另一种查看`iptables`规则的方式,是使用`iptables-save`工具: + +``` +root@vm1:/home/user1# iptables-save +# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012 +#(1) +*mangle +#(2) (3) (4) (5) +:PREROUTING ACCEPT [15662:802240] +:INPUT ACCEPT [15662:802240] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [12756:3671974] +:POSTROUTING ACCEPT [12756:3671974] +COMMIT +# Completed on Fri Jul 13 08:09:04 2012 +# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012 +*nat +:PREROUTING ACCEPT [18:792] +:POSTROUTING ACCEPT [42:2660] +:OUTPUT ACCEPT [42:2660] +COMMIT +# Completed on Fri Jul 13 08:09:04 2012 +# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012 +*raw +:PREROUTING ACCEPT [15854:814892] +:OUTPUT ACCEPT [12855:3682054] +-A PREROUTING -p tcp -m tcp --dport 80 -j TRACE +-A OUTPUT -p tcp -m tcp --sport 80 -j TRACE +COMMIT +# Completed on Fri Jul 13 08:09:04 2012 +# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012 +*filter +:INPUT ACCEPT [35107:2459066] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [26433:10670628] +COMMIT +# Completed on Fri Jul 13 08:09:04 2012 +``` + +` iptables-save`字段如下所示: + +| 字段 | 描述 | +| --- | --- | +| (1) | 表名称 | +| (2) | 链名称 | +| (3) | 链策略 | +| (4) | 封包计数 | +| (5) | 字节计数 | + +3\. 我启动`nc`来监听端口 80: + +``` +nc -l 80 +``` + +4\. 我向`vm1`发送字符串: + +``` +echo 'Hello, world!' | nc localhost 80 +``` + +下面的是我的家用 PC 和`vm1`之间的交换: + +``` +08:00:05.655339 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [S], seq 4164179969, win 65535, options [mss 1460], length 0 +08:00:05.655653 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [S.], seq 4149908960, ack 4164179970, win 5840, options [mss 1460], length 0 +08:00:05.655773 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 1, win 65535, length 0 +08:00:05.655868 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [P.], seq 1:15, ack 1, win 65535, length 14 +08:00:05.655978 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [.], ack 15, win 5840, length 0 +08:00:10.037978 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [F.], seq 15, ack 1, win 65535, length 0 +08:00:10.038287 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [F.], seq 1, ack 16, win 5840, length 0 +08:00:10.038993 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 2, win 65535, length 0 +``` + +让我们回忆,数据如何交换。为此,让我们拆开第一个封包。 + +``` +# (13) (15) (14) (16) (20) (17) (25) +08:00:05.655339 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [S], seq 4164179969, win 65535, +# (8) (9) +options [mss 1460], length 0 +# (1) (2) (3) (4) (5) +# ____ ____ ____ ___________________ ____ + 0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5..... +# (6) (7) (8) (9)(10,11)(12) (13) +# ____ ____ ____ ____ /\/\ ____ _________ + 0x0010: 4500 002c a006 0000 4006 c2b5 0a00 0202 E..,....@....... +# (14) (15) (16) (17) (18) +# _________ ____ ____ _________ __________ + 0x0020: 0a00 020f c94e 0050 f834 5801 0000 0000 .....N.P.4X..... +# (19,20)(21) (22) (23) (24) (25) +# /\/\ ____ ____ ____ ____ ____ + 0x0030: 6002 ffff 6641 0000 0204 05b4 0000 `...fA........ +``` + +我们封包中的字段和描述: + +| DOD 模型层 | OSI 模型层 | 位于 | 字段 | 描述 | +| --- | --- | --- | --- | --- | --- | +| 链路 | 物理/数据链路 | `LINUX_SLL` 头部 | (1) | 封包类型 | +| | | | (2) | `ARPHRD_` 类型 | +| | | | (3) | 链路层 (MAC) 地址长度 | +| | | | (4) | 链路层 (MAC) 源地址 | +| | | | (5) | 协议类型 (IP) | +| 互联网 | 网络 | IPv4 头部 | (6) | 版本,互联网头部长度,差分服务代码点,显式拥塞通知. | +| | | | (7) | 总长度 | +| | | | (8) | 身份,主要用于源 IP 数据报的段的唯一性鉴定 | +| | | | (9) | 标志,段的偏移 | +| | | | (10) | 生存时间 (TTL) | +| | | | (11) | 协议编号 | +| | | | (12) | 头部校验和 | +| | | | (13) | 源 IP 地址 | +| | | | (14) | 目标 IP 地址 | +| 传输 | 传输 | TCP 头部 | (15) | 源 TCP 端口 | +| | | | (16) | 目标 TCP 端口 | +| | | | (17) | TCP 初始序列号 | +| | | | (18) | ACK 编号字段 (空的,由于它是第一个封包) | +| | | | (19) | | +| | | | (20) | SYN TCP 标志 | +| | | | (21) | TCP 窗口大小 | +| | | | (22) | TCP 校验和 | +| | | | (23) | 紧急指针 | +| | | | (24) | 可选字段的开始 | +| | | | (25) | TCP 最大段大小 (最大传输单元 - 40 字节) | + +让我们看看`iptables`中,这个封包发生了什么: + +``` +#(1)(2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) +raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 +# (13) (14) (15) (16) (17) (18) (19) (20) + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 +# (21) (22) (23) (24) (25)(26) (27) + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +nat:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +mangle:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +filter:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +``` + +`iptables`日志的字段的描述: + +| 字段 | 描述 | +| --- | --- | +| (1) | 表名称 | +| (2) | 链名称 | +| (3) | 类型 (用于内建链的策略) | +| (4) | 规则编号 | +| (5) | 输入接口 | +| (6) | 输出接口 (空的,因为封包的目标是 vm1 自身) | +| (7) | MAC 地址 | +| (8) | 目标 (vm1) MAC | +| (9) | 源 MAC | +| (10) | 协议类型:IP | +| (11) | 源 IP 地址 | +| (12) | 目标 IP 地址 | +| (13) | IP 封包长度,以字节为单位 (不包括链路层头部) | +| (14) | IP 服务类型 | +| (15) | IP 优先级 | +| (16) | IP 生存时间 | +| (17) | IP 封包 ID | +| (18) | 协议类型:TCP | +| (19) | TCP 源端口 | +| (20) | TCP 目标端口 | +| (21) | TCP 序列号 | +| (22) | TCP 应答编号 | +| (23) | TCP 窗口大小 | +| (24) | TCP 保留位 | +| (25) | TCP SYN 标志已设置 | +| (25) | TCP 紧急指针未设置 | +| (25) | TCP 选项 | + +现在我将使用`tcpdump`输出和`iptables`日志,并排(更多的是逐段)向你显示这个交换。你的任务是逐行浏览这个交换,了解会发生什么。我建议你打印这个交换,并使用笔和纸进行处理它,你可以从[特殊页面](http://nixsrv.com/llthw/ex26/log)打印它。你需要回答的问题是: + ++ 每个字段的意思是什么?拿着铅笔,将字段从`tcpdump`的踪迹连接到原始数据包的十六进制数据,再到`iptables`日志。 ++ 数据包以什么顺序进行处理?首先是哪个表,最后是哪个,为什么? ++ 为什么只有第一个数据包通过`nat`表进行处理? + +这是输出,看看: + +``` +08:00:05.655339 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [S], seq 4164179969, win 65535, options [mss 1460], length 0 + 0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5..... + 0x0010: 4500 002c a006 0000 4006 c2b5 0a00 0202 E..,....@....... + 0x0020: 0a00 020f c94e 0050 f834 5801 0000 0000 .....N.P.4X..... + 0x0030: 6002 ffff 6641 0000 0204 05b4 0000 `...fA........ +` +raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +nat:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +mangle:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) +filter:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B4) + +08:00:05.655653 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [S.], seq 4149908960, ack 4164179970, win 5840, options [mss 1460], length 0 + 0x0000: 0004 0001 0006 0800 27d4 4568 0000 0800 ........'.Eh.... + 0x0010: 4500 002c 0000 4000 4006 22bc 0a00 020f E..,..@.@."..... + 0x0020: 0a00 0202 0050 c94e f75a 95e0 f834 5802 .....P.N.Z...4X. + 0x0030: 6012 16d0 c224 0000 0204 05b4 `....$...... +' +raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN URGP=0 OPT (020405B4) UID=0 GID=0 +mangle:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN URGP=0 OPT (020405B4) UID=0 GID=0 +filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN URGP=0 OPT (020405B4) UID=0 GID=0 +mangle:POSTROUTING:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN URGP=0 OPT (020405B4) UID=0 GID=0 + +08:00:05.655773 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 1, win 65535, length 0 + 0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5..... + 0x0010: 4500 0028 a007 0000 4006 c2b8 0a00 0202 E..(....@....... + 0x0020: 0a00 020f c94e 0050 f834 5802 f75a 95e1 .....N.P.4X..Z.. + 0x0030: 5010 ffff f0b1 0000 0000 0000 0000 P............. + +raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0 +mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0 +mangle:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0 +filter:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0 + +08:00:05.655868 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [P.], seq 1:15, ack 1, win 65535, length 14 + 0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5..... + 0x0010: 4500 0036 a008 0000 4006 c2a9 0a00 0202 E..6....@....... + 0x0020: 0a00 020f c94e 0050 f834 5802 f75a 95e1 .....N.P.4X..Z.. + 0x0030: 5018 ffff af45 0000 4865 6c6c 6f2c 2077 P....E..Hello,.w + 0x0040: 6f72 6c64 210a orld!. + +raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH URGP=0 +mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH URGP=0 +mangle:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH URGP=0 +filter:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH URGP=0 + +08:00:05.655978 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [.], ack 15, win 5840, length 0 + 0x0000: 0004 0001 0006 0800 27d4 4568 0000 0800 ........'.Eh.... + 0x0010: 4500 0028 377c 4000 4006 eb43 0a00 020f E..(7|@.@..C.... + 0x0020: 0a00 0202 0050 c94e f75a 95e1 f834 5810 .....P.N.Z...4X. + 0x0030: 5010 16d0 d9d3 0000 P....... +' +raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0 +mangle:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0 +filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0 +mangle:POSTROUTING:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0 + +08:00:10.037978 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [F.], seq 15, ack 1, win 65535, length 0 + 0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5..... + 0x0010: 4500 0028 a00e 0000 4006 c2b1 0a00 0202 E..(....@....... + 0x0020: 0a00 020f c94e 0050 f834 5810 f75a 95e1 .....N.P.4X..Z.. + 0x0030: 5011 ffff f0a2 0000 0000 0000 0000 P............. + +raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN URGP=0 +mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN URGP=0 +mangle:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN URGP=0 +filter:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN URGP=0 + +08:00:10.038287 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [F.], seq 1, ack 16, win 5840, length 0 + 0x0000: 0004 0001 0006 0800 27d4 4568 0000 0800 ........'.Eh.... + 0x0010: 4500 0028 377d 4000 4006 eb42 0a00 020f E..(7}@.@..B.... + 0x0020: 0a00 0202 0050 c94e f75a 95e1 f834 5811 .....P.N.Z...4X. + 0x0030: 5011 16d0 d9d1 0000 P....... +' +raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN URGP=0 UID=0 GID=0 +mangle:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN URGP=0 UID=0 GID=0 +filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN URGP=0 UID=0 GID=0 +mangle:POSTROUTING:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80 DPT=51534 + SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN URGP=0 UID=0 GID=0 + +08:00:10.038993 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 2, win 65535, length 0 + 0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5..... + 0x0010: 4500 0028 a00f 0000 4006 c2b0 0a00 0202 E..(....@....... + 0x0020: 0a00 020f c94e 0050 f834 5811 f75a 95e2 .....N.P.4X..Z.. + 0x0030: 5010 ffff f0a1 0000 0000 0000 0000 P............. + +raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0 +mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0 +mangle:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0 +filter:INPUT:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00 SRC=10.0.2.2 DST=10.0.2.15 + LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534 DPT=80 + SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0 +``` + +## 这样做 + +``` + 1: sudo iptables-save + 2: sudo iptables -t filter -A INPUT -i lo -j ACCEPT + 3: sudo iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT + 4: sudo iptables -t filter -P INPUT DROP + 5: sudo iptables -nt filter -L --line-numbers + 6: ping -c 2 -W 1 10.0.2.2 + 7: sudo iptables -t filter -A INPUT --match state --state ESTABLISHED -j ACCEPT + 8: sudo iptables -nt filter -L --line-numbers + 9: ping -c 2 -W 1 10.0.2.2 +10: sudo modprobe ipt_LOG +11: sudo iptables -nt raw -L --line-numbers +12: sudo iptables -t raw -A PREROUTING -p udp -m udp --dport 1024 -j TRACE +13: sudo iptables -t raw -A OUTPUT -p udp -m udp --sport 1024 -j TRACE +14: sudo tail -n0 -f /var/log/kern.log | cut -c52-300 & +15: nc -ulp 1024 & +16: echo 'Hello there!' | nc -u localhost 1000 +17: +18: fg +19: +20: fg +21: +``` + +## 你会看到什么 + +``` +user1@vm1:~$ sudo iptables-save +# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012 +*mangle +:PREROUTING ACCEPT [45783:3411367] +:INPUT ACCEPT [45783:3411367] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [30409:9552110] +:POSTROUTING ACCEPT [30331:9543294] +COMMIT +# Completed on Mon Jul 16 09:01:32 2012 +# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012 +*nat +:PREROUTING ACCEPT [24:1056] +:POSTROUTING ACCEPT [755:41247] +:OUTPUT ACCEPT [817:45207] +COMMIT +# Completed on Mon Jul 16 09:01:32 2012 +# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012 +*raw +:PREROUTING ACCEPT [3171:197900] +:OUTPUT ACCEPT [1991:1294054] +-A PREROUTING -p udp -m udp --dport 80 -j TRACE +-A OUTPUT -p udp -m udp --sport 80 -j TRACE +COMMIT +# Completed on Mon Jul 16 09:01:32 2012 +# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012 +*filter +:INPUT ACCEPT [54:3564] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [28:2540] +COMMIT +# Completed on Mon Jul 16 09:01:32 2012 +user1@vm1:~$ sudo iptables -t filter -A INPUT -i lo -j ACCEPT +user1@vm1:~$ sudo iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT +user1@vm1:~$ sudo iptables -t filter -P INPUT DROP +user1@vm1:~$ sudo iptables -nt filter -L --line-numbers +Chain INPUT (policy DROP) +num target prot opt source destination +1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 +2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 + +Chain FORWARD (policy ACCEPT) +num target prot opt source destination + +Chain OUTPUT (policy ACCEPT) +num target prot opt source destination + +user1@vm1:~$ ping -c 2 -W 1 10.0.2.2 +PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data. + +--- 10.0.2.2 ping statistics --- +2 packets transmitted, 0 received, 100% packet loss, time 1008ms + +user1@vm1:~$ sudo iptables -t filter -A INPUT --match state --state ESTABLISHED -j ACCEPT +user1@vm1:~$ sudo iptables -nt filter -L --line-numbers +Chain INPUT (policy DROP) +num target prot opt source destination +1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 +2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 +3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED + +Chain FORWARD (policy ACCEPT) +num target prot opt source destination + +Chain OUTPUT (policy ACCEPT) +num target prot opt source destination + +user1@vm1:~$ ping -c 2 -W 1 10.0.2.2 +PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data. +64 bytes from 10.0.2.2: icmp_req=1 ttl=63 time=0.385 ms +64 bytes from 10.0.2.2: icmp_req=2 ttl=63 time=0.142 ms + +--- 10.0.2.2 ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 999ms +rtt min/avg/max/mdev = 0.142/0.263/0.385/0.122 ms +user1@vm1:~$ sudo iptables -nt raw -L --line-numbers +Chain PREROUTING (policy ACCEPT) +num target prot opt source destination + +Chain OUTPUT (policy ACCEPT) +num target prot opt source destination +user1@vm1:~$ sudo iptables -t raw -A PREROUTING -p udp -m udp --dport 1024 -j TRACE +user1@vm1:~$ sudo iptables -t raw -A OUTPUT -p udp -m udp --sport 1024 -j TRACE +user1@vm1:~$ sudo iptables -nt raw -L --line-numbers +Chain PREROUTING (policy ACCEPT) +num target prot opt source destination +1 TRACE udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1024 + +Chain OUTPUT (policy ACCEPT) +num target prot opt source destination +1 TRACE udp -- 0.0.0.0/0 0.0.0.0/0 udp spt:1024 +user1@vm1:~$ sudo tail -n0 -f /var/log/kern.log | cut -c52-300 & +[1] 10249 +user1@vm1:~$ nc -ulp 1024 & +[2] 10251 +user1@vm1:~$ echo 'Hello there!' | nc -u localhost 1024 +Hello there! +raw:PREROUTING:policy:2 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF PROTO=UDP SPT=50407 DPT=1024 LEN=21 +mangle:PREROUTING:policy:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF PROTO=UDP SPT=50407 DPT=1024 LEN=21 +mangle:INPUT:policy:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF PROTO=UDP SPT=50407 DPT=1024 LEN=21 +filter:INPUT:rule:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF PROTO=UDP SPT=50407 DPT=1024 LEN=21 + +^C +[2]+ Stopped nc -ulp 1024 +user1@vm1:~$ fg +nc -ulp 1024 +^C +user1@vm1:~$ fg +sudo tail -n0 -f /var/log/kern.log | cut -c52-300 +^C +user1@vm1:~$ +``` + +## 解释 + +1. 列出所有表中的所有`iptables`规则。你看不到任何东西。 +1. 允许`lo`([环回](http://en.wikipedia.org/wiki/Localhost))接口上的所有传入流量。 +1. 允许 TCP 端口 22 上的所有传入流量,这是`ssh`。 +1. 将默认`INPUT`策略更改为`DROP`,禁止所有传入连接,除了 TCP 端口 22。如果在此丢失`vm1`的连接,则表示你做错了,在 VirtualBox 中重新启动并重试。 +1. 列出当前的过滤器规则。注意:你可以按号码删除规则,如下所示:`sudo iptables -t filter -D INPUT 2`。请注意策略与规则完全不一样。 +1. 尝试`ping`你的默认网关,失败了。为什么是这样,即使允许传出连接(`Chain OUTPUT (policy ACCEPT)`)?传出的数据包被发送到网关,但是网关的回复不能进入。 +1. 添加一条规则,告诉`iptables`允许属于已建立连接的所有数据包,例如来自`vm1`的所有连接。 +1. 列出当前的过滤器规则。你可以看到我们的新规则。 +1. `ping` `vm1`的默认网关,这次成功了。 +1. 加载 Linux 内核模块,它允许使用包过滤日志功能。 +1. 添加规则,来记录所有发往`vm1`任何接口的 UDP 端口 1024 的传入数据包。 +1. 添加规则,来记录所有来自`vm1`任何接口的 UDP 端口 1024 的传出数据包。 +1. 列出`raw`表规则。 +1. 在后台启动`tail`,将打印写入`/var/log/kern.log`的所有新行。`cut`会在开头删除不必要的日志条目前缀。请注意后台进程如何写入终端。 +1. 以服务器模式启动`nc`,在`vm1`的所有接口上监听 UDP 端口 1024 。 +1. 以客户端模式启动`nc`,将字符串`Hello there!`发送到我们的服务器模式`nc`。`tail`打印出`kern.log`中的所有新行,你可以看到在 Linux 内核封包过滤器中,我们的单个 UDP 数据包从一个表到了另一个表。没有回复,所以只有一个数据包被发送和处理。 +1. 杀死客户端模式`nc`。 +1. 将服务器模式`nc`带到前台。 +1. 杀死服务器模式`nc`。 +1. 将`sudo tail -n0 -f /var/log/kern.log | cut -c52-300 &`带到前台。 +1. 杀死它。 + +## 附加题 + +这个练习本身已经很大了。只需要打印出日志,并使用铅笔浏览它,直到理解了每一行的每个字段都发生了什么。如果你卡住了,去问别人: