Infra: Propuestas de configuración hardering

  • Esto aplica para servidor phplist-hardering servidor expuesto a ip publica
# DATOS

ssh cgi@10.0.100.93 /u4c

Ip: 10.0.100.93
u:c
p:u4c

Configuraciones actuales

  • CTK enabled
  • vmtools
  • nagios client
  • Cortex
  • Wazuh
  • Servicio Nagios:
    • Configurado básico
    • Memory usage
    • ENS190 in and Out
    • Servicio especial: puerto 80

Iptables

  • Instalamos
apt install iptables iptables-persistent -y
  • Configuración defecto Resumen
iptables -F
iptables -t mangle -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p icmp -m limit --limit 5/sec -j ACCEPT
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 33221 -j ACCEPT
iptables -A INPUT -p tcp --dport 5693 -s 10.0.100.24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
  • Explicación
--********************************
-- Limpia reglas anteriores
--********************************
iptables -F
iptables -t mangle -F

--********************************
--Define IN la política por defecto DROP
--********************************
iptables -P INPUT DROP
iptables -P FORWARD DROP

--********************************
--Define OUTPUT la política por defecto DROP
--********************************
iptables -P OUTPUT ACCEPT

--********************************
--Permite conexiones ya establecidas
--********************************
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

--********************************
--Bloquea paquetes inválidos
--********************************
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

--********************************
--Permite loopback
--********************************
iptables -A INPUT -i lo -j ACCEPT

--********************************
-- Permite ping limitado
--********************************
iptables -A INPUT -p icmp -m limit --limit 5/sec -j ACCEPT

--********************************
--Protecciones contra tráfico TCP malicioso 
--********************************
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

--********************************
--SSH
--********************************
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

--********************************
--Protección contra ataques de fuerza bruta SSH
--********************************
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

--********************************
-- WAZUH
--********************************
iptables -A INPUT -p tcp --dport 33221 -j ACCEPT

--********************************
-- NAGIOS
--********************************
iptables -A INPUT -p tcp --dport 5693 -s 10.0.100.24 -j ACCEPT


--********************************
--Protecciones contra escaneo de puertos
--********************************
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
  • Puerto de Aplicación
# WEB 80 / 443
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Aplicaciones java 8080 / 9090
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp --dport 9090 -j ACCEPT

# SMTP
iptables -A INPUT -p tcp --dport 25 -j ACCEPT

# mysql
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

# PostgreSQL
iptables -A INPUT -p tcp --dport 5432 -j ACCEPT

# Nagios CGT
iptables -A INPUT -p tcp --dport 5666 -s 10.0.98.201 -j ACCEPT

# Otros
iptables -A INPUT -p tcp --dport 8005 -j ACCEPT
iptables -A INPUT -p tcp --dport 9450 -j ACCEPT
iptables -A INPUT -p tcp --dport 9451 -j ACCEPT
iptables -A INPUT -p tcp --dport 9400 -j ACCEPT

  • Guardar las reglas
iptables-save > /etc/iptables/rules.v4
iptables-save > /etc/iptables/rules.v6
iptables -L -v

SSH

  • Abrimos
nano /etc/ssh/sshd_config
  • Modificamos
#PermitRootLogin prohibit-password
X
PermitRootLogin no

#MaxAuthTries 6
X
MaxAuthTries 3

#TCPKeepAlive yes
X
TCPKeepAlive no

Fail2ban

  • Instalamos
apt install rsyslog fail2ban -y
  • Habilitamos
systemctl start fail2ban
systemctl enable fail2ban
  • Copiar configuración demo
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
  • Abrimos
nano /etc/fail2ban/jail.local
  • Modificamos
bantime  = 10m
X
bantime = 7200                // bloqueado 2 horas  7200 segundos	

maxretry = 5
X
maxRetry = 3    
  • Reiniciamos
systemctl restart fail2ban

logwatch

  • Instalamos
apt-get install logwatch -y
  • Copiamos el archivos de configuración de «fábrica»
cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/logwatch.conf
  • Creamos una carpeta requerida:
mkdir /var/cache/logwatch
  • Abrimos el archivo:
nano /etc/logwatch/conf/logwatch.conf
  • Modificamos:
