This article relies on the following skills:
Recommended desktop/mobile clients:
Establish VPN-connection. Verify your client traffic is routed via VPN-gateway.
traceroute openwrt.org
Verify your client public IP-Address has changed.
Make sure there are no client-ISP DNS-servers in the DNS-Leak test results.
If using a dual-stack, verify your client IPv6-traffic is routed via VPN6-gateway.
traceroute6 openwrt.org
Verify your client public IPv6-Address has changed.
Request IPv6-pool from your server-ISP and delegate it to VPN-network to pass Browser-Default-IPv6 and Browser-Fallback-IPv4 tests.
Collect and analyze the following information.
# Restart the services, then try to reconnect service log restart; service openvpn restart; sleep 10 # Log and status logread -e openvpn; netstat -l -n -p | grep openvpn # Runtime configuration pgrep -f -a openvpn ip addr show; ip route list; ip rule list; iptables-save # Persistent configuration uci show network; uci show firewall; uci show openvpn head -n -0 /etc/openvpn/*.ovpn
If using a dual-stack, check IPv6-stack runtime configuration.
ip -6 addr show; ip -6 route list; ip -6 rule list; ip6tables-save
If you want to manage OpenVPN instances via LuCI.
opkg update
opkg install luci-app-openvpn
Use Easy-RSA to add clients or revoke their certificates via CRL.
# Set up Easy-RSA parameters EASYRSA_PKI="/etc/easy-rsa/pki" # Add one more client easyrsa --batch --pki-dir="$EASYRSA_PKI" build-client-full vpnclient1 nopass # Add another client encrypting its private key easyrsa --batch --pki-dir="$EASYRSA_PKI" build-client-full vpnclient2 # Revoke vpnclient certificate easyrsa --batch --pki-dir="$EASYRSA_PKI" revoke vpnclient # Generate a CRL and fix permissions easyrsa --batch --pki-dir="$EASYRSA_PKI" gen-crl chmod "u=rwX,g=rX,o=rX" "$EASYRSA_PKI" "$EASYRSA_PKI/crl.pem" # Enable CRL-verification uci set openvpn.vpnserver.crl_verify="$EASYRSA_PKI/crl.pem" uci commit openvpn service openvpn restart vpnserver
Use CCD on VPN-server for client static IP-address allocation, assuming that:
192.168.8.0/24
- VPN-networkfdf1:7610:d152:3a9c::/64
- VPN6-networkmkdir -p /etc/openvpn/ccd cat << "EOF" > /etc/openvpn/ccd/vpnclient ifconfig-push 192.168.8.2 255.255.255.0 ifconfig-ipv6-push fdf1:7610:d152:3a9c::2/64 EOF uci set openvpn.vpnserver.client_config_dir="/etc/openvpn/ccd" uci commit openvpn service openvpn restart vpnserver
If you do not need to push all the traffic via VPN-gateway. Disable gateway redirect on VPN-server.
uci del_list openvpn.vpnserver.push="redirect-gateway def1" uci del_list openvpn.vpnserver.push="redirect-gateway def1 ipv6" uci commit openvpn service openvpn restart vpnserver
Or ignore it on VPN-client.
sed -i -e " /^\s*redirect-gateway/d \$a pull-filter ignore redirect-gateway " /etc/openvpn/vpnclient.ovpn
Implement plain routing between server-LAN and client-LAN, assuming that:
192.168.1.0/24
- server-LAN192.168.2.0/24
- client-LAN192.168.8.0/24
- VPN-network192.168.8.2/24
- VPN-clientEnable CCD on VPN-server, add client-LAN route, push server-LAN route.
mkdir -p /etc/openvpn/ccd cat << "EOF" > /etc/openvpn/ccd/vpnclient ifconfig-push 192.168.8.2 255.255.255.0 iroute 192.168.2.0 255.255.255.0 EOF uci set openvpn.vpnserver.client_config_dir="/etc/openvpn/ccd" uci add_list openvpn.vpnserver.route="192.168.2.0 255.255.255.0 192.168.8.2" uci add_list openvpn.vpnserver.push="route 192.168.1.0 255.255.255.0" uci commit openvpn service openvpn restart vpnserver
Consider VPN-network as private and assign it to LAN-zone on VPN-client.
uci del_list firewall.@zone[1].network="vpnclient" uci add_list firewall.@zone[0].network="vpnclient" uci commit firewall service firewall restart
If VPN-gateway is not your LAN-gateway, assuming that:
192.168.1.0/24
- LAN-network192.168.1.2/24
- VPN-gateway192.168.8.0/24
- VPN-networkAdd port forwarding for VPN-server on LAN-gateway.
uci add firewall redirect uci set firewall.@redirect[-1].name="Redirect-OpenVPN" uci set firewall.@redirect[-1].src="wan" uci set firewall.@redirect[-1].src_dport="1194" uci set firewall.@redirect[-1].dest="lan" uci set firewall.@redirect[-1].dest_ip="192.168.1.2" uci set firewall.@redirect[-1].dest_port="1194" uci set firewall.@redirect[-1].proto="udp" uci set firewall.@redirect[-1].target="DNAT" uci commit firewall service firewall restart
Add VPN-network route via VPN-gateway on LAN-gateway.
uci add network route uci set network.@route[-1].interface="lan" uci set network.@route[-1].target="192.168.8.0/24" uci set network.@route[-1].gateway="192.168.1.2" uci commit network service network reload
Setting up VPN-server as a dual stack gateway. Your server-ISP is required to provide dual stack connectivity.
Enable IPv6-tunnel. Redirect both GW4 and GW6. Replace DNS4 with DNS6. Add default IPv6-route for VPN-clients.
uci set openvpn.vpnserver.server_ipv6="fdf1:7610:d152:3a9c::/64" uci del_list openvpn.vpnserver.push="redirect-gateway def1" uci add_list openvpn.vpnserver.push="redirect-gateway def1 ipv6" uci del_list openvpn.vpnserver.push="dhcp-option DNS $(uci get network.lan.ipaddr)" uci add_list openvpn.vpnserver.push="dhcp-option DNS $(uci get openvpn.vpnserver.server_ipv6 | sed -e "s/\/.*$/1/")" uci commit openvpn service openvpn restart vpnserver source /lib/functions/network.sh network_find_wan6 NET_IF network_get_gateway6 NET_GW "$NET_IF" uci add network route6 uci set network.@route6[-1].interface="$NET_IF" uci set network.@route6[-1].source="$(uci get openvpn.vpnserver.server_ipv6)" uci set network.@route6[-1].target="::/0" uci set network.@route6[-1].gateway="$NET_GW" uci commit network service network reload
Enable NAT6 using a firewall script to populate NAT6-table from NAT4-table dump.
opkg update opkg install kmod-ipt-nat6 cat << "EOF" > /etc/firewall.user iptables-save --table="nat" \ | sed -e "/\s[DS]NAT\s/d" \ | ip6tables-restore --table="nat" EOF uci set firewall.@include[0].reload="1" uci commit firewall service firewall restart
Request IPv6-pool from your server-ISP and delegate it to VPN6-network to avoid NAT6 setup.
Use TCP for troubleshooting.
uci set openvpn.vpnserver.proto="tcp" uci commit openvpn service openvpn restart vpnserver uci set firewall.@rule[-1].proto="$(uci get openvpn.vpnserver.proto)" uci commit firewall service firewall restart sed -i -r -e "s/^(remote\s.*\s).*/\1$(uci get openvpn.vpnserver.proto)/" /etc/openvpn/*.ovpn
If you need to utilize bridging.
VPN_POOL="$(uci get network.lan.ipaddr | sed -r -e 's/(.*)\d+$/\1128 \1254/')" uci delete openvpn.vpnserver.server uci set openvpn.vpnserver.dev="tap0" uci set openvpn.vpnserver.server_bridge="$(uci get network.lan.ipaddr) $(uci get network.lan.netmask) $VPN_POOL" uci commit openvpn service openvpn restart vpnserver uci delete network.vpnserver uci set network.lan.type="bridge" uci set network.lan.ifname="$(uci get network.lan.ifname) $(uci get openvpn.vpnserver.dev)" uci commit network service network reload uci del_list firewall.@zone[0].network="vpnserver" uci commit firewall service firewall restart sed -i -r -e "s/^(dev\s).*/\1$(uci get openvpn.vpnserver.dev | sed -e "s/\d*$//")/" /etc/openvpn/*.ovpn
Enable lz4 compression. Beware of compatibility and security issues.
uci set openvpn.vpnserver.compress="lz4" uci add_list openvpn.vpnserver.push="compress $(uci get openvpn.vpnserver.compress)" uci commit openvpn service openvpn restart vpnserver
Increase log verbosity for troubleshooting.
uci set openvpn.vpnserver.verb="5" uci commit openvpn service openvpn restart vpnserver sed -i -r -e "s/^(verb\s).*/\1$(uci get openvpn.vpnserver.verb)/" /etc/openvpn/*.ovpn
Fix DNS-leak on Linux desktop client using NetworkManager.
nmcli connection modify vpnclient ipv4.dns-priority "-50" ipv6.dns-priority "-50" nmcli connection down vpnclient nmcli connection up vpnclient
Fix DNS-leak for Windows desktop client.
cat << EOF >> /etc/openvpn/vpnclient.ovpn block-outside-dns EOF
If using a dual-stack, fix IPv6-routing for Windows desktop client.
NETSH_IPV6="C:\\\\Windows\\\\System32\\\\cmd.exe /c netsh interface ipv6" cat << EOF >> /etc/openvpn/vpnclient.ovpn script-security 2 up '$NETSH_IPV6 set privacy state=disabled store=active & echo' ipchange '$NETSH_IPV6 set global randomizeidentifiers=disabled store=active & echo' route-up '$NETSH_IPV6 delete route prefix=%ifconfig_ipv6_local%/%ifconfig_ipv6_netbits% interface=%dev_idx% store=active' EOF