Generate server and ca crts and keys when XOS is built
diff --git a/xos/configurations/common/Dockerfile.common b/xos/configurations/common/Dockerfile.common
index 11f51fc..3653632 100644
--- a/xos/configurations/common/Dockerfile.common
+++ b/xos/configurations/common/Dockerfile.common
@@ -131,6 +131,16 @@
RUN pip install python-dateutil
RUN bash /opt/xos/tosca/install_tosca.sh
+# for OpenVPN
+RUN mkdir -p /opt/openvpn
+RUN git clone https://github.com/OpenVPN/easy-rsa.git /opt/openvpn
+RUN git -C /opt/openvpn pull origin master
+RUN cp /opt/xos/services/vpn/vars /opt/openvpn/vars
+RUN source /opt/openvpn/vars
+RUN /opt/openvpn/clean-all
+RUN /opt/openvpn/build-ca --batch
+RUN /opt/openvpn/build-key-server --batch server
+
EXPOSE 8000
# Set environment variables.
diff --git a/xos/services/vpn/admin.py b/xos/services/vpn/admin.py
index 609afa4..53ec31d 100644
--- a/xos/services/vpn/admin.py
+++ b/xos/services/vpn/admin.py
@@ -1,5 +1,4 @@
import time
-from subprocess import PIPE, Popen
from core.admin import ReadOnlyAwareAdmin, SliceInline
from core.middleware import get_request
@@ -7,7 +6,6 @@
from django import forms
from django.contrib import admin
from services.vpn.models import VPN_KIND, VPNService, VPNTenant
-from xos.exceptions import XOSProgrammingError
class VPNServiceAdmin(ReadOnlyAwareAdmin):
@@ -39,33 +37,9 @@
'top',
'administration'),)
- form = VPNServiceForm
-
def queryset(self, request):
return VPNService.get_service_objects_by_user(request.user)
-class VPNServiceForm(forms.ModelForm):
- """The form used to create and edit a VPNService."""
-
-
- def __init__(self, *args, **kwargs):
- super(VPNServiceForm, self).__init__(*args, **kwargs)
-
- def save(self, commit=True):
- if (not self.instance.ca):
- self.instance.ca = self.generate_ca
-
- return super(VPNServiceForm, self).save(commit=commit)
-
- def generate_ca(self):
- """str: Generates a CA certificate."""
- proc = Popen("./ca.sh", shell=True, stdout=PIPE)
- (stdout, stderr) = proc.communicate()
- return stdout
-
- class Meta:
- model = VPNService
-
class VPNTenantForm(forms.ModelForm):
"""The form used to create and edit a VPNTenant.
@@ -87,7 +61,6 @@
is_persistent = forms.BooleanField(required=False)
can_view_subnet = forms.BooleanField(required=False)
-
def __init__(self, *args, **kwargs):
super(VPNTenantForm, self).__init__(*args, **kwargs)
self.fields['kind'].widget.attrs['readonly'] = True
@@ -128,22 +101,25 @@
if (not self.instance.script):
self.instance.script = str(time.time()) + ".vpn"
- if (not self.instance.server_key):
- self.instance.server_key = self.generate_VPN_key()
+ if (not self.instance.ca_cert):
+ self.generate_ca_crt()
- if (self.instance.provider_service):
- self.instance.ca = self.instance.provider_service.ca
- else:
- raise XOSProgrammingError("VPN Tenant does not have provider service)
+ if ((not self.instance.server_cert) or (not self.instance.server_key)):
+ self.generate_server_credentials()
return super(VPNTenantForm, self).save(commit=commit)
- def generate_VPN_key(self):
- """str: Generates a VPN key using the openvpn command."""
- proc = Popen("openvpn --genkey --secret /dev/stdout",
- shell=True, stdout=PIPE)
- (stdout, stderr) = proc.communicate()
- return stdout
+ def generate_ca_crt(self):
+ """str: Generates the ca cert by reading from the ca file"""
+ with open("/opt/openvpn/keys/ca.crt") as crt:
+ return crt.readlines()
+
+ def generate_server_credentials(self):
+ with open("/opt/openvpn/keys/server.crt") as crt:
+ self.instance.server_crt = crt.readlines()
+
+ with open("/opt/openvpn/keys/server.key") as key:
+ self.instance.server_key = key.readlines()
class Meta:
model = VPNTenant
diff --git a/xos/services/vpn/ca.sh b/xos/services/vpn/ca.sh
deleted file mode 100644
index fc94613..0000000
--- a/xos/services/vpn/ca.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-rm -f /usr/share/easy-rsa/vars
-cp -r /usr/share/easy-rsa/* .
-source vars
-sh clean-all
-sh build-ca --batch
-cat keys/ca.crt
diff --git a/xos/services/vpn/models.py b/xos/services/vpn/models.py
index 0876dcb..5a5919d 100644
--- a/xos/services/vpn/models.py
+++ b/xos/services/vpn/models.py
@@ -14,15 +14,6 @@
app_label = "vpn"
verbose_name = "VPN Service"
- @property
- def ca(self):
- """str: the string for the ca certificate"""
- return self.get_attribute("ca", None)
-
- @ca.setter
- def ca(self, value):
- self.set_attribute("ca", value)
-
class VPNTenant(TenantWithContainer):
"""Defines the Tenant for creating VPN servers."""
@@ -41,7 +32,9 @@
'can_view_subnet': False,
'is_persistent': True,
'script': None,
- 'ca': None}
+ 'ca_crt': None,
+ 'server_crt': None,
+ 'server_key': None}
def __init__(self, *args, **kwargs):
vpn_services = VPNService.get_service_objects().all()
@@ -156,13 +149,31 @@
self.set_attribute("script", value)
@property
- def ca(self):
+ def ca_crt(self):
"""str: the string for the ca certificate"""
- return self.get_attribute("ca", self.default_attributes['ca'])
+ return self.get_attribute("ca_crt", self.default_attributes['ca_crt'])
- @ca.setter
- def ca(self, value):
- self.set_attribute("ca", value)
+ @ca_crt.setter
+ def ca_crt(self, value):
+ self.set_attribute("ca_crt", value)
+
+ @property
+ def server_crt(self):
+ """str: the string for the server certificate"""
+ return self.get_attribute("server_crt", self.default_attributes['server_crt'])
+
+ @server_crt.setter
+ def server_crt(self, value):
+ self.set_attribute("server_crt", value)
+
+ @property
+ def server_key(self):
+ """str: the string for the server certificate"""
+ return self.get_attribute("server_key", self.default_attributes['server_key'])
+
+ @server_key.setter
+ def server_key(self, value):
+ self.set_attribute("server_key", value)
def model_policy_vpn_tenant(pk):
diff --git a/xos/services/vpn/vars b/xos/services/vpn/vars
index 2cdc9b2..baec6e5 100644
--- a/xos/services/vpn/vars
+++ b/xos/services/vpn/vars
@@ -1,4 +1,4 @@
-export EASY_RSA="`pwd`"
+export EASY_RSA="/opt/openvpn"
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
@@ -6,7 +6,7 @@
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
-export KEY_DIR="/users/root/"
+export KEY_DIR="$EASY_RSA/keys"
# PKCS11 fixes
export PKCS11_MODULE_PATH="dummy"