analytics

sábado, 11 de noviembre de 2017

OpenVPN Debian 9 (Road to Warrior) - Actualizado

Hola a tod@s,

primeramente darle las gracias a Ismael por darme esta oportunidad para hacer una entrada en el blog. Espero que sea de ayuda e interés.

Escenario:
  1. Equipo con Debian 9.6 instalado desde netinstall y con gestión por ssh. (125 paquetes)
  2. OpenVpn (2.4.0-6), OpenSSL (1.1.0j-1), Easy-RSA (2.2.2-2) y Havged (1.9.1-5)
  3. Dispositivo móvil Android 8
Parametrización previa de la máquina Debian:
  • /boot -> 256Mb ext2 opciones: ro
  • /root -> 1G XFS
  • /tmp -> 256Mb ext4 opciones: nodev,nosuid,noexec
  • /swap -> 256Mb
  • /opt -> 64Mb ext4 opciones: nodev,nosuid,noexec
  • /var -> 512Mb ext4 opciones: nodev,nosuid,noexec
  • /var/log -> 256Mb ext4 opciones: nodev,nosuid,noexec
  • /var/log/audit -> 64Mb ext4 opciones: nodev,nosuid,noexec
  • /usr -> 1,5Gb  ext4
  • /home -> 64Mb XFS opciones: nodev,nosuid,usrquota,grpquota
  • /tmp  /var/tmp    none    rw,nodev,noexec,nosuid,bind 0   0
  • tmpfs /dev/shm    none    rw,nodev,noexec,nosuid      0   0
  • proc    /proc    proc    defaults,hidepid=2     0     0
Paquetería necesaria:
apt update && apt install openssl easy-rsa openvpn haveged -y

Instalaremos el paquete haveged para generar la suficiente cantidad de entropía en el sistema, de manera que podamos generar claves de calidad.

Copiamos el directorio easy-rsa
cp -r /usr/share/easy-rsa/ /etc/openvpn/
Modificaremos el fichero /etc/openvpn/easy-rsa/vars quedando de la siguiente manera:
export EASY_RSA="/etc/openvpn/easy-rsa"

export KEY_SIZE=4096
export CA_EXPIRE=1825
export KEY_EXPIRE=1825
export KEY_COUNTRY="ES"
export KEY_PROVINCE="LCG"
export KEY_CITY="Cambre"
export KEY_ORG="TestLab Enterprises"
export KEY_EMAIL="root@localhost”
export KEY_OU="IT"

Según las lineas anteriores, se van a generar claves y certificados de 4096 bits con duración de 5 años y ubicadas en la ruta /etc/openvpn/easy-rsa

Hacemos source a vars. Recomendaría posicionarse en /etc/openvpn/easy-rsa
source vars

Y probamos que los scripts funcionan correctamente:
./clean-all

Ya podemos empezar a generar los certificados, primeramente la CA
./build-ca CA
El del servidor
./build-key-server srvovpn
Diffie-Helman (Si no es un equipo con cierta potencia, puede tardar unas horas)
./build-dh
Clave TA para evitar DDoS hacia la VPN
openvpn --genkey --secret ta.key
En este punto ya podemos empezar a generar certificados y claves para los usuarios de la VPN
./build-key cliente1

