Browse Source

Add state for setting up OpenVPN tunnels.

Signed-off-by: Maximilian Wilhelm <max@rfc2324.org>
Maximilian Wilhelm 7 years ago
parent
commit
84c89fdbd4
7 changed files with 238 additions and 0 deletions
  1. 10 0
      openvpn/ccd.tmpl
  2. 3 0
      openvpn/ifdown
  3. 3 0
      openvpn/ifup
  4. 4 0
      openvpn/ifup_real
  5. 150 0
      openvpn/init.sls
  6. 54 0
      openvpn/openvpn.conf.tmpl
  7. 14 0
      openvpn/openvpn@.service

+ 10 - 0
openvpn/ccd.tmpl

@@ -0,0 +1,10 @@
+{%- if network_config.get ('device-type', 'tap') == 'tap' %}
+  {%- for ip in host_stanza.get ('ip', []) %}
+    {%- if ':' in ip %}
+ifconfig-ipv6-push {{ ip }}/{{ network_config['netmask_v6'] }}
+    {%- else %}
+      {%- set mask = network_config['netmask_v4'] if '.' in network_config['netmask_v4']|string else '255.255.255.254' %}
+ifconfig-push {{ ip }} {{ mask }}
+    {%- endif %}
+  {%- endfor %}
+{%- endif %}

+ 3 - 0
openvpn/ifdown

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+/usr/bin/flock --exclusive --wait 30 /var/lock/ff_ifupdown2 /sbin/ifdown "$1"

+ 3 - 0
openvpn/ifup

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+/usr/bin/flock --exclusive --wait 30 /var/lock/ff_ifupdown2 /etc/openvpn/ifup_real "$@"

+ 4 - 0
openvpn/ifup_real

@@ -0,0 +1,4 @@
+#!/bin/sh
+
+ifdown --force "$1" 2>/dev/null
+ifup "$1"

+ 150 - 0
openvpn/init.sls

