openvpn-install icon indicating copy to clipboard operation
openvpn-install copied to clipboard

New feature: Split-tunnel configuration

Open brnl opened this issue 4 years ago • 11 comments

I needed my tunnel to be split-tunnel, allowing me to browse the internet normally and only route specific subnets through the tunnel, so I've created a little routine to accommodate that:

See my changes in openvpn-install.sh at line 790 below. If TUNNEL_CIDR_BLOCKS is specified, the config will not push redirect-gateway def1 bypass-dhcp, but only route the specified subnet(s).

# Allow split-tunnel via custom CIDR blocks (ie. 192.168.0.0/24)
if [ ${#PUSH_CIDR_BLOCKS[@]} -gt 0 ]; then
	for cidr in ${PUSH_CIDR_BLOCKS[@]}; do
		echo "Adding $cidr to routed subnets...";
		ROUTE_IP=$(echo $cidr | cut -d"/" -f1)
		ROUTE_BITS=$(echo $cidr | cut -d"/" -f2)
		case $ROUTE_BITS in 
			8)  ROUTE_MASK="255.0.0.0" ;;
			16) ROUTE_MASK="255.255.0.0" ;;
			24) ROUTE_MASK="255.255.255.0" ;;
			32) ROUTE_MASK="255.255.255.255" ;;
		esac
		echo "push \"route ${ROUTE_IP} ${ROUTE_MASK}\"" >> /etc/openvpn/server.conf
	done
else
	echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf
fi

Hope you like it. Let me know if you want me to add a GUI for it and/or allow more subnet bit-lengths.

brnl avatar Feb 27 '20 23:02 brnl

TUNNEL_CIDR_BLOCKS=(10.0.1.0/24 10.0.2.0/24) ./openvpn-install.sh

  • for cidr in ${TUNNEL_CIDR_BLOCKS[@]}
  • echo 'Adding (10.0.1.0/24 to routed subnets...' Adding (10.0.1.0/24 to routed subnets... ++ echo '(10.0.1.0/24' ++ cut -d/ -f1
  • ROUTE_IP='(10.0.1.0' ++ echo '(10.0.1.0/24' ++ cut -d/ -f2
  • ROUTE_BITS=24
  • case $ROUTE_BITS in
  • ROUTE_MASK=255.255.255.0
  • echo 'push "route (10.0.1.0 255.255.255.0"'
  • for cidr in ${TUNNEL_CIDR_BLOCKS[@]}
  • echo 'Adding 10.0.2.0/24) to routed subnets...' Adding 10.0.2.0/24) to routed subnets... ++ echo '10.0.2.0/24)' ++ cut -d/ -f1
  • ROUTE_IP=10.0.2.0 ++ echo '10.0.2.0/24)' ++ cut -d/ -f2
  • ROUTE_BITS='24)'
  • case $ROUTE_BITS in
  • echo 'push "route 10.0.2.0 255.255.255.0"'

GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)

Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic

kstevensonnv avatar Apr 06 '20 11:04 kstevensonnv

@kstevensonnv Did it work ok for you?

angristan avatar Apr 06 '20 12:04 angristan

@angristan no. @kstevensonnv used parenthesis instead of double quotes.

randshell avatar Apr 06 '20 13:04 randshell

@brnl @angristan @randomshell

The updated readme gives two options:

  • Setting inside a script a user has made as an environment variable
  • Passing it to the updated ./openvpn-install.sh script on the command line.

On the command line: TUNNEL_CIDR_BLOCKS=(10.0.1.0/24 10.0.2.0/24) ./openvpn-install.sh

Will produce a malformed configuration file that includes the paranthesis:

push "route (10.0.1.0 255.255.255.0" push "route 10.0.2.0 255.255.255.0"

Setting inside a script or updating what is passed to script works:

On in a script: #!/bin/bash export TUNNEL_CIDR_BLOCKS="10.0.1.0/24 10.0.2.0/24" ./openvpn-install.sh

Or

TUNNEL_CIDR_BLOCKS="10.0.1.0/24 10.0.2.0/24" ./openvpn-install.sh

Will produce the desired output:

push "route 10.0.1.0 255.255.255.0" push "route 10.0.2.0 255.255.255.0"

kstevensonnv avatar Apr 06 '20 14:04 kstevensonnv

@brnl

