From 09724e04dccbc9527248bba0a572c2cfcb2b9832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauri=20V=C3=B5sandi?= Date: Wed, 12 Apr 2017 13:21:49 +0000 Subject: [PATCH] Add preliminary bootstrap API call --- certidude/api/__init__.py | 2 ++ certidude/api/bootstrap.py | 14 +++++++++++ certidude/cli.py | 14 +++++++++-- certidude/config.py | 1 + certidude/templates/bootstrap.conf | 31 +++++++++++++++++++++++++ certidude/templates/openvpn-client.conf | 2 +- 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 certidude/api/bootstrap.py create mode 100644 certidude/templates/bootstrap.conf diff --git a/certidude/api/__init__.py b/certidude/api/__init__.py index 3d3bc0d..f04c2d2 100644 --- a/certidude/api/__init__.py +++ b/certidude/api/__init__.py @@ -190,6 +190,7 @@ def certidude_app(): from .cfg import ConfigResource, ScriptResource from .tag import TagResource, TagDetailResource from .attrib import AttributeResource + from .bootstrap import BootstrapResource app = falcon.API(middleware=NormalizeMiddleware()) app.req_options.auto_parse_form_urlencoded = True @@ -202,6 +203,7 @@ def certidude_app(): app.add_route("/api/request/{cn}/", RequestDetailResource()) app.add_route("/api/request/", RequestListResource()) app.add_route("/api/", SessionResource()) + app.add_route("/api/bootstrap/", BootstrapResource()) # Extended attributes for scripting etc. app.add_route("/api/signed/{cn}/attr/", AttributeResource()) diff --git a/certidude/api/bootstrap.py b/certidude/api/bootstrap.py new file mode 100644 index 0000000..b7edc4a --- /dev/null +++ b/certidude/api/bootstrap.py @@ -0,0 +1,14 @@ +import logging +from certidude.decorators import serialize +from certidude.config import cp +from certidude import authority, config, const +from jinja2 import Template + +logger = logging.getLogger(__name__) + +class BootstrapResource(object): + def on_get(self, req, resp): + resp.body = Template(open(config.BOOTSTRAP_TEMPLATE).read()).render( + authority = const.FQDN, + servers = [cn for cn, path, buf, cert, server in authority.list_signed() if server]) + diff --git a/certidude/cli.py b/certidude/cli.py index af12737..a6d92d2 100755 --- a/certidude/cli.py +++ b/certidude/cli.py @@ -106,6 +106,15 @@ def certidude_request(fork, renew): subprocess.check_call(cmd) except NoOptionError: pass + + try: + endpoint_port = service_config.getint(endpoint, "port") + except NoOptionError: + endpoint_port = 1194 + try: + endpoint_proto = service_config.get(endpoint, "proto") + except NoOptionError: + endpoint_proto = "udp" try: endpoint_insecure = clients.getboolean(authority, "insecure") except NoOptionError: @@ -254,7 +263,8 @@ def certidude_request(fork, renew): nm_config.set("vpn", "tap-dev", "no") nm_config.set("vpn", "remote-cert-tls", "server") # Assert TLS Server flag of X.509 certificate nm_config.set("vpn", "remote", service_config.get(endpoint, "remote")) - nm_config.set("vpn", "port", "51900") + nm_config.set("vpn", "port", endpoint_port) + nm_config.set("vpn", "proto", endpoint_proto) nm_config.set("vpn", "key", endpoint_key_path) nm_config.set("vpn", "cert", endpoint_certificate_path) nm_config.set("vpn", "ca", endpoint_authority_path) @@ -319,7 +329,7 @@ def certidude_request(fork, renew): @click.argument("authority") @click.option("--subnet", "-s", default="192.168.33.0/24", type=ip_network, help="OpenVPN subnet, 192.168.33.0/24 by default") @click.option("--local", "-l", default="0.0.0.0", help="OpenVPN listening address, defaults to all interfaces") -@click.option("--port", "-p", default=51900, type=click.IntRange(1,60000), help="OpenVPN listening port, 51900 by default") +@click.option("--port", "-p", default=1194, type=click.IntRange(1,60000), help="OpenVPN listening port, 1194 by default") @click.option('--proto', "-t", default="udp", type=click.Choice(['udp', 'tcp']), help="OpenVPN transport protocol, UDP by default") @click.option("--route", "-r", type=ip_network, multiple=True, help="Subnets to advertise via this connection, multiple allowed") @click.option("--config", "-o", diff --git a/certidude/config.py b/certidude/config.py index 193e456..58e4183 100644 --- a/certidude/config.py +++ b/certidude/config.py @@ -46,6 +46,7 @@ OUTBOX_MAIL = cp.get("authority", "outbox sender address") BUNDLE_FORMAT = cp.get("bundle", "format") OPENVPN_PROFILE_TEMPLATE = cp.get("bundle", "openvpn profile template") +BOOTSTRAP_TEMPLATE = cp.get("bootstrap", "services template") MACHINE_ENROLLMENT_ALLOWED = { "forbidden": False, "allowed": True }[ diff --git a/certidude/templates/bootstrap.conf b/certidude/templates/bootstrap.conf new file mode 100644 index 0000000..20ddbca --- /dev/null +++ b/certidude/templates/bootstrap.conf @@ -0,0 +1,31 @@ +# This will be merged to /etc/certidude/services.conf + +[Some old connection] +managed = true +enabled = false + +[Connection in another authority] +refers = http://ca2.example.lan/api/bootstrap/ + +[Office LLC] +managed = true +enabled = true + +# Authority FQDN +authority = {{ authority }} + +# Service to be configured on the client +service = init/openvpn +;service = init/strongswan +;service = network-manager/openvpn +;service = network-manager/strongswan + +# Server addresses for the client +remote ={% for server in servers %} {{ server }}{% endfor %} + +# To customize port number advertised for certidude bootstrap +;port = 1194 + +# Protocol to advertise for certidude bootstrap +;proto = udp + diff --git a/certidude/templates/openvpn-client.conf b/certidude/templates/openvpn-client.conf index 8116eb1..8948a54 100644 --- a/certidude/templates/openvpn-client.conf +++ b/certidude/templates/openvpn-client.conf @@ -10,7 +10,7 @@ proto udp {% if servers %} remote-random {% for server in servers %} -remote {{ server }} 51900 +remote {{ server }} 1194 {% endfor %} {% else %} remote 1.2.3.4 1194