linux中的knockd服务--端口敲门

什么是端口碰撞(敲门)

端口碰撞是一种通过在一组预先指定的端口上产生连接请求,从外部打开防火墙上的端口的方法。

一旦收到正确的连接请求序列,防火墙规则就会被动态修改,以允许发送连接请求的主机通过特定端口进行连接。

在Linux中称为 Knockd服务,该服务通过动态的添加iptables规则来隐藏系统开启的端口,使用自定义的一系列端口号来“敲门”,使系统开启需要访问的服务端口,才能对外访问。

不使用时,再使用自定义的端口号来“关门”,将端口关闭,不对外监听。进一步提升了服务和系统的安全性。

端口碰撞的主要目的是防止攻击者通过进行端口扫描来扫描系统中潜在的可利用服务,因为除非攻击者发送正确的碰撞序列,否则受保护的端口将显示为关闭。

例子:

在扫描某台服务器的开放端口时,22端口ssh服务是被过滤的,并且无法进行ssh连接。在这台服务器上设置:同一个用户依次对1024,2024,3024端口进行访问,则开启22端口,并允许外部机器进行访问。

安装

apt install knockd

修改配置文件

基础配置

cat /etc/knockd.conf

[options]
	UseSyslog

[openSSH]
    # 定义敲门的端口顺序
	sequence    = 7000,8000,9000
    # 设置超时时间,时间太小可能会出错 这个超时时间指的是敲门端口之间的间隔时长,默认是5秒,可以根据实际情况,调大点
	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

[openHTTPS]
	sequence    = 12345,54321,24680,13579
	seq_timeout = 5
	command     = /usr/local/sbin/knock_add -i -c INPUT -p tcp -d 443 -f %IP%
	tcpflags    = syn

配置文件的一些说明:

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

注意:

  1. 默认配置上是没有配置端口的,但是端口是有默认值的,是 eth0,但是我们都知道, 只有早些时候的系统才会是 eth0 命名,例如 centOS6 甚至跟早的版本的系统,之后的版本的端口都基本不是这么命名的,所以,当用默认端口启动时,一定会无法启动服务,因为会报 eth0 端口无法找到,所以首先需要添加的就是端口选项
  2. 默认配置中的command是使用的 /sbin/iptables -A XXXXX,我们都知道 -A 是追加规则的选项,而规则的匹配时从上往下匹配,所以,用追加的方式添加的规则,很可能会无法生效,所以,这里需要改成 -I,用插入的方式添加,会添加到最前面。
  3. 这里的command是当敲门顺序成功后,执行的,所以这里是使用的 ACCEPT,是放通或者允许的意思,那么,我们就需要先把防火墙的默认规则设置成拒绝或者丢弃,或者在最下面添加一条默认的拒绝规则,这也是为什么我说插入规则比追加规则好的原因。

所以,这里我们需要先把防火墙的配置修改成拒绝或者丢弃

iptables -P INPUT DROP
# 或者
iptables -A INPUT -j DROP

然后,修改配置

我这里对外的网卡名称是 enp0s3

那么我的配置文件就应该是

[options]
	UseSyslog
    interface=enp0s3

[openSSH]
	sequence    = 7000,8000,9000
	seq_timeout = 30
	command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
	tcpflags    = syn

[closeSSH]
	sequence    = 9000,8000,7000
	seq_timeout = 30
	command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
	tcpflags    = syn

[openHTTPS]
	sequence    = 12345,54321,24680,13579
	seq_timeout = 5
	command     = /usr/local/sbin/knock_add -i -c INPUT -p tcp -d 443 -f %IP%
	tcpflags    = syn

启动服务

systemctl enable knockd
systemctl restart knockd

查看是否启动成功

systemctl status knockd.service

那如何敲门呢

使用knock命令

安装了 knockd 就会有这个命令

如上面的配置配置,那么我的打开22端口的命令就是

