dadv: (Default)
Choose your future ([personal profile] dadv) wrote2023-12-24 01:31 pm

IKEv2 IPSec Road Warrior для FreeBSD

В продолжение темы. Заметка о настройке VPN-доступа для клиентских устройств, с тем чтобы давать им удалённый доступ в локальную сеть. В качестве агента IKEv2 используем strongswan-5.9.11_3, плюс для клиенских подключений создаем интерфейсы ipsecX ради удобства настройки MTU, роутинга, диагностики при помощи bpf (tcpdump/tshark/wireshark/etc.), SNMP-статистики и прочего. Авторизация клиентов методом IKEv2 IPSEC MS-CHAPv2. Условное имя VPN-сервера для клиентов vpn.domain.net.
  • Первым делом добавляем в /usr/local/etc/strongswan.d/charon.conf:

    install_routes = no
    install_virtual_ip = no
    make_before_break = yes
    retransmit_base = 1
    

    Если у шлюза более одного интерфейса и необходимо, чтобы агент использовал порты 500/4500 только на IP-адресах одного из них, можно также добавить:

    interfaces_use = bge0

    Для более подробных журналов, туда же:

    syslog {
      IKE2 {
        log_level = 9
      }
      daemon {
         ike_name = yes
         knl = 3
      }
    }
  • Далее создаём /usr/local/etc/swanctl/conf.d/vpn.conf:
    connections {
      vpn {
        version             = 2
        send_cert           = always
        pull                = 0
        dpd_delay           = 5
        local_addrs         = X.X.X.X # IP-адрес, в который ресолвится vpn.domain.net
    #   pools               = localpool
        pools               = radius
        proposals           = aes256-sha256-modp2048,aes256-sha256-modp1024,aes256-sha256-modp4096,default
        reauth_time         = 43200
        local {
            auth            = pubkey
            certs           = vpn.domain.net.pem
            id              = fqdn:vpn.domain.net
        }
        remote {
    #       auth            = eap-mschapv2
            auth            = eap-radius
            eap_id          = %any
        }
        children {
          roadw-eap {
            mode            = tunnel
            ipcomp          = no
            copy_df         = no
            start_action    = start
            close_action    = clear
            dpd_action      = clear
            reqid           = 0
            policies        = no
    #       local_ts        = 192.168.1.0/24
            local_ts        = 0.0.0.0/0
            remote_ts       = dynamic
    
            esp_proposals   = aes256-sha256-modp2048,aes256-sha256-modp1024,aes256-sha256-modp4096,default
            rekey_time      = 0     # workaroung Windows bug
            updown          = /usr/local/etc/swanctl/conf.d/updown.sh
          }
        }
      }
    }
    

    В данном случае предполагается авторизация пользователей по паролю через RADIUS-сервер (для этого strongswan нужно пересобрать из портов, включив опции EAPDYNAMIC и EAPRADIUS, а заодно добавьте какие вам нравятся ещё типа EAPSIMFILE, FARP, IPSECKEY, MEDITATION, UNITY и XAUTH). При локальной авторизации нужно убрать строчку со словом eap-radius, раскомментировать предыдущую строчку с eap-mschapv2 (то же с именем пула в строчке pools) и добавить описание локального пула IP-адресов для выдачи пользователям в конец файла:

    pools {
      localpool {
        addrs = 192.168.1.64-192.168.1.190
        dns = 192.168.1.1
      }
    }
    

    Закомментированный вариант local_ts соответствует доступу через VPN только в указанную сеть, а раскомментированный для хождения через VPN в публичный интернет.

  • При авторизации через RADIUS добавляем в /usr/local/etc/strongswan.d/charon/eap-radius.conf внутрь секции servers {} одну или более секций с произвольными именами, описывающих используемые серверы RADIUS:

    myserver {
      address             = X.X.X.Y
      port                = 1812
      retransmit_base     = 1.0
      retransmit_tries    = 3
      secret              = XXX
      sockets             = 5
      nas_identifier      = vpn.domain.net
    }
    
  • И, наконец, создаём исполняемый скрипт /usr/local/etc/swanctl/conf.d/updown.sh:

    #!/bin/sh
    PATH=/bin:/sbin:/usr/bin:/usr/sbin
    
    mtu=1460
    me=X.X.X.X # IP-адрес, в который ресолвится vpn.domain.net
    
    case "$PLUTO_CONNECTION" in
    roadw-eap)
        case "$PLUTO_VERB" in
        up-client)
            if [ -n "$PLUTO_REQID" ]; then
              ifname=$(ifconfig -g "r${PLUTO_REQID}g")
              if [ -z "$ifname" ]; then
                ifname=$(ifconfig ipsec create \
                    inet $me "$PLUTO_PEER_SOURCEIP" netmask 255.255.255.255 \
                    tunnel "$PLUTO_ME" "$PLUTO_PEER" \
                    reqid "$PLUTO_REQID" group "r${PLUTO_REQID}g" mtu $mtu \
                    description "ikev2: ${PLUTO_XAUTH_ID} \
                       $PLUTO_PEER_SOURCEIP $PLUTO_ME $PLUTO_PEER"
                )
              fi
            fi
            ;;
        down-client)
            if [ -n "$PLUTO_REQID" ]; then
              ifname=$(ifconfig -g "r${PLUTO_REQID}g")
              [ -n "$ifname" ] && ifconfig "$ifname" destroy
            fi
            ;;
        esac
        ;;
    esac
    exit 0
    
  • Осталось только положить секретный ключ от сертификата сервера в формате PEM в файл /usr/local/etc/swanctl/private/vpn.domain.net.key, а сам сертификат также в формате PEM в файл /usr/local/etc/swanctl/x509/vpn.domain.net.pem и запустить агента, прописав в /etc/rc.conf:

    strongswan_enable="YES"
    strongswan_interface="vici"
    
  • И даём команду service strongswan start

Post a comment in response:

This account has disabled anonymous posting.
(will be screened if not validated)
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org