PR5022 - VPN amb WireGuard i Hardening de Sistemes
Objectius
- Desplegar un servidor VPN WireGuard amb Docker
- Configurar clients VPN amb autenticació per claus
- Aplicar hardening a un servidor Linux (SSH, sysctl, auditd)
- Verificar la seguretat del túnel VPN amb Wireshark
- Escanejar vulnerabilitats de la configuració amb Lynis
Prerequisits
| Element | Detall |
|---|---|
| Temps estimat | 4 hores |
| Eines necessàries | Docker Desktop, Wireshark (opcional) |
| Coneixements previs | Conceptes bàsics de criptografia, claus públiques |
| Mòdul relacionat | Seguretat de Xarxes, Hardening |
Introducció
En aquesta pràctica implementarem una solució VPN corporativa usant WireGuard, el protocol VPN modern que amb menys de 4.000 línies de codi ofereix el millor rendiment i la base de codi més auditable de les opcions actuals.
Combinarem la VPN amb tècniques de hardening del servidor per aplicar els conceptes del mòdul d'enfortiment: SSH sense contrasenya, sysctl per al kernel, i auditoria amb Lynis.
flowchart LR
subgraph client1[Client - Teletreball]
C1[PC Joan Garcia\n10.100.0.2]
end
subgraph client2[Client - Oficina remota]
C2[PC Maria Puig\n10.100.0.3]
end
subgraph server[Servidor VPN]
WG[WireGuard Server\n10.100.0.1\nPort 51820/UDP]
end
subgraph intranet[Xarxa Interna]
APP[Aplicació interna\n192.168.1.10]
DB[(Base de dades\n192.168.1.20)]
end
C1 -->|Túnel xifrat UDP/51820| WG
C2 -->|Túnel xifrat UDP/51820| WG
WG --> APP
WG --> DB
Part 1: Servidor WireGuard
1.1 Generar claus criptogràfiques
WireGuard usa criptografia de corba el·líptica (Curve25519). Cada par servidor/client necessita la seva pròpia parella de claus:
# Crear directori de treball
mkdir -p vpn-NOMCOGNOM/keys
cd vpn-NOMCOGNOM
# Generar claus per al servidor
docker run --rm -v $(pwd)/keys:/keys lscr.io/linuxserver/wireguard:latest \
bash -c "wg genkey | tee /keys/server_private.key | wg pubkey > /keys/server_public.key"
# Generar claus per al client 1 (joan-garcia)
docker run --rm -v $(pwd)/keys:/keys lscr.io/linuxserver/wireguard:latest \
bash -c "wg genkey | tee /keys/client1_private.key | wg pubkey > /keys/client1_public.key"
# Generar claus per al client 2 (maria-puig)
docker run --rm -v $(pwd)/keys:/keys lscr.io/linuxserver/wireguard:latest \
bash -c "wg genkey | tee /keys/client2_private.key | wg pubkey > /keys/client2_public.key"
# Verificar les claus generades
ls -la keys/
cat keys/server_public.key
Protecció de les claus privades
Les claus privades (*_private.key) mai s'han de compartir. Representa la identitat criptogràfica del dispositiu. En producció, es guarden en el fitxer de configuració amb permisos 600 (lectura per al root únicament).
1.2 Configuració del servidor
Crea el fitxer config/server/wg0.conf:
# /etc/wireguard/wg0.conf - Servidor WireGuard NOMCOGNOM
# Generat: 2024
[Interface]
# Adreça IP del servidor dins el túnel VPN
Address = 10.100.0.1/24
# Clau privada del servidor (substituir per el contingut de server_private.key)
PrivateKey = <CONTINGUT_DE_server_private.key>
# Port d'escolta UDP
ListenPort = 51820
# Activar IP forwarding i NAT quan s'iniciï la interfície
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; \
iptables -A FORWARD -o wg0 -j ACCEPT; \
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; \
iptables -D FORWARD -o wg0 -j ACCEPT; \
iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# ===================
# Client 1: Joan Garcia
# ===================
[Peer]
PublicKey = <CONTINGUT_DE_client1_public.key>
# Adreça IP assignada a aquest client dins la VPN
AllowedIPs = 10.100.0.2/32
# ===================
# Client 2: Maria Puig
# ===================
[Peer]
PublicKey = <CONTINGUT_DE_client2_public.key>
AllowedIPs = 10.100.0.3/32
1.3 Docker Compose
# docker-compose.yml
version: '3.8'
services:
# Servidor VPN WireGuard
wireguard-server:
image: lscr.io/linuxserver/wireguard:latest
container_name: vpn-server-NOMCOGNOM
hostname: vpn-server-NOMCOGNOM
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
- SERVERURL=127.0.0.1 # En producció: IP pública del servidor
- SERVERPORT=51820
- PEERS=joan-garcia,maria-puig # Noms dels clients
- PEERDNS=auto
- INTERNAL_SUBNET=10.100.0.0
volumes:
- ./config/server:/config
- /lib/modules:/lib/modules:ro
ports:
- "51820:51820/udp"
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
networks:
vpn_net:
ipv4_address: 172.20.0.10
intranet:
ipv4_address: 192.168.200.1
# Recurs intern accessible via VPN
internal-app:
image: nginx:alpine
container_name: internal-app-NOMCOGNOM
hostname: app-interna-NOMCOGNOM
networks:
intranet:
ipv4_address: 192.168.200.10
volumes:
- ./config/internal-site:/usr/share/nginx/html:ro
networks:
vpn_net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
intranet:
driver: bridge
internal: true # Xarxa interna sense accés a Internet directe
ipam:
config:
- subnet: 192.168.200.0/24
1.4 Iniciar el servidor
# Iniciar el servidor VPN
docker compose up -d wireguard-server
# Verificar que s'ha iniciat correctament
docker logs vpn-server-NOMCOGNOM
# El servidor genera automàticament els fitxers de configuració dels clients
# Veure les configuracions generades:
ls config/server/peer_joan-garcia/
ls config/server/peer_maria-puig/
# Mostrar el QR code per a mòbil (client 1)
docker exec vpn-server-NOMCOGNOM wg showconf wg0
Part 2: Configuració dels clients
2.1 Client Linux (Joan Garcia)
# config/clients/joan-garcia.conf
[Interface]
# Adreça IP del client dins la VPN
Address = 10.100.0.2/24
# Clau privada del client (client1_private.key)
PrivateKey = <CONTINGUT_DE_client1_private.key>
# Servidor DNS a usar quan la VPN està activa
DNS = 10.100.0.1
[Peer]
# Clau pública del servidor
PublicKey = <CONTINGUT_DE_server_public.key>
# Endpoint: adreça pública del servidor
Endpoint = 127.0.0.1:51820
# Xarxes accessibles a través d'aquesta VPN
# 10.100.0.0/24 = xarxa VPN
# 192.168.200.0/24 = xarxa interna
AllowedIPs = 10.100.0.0/24, 192.168.200.0/24
# Keepalive: enviar un paquet cada 25 segons per mantenir la connexió
PersistentKeepalive = 25
2.2 Simular el client amb Docker
# Iniciar un contenidor client per simular el teletreball
docker run -d \
--name vpn-client-joan-NOMCOGNOM \
--cap-add NET_ADMIN \
--sysctl net.ipv4.conf.all.src_valid_mark=1 \
-v $(pwd)/config/clients/joan-garcia.conf:/etc/wireguard/wg0.conf \
lscr.io/linuxserver/wireguard:latest
# Connectar la VPN
docker exec vpn-client-joan-NOMCOGNOM wg-quick up wg0
# Verificar la connexió
docker exec vpn-client-joan-NOMCOGNOM wg show
# Provar l'accés a la xarxa interna via VPN
docker exec vpn-client-joan-NOMCOGNOM ping -c 3 192.168.200.10
docker exec vpn-client-joan-NOMCOGNOM curl http://192.168.200.10
Reflexió 1
Executa wg show dins el client. Quina informació mostra sobre el servidor peer? Quants bytes s'han transferit en el túnel?
Part 3: Hardening del servidor VPN
Un servidor VPN és un punt crític de l'arquitectura. Apliquem hardening per reduir la superfície d'atac:
3.1 Hardening SSH
# Entrar al servidor VPN
docker exec -it vpn-server-NOMCOGNOM bash
# Veure la configuració SSH actual
cat /etc/ssh/sshd_config
# Crear una configuració SSH endurita
cat > /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
# Hardening SSH - NOMCOGNOM
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowTcpForwarding no
Protocol 2
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
EOF
# Reiniciar SSH
service ssh restart
# Verificar que els canvis s'apliquen
sshd -T | grep -E "port|rootlogin|passwordauth"
3.2 Hardening del kernel (sysctl)
# Aplicar paràmetres de hardening del kernel
cat > /etc/sysctl.d/99-hardening.conf << 'EOF'
# Hardening kernel - NOMCOGNOM
# Protecció contre spoofing de IP
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Deshabilitar ICMP redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Protecció SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
# ASLR màxim
kernel.randomize_va_space = 2
# Protegir /proc
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
# Deshabilitar Magic SysRq (innecessari en servidors)
kernel.sysrq = 0
EOF
# Aplicar els canvis
sysctl -p /etc/sysctl.d/99-hardening.conf
# Verificar
sysctl net.ipv4.tcp_syncookies
sysctl kernel.randomize_va_space
3.3 Auditoria amb Lynis
# Instal·lar Lynis
apt-get install -y lynis
# Executar auditoria completa
lynis audit system --no-colors 2>&1 | tee /tmp/lynis-report-NOMCOGNOM.txt
# Veure el resum
grep -A 5 "Hardening index" /tmp/lynis-report-NOMCOGNOM.txt
# Veure suggeriments (warnings)
grep "WARNING" /tmp/lynis-report-NOMCOGNOM.txt | head -20
# Veure suggeriments de millora
grep "SUGGESTION" /tmp/lynis-report-NOMCOGNOM.txt | head -20
Reflexió 2
Quin és l'índex de hardening (Hardening index) que mostra Lynis? Quines són les 3 alertes (WARNING) més importants que detecta? Per cada una, explica breument com la solucionaries.
Part 4: Verificació del xifratge
4.1 Captura de tràfic amb tcpdump
# En el servidor, capturar el tràfic de la interfície física
docker exec vpn-server-NOMCOGNOM bash -c "
apt-get install -y tcpdump &&
# Capturar el tràfic xifrat (UDP/51820) a la interfície física
tcpdump -i eth0 udp port 51820 -w /config/captura-xifrada-NOMCOGNOM.pcap -c 100 &
# Capturar el tràfic desxifrat dins el túnel wg0
tcpdump -i wg0 -w /config/captura-desxifrada-NOMCOGNOM.pcap -c 100 &
sleep 10
"
# Des del client, generar tràfic
docker exec vpn-client-joan-NOMCOGNOM bash -c "
apt-get install -y curl &&
for i in 1 2 3 4 5; do
curl -s http://192.168.200.10 > /dev/null
echo 'Petició $i enviada'
done
"
4.2 Analitzar les captures
# Analitzar el tràfic xifrat (ha de ser il·legible)
docker exec vpn-server-NOMCOGNOM tcpdump -r /config/captura-xifrada-NOMCOGNOM.pcap -nn | head -20
# Has de veure paquets UDP/51820 però NO el contingut HTTP
# Analitzar el tràfic desxifrat dins el túnel (visible)
docker exec vpn-server-NOMCOGNOM tcpdump -r /config/captura-desxifrada-NOMCOGNOM.pcap -nn | head -20
# Has de veure les peticions HTTP en clar (però ja dins la xarxa de confiança)
Reflexió 3
Comparant les dues captures (xifrada i desxifrada), quina diferència observes? Quin protocol apareix a la captura de la interfície física (eth0)? I a la captura del túnel (wg0)? Per què és important que el tràfic VPN sigui indistingible des de fora?
Part 5: Comparativa de solucions VPN
Basant-te en el que has après, completa aquesta taula comparativa:
## Comparativa VPN - NOMCOGNOM
| Característica | WireGuard | OpenVPN | IPSec/IKEv2 |
|----------------|-----------|---------|-------------|
| **Temps de configuració** | | | |
| **Línes de codi** | ~4.000 | ~70.000 | Variable |
| **Rendiment** | | | |
| **Suport mòbil** | | | |
| **Integració empresarial** | | | |
| **Llicència** | GPLv2 | GPLv2 | Estàndard |
## Recomanació per a cada escenari
### Escenari 1: Connexió site-to-site entre dues oficines
**Recomanació**: ____________
**Justificació**: ____________
### Escenari 2: Accés remot per a 200 empleats en teletreball
**Recomanació**: ____________
**Justificació**: ____________
### Escenari 3: Dispositius mòbils corporatius (iOS/Android)
**Recomanació**: ____________
**Justificació**: ____________
Informe final
Crea el document informe_pr5022_NOMCOGNOM.md:
# Informe PR5022 - VPN WireGuard i Hardening
**Alumne**: NOMCOGNOM
**Data**: ____________________
## 1. Configuració del servidor VPN
- IP del servidor en el túnel:
- Port UDP:
- Nombre de clients configurats:
- [Adjunta la configuració del servidor (wg0.conf) anonimitzada]
## 2. Resultat de la connexió VPN
- Adreça IP del client 1 dins el túnel:
- Ping al recurs intern (192.168.200.10): [Captura o output]
## 3. Hardening aplicat
### SSH
- Port canviat a:
- Autenticació per contrasenya desactivada: Sí/No
- [3 opcions de hardening SSH aplicades]
### Kernel (sysctl)
- [Llista els paràmetres aplicats i explica cada un breument]
## 4. Resultat Lynis
- Hardening index: __ / 100
- Principals warnings detectats:
1.
2.
3.
## 5. Anàlisi de les captures de tràfic
- Tràfic a eth0 (xifrat): [Descripció del que observes]
- Tràfic a wg0 (desxifrat): [Descripció del que observes]
## 6. Respostes a les reflexions
[Reflexions 1, 2 i 3]
## 7. Comparativa VPN
[Taula completada + recomanacions]
Pregunta final
Un empleat s'ha quedat sense accés a la VPN perquè ha perdut el dispositiu. Quins passos hauries de fer per:
- Revocar l'accés del dispositiu perdut immediatament
- Crear una nova configuració per al nou dispositiu
- Assegurar-te que el dispositiu perdut no pot accedir a la xarxa interna
Rúbrica
Vegeu Rúbrica PR5022.