Suele pasarme, como a muchos, de tener múltiples servidores en una única IP pública. Para administrarlos mi herramienta favorita es SSH, por lo que solía redireccionar puertos no-estándares a los correspondientes 22/tcp de cada máquina. Por ejemplo, el puerto 22 en la interfaz pública es para el firewall, el 222 para el webserver, el 2222 para el servidor de base de datos.
El problema es que, mucha veces, me conecto desde redes restrictivas, donde algunos de estos puertos está cerrados. Por lo que empezaba a saltar de máquina en máquina, teniendo que recordar contraseña y soportando el delay.
Sumando a esto está el problema de los bruteforcers que constantemente amenazan y molestan a nuestros servidores SSH.
Fue por esto que decidí escribir un cuasi-web knocking para Packet Filter (OpenBSD), mi sistema firewall preferido.
La idea es simple. El firewall tiene una página web que, al ser navegada de una forma particular,
redirecciona el puerto 22/tcp a distintas máquinas de forma que solo la IP que navegó
dicha página tenga acceso.
Premisas, en orden de importancia:
| Aviso: No estoy seguro de haber cumplido con estas premisas, así que acepto sugerencias. Esto de meter un shell y netcat dentro de un chroot me da como mala espina. Hagas lo que hagas, es tu responsabilidad. |
Requerimientos:
Instalación:
El archivo webknock.sh es un script de bash que requiere comandos complementarios dentro del chroot para funcionar. Por lo que deben ser copiados dentro de la siguiente estructura:
/var/www/
|-- bin
| |-- cat
| `-- echo
`-- usr
|-- bin
| |-- cut
| |-- grep
| `-- nc
|-- lib
| |-- libc.so.30.3
| |-- libc.so.38.2
| |-- libtermcap.so.9.0
| `-- libz.so.4.1
|-- libexec
| `-- ld.so
`-- local
`-- bin
`-- bash
Las bibliotecas pueden variar según la versión del sistema operativo. El comando ldd <binario> te ayudará a saber que bibliotecas copiar dentro del chroot.
ScriptAlias /knock "/var/www/cgi-bin/webknock.sh"
<Directory "/var/www/cgi-bin/*">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
table <ssh_orig> persist file "/var/www/conf/webknock/orig" table <ssh_dest> persist file "/var/www/conf/webknock/dest" rdr pass on $ext_if proto tcp from <ssh_orig> to ($ext_if) port 22 -> <ssh_dest>El script pfctl.py es un pequeño daemon escrito en Python que escucha en el puerto 50150 de localhost. Su función es sencilla: cada vez que recibe una conexión, corre el comando pfctl -Tl -f /etc/pf.conf. El script webknock.sh se conectará cada vez que requiera que se recarguen las tablas ssh_orig y ssh_dest.
pfctl.py puede copiarse en /usr/local/sbin/pfctl.py. Para que corra cada vez que se inicia el sistema, en /etc/rc.local se debe incluir:
if [ -x /usr/local/sbin/pfctl.py ]; then
echo -n ' pfctl.py'; /usr/local/sbin/pfctl.py &
fi
Uso:
El webknocking estará accesible desde http:\\[sitio_com]\knock. Para producir algun cambio en la redirección del firewall se puede acceder a los links o directamente a http://[sitio_com]/knock?[password]=[action].