docker,containerd,runc,docker-shim 之间的关系

在看系统进程的时候,发现了这样的进程关系:

systemd 里调用了 

- containerd -> containerd-shim
- dockerd -> docker-proxy

引起了我的兴趣。

ps: 另外上边只是在 docker 19.03 上发现了这样的调用关系,在 docker 17.06 上调用的关系实际上是这样:

-dockerd --registry-mirror=http:/xxx
  | -docker-containe -l unix:///xxx
      | -docker-containe   
  | -docker-proxy -proto xxx

在 19.03 版本中,docker相关的可执行文件如下:

image-20201011113355555

其中以docker开头的,docker, dockerd, docker-init, docker-proxy 是 docker 公司专属的,并非标准。

因为 docker 一直在开发中,网上很多资料都比较陈旧,不过八九不离十,无非是几个组件变了个名字:

  • docker,是一个客户端工具,用来把用户的请求发送给 docker daemon(dockerd)。
  • dockerd, docker daemon,一般也会被称为 docker engine。dockerd 启动时会启动 containerd 子进程。
  • Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性,几乎囊括了单机运行一个容器运行时所需要的一切:执行,分发,监控,网络,构建,日志等。主要作用是:
    • 管理容器的生命周期(从创建容器到销毁容器)
    • 拉取/推送容器镜像
    • 存储管理(管理镜像及容器数据的存储)
    • 调用 runC 运行容器(与 runC 等容器运行时交互)
    • 管理容器网络接口及网络
  • ctr 是 containerd 的 cli。
  • 为了能够支持多种 OCI Runtime,containerd 内部使用 containerd-shim,每启动一个容器都会创建一个新的 containerd-shim 进程,指定容器 ID,Bundle 目录,运行时的二进制(比如 runc)。
  • RunC 是一个轻量级的工具,用来运行容器的,我们可以不用通过 docker 引擎,直接运行容器。事实上,runC 是标准化的产物,它根据 OCI 标准来创建和运行容器。

调用链主要就是下面这张图:

img


善用 nsenter 命令,更好地 debug 容器网络

https://staight.github.io/2019/09/23/nsenter%E5%91%BD%E4%BB%A4%E7%AE%80%E4%BB%8B/

在做容器 debug 的时候,经常出现容器里没有某个命令的尴尬局面。比如ping,telnet等常用命令。如何才能快速debug网络问题,又不需要安装软件呢?

那必须是nsenter命令了。 nsenter是一个可以在指定进程的命令空间下运行指定程序的命令,它最典型的用途就是进入容器的网络命令空间。具体可以参考官方文档:https://github.com/jpetazzo/nsenter.

nsenter 和 docker exec 之间的区别在于,nsenter不进入cgroup,因此规避了资源限制。

此外,nsenter也可以进入mnt, uts, ipc, pid, user命令空间,以及指定根目录和工作目录。

一、安装

我所在的系统默认装有 nsenter 命令。如果没有,按照官方文档如下安装:

$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz
$ tar -xzvf util-linux-2.24.tar.gz
$ cd util-linux-2.24/
$ ./configure --without-ncurses
$ make nsenter
$ sudo cp nsenter /usr/local/bin

然后可以查看nsenter自带的帮助查看命令使用方式:

nsenter -h

Usage:
nsenter [options] [<program> [<argument>...]]
 
Run a program with namespaces of other processes.
 
Options:
-a, --all enter all namespaces
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-C, --cgroup[=<file>] enter cgroup namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork do not fork before exec'ing <program>
-Z, --follow-context set SELinux context according to --target PID

创建自定义 iptables 链

来自:How to create iptables firewall using custom chains

使用自定义链创建iptables防火墙,该自定义链将用于控制传入和传出流量。

创建iptables防火墙,该防火墙将允许已建立的连接,给定源地址的传入ssh,传出icmpntpdnssshhttphttps

# Flush rules and delete custom chains
iptables -F
iptables -X

# Define chain to allow particular source addresses
iptables -N chain-incoming-ssh
iptables -A chain-incoming-ssh -s 192.168.1.148 -j ACCEPT
iptables -A chain-incoming-ssh -s 192.168.1.149 -j ACCEPT
iptables -A chain-incoming-ssh -j DROP

