Attempt to get vpn to work with mutliple clients
diff --git a/xos/configurations/common/Dockerfile.common b/xos/configurations/common/Dockerfile.common
index 3653632..a6a72c5 100644
--- a/xos/configurations/common/Dockerfile.common
+++ b/xos/configurations/common/Dockerfile.common
@@ -140,6 +140,9 @@
 RUN /opt/openvpn/clean-all
 RUN /opt/openvpn/build-ca --batch
 RUN /opt/openvpn/build-key-server --batch server
+RUN /opt/openvpn/build-dh
+RUN chmod 777 /opt/openvpn/keys/server.key
+RUN chmod 777 /opt/openvpn/keys/dh2048.pem
 
 EXPOSE 8000
 
diff --git a/xos/services/vpn/admin.py b/xos/services/vpn/admin.py
index 53ec31d..617d19b 100644
--- a/xos/services/vpn/admin.py
+++ b/xos/services/vpn/admin.py
@@ -54,12 +54,11 @@
 
     """
     creator = forms.ModelChoiceField(queryset=User.objects.all())
-    server_address = forms.GenericIPAddressField(
-        protocol='IPv4', required=True)
-    client_address = forms.GenericIPAddressField(
-        protocol='IPv4', required=True)
+    server_network = forms.GenericIPAddressField(
+        protocol="IPv4", required=True)
+    vpn_subnet = forms.GenericIPAddressField(protocol="IPv4", required=True)
     is_persistent = forms.BooleanField(required=False)
-    can_view_subnet = forms.BooleanField(required=False)
+    clients_can_see_each_other = forms.BooleanField(required=False)
 
     def __init__(self, *args, **kwargs):
         super(VPNTenantForm, self).__init__(*args, **kwargs)
@@ -72,31 +71,30 @@
 
         if self.instance:
             self.fields['creator'].initial = self.instance.creator
+            self.fields['vpn_subnet'].initial = self.instance.vpn_subnet
             self.fields[
-                'server_address'].initial = self.instance.server_address
+                'server_network'].initial = self.instance.server_network
             self.fields[
-                'client_address'].initial = self.instance.client_address
+                'clients_can_see_each_other'].initial = self.instance.clients_can_see_each_other
             self.fields['is_persistent'].initial = self.instance.is_persistent
-            self.fields[
-                'can_view_subnet'].initial = self.instance.can_view_subnet
 
         if (not self.instance) or (not self.instance.pk):
             self.fields['creator'].initial = get_request().user
-            self.fields['server_address'].initial = "10.8.0.1"
-            self.fields['client_address'].initial = "10.8.0.2"
+            self.fields['vpn_subnet'].initial = "255.255.255.0"
+            self.fields['server_network'].initial = "10.66.77.0"
+            self.fields['clients_can_see_each_other'].initial = True
             self.fields['is_persistent'].initial = True
-            self.fields['can_view_subnet'].initial = False
             if VPNService.get_service_objects().exists():
                 self.fields["provider_service"].initial = VPNService.get_service_objects().all()[
                     0]
 
     def save(self, commit=True):
         self.instance.creator = self.cleaned_data.get("creator")
-        self.instance.server_address = self.cleaned_data.get("server_address")
-        self.instance.client_address = self.cleaned_data.get("client_address")
         self.instance.is_persistent = self.cleaned_data.get('is_persistent')
-        self.instance.can_view_subnet = self.cleaned_data.get(
-            'can_view_subnet')
+        self.instance.vpn_subnet = self.cleaned_data.get("vpn_subnet")
+        self.instance.server_network = self.cleaned_data.get('server_network')
+        self.instance.clients_can_see_each_other = self.cleaned_data.get(
+            'clients_can_see_each_other')
 
         if (not self.instance.script):
             self.instance.script = str(time.time()) + ".vpn"
@@ -121,19 +119,23 @@
         with open("/opt/openvpn/keys/server.key") as key:
             self.instance.server_key = key.readlines()
 
+        with open("/opt/openvpn/keys/dh2048.pem") as dh:
+            self.instance.dh = dh.readlines()
+
     class Meta:
         model = VPNTenant
 
 
 class VPNTenantAdmin(ReadOnlyAwareAdmin):
     verbose_name = "VPN Tenant Admin"
-    list_display = ('id', 'backend_status_icon', 'instance')
-    list_display_links = ('id', 'backend_status_icon', 'instance')
+    list_display = ('id', 'backend_status_icon', 'instance',
+                    'server_network', 'vpn_subnet')
+    list_display_links = ('id', 'backend_status_icon',
+                          'instance', 'server_network', 'vpn_subnet')
     fieldsets = [(None, {'fields': ['backend_status_text', 'kind',
                                     'provider_service', 'instance', 'creator',
-                                    'script_link', 'server_address',
-                                    'client_address', 'is_persistent',
-                                    'can_view_subnet'],
+                                    'server_network', 'vpn_subnet', 'is_persistent',
+                                    'clients_can_see_each_other', 'script_link'],
                          'classes': ['suit-tab suit-tab-general']})]
     readonly_fields = ('backend_status_text', 'instance', 'script_link')
     form = VPNTenantForm
diff --git a/xos/services/vpn/models.py b/xos/services/vpn/models.py
index 5a5919d..97c781b 100644
--- a/xos/services/vpn/models.py
+++ b/xos/services/vpn/models.py
@@ -27,14 +27,15 @@
     sync_attributes = ("nat_ip", "nat_mac",)
 
     default_attributes = {'server_key': None,
-                          'server_address': '10.8.0.1',
-                          'client_address': '10.8.0.2',
-                          'can_view_subnet': False,
+                          'vpn_subnet': None,
+                          'server_network': None,
+                          'clients_can_see_each_other': True,
                           'is_persistent': True,
                           'script': None,
                           'ca_crt': None,
                           'server_crt': None,
-                          'server_key': None}
+                          'server_key': None,
+                          'dh': None}
 
     def __init__(self, *args, **kwargs):
         vpn_services = VPNService.get_service_objects().all()
@@ -96,26 +97,26 @@
         return self.addresses.get("subnet", None)
 
     @property
-    def server_address(self):
+    def server_network(self):
         """str: The IP address of the server on the VPN."""
         return self.get_attribute(
-            'server_address',
-            self.default_attributes['server_address'])
+            'server_network',
+            self.default_attributes['server_network'])
 
-    @server_address.setter
-    def server_address(self, value):
-        self.set_attribute("server_address", value)
+    @server_network.setter
+    def server_network(self, value):
+        self.set_attribute("server_network", value)
 
     @property
-    def client_address(self):
+    def vpn_subnet(self):
         """str: The IP address of the client on the VPN."""
         return self.get_attribute(
-            'client_address',
-            self.default_attributes['client_address'])
+            'vpn_subnet',
+            self.default_attributes['vpn_subnet'])
 
-    @client_address.setter
-    def client_address(self, value):
-        self.set_attribute("client_address", value)
+    @vpn_subnet.setter
+    def vpn_subnet(self, value):
+        self.set_attribute("vpn_subnet", value)
 
     @property
     def is_persistent(self):
@@ -129,15 +130,15 @@
         self.set_attribute("is_persistent", value)
 
     @property
-    def can_view_subnet(self):
+    def clients_can_see_each_other(self):
         """bool: True if the client can see the subnet of the server, false otherwise."""
         return self.get_attribute(
-            "can_view_subnet",
-            self.default_attributes['can_view_subnet'])
+            "clients_can_see_each_other",
+            self.default_attributes['clients_can_see_each_other'])
 
-    @can_view_subnet.setter
-    def can_view_subnet(self, value):
-        self.set_attribute("can_view_subnet", value)
+    @clients_can_see_each_other.setter
+    def clients_can_see_each_other(self, value):
+        self.set_attribute("clients_can_see_each_other", value)
 
     @property
     def script(self):
@@ -175,6 +176,15 @@
     def server_key(self, value):
         self.set_attribute("server_key", value)
 
+    @property
+    def dh(self):
+        """str: the string for the server certificate"""
+        return self.get_attribute("dh", self.default_attributes['dh'])
+
+    @dh.setter
+    def server_key(self, value):
+        self.set_attribute("dh", value)
+
 
 def model_policy_vpn_tenant(pk):
     """Manages the contain for the VPN Tenant."""
diff --git a/xos/synchronizers/vpn/steps/sync_vpntenant.py b/xos/synchronizers/vpn/steps/sync_vpntenant.py
index 0ac9b92..bd7a571 100644
--- a/xos/synchronizers/vpn/steps/sync_vpntenant.py
+++ b/xos/synchronizers/vpn/steps/sync_vpntenant.py
@@ -1,12 +1,16 @@
 import os
 import sys
-from django.db.models import Q, F
-from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
+import time
+
+from django.db.models import F, Q
 from services.vpn.models import VPNTenant
+from synchronizers.base.SyncInstanceUsingAnsible import \
+    SyncInstanceUsingAnsible
 
 parentdir = os.path.join(os.path.dirname(__file__), "..")
 sys.path.insert(0, parentdir)
 
+
 class SyncVPNTenant(SyncInstanceUsingAnsible):
     """Class for syncing a VPNTenant using Ansible."""
     provides = [VPNTenant]
@@ -27,12 +31,16 @@
 
         return objs
 
-    def get_extra_attributes(self, o):
-        return {"server_key": o.server_key.splitlines(),
-                "is_persistent": o.is_persistent,
-                "can_view_subnet": o.can_view_subnet,
-                "server_address": o.server_address,
-                "client_address": o.client_address}
+    def get_extra_attributes(self, tenant):
+        return {"server_key": tenant.server_key,
+                "is_persistent": tenant.is_persistent,
+                "vpn_subnet": tenant.vpn_subnet,
+                "server_network": tenant.server_network,
+                "clients_can_see_each_other": tenant.clients_can_see_each_other,
+                "ca_crt": tenant.ca_crt,
+                "server_crt": tenant.server_crt,
+                "dh": tenant.dh
+                }
 
     def create_client_script(self, tenant):
         script = open("/opt/xos/core/static/vpn/" + str(tenant.script), 'w')
@@ -46,6 +54,13 @@
         for line in self.generate_client_conf(tenant).splitlines():
             script.write(line + r"\n")
         script.write("\" > client.conf\n")
+        script.write("printf \"")
+        for line in self.generate_login().splitlines():
+            script.write(line + r"\n")
+        script.write("\" > login.up\n")
+        for line in tenant.ca_crt:
+            script.write(line + r"\n")
+        script.write("\" > ca.crt\n")
         # make sure openvpn is installed
         script.write("apt-get update\n")
         script.write("apt-get install openvpn\n")
@@ -57,6 +72,9 @@
         self.create_client_script(o)
         super(SyncVPNTenant, self).run_playbook(o, fields)
 
+    def generate_login(self):
+        return str(time.time()) + "\npassword\n"
+
     def generate_client_conf(self, tenant):
         """str: Generates the client configuration to use to connect to this VPN server.
 