Crearemos la configuración del servidor VPN en /etc/openvpn/server.conf
dev tun
proto udp
tun-mtu 1460
port 11194
### Aumenta el cache del buffer de envio de paquetes
sndbuf  393216
### Aumenta el cache del buffer de descarga de paquetes
rcvbuf 393216
### Certificados y claves del servidor
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/srvovpn.crt
key /etc/openvpn/easy-rsa/keys/srvovpn.key
dh /etc/openvpn/easy-rsa/keys/dh4096.pem
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
remote-cert-tls client
crl-verify /etc/openvpn/easy-rsa/keys/crl.pem
### Hace que OpenVPN trabaje con este user/group
user nobody
group nogroup
### Graceful transition from old to new key
tran-window 256
### Subnet de la VPN
server 10.58.0.0 255.255.255.224
### Fichero para mantener una asociación continua de IP y dispositivos
ifconfig-pool-persist ipp.txt
### Servidores DNS
push "dhcp-option DNS DNSINTERNO1" # Podríamos usar un servidor externo
push "dhcp-option NTP NTPINTERNO1"
push "sndbuf 393216" 
push "rcvbuf 393216"
### Redirecciona todo el trafico del cliente Openvpn hasta el gw del servidor
push "redirect-gateway def1"
### Cifrado y Encriptacion
tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
cipher aes-256-cbc
auth sha512
auth-nocache
tls-version-min 1.2
### Habilita el servidor TLS y empieza a negociar la clave
tls-server
### Sale en el caso de que la negociacion TLS falle.
tls-exit
persist-key
push "persist-key"
persist-tun
### Maximo de clientes de la VPN y posibilidad de verse entre ellos
max-clients 6
client-to-client
### Compresion
compress lz4-v2
### Ping cada 10 segundos y máximo de 120 para contestación
keepalive 10 120
### Logs
log-append /var/log/openvpn.log
status /var/log/openvpn-status.log
verb 4
explicit-exit-notify 1

Guardamos cambios y ejecutamos:
touch /var/log/openvpn.log && /etc/init.d/openvpn restart

Si todo ha ido bien, deberíamos de ver que el servicio se ha iniciado correctamente con la configuración que hemos establecido anteriormente.

Seguidamente, creamos un script de iptables para dar cierta seguridad al entorno:

nano -c /etc/init.d/nombrescript

#!/bin/bash
### BEGIN INIT INFO
# Provides:             fwipv4-Statefull
# Required-Start:       $network
# Required-Stop:        $network
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description: Activando Iptables SPI
# Autor: https://www.linkedin.com/in/fblancos
# Date: 12/11/2018 Version: 0.9
### END INIT INFO
flush_reglas(){
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
}
set_policy(){
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
}
unset_policy(){
iptables -P INPUT ACCEPT
iptables -P OUTPUT DROP
iptables -P FORWARD ACCEPT
}
reglas(){
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
#Reglas
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
### 1: DROP INVALID PACKETS ###
iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
### 1.B: DROP TCP PACKETS THAT ARE NEW AND ARE NOT SYN ###
iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
### 1.C: DROP TCP PACKETS THAT ARE NEW AND ARE NOT SYN ###
iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
### 2: BLOCK PACKETS WITH BOGUS TCP FLAGS ###
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP
### 3: BLOCK SPOOFED PACKETS ###
iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP
iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
iptables -t mangle -A PREROUTING -s 248.0.0.0/5 -j DROP
iptables -t mangle -A PREROUTING -s 255.255.255.255/32 -j DROP
### OpenVPN RULES ###
# DROP INVALID SYN PACKETS
iptables -A FORWARD -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP
iptables -A FORWARD -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A FORWARD -o ens160 -p udp --dport 53 -m state -d DNSINTERNO1 --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ens160 -p udp --sport 53 -m state -s DNSINTERNO1 --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -o ens160 -p udp --dport 123 -m state -d NTPINTERNO1 --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ens160 -p udp --sport 123 -m state -s NTPINTERNO1 --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -o ens160 -p tcp -m multiport --dports 80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ens160 -p tcp -m multiport --sports 80,443 -m state --state ESTABLISHED -j ACCEPT
# ALLOW WHATSAPP :-)
iptables -A FORWARD -o ens160 -p tcp -m multiport --dports 5222:5228 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ens160 -p tcp -m multiport --sports 5222:5228 -m state --state ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.58.0.0/27 -o ens160 -j SNAT --to LOCALIPSERVER
# MAKE SURE NEW OUTGOING TCP CONNECTIONS ARE SYN PACKETS; OTHERWISE WE NEED TO DROP THEM
iptables -A FORWARD -p tcp ! --syn -m state --state NEW -j DROP
### LISTENING PORTS ###
iptables -A INPUT -i ens160 -p tcp -s NETLAN/CIDR --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens160 -p tcp -d NETLAN/CIDR --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --dport 11194 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp --sport 11194 -m state --state ESTABLISHED -j ACCEPT
### OUT TO LAN ###
iptables -A OUTPUT -o ens160 -p udp --dport 53 -m state -d DNSINTERNO1 --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens160 -p udp --sport 53 -m state -s DNSINTERNO1 --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens160 -p udp --dport 123 -m state -d NTPINTERNO1 --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens160 -p udp --sport 123 -m state -s NTPINTERNO1 --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens160 -p tcp -m multiport --dports 80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i ens160 -p tcp -m multiport --sports 80,443 -m state --state ESTABLISHED -j ACCEPT
# INVALID PACKAGES
iptables -A OUTPUT -m conntrack --ctstate INVALID -j DROP
# INVALID SYN PACKAGES
iptables -A OUTPUT -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP
iptables -A OUTPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A OUTPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# MAKE SURE NEW OUTGOING TCP CONNECTIONS ARE SYN PACKETS; OTHERWISE WE NEED TO DROP THEM
iptables -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP
# DROP PACKETS WITH OUTGOING FRAGMENTS. THIS ATTACK RESULT INTO LINUX SERVER PANIC SUCH DATA LOSS
iptables -A OUTPUT -f -j DROP
# DROP OUTGOING MALFORMED XMAS PACKETS
iptables -A OUTPUT -p tcp --tcp-flags ALL ALL -j DROP
# DROP OUTGOING MALFORMED NULL PACKETS
iptables -A OUTPUT -p tcp --tcp-flags ALL NONE -j DROP
# INVALID ICMP PACKETS NEED TO BE DROPPED TO PREVENT A POSSIBLE EXPLOIT
iptables -A OUTPUT -m state -p icmp --state INVALID -j DROP
# DROPS
#iptables -N LOGGING #Crea la cadena
#iptables -A INPUT -j LOGGING #Pasa los input por la cadena de logs
#iptables -A FORWARD -j LOGGING #Pasa los forward por la cadena de logs
#iptables -A OUTPUT -j LOGGING #Pasa los outgoing por la cadena de logs
#iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
#iptables -A LOGGING -j DROP

}
case "$1" in

