Port knocking уязвим к атакам с перехватом сетевых данных, а также требует дополнительного ПО (скрипт или приложение для android/ios/…), что не всегда удобно. Но при этом нужно как-то закрыть дополнительным образом некоторые порты.
Нужно добавить строку
session optional pam_exec.so /path/to/open_port.sh
самым последним элементом в списке для удаленной аутентификации, например, в случае с gentoo:
host ~ # cat /etc/pam.d/system-remote-login
auth include system-login
account include system-login
password include system-login
session include system-login
session optional pam_exec.so /path/to/open_port.sh
#!/bin/bash
[ "$PAM_TYPE" = "open_session" ] || exit 0
function open_port_ip() {
IP=$1
PORT=$2
iptables -A INPUT -m state --state NEW -s ${IP} -p tcp --dport ${PORT} -j ACCEPT
}
function close_port_ip() {
IP=$1
PORT=$2
iptables -D INPUT -m state --state NEW -s ${IP} -p tcp --dport ${PORT} -j ACCEPT
}
function timeout_open_port_ip() {
IP=$1
PORT=$2
TIMEOUT=$3
open_port_ip ${IP} ${PORT}
sleep ${TIMEOUT} && close_port_ip ${IP} ${PORT} &
}
function main() {
for IP in $(who | grep -o -P '(?<=\().*(?=\))' | sort | uniq); do
timeout_open_port_ip ${IP} 80 30s
done
}
sleep 1s && main &
Зачем нужен sleep? Дело в том, что удаленные IP адреса в данном случае получаются с помощью команды who, а для того, чтобы там был нужный IP адрес, необходимо, чтобы pam полностью отработал.