@@ -64,14 +82,19 @@
             tenant (VPNTenant): The tenant to generate the client configuration for.
 
         """
-        conf = "remote " + str(tenant.nat_ip) + "\n"
-        conf += "dev tun\n"
-        conf += "ifconfig " + tenant.client_address + " " + tenant.server_address + "\n"
-        conf += "secret static.key"
+        conf = ("client\n" +
+            "auth-user-pass login.up\n" +
+            "dev tun\n" +
+            "proto udp\n" +
+            "remote " + str(tenant.nat_ip) + " 1194\n" +
+            "resolv-retry infinite\n" +
+            "nobind\n" +
+            "ca ca.crt\n" +
+            "comp-lzo\n" +
+            "verb 3\n")
+
         if tenant.is_persistent:
-            conf += "\nkeepalive 10 60\n"
-            conf += "ping-timer-rem\n"
             conf += "persist-tun\n"
-            conf += "persist-key"
+            conf += "persist-key\n"
 
         return conf
diff --git a/xos/synchronizers/vpn/steps/sync_vpntenant.yaml b/xos/synchronizers/vpn/steps/sync_vpntenant.yaml
index 02e2feb..2ed1154 100644
--- a/xos/synchronizers/vpn/steps/sync_vpntenant.yaml
+++ b/xos/synchronizers/vpn/steps/sync_vpntenant.yaml
@@ -5,10 +5,14 @@
   user: ubuntu
   sudo: yes
   vars:
-    server_address: {{ server_address }}
-    client_address: {{ client_address }}
+    ca_crt: {{ ca_crt }}
+    server_crt: {{ server_crt }}
     server_key: {{ server_key }}
+    server_network: {{ server_network }}
     is_persistent: {{ is_persistent }}
+    vpn_subnet: {{ vpn_subnet }}
+    clients_can_see_each_other: {{ clients_can_see_each_other }}
+    dh: {{ dh }}
 
   tasks:
   - name: install openvpn
@@ -17,28 +21,67 @@
   - name: stop openvpn
     shell: killall openvpn | true
 
-  - name: erase key
-    shell: rm -f static.key
+  - name: erase server key
+    shell: rm -f server.key
 
-  - name: write key
-    shell: echo {{ '{{' }} item {{ '}}' }} >> static.key
+  - name: write server key
+    shell: echo {{ '{{' }} item {{ '}}' }} >> server.key
     with_items: "{{ server_key }}"
 
+  - name: erase server crt
+    shell: rm -f server.crt
+
+  - name: write server crt
+    shell: echo {{ '{{' }} item {{ '}}' }} >> server.crt
+    with_items: "{{ server_crt }}"
+
+  - name: erase ca crt
+    shell: rm -f ca.crt
+
+  - name: write ca crt
+    shell: echo {{ '{{' }} item {{ '}}' }} >> ca.crt
+    with_items: "{{ ca_crt }}"
+
+  - name: erase dh
+    shell: rm -f dh2048.pem
+
+  - name: write dh
+    shell: echo {{ '{{' }} item {{ '}}' }} >> dh2048.pem
+    with_items: "{{ dh }}"
+
   - name: erase config
     shell: rm -f server.conf
 
+  - name: erase auth script
+    shell: rm -f auth.sh
+
+  - name: write auth script
+    shell: "exit 0" > auth.sh
+
   - name: write base config
     shell:
        |
-       printf "dev tun
-       ifconfig {{ server_address }} {{ client_address }}
-       secret static.key" > server.conf
+       printf "script-security 3 system
+       port 1194
+       proto udp
+       dev tun
+       cert server.crt
+       key server.key
+       dh dh2048.pem
+       server {{ server_network }} {{ vpn_subnet }}
+       ifconfig-pool-persist ipp.txt
+       comp-lzo
+       status openvpn-status.log
+       verb 3
+       auth-user-pass-verify auth.sh via-file
+       client-cert-not-required
+       username-as-common-name
+       " > server.conf
 
   - name: write persistent config
     shell:
       |
       printf "\nkeepalive 10 60
-      ping-timer-rem
       persist-tun
       persist-key" >> server.conf
     when: {{ is_persistent }}