================================================================
SD Tech Solutions — Barebones IKEv2 Road-Warrior VPN  (v1.0)
================================================================
Minimal, modern-crypto-only IKEv2 remote-access VPN. Two recipes:
(A) pfSense / OPNsense checklist, (B) Linux strongSwan (swanctl).
Replace ALL <PLACEHOLDER> values. EAP-MSCHAPv2 with per-user
credentials + server certificate; no shared-secret-only setups.

CRYPTO BASELINE (both recipes — do not weaken)
  IKE (phase 1):  AES-256-GCM / SHA-384 / DH group 20 (ECP-384)
  ESP (phase 2):  AES-256-GCM  (AEAD — no separate auth needed)
  Rekey: IKE 8h, Child 1h. Dead peer detection 30s.
  NO: 3DES, SHA1, DH group 2/5, aggressive mode, IKEv1.

----------------------------------------------------------------
(A) pfSense / OPNsense CHECKLIST
----------------------------------------------------------------
 1. System > Cert Manager: create internal CA, then a SERVER cert
    with SAN = vpn.<CLIENT_DOMAIN> (must match what clients dial).
 2. VPN > IPsec > Mobile Clients: enable, Virtual Address Pool =
    <VPN_POOL>/24 (e.g. 10.77.0.0/24), DNS server = internal DNS.
 3. Phase 1: IKEv2, interface WAN, auth = EAP-MSCHAPv2,
    my identifier = distinguished name of server cert,
    encryption AES256-GCM / SHA384 / DH 20.
 4. Phase 2: mode tunnel, local network = LAN (or "Network" list),
    AES256-GCM.
 5. User Manager: one account per human (never shared), strong
    passphrases; disable account on offboarding SAME DAY.
 6. Firewall > Rules > IPsec tab: default deny; allow only the
    subnets/ports remote staff actually need (least privilege).
 7. Export the CA cert to clients (Windows: machine Trusted Root;
    macOS/iOS: profile). Built-in clients on Win/macOS/iOS/Android
    all speak IKEv2/EAP — no third-party VPN app needed.

----------------------------------------------------------------
(B) Linux strongSwan — /etc/swanctl/swanctl.conf
----------------------------------------------------------------
connections {
  rw {
    version = 2
    local_addrs = <SERVER_PUBLIC_IP>
    proposals = aes256gcm16-prfsha384-ecp384
    pools = rw_pool
    local {
      auth = pubkey
      certs = server-cert.pem            # CN/SAN = vpn.<CLIENT_DOMAIN>
      id = vpn.<CLIENT_DOMAIN>
    }
    remote {
      auth = eap-mschapv2
      eap_id = %any
    }
    children {
      rw {
        local_ts = <LAN_SUBNET>          # e.g. 192.168.10.0/24
        esp_proposals = aes256gcm16
        rekey_time = 1h
        dpd_action = clear
      }
    }
  }
}
pools {
  rw_pool { addrs = <VPN_POOL>/24  dns = <INTERNAL_DNS> }
}
secrets {
  eap-user1 { id = <USERNAME>  secret = "<PER-USER-PASSPHRASE>" }
}

# Kernel: net.ipv4.ip_forward=1 ; open UDP 500 + 4500 on the edge.
# Verify:  swanctl --load-all && swanctl --list-conns
----------------------------------------------------------------

HARDENING NOTES
 - Management of the VPN box itself belongs on the MGMT VLAN.
 - Log and review connection events (who / when / from where).
 - Prefer certificates or EAP-TLS per device when the client can
   manage them; MSCHAPv2 passphrases are the pragmatic floor.

Deployed by SD Tech Solutions · sd-techsolutions.com
