Salta el contingut

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:

  1. Revocar l'accés del dispositiu perdut immediatament
  2. Crear una nova configuració per al nou dispositiu
  3. Assegurar-te que el dispositiu perdut no pot accedir a la xarxa interna

Rúbrica

Vegeu Rúbrica PR5022.