From 98c34b22a7e7ef523a1c81938586c9d3a0acbfbe Mon Sep 17 00:00:00 2001 From: Christos Date: Mon, 1 Aug 2016 13:26:31 +0300 Subject: [PATCH 1/4] Specify the underlying protocol of a VPN tunnel --- vpn-proxy/app/models.py | 10 ++++++++++ vpn-proxy/app/tunnels.py | 6 ++++-- vpn-proxy/app/views.py | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/vpn-proxy/app/models.py b/vpn-proxy/app/models.py index c22fc81..78b7ca7 100644 --- a/vpn-proxy/app/models.py +++ b/vpn-proxy/app/models.py @@ -145,6 +145,7 @@ class Tunnel(BaseModel): client = models.GenericIPAddressField(protocol='IPv4', validators=[check_ip]) key = models.TextField(default=gen_key, blank=False, unique=True) + protocol = models.CharField(default='udp', choices=('udp', 'tcp')) @property def name(self): @@ -182,6 +183,14 @@ def client_conf(self): def client_script(self): return get_client_script(self) + @property + def server_protocol(self): + return 'tcp-server' if self.protocol == 'tcp' else 'udp' + + @property + def client_protocol(self): + return 'tcp-client' if self.protocol == 'tcp' else 'udp' + def _enable(self): start_tunnel(self) for forwarding in self.forwarding_set.all(): @@ -200,6 +209,7 @@ def to_dict(self): 'name': self.name, 'server': self.server, 'client': self.client, + 'protocol': self.protocol, 'port': self.port, 'key': self.key, 'active': self.active, diff --git a/vpn-proxy/app/tunnels.py b/vpn-proxy/app/tunnels.py index e386b77..d876ace 100644 --- a/vpn-proxy/app/tunnels.py +++ b/vpn-proxy/app/tunnels.py @@ -228,7 +228,8 @@ def get_conf(tunnel): 'dev-type tun', 'port %s' % tunnel.port, 'ifconfig %s %s' % (tunnel.server, tunnel.client), - 'secret %s' % tunnel.key_path]) + 'secret %s' % tunnel.key_path, + 'proto %s' % tunnel.server_protocol]) def get_client_conf(tunnel): @@ -237,7 +238,8 @@ def get_client_conf(tunnel): 'dev-type tun', 'port %s' % tunnel.port, 'ifconfig %s %s' % (tunnel.client, tunnel.server), - 'secret %s' % tunnel.key_path]) + 'secret %s' % tunnel.key_path, + 'proto %s' % tunnel.client_protocol]) def get_client_script(tunnel): diff --git a/vpn-proxy/app/views.py b/vpn-proxy/app/views.py index 3a685d0..92a1d96 100644 --- a/vpn-proxy/app/views.py +++ b/vpn-proxy/app/views.py @@ -32,6 +32,8 @@ def tunnels(request): client = choose_ip(cidrs, excluded_cidrs) params['client'] = client params['server'] = choose_ip(cidrs, excluded_cidrs, client_addr=client) + if 'proto' in request.POST: + params['protocol'] = request.POST['proto'] tun = Tunnel(**params) tun.save() return JsonResponse(tun.to_dict()) From f5ec83c0c6bcff5b96a7c3f21a64ba7ba6be9234 Mon Sep 17 00:00:00 2001 From: Christos Date: Mon, 1 Aug 2016 16:17:01 +0300 Subject: [PATCH 2/4] Add `protocol` field to Tunnel model --- .../app/migrations/0005_tunnel_protocol.py | 20 +++++++++++++++++++ vpn-proxy/app/models.py | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 vpn-proxy/app/migrations/0005_tunnel_protocol.py diff --git a/vpn-proxy/app/migrations/0005_tunnel_protocol.py b/vpn-proxy/app/migrations/0005_tunnel_protocol.py new file mode 100644 index 0000000..6448729 --- /dev/null +++ b/vpn-proxy/app/migrations/0005_tunnel_protocol.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-01 13:16 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0004_remove_forwarding_src_addr'), + ] + + operations = [ + migrations.AddField( + model_name='tunnel', + name='protocol', + field=models.CharField(choices=[('udp', 'UDP'), ('tcp', 'TCP')], default='udp', max_length=3), + ), + ] diff --git a/vpn-proxy/app/models.py b/vpn-proxy/app/models.py index 78b7ca7..c301b75 100644 --- a/vpn-proxy/app/models.py +++ b/vpn-proxy/app/models.py @@ -145,7 +145,8 @@ class Tunnel(BaseModel): client = models.GenericIPAddressField(protocol='IPv4', validators=[check_ip]) key = models.TextField(default=gen_key, blank=False, unique=True) - protocol = models.CharField(default='udp', choices=('udp', 'tcp')) + protocol = models.CharField(max_length=3, default='udp', + choices=[('udp', 'UDP'), ('tcp', 'TCP')]) @property def name(self): From ea8a22b4d7d966ecd93be2740d20a12517e72c4c Mon Sep 17 00:00:00 2001 From: Christos Date: Mon, 1 Aug 2016 19:56:41 +0300 Subject: [PATCH 3/4] Append MASQUERADE rule for all ifaces apart from lo --- vpn-proxy/app/tunnels.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vpn-proxy/app/tunnels.py b/vpn-proxy/app/tunnels.py index d876ace..9cd8084 100644 --- a/vpn-proxy/app/tunnels.py +++ b/vpn-proxy/app/tunnels.py @@ -259,7 +259,6 @@ def get_client_script(tunnel): echo "Could not find a package management tool" exit 1 fi - } if ! which openvpn > /dev/null; then @@ -282,9 +281,9 @@ def get_client_script(tunnel): echo 1 > /proc/sys/net/ipv4/ip_forward -ifaces=`ip link show | grep '^[0-9]*:' | awk '{print $2}' | sed 's/:$//'` -eth_ifaces=`echo "$ifaces" | grep ^eth` -for iface in $eth_ifaces; do +ifaces=`ip link show | grep '^[0-9]*:' | awk '{print $2}' | sed 's/:$//' | \ + grep -v ^lo$` +for iface in $ifaces; do iptables -t nat -A POSTROUTING -o $iface -j MASQUERADE done """ % {'key_path': tunnel.key_path, 'conf_path': tunnel.conf_path, From fd4d4671b90cdfb06b0f4a8af5a4039a8b9e8bb3 Mon Sep 17 00:00:00 2001 From: Christos Date: Tue, 2 Aug 2016 11:22:07 +0300 Subject: [PATCH 4/4] Set `keepalive` conf to client script --- vpn-proxy/app/tunnels.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vpn-proxy/app/tunnels.py b/vpn-proxy/app/tunnels.py index 9cd8084..3567371 100644 --- a/vpn-proxy/app/tunnels.py +++ b/vpn-proxy/app/tunnels.py @@ -239,7 +239,8 @@ def get_client_conf(tunnel): 'port %s' % tunnel.port, 'ifconfig %s %s' % (tunnel.client, tunnel.server), 'secret %s' % tunnel.key_path, - 'proto %s' % tunnel.client_protocol]) + 'proto %s' % tunnel.client_protocol, + 'keepalive 10 120']) def get_client_script(tunnel):