-------------------------------------------------------------- 
Output = stdout 
X 
Output = mail 
-------------------------------------------------------------- 
Format = text 
X 
Format = html 
-------------------------------------------------------------- 
MailTo = root 
X 
MailTo = gustavo.matamoros.gonzalez@una.ac.cr
-------------------------------------------------------------- 
MailFrom = Logwatch 
X 
MailFrom = phplist@una.ac.cr
 -------------------------------------------------------------- 
Detail = Low
X 
Detail = 8 
--------------------------------------------------------------
  • Probar
logwatch
  • Resultado de correo
  • Se registraron 2 intentos de usar hacks conocidos por parte de 2 hosts:
  • Significa que 2 IPs intentaron acceder usando rutas conocidas de hackeo.
  • Connection attempts using mod_proxy:
  • Alguien intentó usar tu servidor Apache como proxy para conectarse a otro sitio.
  • En tu caso no funcionó, solo fue intento.
  • A total of 2 sites probed the server
  • Significa que 2 IPs escanearon tu servidor buscando vulnerabilidades.
  • 400 Bad Request
  • Esto significa que bots enviaron peticiones malformadas o inválidas.
  • Eso intenta explotar routers o cámaras vulnerables.
  • HTTPD Errors
  • Errores registrados por Apache.
  • Significa que alguien intentó acceder a: services.php pero Apache lo bloqueó por configuración.
  • Errores en conexiones SSHD
  • Conexiones creadas

Recomendaciones: SSH

  • Agregar estas configuraciones
##############################
# Modo estricto
##############################
# SSH verifica los permisos de archivos del usuario antes de permitir login.
# revisa
# ~/.ssh
# ~/.ssh/authorized_keys
# Si los permisos son inseguros (ejemplo 777):
# SSH bloquea el acceso.

StrictModes yes
##############################
# MaxSessions
##############################
# Define cuántas sesiones simultáneas puede abrir un mismo usuario en una conexión SSH.

MaxSessions 8
##############################
# PubkeyAuthentication
##############################
# Permite autenticación mediante llaves SSH
# Más seguro que contraseña.
PubkeyAuthentication yes
##############################
# PasswordAuthentication
##############################
# Permite login con contraseña.
# PasswordAuthentication no
# solo permitiría llaves SSH.
# Eliminar esto elimina 99% de ataques automáticos.
PasswordAuthentication yes
##############################
# AllowUsers
##############################
# Solo estos usuarios pueden conectarse por SSH:
# Esto es muy importante.

AllowUsers root orion
##############################
# PermitEmptyPasswords no
##############################
# no permitir passwrod vacios
##############################
# LoginGraceTime
##############################
# Define cuánto tiempo tiene un usuario para autenticarse después de conectarse al SSH.
# Cuando se conecta a puerto 22 cuanto tiempo tiene para autenticar
# Recomendacion 30 segundo
LoginGraceTime 30

##############################
# Puerto defecto
##############################
# Reduce bots automáticos.
Port 2222
##############################
# Desactivar X11 forwarding
##############################
# si no se conecta uno por GUI se puede desactivar
X11Forwarding no
##############################
# Usar protocolo seguro
##############################
# esto limita solo usar la versión v2 más segura
Protocol 2
##############################
# Desactivar túneles si no se usan
##############################
# Evita Un atacante podría usar tu servidor como puente hacia otras redes internas.
AllowTcpForwarding no
##############################
# Limitar conexiones simultáneas
##############################
# Protege contra ataques de conexión masiva.
# Controla cuántas conexiones SSH pueden estar abiertas al mismo tiempo SIN autenticarse todavía.
# conexiones que solo llegaron al puerto 22 pero aún no han puesto contraseña o llave.
# Esto es importante porque muchos ataques hacen miles de conexiones simultáneas para saturar el servidor.

# Sintaxis
MaxStartups inicio:probabilidad:maximo
Valor	Explicación
10	después de 10 conexiones sin autenticarse empieza la protección
30	30% de nuevas conexiones serán rechazadas
60	cuando llegue a 60 conexiones se bloquean todas

Cómo funciona paso a paso

Supongamos:

MaxStartups 10:30:60
Hasta 10 conexiones

SSH acepta todo normalmente.

De 10 a 60 conexiones

SSH empieza a rechazar conexiones aleatoriamente.

Probabilidad:

30 %

Esto reduce ataques automáticos.