start)
flush_reglas
set_policy
reglas
echo "Firewall activado"
;;

stop)
flush_reglas
unset_policy
echo "Firewall desactivado"
;;

restart)

$0 stop
$0 start
;;

*)

echo "Usar ejecutando: /etc/init.d/$0 {start|stop|restart}"
;;

esac


Damos permisos y hacemos que se ejecute en cada arranque

chmod 700 nombrescript && chown root:root nombrescript && chmod +x nombrescript && update-rc-d nombrescript defaults

Ahora hacemos un pequeño tunning en el sysctl.conf y añadimos:
# DMESG only readeable by root
kernel.dmesg_restrict = 1
######### VPN #########
net.ipv4.ip_forward = 1
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Size of the listen queue for accepting new TCP connections (default: 128)
net.core.somaxconn = 4096
# Maximum Socket Receive Buffer for all protocols (in bytes)
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
# Set Linux autotuning TCP buffer limits
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216

######### GENERAL SECURITY OPTIONS ################
# Automatically Reboot Server in 30 Seconds after a Kernel Panic
vm.panic_on_oom = 1
kernel.panic = 30
kernel.panic_on_oops = 30
# Enable ExecShield
kernel.randomize_va_space = 2
# Controls whether core dumps will append the PID to the core filename
kernel.core_uses_pid = 1
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 3
# Protected links
fs.protected_symlinks = 1
fs.protected_hardlinks = 1
# Martian packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0

Es el turno de configurar el cliente:
dev tun
client
proto udp
remote direccionipexterna 11194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher aes-256-cbc
auth sha512
tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA256
ca ca.crt #Fichero a copiar en el dispositivo cliente
cert cliente1.crt #Fichero a copiar en el dispositivo cliente
key cliente1.key #Fichero a copiar en el dispositivo cliente
tls-auth ta.key 1 #Fichero a copiar en el dispositivo cliente
auth-nocache
comp-lzo
verb 3

Como comentaba al principio, en Android se puede usar esta aplicación OpenVPN for Android 

Ya quedaría complemente listo y funcional.

Saludos a tod@s!


No hay comentarios:

Publicar un comentario