# Define chain to allow particular services
iptables -N chain-outgoing-services
iptables -A chain-outgoing-services -p tcp --dport 53  -j ACCEPT
iptables -A chain-outgoing-services -p udp --dport 53  -j ACCEPT
iptables -A chain-outgoing-services -p tcp --dport 123 -j ACCEPT
iptables -A chain-outgoing-services -p udp --dport 123 -j ACCEPT
iptables -A chain-outgoing-services -p tcp --dport 80  -j ACCEPT
iptables -A chain-outgoing-services -p tcp --dport 443 -j ACCEPT
iptables -A chain-outgoing-services -p tcp --dport 22  -j ACCEPT
iptables -A chain-outgoing-services -p icmp            -j ACCEPT
iptables -A chain-outgoing-services -j DROP

# Define chain to allow established connections
iptables -N chain-states
iptables -A chain-states -p tcp  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A chain-states -p udp  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A chain-states -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A chain-states -j RETURN

# Drop invalid packets
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# Accept everything on loopback
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Accept incoming/outgoing packets for established connections
iptables -A INPUT  -j chain-states
iptables -A OUTPUT -j chain-states

# Accept incoming ICMP
iptables -A INPUT -p icmp -j ACCEPT

# Accept incoming SSH
iptables -A INPUT -p tcp --dport 22 -j chain-incoming-ssh

# Accept outgoing 
iptables -A OUTPUT -j chain-outgoing-services

## Drop everything else
iptables -P INPUT   DROP
iptables -P FORWARD DROP
iptables -P OUTPUT  DROP

列出所有防火墙规则,以验证是否按需应用了执行的命令。

$ sudo iptables -L -v -n

