docker: OpenVPN Server

サーバ用の設定をメモしておく。

Open VPN network

vpsで動かすOpen VPNのサーバ用のdocker-composeは次のようにし、VPNサーバの動作に必要な証明書、Open VPNのconfigファイルを指定する。

version: '2.3'
services:
  ovpnserver:
    image: ovpn:alpine_3.12.0r1
    container_name: ovpnserver
    init: true
    cap_add:
      - NET_ADMIN
    cap_drop:
      - fowner
      - sys_chroot
      - audit_write
      - setfcap
      - fsetid
    working_dir: /etc/files/OVPN
    network_mode: "host"
    command: RUN
    restart: unless-stopped
    volumes:
      - "./files/serverUDP.conf:/etc/files/OVPN/config.conf"
      - "./files/ccd:/etc/files/OVPN/ccd"
      - "./files/start.sh:/etc/files/OVPN/start.sh"
      - "./files/log:/etc/files/OVPN/log"
      - "./files/cert/pki/ca.crt:/etc/files/CA/ca.crt"
      - "./files/cert/pki/crl.pem:/etc/files/CA/crl.pem"
      - "./files/cert/pki/issued/server.crt:/etc/files/CA/server.crt"
      - "./files/cert/pki/private/server.key:/etc/files/CA/server.key"
      - "./files/cert/ta.key:/etc/files/OVPN/ta.key"

Open VPN サーバのサンプルコンフィグは次。fragmentはipv4(v6plus)またはipv6で接続することを想定して1432で設定している。ipv4(flet’s)が入るなら1426、ipv6だけなら1452になるはず。

# cat serverUDP.conf
proto udp6
port 1194
topology subnet
keepalive 5 30

cipher AES-256-GCM
ncp-ciphers AES-256-GCM
auth SHA256
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
reneg-sec 3600

fragment 1432
mssfix

user nobody
group nobody

verb 3
log-append /etc/files/OVPN/log/ovpn_log.txt
status /etc/files/OVPN/log/openvpn-status.log

ca         /etc/files/CA/ca.crt
cert       /etc/files/CA/server.crt
dh none
ecdh-curve secp521r1
key        /etc/files/CA/server.key
crl-verify /etc/files/CA/crl.pem
tls-crypt   /etc/files/OVPN/ta.key

persist-key
persist-tun

dev tun01
server 10.8.1.0 255.255.255.0
client-config-dir ccd
client-to-client

fragmentの値は接続する回線のMSS (UDP)から最小になるものを選ぶ。なお、Docomo網やVPSはMTU=1500であった。私の環境では1432が最小値となる。出先で接続することを考えれば、安全に1400ぐらいに設定してしまってもよいかもしれない。大きい方がパフォーマンスが良くなるのでfragment=1400のコンテナを別のportにアサインして動かしておくでも良いかも。

IPv4: IPheader=20bytes, udp header=8bytes ---> MSS = MTU - 28bytes
IPv6: IPheader=40bytes, udp header=8bytes ---> MSS = MTU - 48bytes

IPv4 flet's (MTU, MSS) = (1454, 1426)
IPv4 v6plus (MTU, MSS) = (1460, 1432)
IPv4 IPoE   (MTU, MSS) = (1500, 1472)
IPv6 IPoE   (MTU, MSS) = (1500, 1452)

OpenVPNのconfigでは例えば次のようなroute, push “route XXX”を通常は設定する。

# for host kernel
route 192.168.0.0 255.255.0.0

# for vpn client
push "route-metric 90"
push "route 192.168.0.0 255.255.0.0"
push "route 172.16.0.0 255.255.0.0"

今回はFRRでルーティングの交換を行わせるのでOpenVPNのconfigには記載しないでも動く予定。スマートフォンや外出先のラップトップからVPNに接続する場合はOSPFやBGPでのルート交換が難しいのでOpen VPNでルートを流しておいた方が良い。clientのtunnel addressはOSPFやBGPのNeighborアドレスになり変動すると困るのでccdフォルダ下で定義しておく。

# cat ccd/clientB
ifconfig-push 10.8.1.11 255.255.255.0
iroute 192.168.16.0 255.255.240.0

# cat ccd/clientC
ifconfig-push 10.8.1.12 255.255.255.0
iroute 192.168.32.0 255.255.240.0