芝麻开门 Port-knocking

如果你有一台公众可访问的服务器,脚本小子可以轻松扫描其IP地址,查找服务器上的开放端口(尤其是用于SSH的端口22),然后暴力破解。

防止SSH端口被暴力破解一般有以下几种方式
1.修改默认端口22为其它端口
2.禁止密码登陆,只允许密钥登陆或者使用PAM模块开启二次认证
3.使用ipfailban屏蔽暴力登陆的IP

除了以上几种做法,还有一种安全加固的手段叫port knocking。如字面意思,类似‘敲门’,只是这里敲的是‘端口’,而且需要按照顺序‘敲’端口。如果敲击规则匹配,则可以让防火墙实时更改策略。从而达到开关防火墙的目的。

简单的做法是安装knockd。knockd是一种端口试探服务器工具。它侦听以太网或其他可用接口上的所有流量,等待特殊序列的端口命中(port-hit)。telnet或Putty等客户软件通过向服务器上的端口发送TCP或数据包来启动端口命中。
官网:https://zeroflux.org/projects...

安装

并没有yum源,所以只能自己编译安装

wget http://www.zeroflux.org/proj/knock/files/knock-0.8.tar.gz
yum install  libpcap-devel
yum  install autoconf
autoreconf -fi
./configure --prefix=/usr/local
make
sudo make install
cp knockd.conf /etc/
knockd -V

启动服务

knockd -i ens192 -d -v

配置 knockd 服务

使用默认的配置文件

cat /etc/knockd.conf
[options]
    UseSyslog
[openSSH]
    sequence    = 7000,8000,9000
    seq_timeout = 5
    command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags    = syn
[closeSSH]
    sequence    = 9000,8000,7000
    seq_timeout = 5
    command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags    = syn

配置文件里有两个参数:

sequence:按照顺序依次访问端口,command执行的条件。比如这里是依次访问7000, 8000, 9000端口,默认使用TCP访问。
command:当knockd监测到sequence端口访问完成,然后执行此处command,这里为通过iptables开启关闭ssh外部访问。

构造knock sequence

  1. 直接手工构造

打开 SSH iptables

telnet   7000
telnet   8000
telnet   9000

关闭 SSH iptables

telnet   9000
telnet   8000
telnet   7000
  1. 使用knock程序

    开启
    knock    7000 8000 9000
    关闭
    knock    9000 8000 7000
  2. NC 或者 Nmap

    Open:
    nc -z  7000 8000 9000
    Close:
    nc -z  9000 8000 7000
    
    for x in  7000 8000 9000; do nmap -Pn --host_timeout 201 --max-retries 0 -p $x   ; done

    一般情况到这里就完了。但如果只是cv大法的话,就没必要写这篇文章了。

这里有坑

按照默认配置,我以为这样敲门knock -v 10.180.249.61 7000 8000 9000 应该是顺理成章的,结果它给我来了这个

[root@manager knock-0.8]#  knockd -i ens192 -v
listening on ens192...
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 2
10.180.205.102: closeSSH: Stage 1
10.180.205.102: closeSSH: Stage 1
10.180.205.102: closeSSH: Stage 1
10.180.205.102: closeSSH: Stage 2
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 1

咦,它把敲门信号当成关门信号了,好吧,我把敲门端口和关门端口全部设置成不同的端口,然而,依然是莫名奇妙的输出,并不是我预料中的Stage 1,Stage 2,Stage 3 ,command这样的执行日志。能收到第一个和第二个信号,但是第三个信号无论如何都收不到。莫非前人欺我?

改成敲门,关门只接收两个信号

PS C:\Windows> telnet 10.180.249.61 7000
正在连接10.180.249.61...无法打开到主机的连接。 在端口 7000: 连接失败
PS C:\Windows> telnet 10.180.249.61 8000
正在连接10.180.249.61...无法打开到主机的连接。 在端口 8000: 连接失败

[root@manager knock-0.8]#  knockd -i ens192 -v
listening on ens192...
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 1
10.180.205.102: openSSH: Stage 2
10.180.205.102: openSSH: OPEN SESAME
openSSH: running command: /usr/sbin/iptables -A INPUT -s 10.180.205.102 -p tcp --dport 22 -j ACCEPT

[root@manager ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  10.180.205.102       anywhere             tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

也就是说,knock只能接收两个敲门信号,超过两个就会导致敲不开门,关不了门。这是一个bug吗?

概率是因为ip包到达服务器的时间有可能是乱序的,这会导致敲门失败,如果遇到只看到open/closeSSH: Stage 1或者open/closeSSH: Stage 2,看不到opencloseSSH: Stage 3的情况,可以多试几次,或者手工依次执行。如果还是不行,建议检查端口是否被占用。如果最后依然不行,结论还是属于knockd对tcp信号处理的bug,不建议配置超出两个的敲门信号。

至于iptables的应用就不再细数了。另外,为了在重启的过程保存和恢复iptables设置,我们可以在knockd命令中增加相应的iptables-save和iptables-restore操作。

看来knock还是有一定局限性。有没有其它工具呢。knock官网也推荐了替代工具doorman和pasmal。

简单直接不依赖三方工具实现Port-knocking

还有更简单的吗?直接用iptables就能搞定,先在服务器添加两条策略

iptables \
  -i eth0 \
  -t raw --append PREROUTING \
  -p tcp --dport 8080 --syn \
  -m recent --name knocked ! --rcheck --seconds 600 \
  -j DROP

iptables \
  -i eth0 \
  -t raw --append PREROUTING \
  -p udp --dport 30000 \
  -m string --string "OpenSesame" --algo bm \
  -m recent --name knocked --set \
  -j DROP

然后测试下

[root@manager ~]# yum install -y socat
[root@manager ~]# curl -i   --connect-timeout 5 http://146.56.248.195:8080/hello
curl: (28) Connection timed out after 5001 milliseconds
[root@manager ~]# echo "OpenSesame" | socat - udp4-datagram:146.56.248.195:30000
[root@manager ~]# curl -i   --connect-timeout 5 http://146.56.248.195:8080/hello
HTTP/1.1 200 OK
Date: Tue, 27 Jul 2021 02:38:47 GMT
Content-Type: text/plain
Content-Length: 21
Connection: keep-alive
Expires: Tue, 27 Jul 2021 02:38:46 GMT
Cache-Control: no-cache
content-type: text/html

Hello World!

[root@manager ~]#

会敲门了,相信关门也会了。

Port-knocking 并不能作为一种独立的安全防御措施,因为它属于security by obscurity。多种策略组合,才能提高系统的安全性

芝麻开门 Port-knocking_第1张图片

你可能感兴趣的:(linux安全)