| Jeremy Mowery | 4cdec80 | 2015-12-04 13:50:05 -0700 | [diff] [blame] | 1 | import os |
| 2 | import sys |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 3 | import time |
| 4 | |
| 5 | from django.db.models import F, Q |
| Jeremy Mowery | 3384d2d | 2016-01-05 00:30:24 -0700 | [diff] [blame] | 6 | from services.vpn.models import VPNTenant |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 7 | from synchronizers.base.SyncInstanceUsingAnsible import \ |
| 8 | SyncInstanceUsingAnsible |
| Jeremy Mowery | 4cdec80 | 2015-12-04 13:50:05 -0700 | [diff] [blame] | 9 | |
| 10 | parentdir = os.path.join(os.path.dirname(__file__), "..") |
| 11 | sys.path.insert(0, parentdir) |
| 12 | |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 13 | |
| Jeremy Mowery | 4cdec80 | 2015-12-04 13:50:05 -0700 | [diff] [blame] | 14 | class SyncVPNTenant(SyncInstanceUsingAnsible): |
| Jeremy Mowery | 4cf74cf | 2016-01-08 16:36:22 -0700 | [diff] [blame] | 15 | """Class for syncing a VPNTenant using Ansible.""" |
| Jeremy Mowery | 4cdec80 | 2015-12-04 13:50:05 -0700 | [diff] [blame] | 16 | provides = [VPNTenant] |
| 17 | observes = VPNTenant |
| 18 | requested_interval = 0 |
| 19 | template_name = "sync_vpntenant.yaml" |
| Jeremy Mowery | 594b796 | 2016-01-24 19:42:30 -0700 | [diff] [blame] | 20 | service_key_name = "/opt/xos/synchronizers/vpn/vpn_private_key" |
| Jeremy Mowery | 4cdec80 | 2015-12-04 13:50:05 -0700 | [diff] [blame] | 21 | |
| 22 | def __init__(self, *args, **kwargs): |
| 23 | super(SyncVPNTenant, self).__init__(*args, **kwargs) |
| 24 | |
| 25 | def fetch_pending(self, deleted): |
| 26 | if (not deleted): |
| 27 | objs = VPNTenant.get_tenant_objects().filter( |
| 28 | Q(enacted__lt=F('updated')) | Q(enacted=None), Q(lazy_blocked=False)) |
| 29 | else: |
| 30 | objs = VPNTenant.get_deleted_tenant_objects() |
| 31 | |
| 32 | return objs |
| 33 | |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 34 | def get_extra_attributes(self, tenant): |
| 35 | return {"server_key": tenant.server_key, |
| 36 | "is_persistent": tenant.is_persistent, |
| 37 | "vpn_subnet": tenant.vpn_subnet, |
| 38 | "server_network": tenant.server_network, |
| 39 | "clients_can_see_each_other": tenant.clients_can_see_each_other, |
| Jeremy Mowery | 3413300 | 2016-02-11 18:15:25 -0700 | [diff] [blame] | 40 | "ca_crt": tenant.ca_crt, |
| 41 | "server_crt": self.get_escaped_ca_crt(tenant), |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 42 | "dh": tenant.dh |
| 43 | } |
| Jeremy Mowery | 6cacf1b | 2016-01-05 17:50:56 -0700 | [diff] [blame] | 44 | |
| Jeremy Mowery | fadbb20 | 2016-02-10 00:50:51 -0700 | [diff] [blame] | 45 | def get_escaped_ca_crt(self, tenant): |
| 46 | result = list() |
| Jeremy Mowery | 3413300 | 2016-02-11 18:15:25 -0700 | [diff] [blame] | 47 | for line in tenant.server_crt: |
| Jeremy Mowery | f1aa786 | 2016-02-11 17:49:03 -0700 | [diff] [blame] | 48 | result.append("\"" + line + "\"") |
| Jeremy Mowery | fadbb20 | 2016-02-10 00:50:51 -0700 | [diff] [blame] | 49 | |
| 50 | return result |
| 51 | |
| Jeremy Mowery | da2c313 | 2016-01-10 15:21:52 -0700 | [diff] [blame] | 52 | def create_client_script(self, tenant): |
| Jeremy Mowery | 0111e92 | 2016-01-25 20:51:11 -0700 | [diff] [blame] | 53 | script = open("/opt/xos/core/static/vpn/" + str(tenant.script), 'w') |
| Jeremy Mowery | da2c313 | 2016-01-10 15:21:52 -0700 | [diff] [blame] | 54 | # write the configuration portion |
| Jeremy Mowery | d8288c4 | 2016-02-12 00:19:31 -0700 | [diff] [blame^] | 55 | script.write("printf \"%b\" \"") |
| Jeremy Mowery | da2c313 | 2016-01-10 15:21:52 -0700 | [diff] [blame] | 56 | for line in self.generate_client_conf(tenant).splitlines(): |
| 57 | script.write(line + r"\n") |
| 58 | script.write("\" > client.conf\n") |
| Jeremy Mowery | d8288c4 | 2016-02-12 00:19:31 -0700 | [diff] [blame^] | 59 | script.write("printf \"%b\" \"") |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 60 | for line in self.generate_login().splitlines(): |
| 61 | script.write(line + r"\n") |
| 62 | script.write("\" > login.up\n") |
| Jeremy Mowery | d8288c4 | 2016-02-12 00:19:31 -0700 | [diff] [blame^] | 63 | script.write("printf \"%b\" \"") |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 64 | for line in tenant.ca_crt: |
| Jeremy Mowery | 072f08a | 2016-02-09 23:30:57 -0700 | [diff] [blame] | 65 | script.write(line.rstrip() + r"\n") |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 66 | script.write("\" > ca.crt\n") |
| Jeremy Mowery | da2c313 | 2016-01-10 15:21:52 -0700 | [diff] [blame] | 67 | # make sure openvpn is installed |
| 68 | script.write("apt-get update\n") |
| 69 | script.write("apt-get install openvpn\n") |
| Jeremy Mowery | 9d131a0 | 2016-01-26 18:17:30 -0700 | [diff] [blame] | 70 | script.write("openvpn client.conf &\n") |
| Jeremy Mowery | da2c313 | 2016-01-10 15:21:52 -0700 | [diff] [blame] | 71 | # close the script |
| 72 | script.close() |
| 73 | |
| Jeremy Mowery | 0111e92 | 2016-01-25 20:51:11 -0700 | [diff] [blame] | 74 | def run_playbook(self, o, fields): |
| 75 | self.create_client_script(o) |
| 76 | super(SyncVPNTenant, self).run_playbook(o, fields) |
| 77 | |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 78 | def generate_login(self): |
| 79 | return str(time.time()) + "\npassword\n" |
| 80 | |
| Jeremy Mowery | 6cacf1b | 2016-01-05 17:50:56 -0700 | [diff] [blame] | 81 | def generate_client_conf(self, tenant): |
| Jeremy Mowery | 4cf74cf | 2016-01-08 16:36:22 -0700 | [diff] [blame] | 82 | """str: Generates the client configuration to use to connect to this VPN server. |
| 83 | |
| 84 | Args: |
| 85 | tenant (VPNTenant): The tenant to generate the client configuration for. |
| Jeremy Mowery | 8c52f56 | 2016-01-09 10:45:36 -0700 | [diff] [blame] | 86 | |
| Jeremy Mowery | 4cf74cf | 2016-01-08 16:36:22 -0700 | [diff] [blame] | 87 | """ |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 88 | conf = ("client\n" + |
| 89 | "auth-user-pass login.up\n" + |
| 90 | "dev tun\n" + |
| 91 | "proto udp\n" + |
| 92 | "remote " + str(tenant.nat_ip) + " 1194\n" + |
| 93 | "resolv-retry infinite\n" + |
| 94 | "nobind\n" + |
| 95 | "ca ca.crt\n" + |
| 96 | "comp-lzo\n" + |
| 97 | "verb 3\n") |
| 98 | |
| Jeremy Mowery | 8c52f56 | 2016-01-09 10:45:36 -0700 | [diff] [blame] | 99 | if tenant.is_persistent: |
| Jeremy Mowery | 8c52f56 | 2016-01-09 10:45:36 -0700 | [diff] [blame] | 100 | conf += "persist-tun\n" |
| Jeremy Mowery | 37d8a43 | 2016-02-07 17:07:55 -0700 | [diff] [blame] | 101 | conf += "persist-key\n" |
| Jeremy Mowery | 8c52f56 | 2016-01-09 10:45:36 -0700 | [diff] [blame] | 102 | |
| Jeremy Mowery | 6cacf1b | 2016-01-05 17:50:56 -0700 | [diff] [blame] | 103 | return conf |