Más de 60 conexiones

SSH bloquea todas las nuevas conexiones.

Hasta que bajen las activas.

Qué problema evita

Ataques llamados:

SSH connection flood

Los bots hacen:

abrir
abrir
abrir
abrir
abrir
abrir

pero sin autenticarse.

Eso puede llenar:

memoria

procesos SSH

sockets

Valores recomendados

Para servidores normales:

MaxStartups 10:30:60

Para servidores más estrictos:

MaxStartups 5:20:20

Para servidores muy cargados:

MaxStartups 20:50:100


MaxStartups 10:30:60
##############################
# Desactivar autenticación interactiva
##############################
KbdInteractiveAuthentication no

Comando para saber ataques SSH

Ataque en tiempo real

  • Ataques en tiempo real
sudo tail -f /var/log/auth.log
  • Buscar
Failed password for root from 185.220.101.45 port 45532 ssh2

Ips que mas atacan

  • Ejecutar
grep "Failed password" /var/log/auth.log | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort | uniq -c | sort -nr | head
  • O ver los intentos
grep "Failed password" /var/log/auth.log

Ver usuarios conectados ahora

who
  • o con mas detalle
w

Ver últimos accesos al servidor

last -a | head

Ver procesos sospechosos

ps aux --sort=-%cpu | head

Ver puertos abiertos y qué los usa

ss -tulnp

Ver conexiones activas

ss -antp

MODO RESUMEN

echo "USERS:" && who && echo "PORTS:" && ss -tulnp && echo "CONNECTIONS:" && ss -antp | head

Ver crones de todos los usuarios

for user in $(cut -f1 -d: /etc/passwd); do
  crontab -u $user -l 2>/dev/null
done

Ver servicios

systemctl list-units --type=service
  • Instalados
systemctl list-unit-files

RESUMEN

echo "=== CRON ===" && ls -la /etc/cron* && echo "=== SERVICES ===" && systemctl list-unit-files | grep enabled && echo "=== USERS ===" && cut -d: -f1 /etc/passwd

SCRIPT de Chequeo

echo "===== USERS LOGGED IN ====="
who

echo
echo "===== LAST LOGINS ====="
last -a | head

echo
echo "===== FAILED SSH ATTEMPTS ====="
grep "Failed password" /var/log/auth.log | tail

echo
echo "===== SUCCESSFUL SSH LOGINS ====="
grep "Accepted" /var/log/auth.log | tail

echo
echo "===== USERS IN SYSTEM ====="
cut -d: -f1 /etc/passwd

echo
echo "===== SUDO USERS ====="
getent group sudo

echo
echo "===== CRON JOBS ====="
ls -la /etc/cron* 

echo
echo "===== ENABLED SERVICES ====="
systemctl list-unit-files | grep enabled

echo
echo "===== OPEN PORTS ====="
ss -tulnp

echo
echo "===== ACTIVE CONNECTIONS ====="
ss -antp | head

echo
echo "===== FILES IN TEMP DIRECTORIES ====="
ls -la /tmp
ls -la /var/tmp
ls -la /dev/shm

Instalación de lynis

  • Instalación
apt install lynis -y
lynis --version
  • Ejecutar auditoria
lynis audit system
  • Resultado

  • Ejemplo de SSH
  • Resumen

Instalar SSH-Audit

git clone https://github.com/jtesta/ssh-audit
cd ssh-audit
python3 ssh-audit.py
  • Ejecutarlo
# en localhost
python3 ssh-audit.py localhost

# Servidor remoto
python3 ssh-audit.py 10.0.3.233

# Puerto diferente
python3 ssh-audit.py 10.0.3.233:2222
  • Para obtener recomendaciones de hardening SSH:
python3 ssh-audit.py --get-hardening-guide ubuntu
  • Corregir
nano /etc/ssh/sshd_config
  • Agregar al final
KexAlgorithms sntrup761x25519-sha512@openssh.com

HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
  • Reiniciar
sudo systemctl restart ssh
  • Ejecutar de nuevo
python3 ssh-audit.py localhost
  • Resultado

Recomendaciones: Desactivar IPv6

  • Abrimos
sudo nano /etc/sysctl.conf
  • Agregamos
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
  • Aplicamos
sudo sysctl -p

Recomendaciones: Fail2ban