VPN service

1. About

A virtual private network (VPN) is a mechanism for creating a secure connection to extend access to a private network (one that disallows or restricts public access) to users who do not have direct access to it, such as an office network allowing secure access using an insecure communication medium such as the public Internet.

2. Systems

2.1 Frontend

FQDN IPv6 IPv4 Notes
connect.vpn.bfh.science High-available entry-point for all VPN connections
vpn.bfh.science Setup URL for VPN configuration (without split tunneling recommended)
all.vpn.bfh.science Setup URL for VPN configuration (without split tunneling)
FQDN IPv6 IPv4 Notes
connect.vpn-test.bfh.science High-available entry-point for all VPN-Test connections
vpn-test.bfh.science Setup URL for VPN Test configuration (without split tunneling recommended)
all.vpn-test.bfh.science Setup URL for VPN Test configuration (without split tunneling)

2.2 Backend

Warning
Always use the frontend DNS record

Never use the backend nodes directly:

  • backend may change without notice at any time (e.g. IP addresses, DNS records, configuration, etc.)
  • backend has no legacy support or grace periods, changes are implemented instantly
  • backend can be rebootet without notice at any time
  • backend access will soon be restricted

FQDN IPv6 IPv4
node1.vpn.bfh.science 2a07:6b44:115:11::21 10.4.123.21
node2.vpn.bfh.science 2a07:6b44:115:11::22 10.4.123.22
node3.vpn.bfh.science 2a07:6b44:115:11::23 10.4.123.23
node4.vpn.bfh.science 2a07:6b44:115:11::24 10.4.123.24
proxy.vpn.bfh.science 2a07:6b44:115:11::10 147.87.28.2
node1.proxy.vpn.bfh.science 2a07:6b44:115:11::11 147.87.28.3
node2.proxy.vpn.bfh.science 2a07:6b44:115:11::12 147.87.28.4
proxy.oauth2.vpn.bfh.science 2a07:6b44:115:11::26 147.87.28.10
node1.proxy.oauth2.vpn.bfh.science 2a07:6b44:115:11::27 147.87.28.11
node2.proxy.oauth2.vpn.bfh.science 2a07:6b44:115:11::28 147.87.28.12
web.vpn.bfh.science 2a07:6b40::82 147.87.0.82
FQDN IPv6 IPv4
node1.vpn-test.bfh.science 2a07:6b44:116:11::21 10.4.124.21
node2.vpn-test.bfh.science 2a07:6b44:116:11::22 10.4.124.22
node3.vpn-test.bfh.science 2a07:6b44:116:11::23 10.4.124.23
node4.vpn-test.bfh.science 2a07:6b44:116:11::24 10.4.124.24
proxy.vpn-test.bfh.science 2a07:6b44:116:11::18 147.87.28.18
node1.proxy.vpn-test.bfh.science 2a07:6b44:116:11::19 147.87.28.19
node2.proxy.vpn-test.bfh.science 2a07:6b44:116:11::20 147.87.28.20
proxy.oauth2.vpn-test.bfh.science 2a07:6b44:116:11::26 147.87.28.26
node1.proxy.oauth2.vpn-test.bfh.science 2a07:6b44:116:11::27 147.87.28.27
node2.proxy.oauth2.vpn-test.bfh.science 2a07:6b44:116:11::28 147.87.28.28
web.vpn-test.bfh.science 2a07:6b40::84 147.87.0.84
FQDN IPv6 IPv4
vc41.bfh.ch 147.87.19.66
vc42.bfh.ch 147.87.19.67
vc43.bfh.ch 147.87.19.68
vc39.bfh.ch 147.87.19.74

3. Features

3.1 Access

  • all staff and student accounts are automatically granted the permission to use VPN, unless they are member of the IDM.perm.infrastructure.vpn.no-access group in LDAP.

  • all other accounts can be manually granted permission if needed (such as guest and ext accounts) by making them a member of the IDM.perm.infrastructure.vpn.access group in LDAP.

  • cliens use TLS-CRYPT certificate as shared secret