@@ -0,0 +1,150 @@
+#
+# OpenVPN
+#
+
+include:
+  - cert.x509
+  - network.interfaces
+
+
+openvpn:
+  pkg.installed:
+    - name: openvpn
+    - require:
+      - file: /etc/network/interfaces
+  service.running:
+    - enable: True
+    - reload: True
+
+
+/etc/systemd/system/openvpn@.service:
+  file.managed:
+    - source: salt://openvpn/openvpn@.service
+    - require:
+      - pkg: openvpn
+
+
+/etc/openvpn/ifup:
+  file.managed:
+    - source: salt://openvpn/ifup
+    - user: root
+    - group: root
+    - mode: 755
+    - require:
+      - pkg: openvpn
+
+/etc/openvpn/ifup_real:
+  file.managed:
+    - source: salt://openvpn/ifup_real
+    - user: root
+    - group: root
+    - mode: 755
+    - require:
+      - pkg: openvpn
+
+/etc/openvpn/ifdown:
+  file.managed:
+    - source: salt://openvpn/ifdown
+    - user: root
+    - group: root
+    - mode: 755
+    - require:
+      - pkg: openvpn
+
+
+# Create 1024 bit DH params, if not present already
+/etc/openvpn/dh1024.pem:
+  cmd.run:
+    - name: openssl dhparam -out /etc/openvpn/dh1024.pem 1024
+#    - creates: /etc/openvpn/dh1024.pem
+    - unless: ls /etc/openvpn/dh1024.pem
+
+
+# Create log directory for status log
+/var/log/openvpn:
+  file.directory:
+    - user: root
+    - group: root
+    - mode: 755
+    - makedirs: True
+
+
+# Set up configuration for each and every network configured for this node
+{% for netname, network in salt['pillar.get']('ovpn', {}).items () %}
+  {% if grains['id'] in network %}
+    {% set network_config = network.get ('config') %}
+    {% set host_stanza = network.get (grains['id'], {}) %}
+    {% set host_config = host_stanza.get ('config', {}) %}
+    {# Merge network_config and host_config with host_config inheriting network_config an overwriting options #}
+    {% set config = {} %}
+    {% for keyword, net_argument in network_config.iteritems () if keyword[0] != '_' %}
+      {% do config.update ({ keyword : net_argument }) %}
+    {% endfor %}
+    {#- If there's a "config:" entry in host YAML without any content it will
+    #  wind up as an empty string here. Be kind and silenty handle that.  #}
+    {% if host_config is not string or host_config != "" %}
+      {% for keyword, host_argument in host_config.items () %}
+        {% do config.update ({ keyword : host_argument }) %}
+      {% endfor %}
+    {% endif %}
+    {# END merge #}
+
+# Create systemd start link
+openvpn@{{ netname }}:
+  service.running:
+    - enable: True
+    - reload: True
+    - require:
+      - file: /etc/systemd/system/openvpn@.service
+      - file: Cleanup /etc/openvpn/{{ netname }}
+
+
+/etc/openvpn/{{ netname }}.conf:
+  file.managed:
+    - source: salt://openvpn/openvpn.conf.tmpl
+    - template: jinja
+    - context:
+      netname : {{ netname }}
+      network_config: {{ network_config }}
+      host_config:    {{ host_config }}
+      config:         {{ config }}
+    - require:
+      - pkg: openvpn
+    - watch_in:
+      - service: openvpn@{{ netname }}
+
+
+    {% if config.get ('mode', '') == "server" %}
+# Create config dir
+Create /etc/openvpn/{{ netname }}:
+  file.directory:
+    - name: /etc/openvpn/{{ netname }}
+    - user: root
+    - group: root
+    - mode: 755
+    - makedirs: True
+    - require:
+      - pkg: openvpn
+
+Cleanup /etc/openvpn/{{ netname }}:
+  file.directory:
+    - name: /etc/openvpn/{{ netname }}
+    - clean: true
+
+      {% for host, host_stanza in network.items () if not host == 'config' and host != grains['id'] %}
+/etc/openvpn/{{ netname }}/{{ host }}:
+  file.managed:
+    - source: salt://openvpn/ccd.tmpl
+    - template: jinja
+    - context:
+      host_stanza: {{ host_stanza }}
+      network_config: {{ network_config }}
+    - require:
+      - file: Create /etc/openvpn/{{ netname }}
+    - require_in:
+      - file: Cleanup /etc/openvpn/{{ netname }}
+
+      {% endfor %}
+    {% endif %}
+  {% endif %}
+{% endfor %}

+ 54 - 0
openvpn/openvpn.conf.tmpl

@@ -0,0 +1,54 @@
+#
+# {{ netname }} / {{ network_config.get ('_desc', '') }} (Salt managed)
+#
+
+{%- set mode = config.get ('mode', 'client') %}
+{%- if 'server' in mode %}
+local   {{ network_config.get ('server_ip') }}
+port    {{ network_config.get ('port') }}
+
+tls-server
+{%- elif 'client' in mode %}
+remote	{{ config.get ('remote', config.get ('server_ip')) }} {{ network_config.get ('port') }}
+
+tls-client
+nobind
+{%- endif %}
+
+{%- if 'bind_dev' in config %}
+bind-dev	{{ config.get ('bind_dev') }}
+{%- endif %}
+
+proto   {{ network_config.get ('proto', 'udp') }}
+
+dev-type {{ network_config.get ('dev-type', 'tap') }}
+dev {{ config.get ('interface') }}
+
+{%- if mode == 'server' %}
+mode server
+
+client-config-dir /etc/openvpn/{{ netname }}
+ccd-exclusive
+
+push "route remote_host  255.255.255.255 net_gateway"
+{%- endif %}
+
+ca      /etc/ssl/certs/ffho-cacert.pem
+cert    /etc/ssl/certs/{{ host_config.get ('cert_cn', grains['id']) }}.cert.pem
+key     /etc/ssl/private/{{ host_config.get ('cert_cn', grains['id']) }}.key.pem
+dh      /etc/openvpn/dh1024.pem
+
+script-security 2
+up      /etc/openvpn/ifup
+down    /etc/openvpn/ifdown
+
+keepalive 10 30
+
+comp-lzo
+
+persist-key
+persist-tun
+
+status /var/log/openvpn/openvpn-status-{{ netname }}.log
+
+verb 1

+ 14 - 0
openvpn/openvpn@.service

@@ -0,0 +1,14 @@
+[Unit]
+Description=OpenVPN connection to %i
+PartOf=openvpn.service
+ReloadPropagatedFrom=openvpn.service
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --config /etc/openvpn/%i.conf
+ExecReload=/bin/kill -HUP $MAINPID
+WorkingDirectory=/etc/openvpn
+
+[Install]
+WantedBy=multi-user.target