TUNNEL_CIDR_BLOCKS="216.239.32.21/32 216.239.34.21/32 216.239.36.21/32 216.239.38.21/32 172.217.15.115/32" ./openvpn-install.sh

server.conf:

port 1194
proto udp
dev tun
user nobody
group nogroup
persist-key
persist-tun
keepalive 10 120
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 1.0.0.1"
push "dhcp-option DNS 1.1.1.1"
push "route 216.239.32.21 255.255.255.255"
push "route 216.239.34.21 255.255.255.255"
push "route 216.239.36.21 255.255.255.255"
push "route 216.239.38.21 255.255.255.255"
push "route 172.217.15.115 255.255.255.255"
dh none
ecdh-curve prime256v1
tls-crypt tls-crypt.key 0
crl-verify crl.pem
ca ca.crt
cert server_6UfU8Imz3RXM7TmD.crt
key server_6UfU8Imz3RXM7TmD.key
auth SHA256
cipher AES-128-GCM
ncp-ciphers AES-128-GCM
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
status /var/log/openvpn/status.log
verb 3

user.ovpn:

client
proto udp
remote <snip>  1194
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server_6UfU8Imz3RXM7TmD name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3
<ca>
-----BEGIN CERTIFICATE-----
     <snip>
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
    <snip>
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
    <snip>
-----END PRIVATE KEY-----
</key>
<tls-crypt>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
    <snip>
-----END OpenVPN Static key V1-----
</tls-crypt>

~~The client configuration imported into OpenVPN Connect, but it does not connect.~~

~~/var/log/syslog, repeats the same error over and over on different ephemeral ports: ~~

~~>Apr 6 17:18:28 ubuntu ovpn-server[2594]: tls-crypt unwrap error: packet too short~~ ~~>Apr 6 17:18:28 ubuntu ovpn-server[2594]: TLS Error: tls-crypt unwrapping failed from [AF_INET]:50381~~

~~OpenVPN 2.4.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] ~~[MH/PKTINFO] [AEAD] built on May 14 2019~~ ~~library versions: OpenSSL 1.1.1 11 Sep 2018, LZO 2.08~~

I commented out "tls-crypt tls-crypt.key 0" and restarted OpenVPN on the server, then I was able to connect.

I set up a split tunnel using all the A records ifconfig.me uses. When I visit ifconfig.me it says my IP address is the VPN server IP address. When I visit whatismyipaddress.com it says my IP address is my home IP address.

traceroute to whatismyip.com (104.27.199.90), 64 hops max, 52 byte packets 1 192.168.0.1 2.959 ms

traceroute to ifconfig.me (216.239.38.21), 64 hops max, 52 byte packets 1 10.8.0.1 35.061 ms

Routing tables Internet: Destination Gateway Flags Netif Expire default 192.168.0.1 UGSc en0
10.8/24 10.8.0.2 UGSc utun2
10.8.0.1 10.8.0.2 UH utun2
172.217.15.115/32 10.8.0.1 UGSc utun2
216.239.32.21/32 10.8.0.1 UGSc utun2
216.239.34.21/32 10.8.0.1 UGSc utun2
216.239.36.21/32 10.8.0.1 UGSc utun2
216.239.38.21/32 10.8.0.1 UGSc utun2

Connecting to local devices is still working.

Seems to be working nicely.

kstevensonnv avatar Apr 06 '20 15:04 kstevensonnv

@angristan I was thinking instead of adding this test case to the script is better if we write it in the FAQ now that we support client specific configuration too. For example if I want to add another IP to split tunnel after installation I still have to do it manually.

randshell avatar Apr 26 '20 00:04 randshell

Hello, any news from the pr author ?

romain-neil avatar Jun 11 '22 12:06 romain-neil

Hello, any news from the pr author ?

I'm really sorry, no news from me. I've switched jobs so this got off my radar. Feel free to close the PR if needed. Again, sorry for the inconvenience.

brnl avatar Jun 11 '22 20:06 brnl

Would like to get this going again.

P-a-d-r-a-i-g avatar Nov 08 '22 16:11 P-a-d-r-a-i-g

This would be nice to support.

gabrielmocanu avatar Nov 11 '22 13:11 gabrielmocanu

Hello everyone!

You may find this comment useful!

ignacioinnovo avatar Aug 06 '23 13:08 ignacioinnovo