$ knock 10.1.0.200 7000 8000 9000 -v
hitting tcp 10.1.0.200:7000
hitting tcp 10.1.0.200:8000
hitting tcp 10.1.0.200:9000

而 关闭22端口的方法就是

$ knock 10.1.0.200 9000 8000 7000 -v
hitting tcp 10.1.0.200:9000
hitting tcp 10.1.0.200:8000
hitting tcp 10.1.0.200:7000

或者可以指定端口类型

knock 10.1.0.200 9000:tcp 8000:udp 7000:udp -v

其他方法

都说nmap、telnet 、nc也可以,但是经测试,只有nc能成功,但是nc并不是每次都成功

nc的方式

nc -z 10.1.0.200 7000 8000 9000 -w 1
nc -z 10.1.0.200 9000 8000 7000 -w 1

这里使用 -w,设置超时时长为1秒,主要是为了能快速的结束,因为这几个端口其实通常都不是开放的,所以,当测试端口的时候,会一直等到超时,那很可能会超过 knockd 设置的 seq_timeout,就无法触发规则。

所以最好还是使用 knock 来敲门

其他配置示例

通过单个单元配置开启和关闭

[options]
     logfile = /var/log/knockd.log

[opencloseSSH]
     sequence      = 2222:udp,3333:tcp,4444:udp
     seq_timeout   = 15
     tcpflags      = syn,ack
     start_command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --syn -j ACCEPT
     cmd_timeout   = 5
     stop_command  = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --syn -j ACCEPT

此示例是使用单个敲门来控制对端口22(SSH)的访问。
在收到成功的敲门后,守护进程将运行 start_command,等待 cmd_timeout 中指定的时间,然后执行 stop_command
这对于自动关闭门环后面的门很有用。敲门序列同时使用UDP和TCP端口。

通过迷惑方式来敲门

[options]
     logfile = /var/log/knockd.log

[opencloseSMTP]
     one_time_sequences = /etc/knockd/smtp_sequences
     seq_timeout        = 15
     tcpflags           = fin,!ack
     start_command      = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 25 -j ACCEPT
     cmd_timeout        = 5
     stop_command       = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 25 -j ACCEPT

此示例不使用单个固定的敲门序列来触发事件,而是使用从序列文件中提取的一组序列(一次性序列),由one_time_sequences指令指定。
每次成功爆震后,使用的序列将无效,序列文件中的下一个序列必须用于成功敲门。
这可以防止攻击者在发现序列后(例如,在嗅探网络时)进行重放攻击。

同时支持IPv6和IPv4

[options]
     logfile = /var/log/knockd.log

[opencloseSMTP]
     one_time_sequences = /etc/knockd/smtp_sequences
     seq_timeout        = 15
     tcpflags           = fin,!ack
     start_command      = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 25 -j ACCEPT
     start_command_6    = /usr/sbin/ip6tables -A INPUT -s %IP% -p tcp --dport 25 -j ACCEPT
     cmd_timeout        = 5
     stop_command       = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 25 -j ACCEPT
     stop_command_6     = /usr/sbin/ip6tables -D INPUT -s %IP% -p tcp --dport 25 -j ACCEPT

支持IPv4和IPv6的示例。可以为这两种协议中的每一种提供专用命令。

全局其他配置

  • UseSyslog 通过syslog()记录操作消息。这将在/var/log/messages或等效文件中插入日志条目。
  • LogFile = /path/to/file 将操作直接记录到文件中,通常是/var/Log/kockd.Log。
  • PidFile = /path/to/file 在守护进程模式下使用的Pidfile,默认值:/var/run/kockd.pid。
  • Interface = <interface_name> 要监听的网络接口。只需要给出它的名称,而不需要给出设备的路径(例如,“eth0”而不是“/dev/eth0”)。默认值:eth0。
posted @ 2024-09-07 22:41  厚礼蝎  阅读(387)  评论(0编辑  收藏  举报