Skip to content

Instantly share code, notes, and snippets.

@hapylestat
Last active October 25, 2022 15:12
Show Gist options
  • Save hapylestat/c74c4c7c61546c14a047707ec9fabdce to your computer and use it in GitHub Desktop.
Save hapylestat/c74c4c7c61546c14a047707ec9fabdce to your computer and use it in GitHub Desktop.
Configure OpenVPN to work using external DHCP server

Configuration steps:

  • create bridge vpn-bridge and tap device connected to this bridge vpn-server:
nmcli con add ifname vpn-bridge type bridge con-name vpn-bridge-server
nmcli con modify vpn-bridge-server bridge.stp no
nmcli con add type tun ifname vpn-server con-name vpn-server-slave mode tap master vpn-bridge
  • add systemd service in such format: openvpn-server.conf; make sure you fix path for ovpn profile directory
  • create openvpn server file like server.conf
  • update isc dhcpd server configuration with sections in dhcpd.conf
  • create client configuration like in client.ovpn

For making dhcpd client work for such kind of connection, required a bit special systemd service definition:

  • openvpn-client-dh@.service
  • openvpn-dhclient@.service

New service require openvpn-dhclient to be started after OpenVPN Client which assigning proper address.

!!!! Be aware, this setup require VPN Interface and and VPN Profile to be exact same names !!!!

remote ip port
dev tap
dev-node tap
proto udp
resolv-retry infinite
client
nobind
persist-key
persist-tun
ca "ca.crt"
cert "cert.crt"
key "key.key"
# route-gateway 192.168.0.1 <!---use this to force all traffic via vpn, where 192.168.0.1 is an ip of vpn-bridge
verb 2
#........
# ================define custom options for static routes
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
option ms-classless-static-routes code 249 = array of unsigned integer 8;
#.........
#===========================vpn subnet!!!!!!!!!!!!!!
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.5 192.168.0.180;
option routers 192.168.0.1;
option ip-forwarding on;
option broadcast-address 192.168.0.255;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.0.1;
option domain-search ".local";
next-server 192.168.0.1;
# defining routes:
# - 1.1.1.0/24 via 192.168.0.1
# - 2.2.2.0/24 via 192.168.0.1
# - 192.168.10.0/24 via 192.168.0.1
# Linux:
option rfc3442-classless-static-routes 24, 1,1,1, 192,168,0,1,
24, 2,2,2, 192,168,0,1,
24, 192,168,10, 192,168,0,1;
# Windows:
option ms-classless-static-routes 24, 1,1,1, 192,168,0,1,
24, 2,2,2, 192,168,0,1,
24, 192,168,10, 192,168,0,1;
}
client
dev vpn-dev
dev-type tap
proto udp
remote 127.0.0.1 1234
resolv-retry infinite
nobind
persist-key
persist-tun
ca "ca.crt"
cert "pc.crt"
key "pc.key"
remote-cert-tls server
cipher AES-256-CBC <!--- used cipher
lladdr 00:00:00:00:00:00 <!-- if tap adapter created by openvpn client, would be assigned such link address
verb 3
#============= disallow default gateway override
route 0.0.0.0 192.0.0.0 net_gateway
route 64.0.0.0 192.0.0.0 net_gateway
route 128.0.0.0 192.0.0.0 net_gateway
route 192.0.0.0 192.0.0.0 net_gateway
# force defaut route
#route-gateway 127.0.0.1
[Unit]
Description=OpenVPN tunnel for %I
After=syslog.target network-online.target
Before=openvpn-dhclient@.service
Wants=network-online.target
BindsTo=openvpn-dhclient@.service
[Service]
Type=notify
PrivateTmp=true
WorkingDirectory=/etc/openvpn/client
ExecStart=/usr/sbin/openvpn --suppress-timestamps --nobind --config %i.conf
#ExecStartPost=/bin/sleep 2
#ExecStartPost=/sbin/dhclient %i
#ExecStopPre=-/sbin/dhclient -x %i
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_SYS_ADMIN CAP_NET_BIND_SERVICE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
ProtectSystem=true
ProtectHome=true
KillMode=process
[Install]
WantedBy=multi-user.target
[Unit]
Description=OpenVPN dhclient for tunnels with External DHCPD (%I)
After=syslog.target network-online.target openvpn-client-dh@.service
Requires=openvpn-client-dh@.service
Wants=network-online.target
[Service]
Type=forking
PrivateTmp=true
WorkingDirectory=/etc/openvpn/client
ExecStartPre=/bin/sleep 2
ExecStart=/sbin/dhclient %i
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_SYS_ADMIN CAP_NET_BIND_SERVICE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
ProtectSystem=true
ProtectHome=true
KillMode=process
[Install]
WantedBy=multi-user.target
[Unit]
Description=Hell Router OpenVPN Server
After=network-online.target dhcpd.service dhcpd6.service NetworkManager.service
[Service]
PrivateTmp=true
Type=forking
PIDFile=/var/run/openvpn/server.pid
ExecStartPre=-/usr/bin/mkdir /var/log/openvpn
ExecStartPre=-/usr/bin/mkdir /var/run/openvpn
ExecStart=/usr/srv/openvpn/sbin/openvpn --daemon --mode server --tls-server --log-append /var/log/openvpn/server.log --writepid /var/run/openvpn/server.pid --cd /usr/srv/_conf/openvpn/profiles/server --config server.conf
ExecStartPost=-/usr/sbin/ip link set vpn-bridge up
ExecStartPost=-/usr/sbin/ip link set vpn-server up
Restart=on-failure
RestartSec=42s
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE
[Install]
WantedBy=multi-user.target
local <server>
port <port>
dev vpn-server
dev-type tap
proto udp
cert cert.crt
key key.key
ca ca.crt
dh .pem
# use external dhcpd
server-bridge # <!-------------------this is importand to be exactly like this
#internet via tunnel <!----add to route all traffic via tunnel
push "route-delay 5"
push "redirect-gateway def1"
persist-key
persist-tun
client-to-client
# check if remote cert is a client
remote-cert-tls client
mode server
tls-server
keepalive 10 60
topology subnet
push "topology subnet"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment