Soluciones informáticas con sistemas Linux
Iptables Logging
Uno de los problemas comunes a los que se enfrenta un linuxero (sysadmin/developer/linux-user-wanabee) es crear una serie de reglas de iptables decente para proteger su instalación. El problema se encuentra en que muchas veces no se sabe exactamente que es lo que iptables está bloqueando y si no se conocen comandos comúnes de como diagnosticar en que puerto X aplicación está escuchando el problema crece exponencialmente.
Para conocer en que puertos está escuchando tu linux box, netstat es muy útil:
[root@monitor ~]# netstat -luntp | grep -i listen
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2457/portmap
tcp 0 0 0.0.0.0:980 0.0.0.0:* LISTEN 2494/rpc.statd
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 20873/xinetd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 2706/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2752/sendmail: acce
tcp 0 0 :::80 :::* LISTEN 20394/httpd
tcp 0 0 :::22 :::* LISTEN 2695/sshd
tcp 0 0 :::443 :::* LISTEN 20394/httpd
[root@monitor ~]#
En este caso vams a tomar el puerto 21 como ejemplo, aquí tenemos proftpd corriendo y escuchando en el puerto 21 pero este puerto no está abierto en el firewall.
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-port-unreachable
COMMIT
Por lo tanto, cuando trato conectarme al puerto 21 (aquí voy a utilizar telnet solo para verificar que el puerto está abierto/cerrado) voy a ver lo siguiente:
dan@dan:/home/dan
$ telnet monitor 21
Trying 192.168.98.164...
telnet: Unable to connect to remote host: Connection refused
dan@dan:/home/dan
$
Aquí es donde puedo utilizar la utilería de iptables para loggear, en mi Linux CentOS 5.3 hice lo siguiente:
Modifiqué lo siguiente en /etc/syslog.conf
[root@monitor ~]# cat /etc/syslog.conf
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
kern.* /var/log/kernel
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;news.none;authpriv.none;cron.none,kern.none /var/log/messages
.
.
.
Reinicio syslog con /etc/init.d/syslog restart
y le agrego la siguiente línea a /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -j LOG --log-prefix "Dropped Packets: " --log-level=info
Ahora, mi iptables queda de la siguiente manera:
[root@monitor ~]# cat /etc/sysconfig/iptables
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -j LOG --log-prefix "Dropped Packets: " --log-level=info
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-port-unreachable
COMMIT
[root@monitor ~]#
Y ahora, puedo ver lo siguiente en /var/log/kernel
dan@dan:/home/dan
$ telnet monitor 21
Trying 192.168.98.164...
telnet: Unable to connect to remote host: Connection refused
dan@dan:/home/dan
$
.
.
.
[root@monitor ~]# tail -f /var/log/kernel | grep 192.168.98.129
Sep 25 15:12:36 monitor kernel: Dropped Packets: IN=eth0 OUT= MAC=00:19:bb:d6:88:ca:00:19:bb:49:8e:31:08:00 SRC=192.168.98.129 DST=192.168.98.164 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=25720 DF PROTO=TCP SPT=46080 DPT=21 WINDOW=5840 RES=0x00 SYN URGP=0
[root@monitor ~]#
Los 2 campos que son importantes para comenzar es PROTO y DPT, protocolo y puerto destino, ahí me dice que es una conección TCP al puerto 21 … ya con eso tengo más que suficiente para modificar mi /etc/sysconfig/iptables y reinciar.
Aunque editar el archivo y reiniciar iptables no es la manera más elegante de hacerlo, funciona.
En el siguiente post voy a hablar de como agregar reglas al vuelo y en un órden específico.