3.2 Sessions

  • there is no session limit, multiple devices can be connect with one account at the same time.

  • there is session timeout of 3d after which clients are automatically disconnected.

  • there is no bandwith limit, however individual client connections currently top-out at around 1GB/s.

  • VPN connections from BFH internal network are blocked.

3.3 Client addresses

  • each client recieves both a public IPv4 (147.87.80.0/20) and a public IPv6 address (2a07:6b44:209::/48) managed by the VPN server (not via DHCP), detailed subnet to node mappings are listed in the subnet list.

  • there is no subnet propagation, the VPN service is for connecting single clients to the BFH network, not entire subnets (site-to-site).

  • there is no client isolation, VPN clients are part of fabric-clients and can reach each other as well as any network addresses just as LAN and WLAN clients.

  • there is no DDNS for clients conntected to VPN.

3.4 Client routing

  • VPN is a Layer 3 Tunnel (tun) via UDP on the default port 1194 with fallback on TCP port 443.

  • General connection preference is: udp6 → udp4 → tcp6 → tcp4

  • failover indiscriminatly, regardless of connectivity or daemon load.

  • with the default profile (vpn.bfh.science), only BFH IPv6 subnets and IPv4 subnets go through VPN, everything else goes through the local internet uplink.

  • exceptions are maintained for e.g. book publishers that have allowed BFH subnets for their services, these are also going through VPN.

  • with the all profile (all.vpn.bfh.science), all traffic goes through the tunnel.

  • DNS queries for bfh.ch are tunneled through VPN when using a windows client, all other DNS queries do not go through the tunnel but the to the local resolver, → see client matrix.

3.5 Client configuration

  • only openvpn3 clients are supported.

  • the setup URLs are:

    • either https://vpn.bfh.science (with split tunneling, recommended)

    • or https://all.vpn.bfh.science (without split tunneling)

  • the connection host is connect.vpn.bfh.science

  • the configuration is only downloaded once during the setup of the client, there is no automatic configuration update (needs to be triggered manually on the client by re-running the setup).

  • users authenticate with their BFH UPN and password as present in LDAP (e.g. foo1@bfh.ch).

  • client uses nobind to have the tun interface move on top the active interface (LAN vs. WLAN)

  • client verifies endpoint client certificate (with embedded root ca certificate)

  • client uses decreased poll timeout to 5s

  • data cipher is CHACHA20-POLY1305

3.6 Server load-balancing

  • 2 nodes with nft as loadbalancer (active/passive)

  • nft loadbalancer does round-robin on both backends and instances

  • traffic to the loadbalancers (/29) are excluded from the tunnel

3.7 Server connections

  • each backend has multiple daemons to handle many sessions in parallel for maximizing bandwith

  • each daemon has its own subnet (openvpn is setup in subnet topology)

  • management port per daemon on socket (/run/openvpn/management_$id.socket)

3.8 Split tunneling

  • we recommend using split tunneling, i.e. only traffic to the BFH network is routed through the VPN tunnel.

  • we maintain a list of exceptions that are also routed through the tunnel, such as library resources and scientific publishes where BFH has a IP-restriction based subscription. new exceptions can be requested via servicedesk

  • we don’t recommend choosing to route all traffic trought the the VPN tunnel, i.e. disabling split tunneling, in order to avoid local network problems, issues with cloud services, and for performance reasons.

4. Operations

4.1 Client

  • Download Client:

  • On managed BFH Clients (macOS and Windows):

    • Team MWS provides regularly on their on schedule new versions of the openvpn client.

    • Generally always the newest client can and should be used.

    • If we are aware of important security fixes, we proactively ask Team MWS to deploy updates.

  • On unmanaged Clients:

    • Users have to update the package on their own. On Linux, we recommend to use automatic updates (of all packages, not just openvpn).

4.2 Client features

