iptables使用
结构
iptables监控reset的连接信息
如果连接被reset需要记录下reset包是哪边发出来的,并记录reset连接的四元组信息
iptables规则
1 | Generated by iptables-save v1.4.21 on Wed Apr 1 11:39:31 2020 |
将如上配置保存在 plantegg_filter.conf中,设置开机启动:
1 | //注意,tee 命令的 "-a" 选项的作用等同于 ">>" 命令,如果去除该选项,那么 tee 命令的作用就等同于 ">" 命令。 |
单独记录到日志文件中
默认情况下 iptables 日志记录在 dmesg中不方便查询,可以修改rsyslog.d规则将日志存到单独的文件中:
1 | # cat /etc/rsyslog.d/plantegg_filter_log.conf |
将 [plantegg] 开头的日志存到对应的文件
将如上配置放到: /etc/rsyslog.d/ 目录下, 重启 rsyslog 就生效了
1 | sudo cp /home/admin/plantegg-worker/install/plantegg_filter_log.conf /etc/rsyslog.d/plantegg_filter_log.conf |
防止日志打满磁盘
配置 logrotate, 保留最近30天的
1 | cat /etc/logrotate.d/drds |
logrotate操作的日志需要权限正常,并且上级目录权限也要对,解决方案参考:https://chasemp.github.io/2013/07/24/su-directive-logrotate/ 报错信息:
1 | rotating pattern: /var/log/myapp/*.log weekly (4 rotations) |
最终效果
1 | $tail -10 logs/drds-tcp.log |
tracing_point 监控
对于 4.19内核的kernel,可以通过tracing point来监控重传以及reset包
1 | grep tcp:tcp /sys/kernel/debug/tracing/available_events |
iptables 打通网络
1 | //本机到 172.16.0.102 不通,但是和 47.100.29.16能通(阿里云弹性ip) |
ipset 组合iptables使用
ipset是iptables的扩展,它允许创建匹配地址集合的规则。普通的iptables链只能单IP匹配, 进行规则匹配时,是从规则列表中从头到尾一条一条进行匹配,这像是在链表中搜索指定节点费力。ipset 提供了把这个 O(n) 的操作变成 O(1) 的方法:就是把要处理的 IP 放进一个集合,对这个集合设置一条 iptables 规则。像 iptable 一样,IP sets 是 Linux 内核提供,ipset 这个命令是对它进行操作的一个工具。
另外ipset的一个优势是集合可以动态的修改,即使ipset的iptables规则目前已经启动,新加的入ipset的ip也生效。
ipset可以以set的形式管理大批IP以及IP段,set可以有多个,通过 ipset修改set后可以立即生效。不用再次修改iptables规则。k8s也会用ipset来管理ip集合
ipset is an extension to iptables that allows you to create firewall rules that match entire “sets” of addresses at once. Unlike normal iptables chains, which are stored and traversed linearly, IP sets are stored in indexed data structures, making lookups very efficient, even when dealing with large sets.
接下来用一个ip+port的白名单案例来展示他们的用法,ipset负责白名单,iptables负责拦截规则:
1 | 240 [2021-11-30 19:57:10] ipset list drds_whitelist_ips |grep "^127.0." |
经过如上操作后,可以得到iptables规则如下
1 | iptables -L -n --line-numbers |
从以上Chain drds_whitelist中删除第三条规则
1 | iptables -D drds_whitelist 3 |
block ip 案例
模拟断网测试的时候可以通过iptables固定屏蔽某几个ip来实现。
创建ipset,存放好需要block的ip列表
1 | ipset create block_ips hash:net timeout 259200 |
添加iptables过滤规则,规则中不需要列出一堆ip,只需要指定上一步创建好的ipset,以后屏蔽、放开某些ip不需要修改iptables规则了,只需要往ipset添加、删除目标ip
1 | iptables -N drds_rule //创建新规则链 |
iptables记录日志
记录每个新连接创建的时间,日志在/var/log/kern或者/var/log/dmesg中:
1 | iptables -I INPUT -m state --state NEW -j LOG --log-prefix "Connection In: " |
在宿主机上执行,然后在dmesg中能看到包的传递流程。只有raw有TRACE能力,nat、filter、mangle都没有。这个方式对性能影响非常大,时延高(增加1秒左右)
1 | iptables -t raw -A OUTPUT -p icmp -j TRACE |
端口转发
iptables
1 | iptables -t nat -A PREROUTING -d 10.176.7.5 -p tcp --dport 8507 -j DNAT --to-destination 10.176.7.6:3307 |
iptables 工作图如下,进来的包走1、2;出去的包走4、5;转发的包走1、3、5
ncat端口转发
1 | 监听本机 9876 端口,将数据转发到 192.168.172.131的 80 端口 |
scat
1 | 在本地监听12345端口,并将请求转发至192.168.172.131的22端口。 |
iptables 屏蔽IP
一分钟内新建22端口连接超过 4 次,不分密码对错, 直接 block.
1 | iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH --rsource |
Per-IP rate limiting with iptables
iptables 扔掉指定端口的 ack 包
1 | //扔掉发给 8000 端口的 ack 包,但是不要扔 rst包 |
将 ack delay 1 秒中,故意制造乱序:
1 | tc qdisc add dev eth0 root handle 1: prio |
执行效果(在 172.26.137.120.17922 端抓包):
1 | 15:31:57.815944 IP 172.26.137.120.17922 > 172.26.137.130.8000: Flags [S], seq 2408440162, win 29200, options [mss 1460,sackOK,TS val 1952321086 ecr 0,nop,wscale 7], length 0 |
iptables 常用参数
-I : Insert rule at given rule number
-t : Specifies the packet matching table such as nat, filter, security, mangle, and raw.
-L : List info for specific chain (such as INPUT/FORWARD/OUTPUT) of given packet matching table
–line-numbers : See firewall rules with line numbers
-n : Do not resolve names using dns i.e. only show numeric output for IP address and port numbers.
-v : Verbose output. This option makes the list command show the interface name, the rule options (if any), and the TOS masks
NetFilter Hooks
下面几个 hook 是内核协议栈中已经定义好的:
NF_IP_PRE_ROUTING
: 接收到的包进入协议栈后立即触发此 hook,在进行任何路由判断 (将包发往哪里)之前NF_IP_LOCAL_IN
: 接收到的包经过路由判断,如果目的是本机,将触发此 hookNF_IP_FORWARD
: 接收到的包经过路由判断,如果目的是其他机器,将触发此 hookNF_IP_LOCAL_OUT
: 本机产生的准备发送的包,在进入协议栈后立即触发此 hookNF_IP_POST_ROUTING
: 本机产生的准备发送的包或者转发的包,在经过路由判断之后, 将触发此 hook
IPTables 表和链(Tables and Chains)
下面可以看出,内置的 chain 名字和 netfilter hook 名字是一一对应的:
PREROUTING
: 由NF_IP_PRE_ROUTING
hook 触发INPUT
: 由NF_IP_LOCAL_IN
hook 触发FORWARD
: 由NF_IP_FORWARD
hook 触发OUTPUT
: 由NF_IP_LOCAL_OUT
hook 触发POSTROUTING
: 由NF_IP_POST_ROUTING
hook 触发
如果没有匹配到任何规则那么执行默认规则。下面括号中的policy
1 | #iptables -L | grep policy |
If you would rather deny all connections and manually specify which ones you want to allow to connect, you should change the default policy of your chains to drop. Doing this would probably only be useful for servers that contain sensitive information and only ever have the same IP addresses connect to them.
1
2
3
4 > iptables --policy INPUT DROP`
> `iptables --policy OUTPUT DROP`
> `iptables --policy FORWARD DROP
>
iptables规则对性能的影响
蓝色是iptables规则数量,不过如果规则内容差不多,只是ip不一样,完全可以用ipset将他们合并到一条或者几条规则,从而提升性能
iptables 丢包监控
1 | //每 2 秒中 diff 一下因为命中 iptables 导致的 Drop 包的数量,并高亮差异(丢包数), -v :Verbose output |