Chain INPUT (policy DROP 2 packets, 92 bytes)
 pkts bytes target              prot opt in     out     source               destination         
    0     0 DROP                all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
    1    29 ACCEPT              all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
  190 15639 chain-states        all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT              icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
    1    60 chain-incoming-ssh  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target        prot opt in     out     source               destination         
    1    29 ACCEPT        all  --  *      lo      0.0.0.0/0            0.0.0.0/0           
  150 39893 chain-states  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    1    62 chain-outgoing-services  all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain chain-incoming-ssh (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       192.168.1.148        0.0.0.0/0           
    1    60 ACCEPT     all  --  *      *       192.168.1.149        0.0.0.0/0           
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain chain-outgoing-services (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    1    62 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:123
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:123
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain chain-states (2 references)
 pkts bytes target     prot opt in     out     source               destination         
  335 55240 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    1    78 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    4   214 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

我已经使用了RETURNtarget,chain-states因此数据包将继续通过防火墙。

编辑地址清单

在源地址列表中列出防火墙规则。

$ sudo iptables -n --list chain-incoming-ssh --line-numbers

Chain chain-incoming-ssh (1 references)
num  target     prot opt source               destination         
1    ACCEPT     all  --  192.168.1.148        0.0.0.0/0           
2    ACCEPT     all  --  192.168.1.149        0.0.0.0/0           
3    DROP       all  --  0.0.0.0/0            0.0.0.0/0           

删除第一个条目。

$ sudo iptables -D chain-incoming-ssh  1

在链的开头添加新规则。

$ sudo iptables -I chain-incoming-ssh 1 -s 192.168.1.140 -j ACCEPT 

在上一个条目之前添加一个新规则。

$ sudo iptables -I chain-incoming-ssh 3 -s 192.168.1.150 -j ACCEPT 

在源地址列表中列出防火墙规则。

$ sudo iptables -n --list chain-incoming-ssh --line-numbers
Chain chain-incoming-ssh (1 references)
num  target     prot opt source               destination         
1    ACCEPT     all  --  192.168.1.140        0.0.0.0/0           
2    ACCEPT     all  --  192.168.1.149        0.0.0.0/0           
3    ACCEPT     all  --  192.168.1.150        0.0.0.0/0           
4    DROP       all  --  0.0.0.0/0            0.0.0.0/0           

补充说明

您可以使用以下命令检查特定的链条。

$ sudo iptables -n --list chain-outgoing-services

Chain chain-outgoing-services (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:123
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:123
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0  

您还可以在shell脚本中使用它根据其存在来执行不同的操作。

iptables --list chain-outgoing-services &>/dev/null
if [ "$?" -eq "0" ]; then
  iptables -F chain-outgoing-services
else
  iptables -N chain-outgoing-services
fi

iptables/ipset 备忘 - vqiu.cn

转自:https://vqiu.cn/ipset-note/,文章有点机翻的痕迹,不过不影响理解。

简介

ipset是iptables的扩展,允许创建一次匹配整个“地址”集的防火墙规则。 与通过线性存储和遍历的普通iptables链不同,IP集存储在索引数据结构中,即使在处理大型集时,查找也非常高效。

ipset只是iptables的扩展,所以本篇文章不仅是ipset的使用笔记,同时也是iptables的使用笔记。

安装

// Debian
apt-get install ipset

//RHEL
yum -y install ipset
12345

快速入门

需求,禁1.1.1.12.2.2.2IP访问服务器,使用以下iptables 命令可实现:

iptables -A INPUT -s 1.1.1.1 -j DROP
iptables -A INPUT -s 2.2.2.2 -j DROP

同时,我们如果使用ipset也可以实现

ip -N myset iphash
ipset -A myset 1.1.1.1
ipset -A myset 2.2.2.2
iptables -A INPUT -m set --set myset src -j DROP

上面的ipset命令创建了一个带有两个地址(1.1.1.1和2.2.2.2)的新集合( ipset类型为iphash )。

然后iptables命令引用带有匹配规范的-m set --set myset src ,这意味着“匹配源头与之匹配(即包含在内)名为myset的集合的数据包”

标志src表示匹配“源”。 标志dst将匹配“destination”,并且标志src,dst将在源和目标上匹配。

在上面的第二个版本中,只需要一个iptables命令,无论该组中包含多少额外的IP地址。 尽管此示例仅使用两个地址,但您可以轻松定义1,000个地址,而基于ipset的配置仍然只需要一个iptables规则,而前一种方法,如果没有ipset的优势,则需要1,000个iptables规则。

应用场景

ipset优点

除了性能提升之外,ipset还允许在许多场景中进行更直接的配置。

如果要定义一个防火墙条件,该条件与1.1.1.1或2.2.2.2中的所有数据包相匹配,并在mychain中继续处理,请注意以下内容不起作用:

iptables -A INPUT -s ! 1.1.1.1 -g mychain
iptables -A INPUT -s ! 2.2.2.2 -g mychain

如果一个数据包来自1.1.1.1,它将与第一个规则不匹配(因为源地址 1.1.1.1),但它将匹配第二个规则(因为源地址不是 2.2.2.2)。 如果数据包来自2.2.2.2,它将匹配第一个规则(因为源地址不是 1.1.1.1)。 规则相互抵消,所有数据包都匹配,包括1.1.1.1和2.2.2.2。

虽然还有其他方法可以正确构建规则并在没有ipset的情况下实现所需的结果,但没有一种方法可以直观或直接:

ipset -N myset iphash
ipset -A myset 1.1.1.1
ipset -A myset 2.2.2.2
iptables -A INPUT -m set ! --set myset src -g mychain

在上面,如果一个数据包来自1.1.1.1,它将与规则不匹配(因为源地址1.1.1.1与设置的myset匹配)。 如果数据包来自2.2.2.2,则它与规则不匹配(因为源地址2.2.2.2与设置的myset匹配)。

虽然这是一个简单的例子,但它说明了在单个规则中拟合完整条件的基本好处。 在许多方面,单独的iptables规则彼此是相互独立的,并且将单独的规则合并为单个逻辑条件并不总是直截了当,直观或最优,特别是当涉及混合正常和反向测试时。 ipset只是让这些情况下的生活更轻松。

ipset的另一个好处是可以独立于活动的iptables规则来操作集合。 添加/更改/删除条目是一件小事,因为信息简单且顺序无关紧要。 编辑平面列表不需要经过深思熟虑。 另一方面,在iptables中,除了每个规则是一个明显更复杂的对象这一事实之外,规则的顺序至关重要,因此就地规则修改更加繁重且可能容易出错。

配合NAT使用

出站NAT(SNAT或IP伪装)允许专用LAN内的主机访问Internet。 适当的iptables NAT规则匹配源自专用LAN的Internet绑定数据包,并将源地址替换为网关本身的地址(使网关看起来是源主机并隐藏其后面的私有“真实”主机)。

NAT会自动跟踪活动连接,以便将返回的数据包转发回正确的内部主机(通过将目标地址从网关地址更改回原始内部主机的地址)。

以下是执行此操作的简单出站NAT规则的示例,其中10.0.0.0/24是内部LAN:

iptables -t nat -A POSTROUTING \ -o eth0 -j MASQUERADE 

事实证明,这是ipset的另一个伟大的应用程序。 假设除了充当本地专用LAN(10.0.0.0/24)的Internet网关之外,您的盒子还可以直接路由到其他四个专用网络(10.30.30.0/24,10.40.40.0/24,192.168.4.0/23和172.22.0.0/22)。 运行以下命令:

ipset -N routed_nets nethash
ipset -A routed_nets 10.30.30.0/24
ipset -A routed_nets 10.40.40.0/24
ipset -A routed_nets 192.168.4.0/23
ipset -A routed_nets 172.22.0.0/22
iptables -t nat -A POSTROUTING \
         -s 10.0.0.0/24 \
         -m set ! --set routed_nets dst \
         -j MASQUERADE

正如您所看到的,ipset可以很容易地确定您想要匹配的内容和不需要的内容。 此规则将伪装从内部LAN(10.0.0.0/24)通过该框的所有流量,除了绑定到routed_nets集中任何网络的数据包,保留对这些网络的正常直接IP路由。 由于此配置完全基于网络地址,因此您不必担心适当的连接类型(VPN的类型,跳数等),也不必担心物理接口和拓扑。

这应该是这样的。 因为这是纯粹的第3层(网络层)实现,所以实现它所需的基础分类也应该是纯层3。

限制某些PC只能访问某些公共主机

让我们说老板担心某些员工在互联网上玩而不是工作,并要求你限制他们的PC访问他们需要能够工作的特定网站,但他不希望这样。影响所有PC(例如他)。

要限制三台PC(10.0.0.5,10.0.0.6和10.0.0.7)只能访问worksite1.com,worksite2.com和worksite3.com,请运行以下命令:

ipset -N limited_hosts iphash
ipset -A limited_hosts 10.0.0.5
ipset -A limited_hosts 10.0.0.6
ipset -A limited_hosts 10.0.0.7
ipset -N allowed_sites iphash
ipset -A allowed_sites worksite1.com
ipset -A allowed_sites worksite2.com
ipset -A allowed_sites worksite3.com
iptables -I FORWARD \
         -m set --set limited_hosts src \
         -m set ! --set allowed_sites dst \
         -j DROP

此示例与单个规则中的两个集匹配。 如果源匹配limited_hosts且目标与allowed_sites不匹配,则丢弃该数据包(因为limited_hosts仅允许与allowed_sites通信)。

请注意,因为此规则位于FORWARD链中,所以它不会影响与防火墙本身之间的通信,也不会影响内部流量(因为该流量甚至不会涉及防火墙)。

阻止除某些PC之外的所有主机的访问(反向场景)

假设老板想阻止访问局域网内所有主机上的一组站点,除了他的PC和他的助手的PC。 对于多样性,在这个例子中,让我们通过MAC地址而不是IP匹配boss和助手PC。 让我们说MAC是11:11:11:11:11:11和22:22:22:22:22:22,其他人阻止的网站是badsite1.com,badsite2.com和badsite3.com 。

代替使用第二个ipset来匹配MAC,让我们利用带有MARK目标的多个iptables命令来标记数据包,以便在同一链中的后续规则中进行处理:

ipset -N blocked_sites iphash
ipset -A blocked_sites badsite1.com
ipset -A blocked_sites badsite2.com
ipset -A blocked_sites badsite3.com
iptables -I FORWARD -m mark --mark 0x187 -j DROP
iptables -I FORWARD \
         -m mark --mark 0x187 \
         -m mac --mac-source 11:11:11:11:11:11 \
         -j MARK --set-mark 0x0
iptables -I FORWARD \
         -m mark --mark 0x187 \
         -m mac --mac-source 22:22:22:22:22:22 \
         -j MARK --set-mark 0x0
iptables -I FORWARD \
         -m set --set blocked_sites dst \
         -j MARK --set-mark 0x187

正如您所看到的,因为您没有使用ipset来执行上一个示例中的所有匹配工作,所以这些命令更复杂。 因为有多个iptables命令,所以必须认识到它们的顺序非常重要。

请注意,这些规则是使用-I选项(插入)而不是-A(追加)添加的。 插入规则后,它将添加到链的顶部,将所有现有规则向下推。 因为正在插入这些规则中的每一个,所以有效顺序是相反的,因为随着每个规则的添加,它将被插入到前一个规则之上。

上面的最后一个iptables命令实际上成为FORWARD链中的第一个规则。 此规则匹配目标与blocked_sites ipset匹配的所有数据包,然后使用0x187(任意选择的十六进制数)标记这些数据包。 接下来的两条规则仅匹配要排除的主机的数据包以及已标记为0x187的数据包。 然后这两个规则将这些数据包上的标记设置为0x0,“清除”0x187标记。

最后,最后一个iptables规则(由上面的第一个iptables命令表示)丢弃所有具有0x187标记的数据包。 这应该匹配在blocked_sites集中具有目的地的所有数据包,除了来自任一排除的MAC的数据包,因为这些数据包上的标记在达到DROP规则之前被清除。

这只是解决问题的一种方法。 除了使用第二个ipset之外,另一种方法是利用用户定义的链。

如果你想使用第二个ipset而不是mark技术,你将无法达到上述的确切结果,因为ipset没有machash集类型。 但是,有一个macipmap集类型,但这需要在IP和MAC上匹配,而不是像上面那样单独使用MAC。

注意事项:在大多数实际情况中,此解决方案实际上不适用于网站,因为许多可能成为blocked_sites集合的主机(如Facebook,MySpace等)可能有多个IP地址,这些IP可能经常变化。 iptables / ipset的一般限制是只有在解析为单个IP时才应指定主机名。

此外,主机名查找仅在命令运行时发生,因此如果IP地址更改,防火墙规则将不会知道更改,仍将引用旧IP。 因此,实现这些类型的Web访问策略的更好方法是使用HTTP代理解决方案,例如Squid。 该主题显然超出了本文的范围。

自动禁止尝试访问无效服务的主机

ipset还为iptables提供了“目标扩展”,它提供了一种基于任何iptables规则动态添加和删除集合条目的机制。 您无需使用ipset命令手动添加条目,而是可以让iptables随时为您添加条目。

例如,如果远程主机尝试连接到端口25,但您没有运行SMTP服务器,则可能没有任何好处。 要拒绝主持人有机会主动尝试其他任何操作,请使用以下规则:

ipset -N banned_hosts iphash
iptables -A INPUT \
         -p tcp --dport 25 \
         -j SET --add-set banned_hosts src
iptables -A INPUT \
         -m set --set banned_hosts src \
         -j DROP

如果数据包到达端口25,比如源地址为1.1.1.1,则会立即将其添加到banned_hosts,就像运行此命令一样:

ipset -A banned_hosts 1.1.1.1

由于DROP规则,从1.1.1.1开始的所有流量都被阻止。

请注意,这也将禁止尝试运行端口扫描的主机,除非他们知道要避免端口25。

清除运行配置

如果要清除ipset和iptables配置(设置,规则,条目)并重置为新的打开防火墙状态(在防火墙脚本的顶部有用),请运行以下命令:

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -t filter -F
iptables -t raw -F
iptables -t nat -F
iptables -t mangle -F
ipset -F
ipset -X

无法销毁“正在使用”的集合,这意味着由一个或多个iptables规则引用(使用ipset -X )。 因此,为了确保从任何状态完全“重置”,必须首先刷新iptables链(如上所示)。

生产实例

结合生产的SSH,配置如下:

ipset create whitelist-ssh hash:net hashsize 4096
ipset add whitelist-ssh 192.168.10.0/23

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m set --match-set whitelist-ssh src -p tcp --dport 22 -m comment --comment "Allow Access SSH" -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m comment --comment "Deny Access SSH" -j DROP

ipset list
iptables -t filter -vxnL

ipset save > /etc/ipset.up.rules
iptables-save > /etc/iptables/rules.v4

//往/etc/rc.local加入以下:
ipset restore < /etc/ipset.up.rules
iptables-restore < /etc/iptables/rules.v4

模拟fail2ban 功能

60秒内访问3次SSH,将源IP禁止60秒

``` ipset create badguys hash:net timeout 900 ipset add badguys 192.168.0.0/16 nomatch ipset add badguys 172.16.0.0/16 nomatch

iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m set –match-set badguys -j DROP


iptables 限速

从知乎这个问题开始,限速命令如下:

iptables -A OUTPUT -d 192.168.4.204 -m limit --limit 35/s --limit-burst 40 -j ACCEPT
iptables -A OUTPUT -d 192.168.4.204 -j DROP

命令行中主要用到了 iptables 的扩展模块 limit,也就是 -m limit

Limit match

这个匹配操作必须由-m limit明确指定才能使用。有了它的帮助,就可以对指定的规则的日志数量加以限制,以免你被信息的洪流淹没哦。比如,你可以事先设定一个限定值,当符合条件 的包的数量不超过它时,就记录;超过了,就不记录了。我们可以控制某条规则在一段时间内的匹配次数 (也就是可以匹配的包的数量),这样就能够减少DoS syn flood攻击的影响。这是它的主要作用,当然,还有很多其他作用(译者注:比如,对于某些不常用的服务可以限制连接数量,以 免影响其他服务)。limit match也可以用英文感叹号取反,如:-m limit ! --limit 5/s 表示在数量超过限定值后,所有的包都会被匹配。