Feature Linux macOS Windows Android iOS
Client version (as of 2026-01-27) 26+dfsg-2 3.8.1 3.8.0 3.7.1 3.7.2
Config download works? yes yes yes yes yes
IPv6 routes set? yes yes yes yes yes
IPv4 routes set? yes yes yes yes yes
DNS internal view for bfh.ch? yes yes yes yes no
IPv6 precedence over IPv4? yes yes yes yes yes
Fail-over-duration when daemon full? TODO TODO 43s TODO TODO
Access to hotspots VPN? TODO no
Uses system TLS certificates? yes no no TODO no

4.3 VPN throughput

Prerequisites Linux macOS Windows 11 (BFH) Windows 11
CPU i7-1165G7 M1 i7-1165G7 i7-1165G7
Raw LAN on AC 881Mbps 923Mbps 930Mbps 925Mbps
VPN via LAN on AC 800Mbps 729Mbps 421Mbps 669Mbps
Raw LAN on DC 870Mbps 909Mbps 927Mbps 927Mbps
VPN via LAN on DC 784Mbps 724Mbps 109Mbps 257Mbps
Raw WLAN on AC 208Mbps 182Mbps 207Mbps 196Mbps
VPN via WLAN on AC 160Mbps 183Mbps 142Mbps 154Mbps
Raw WLAN on DC 214Mbps 191Mbps 212Mbps 154Mbps
VPN via WLAN on DC 159Mbps 181Mbps 112Mbps 130Mbps

4.4 Server recovery

  • On base[5-8] and base10 start all vpn.bfh.science containers

  • Check if all vpn workers (daemon*.node*.vpn.bfh.science) are running (# sudo systemctl status openvpn-server@* | grep "^Active"). There should be 16 running daemons listed for each node.

  • Check if oAuth2 proxy (node*.proxy.oauth2.vpn.bfh.science) is running by checking if https://oauth2.vpn.bfh.science/101/ready. This should return “OK”. Please iterate “101” from 101 to 116, 201 to 216, 301 to 316 and 401 to 416.

  • Check if the loadbalancer (node*.proxy.vpn.bfh.science) is running by checking if nftables is populated on the node (# nft list ruleset should have chains like TO_NODE*, loadbalancing, ratelimiting …). Pinging (v4 and v6) to connect.vpn.bfh.science should be successful.

  • Check if there are already users (# ssh node*.vpn.bfh.science sudo /srv/node*.vpn.bfh.science/openvpn/bin/get_all_loggedin_clients).

  • Check if rate limiter has been hit (# ssh connect.vpn.bfh.science sudo nft list sets). IP addresses which are in the set “BAN_V*” cannot establish new connections.

6. Backlog

Legacy

  • Switch off Cisco ASA (VPN-ext) on 4.5.2026

Setup

  • shs1: redesign of VPN subnets for better firewall deployment

  • krj2: unblock script for ratelmited IPs

  • krj2: script usual operations like killing sessions of a user etc.

  • krj2: Entra oAuth2 Passwort in Azure Appreg durch Zertifikat ersetzen (#857)

  • bad9: tidy apache config to allow allowed users only (i.e. no ext on main, no main on ext)

  • TODO: aggregate logs on vpn.bfh.science

  • TODO: vpn desaster recovery documentation/exercise

Features

  • try Data Channel Offload (DCO) with Linux >= 6.16

  • try DDNS via client-connect/client-disconnect hooks auf openvpn-server

  • authentication with certificates

  • replace nft loadbalancer with udp aware proxy

Known issues

  • configuration inconsistency: OpenVPN Client bug on IPv6-only systems (#351)

  • android: “always on” vpn warnings

  • openvpn3-client doesn’t support connection profiles (#15)

  • there’s no possibility to push config changes or an updated config to the client

  • openvpn-auth-ldap doesn’t support defered authentication (#66, #67)

  • OpenVPN3 connect client (version >= 3.8.0) hangs trying to connect. Cause: if any modifications (username or password entry) are done after the import of the profile. Workaround: Purge profile, fetch profile with the correct username, do not modify the config (no password save).

  • iPerf3 and iPerf3-darwin on MacOS and iOS does not send packages through VPN. Ping and traceroute on the other hand do.