knockd и дублирование правил iptables

Jan 24, 2020 11:23


Предположим, есть debian-хост с установленным knockd. Его IP = 192.168.4.1. Также имеется такой конфиг knockd:

[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

Если мы удаленно постучимся вот так: knock 192.168.4.1 7000 8000 9000 - то откроем порт SSH. Если же: knock 192.168.4.1  9000 8000 7000 -
то получим «Закрой за мной дверь, я ухожу...» Все просто.

А что, если мы раза три постучимся на «открытие» порта? Внезапно, добавится ТРИ одинаковых iptables- правила. И, соответственно, уходя и закрывая порт мы удалим лишь одно из них. И порт таки останется открытым.

Почему iptables не проверяет на «дубли» одинаковых правил при их добавлении - неизвестно. Неприятный момент. Но вопрос таки решаем.

Есть разные варианты: iptables-save + uniq + iptables-restore, iptables-save + grep, наваять скрипт перебора правил и удаления дублей, ... Но есть, КМК, более простой и элегантный путь.

iptables начиная с давних версий (по крайней мере ядро 2.6.32-5 и iptables-1.4.14 уже знают такой ключ) имеет ключ -C --check . Просто вводим вышеуказанное правило с -C INPUT и ловим код ошибки. Если 0 - все норм, правила нет, добавляем. Не 0 - правило уже есть в цепочке.

Соответственно, перепишем конфиг вот так:

[options]
        UseSyslog

[openSSH]
       sequence    = 7000,8000,9000
       seq_timeout = 5
       command     = /sbin/iptables -C INPUT -s %IP% -p tcp --dport 22 -j ACCEPT  || /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

И все. Правило всегда будет одно, хоть обстучись на открытие порта. На каждое следующее "открытие" порта в логах будет ошибка типа:
...
knockd[1968]: iptables: Bad rule (does a matching rule exist in that chain?).
...

iptables, knock, debian, linux

Previous post Next post
Up