diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 70336e6..b23d528 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,6 +1,6 @@ [bumpversion] commit = True -current_version = 2.0.4 +current_version = 2.0.5 tag = True tag_name = {new_version} diff --git a/defaults/main.yml b/defaults/main.yml index 6daba2d..4d3706a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,21 +1,29 @@ --- openvpn_enabled: yes # The role is enabled +openvpn_generate_keys: no openvpn_etcdir: /etc/openvpn openvpn_keydir: "{{openvpn_etcdir}}/keys" +openvpn_cert_pass: "" # Default settings (See OpenVPN documentation) openvpn_host: "{{inventory_hostname}}" # The server address openvpn_port: 1194 -openvpn_proto: udp +openvpn_proto: tcp openvpn_dev: tun openvpn_server: 10.8.0.0 255.255.255.0 # Set empty for skip +#openvpn_push_nets: [] +#openvpn_dns: [] +openvpn_topology: subnet # Recommended topology but + # brake compatibility with old Windows + # net30 - legacy topology openvpn_max_clients: 100 openvpn_log: /var/log/openvpn.log # Log's directory -openvpn_keepalive: "10 120" +openvpn_keepalive: "10 30" openvpn_ifconfig_pool_persist: ipp.txt openvpn_comp_lzo: yes # Enable compression +openvpn_float: yes # Allow remote peer to change its IP address and/or port number openvpn_status: openvpn-status.log openvpn_verb: 3 openvpn_user: nobody @@ -42,7 +50,8 @@ openvpn_clients: [client] # Make clients certificate openvpn_clients_revoke: [] # Revoke clients certificates # Use PAM authentication -openvpn_use_pam: yes +openvpn_use_pam: no +openvpn_disable_cert: no openvpn_use_pam_users: [] # If empty use system users # otherwise use users from the option # openvpn_use_pam_users: diff --git a/handlers/main.yml b/handlers/main.yml index 71ddb38..e4421f2 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -4,6 +4,11 @@ service: name=openvpn state=restarted - name: openvpn pack clients - command: tar cvzf {{openvpn_keydir}}/{{item.item}}.tar.gz -C {{openvpn_keydir}} {{item.item}}.crt {{item.item}}.key {{item.item}}.ovpn ca.crt + command: zip -j {{openvpn_keydir}}/{{item.item.name}} {{openvpn_keydir}}/{{item.item.name}}.p12 {{openvpn_keydir}}/{{item.item.name}}.ovpn {{openvpn_keydir}}/ca.crt when: item.changed - with_items: openvpn_clients_changed.results + with_items: pfx.results + +- name: openvpn copy pack clients + fetch: src={{openvpn_keydir}}/{{item.item.name}}.zip dest=vpn_keys/{{item.item.name}}.zip flat=yes + when: item.changed + with_items: pfx.results diff --git a/tasks/configure.yml b/tasks/configure.yml index 3ad9eb1..8b38aed 100644 --- a/tasks/configure.yml +++ b/tasks/configure.yml @@ -1,6 +1,4 @@ --- -- name: Ensure openvpn key dir has the right permission - file: path={{openvpn_keydir}} state=directory mode=0700 owner={{openvpn_user}} - name: Extract easy-rsa files unarchive: src=easy-rsa.tar.gz dest={{openvpn_etcdir}} @@ -11,14 +9,43 @@ - name: Generate Server keys command: "{{openvpn_etcdir}}/build-server.sh" - args: { creates: "{{ openvpn_keydir }}" } + args: { creates: "{{ openvpn_keydir }}/server.key" } + notify: [openvpn restart] + when: openvpn_generate_keys - name: Generate Clients keys - command: "{{openvpn_etcdir}}/build-client.sh {{item}}" - args: { creates: "{{ openvpn_keydir }}/{{item}}.crt" } + command: "{{openvpn_etcdir}}/build-client.sh {{item.name}}" + args: { creates: "{{ openvpn_keydir }}/{{item.name}}.crt" } with_items: openvpn_clients + when: openvpn_generate_keys + +- name: Convert Clients cert/key to p12 + command: "openssl pkcs12 -export -out {{openvpn_keydir}}/{{item.name}}.p12 -inkey {{openvpn_keydir}}/{{item.name}}.key -in {{openvpn_keydir}}/{{item.name}}.crt -certfile {{openvpn_keydir}}/ca.crt -password pass:{{item.password}}" + args: { creates: "{{ openvpn_keydir }}/{{item.name}}.p12" } + with_items: openvpn_clients + notify: + - openvpn pack clients + - openvpn copy pack clients + register: pfx + when: openvpn_generate_keys + +- name: Ensure openvpn key dir has the right permission + file: path={{openvpn_keydir}} state=directory mode=0700 owner={{openvpn_user}} + +- name: Server keys and certs are copied + copy: src="../../../../../../VPN keys/server/{{ item }}" + dest={{openvpn_keydir}}/{{ item }} + owner=root group=root mode=0600 + with_items: [ "ca.crt","server.crt","server.key","dh1024.pem" ] + when: not openvpn_generate_keys -- name: Revoke Clients keys +- name: Get client certificate fingerprint + shell: "openssl pkcs12 -in {{openvpn_keydir}}/{{item.item.name}}.p12 -nodes -passin pass:{{item.item.password}} | openssl x509 -noout -fingerprint | cut -d= -f2 | sed 's/:/ /g'" + with_items: pfx.results + when: item.changed and openvpn_generate_keys + register: cert_fp + +- name: Revoke Clients command: "{{openvpn_etcdir}}/revoke-client.sh {{item}}" args: { removes: "{{ openvpn_keydir }}/{{item}}.crt" } with_items: openvpn_clients_revoke @@ -30,21 +57,30 @@ state=directory when: openvpn_client_config_dir is defined +- name: Revoke Users + lineinfile: dest=/etc/openvpn/users regexp='^{{item}}:' state=absent + with_items: openvpn_use_pam_users_revoke + tags: rev_user + - name: Check if crl.pem exists stat: path={{openvpn_keydir}}/crl.pem register: crl_pem_file +- name: Check crl.pem ACL + file: path={{openvpn_keydir}}/crl.pem + owner={{ openvpn_user }} mode=400 + when: crl_pem_file.stat.exists + - name: Generate Clients configurations - template: src=client.conf.j2 dest={{openvpn_keydir}}/{{item}}.ovpn - with_items: openvpn_clients - notify: openvpn pack clients - register: openvpn_clients_changed + template: src=client.conf.j2 dest={{openvpn_keydir}}/{{item.item.item.name}}.ovpn + with_items: cert_fp.results + when: item.changed and openvpn_generate_keys - name: Setup PAM template: src=openvpn.pam.j2 dest=/etc/pam.d/openvpn when: openvpn_use_pam -- name: Configure users +- name: Configure PAM users htpasswd: path={{openvpn_etcdir}}/users name={{item.name}} password={{item.password}} crypt_scheme=des_crypt with_items: openvpn_use_pam_users @@ -55,3 +91,10 @@ - name: Configure server template: src=server.conf.j2 dest={{openvpn_etcdir}}/server.conf notify: [openvpn restart] + +- name: UFW allow limited OpenVPN + ufw: rule=limit port=openvpn + tags: + - ufw + - openvpn + - ufw_openvpn \ No newline at end of file diff --git a/tasks/install.deb.yml b/tasks/install.deb.yml index b569199..0a750a7 100644 --- a/tasks/install.deb.yml +++ b/tasks/install.deb.yml @@ -2,7 +2,7 @@ - name: Install requirements (Debian) apt: name={{item}} - with_items: [openvpn, udev, openssl] + with_items: [openvpn, udev, openssl, zip] - name: Install dependencies (Debian) apt: name={{item}} diff --git a/templates/build-server.sh.j2 b/templates/build-server.sh.j2 index b2440d9..6789b24 100644 --- a/templates/build-server.sh.j2 +++ b/templates/build-server.sh.j2 @@ -20,5 +20,5 @@ $EASY_RSA/pkitool --server server && \ $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE} {% for client in openvpn_clients %} -$EASY_RSA/pkitool {{ client }} +$EASY_RSA/pkitool {{ client.name }} {% endfor %} diff --git a/templates/client.conf.j2 b/templates/client.conf.j2 index 14fe1da..826f44c 100644 --- a/templates/client.conf.j2 +++ b/templates/client.conf.j2 @@ -36,8 +36,10 @@ persist-tun # use a separate .crt/.key file pair for each client. A single ca file can be # used for all clients. ca ca.crt -cert {{client}}.crt -key {{client}}.key +# It works cool for Windows certificate store +# For Linux need to use this: +# pkcs12 certname.p12 +cryptoapicert "THUMB:{{ item.stdout }}" # Verify server certificate by checking that the certicate has the nsCertType # field set to "server". This is an important precaution to protect against a @@ -66,3 +68,10 @@ auth-user-pass {% for option in openvpn_client_options %} {{option}} {% endfor %} + +# This updates the resolvconf with dns settings +# uncomment it for Linux clients +#script-security 2 +#setenv PATH /usr/bin +#up /etc/openvpn/update-resolv-conf +#down /etc/openvpn/update-resolv-conf diff --git a/templates/revoke-client.sh.j2 b/templates/revoke-client.sh.j2 index 85e4b86..f8e1a4d 100644 --- a/templates/revoke-client.sh.j2 +++ b/templates/revoke-client.sh.j2 @@ -11,4 +11,4 @@ $EASY_RSA/revoke-full $@ export CLIENT=$1 -rm -rf $KEY_DIR/$CLIENT* +rm -f $KEY_DIR/$CLIENT.* diff --git a/templates/server.conf.j2 b/templates/server.conf.j2 index 6ecc01e..90f7422 100644 --- a/templates/server.conf.j2 +++ b/templates/server.conf.j2 @@ -43,8 +43,8 @@ key {{openvpn_keydir}}/server.key # This file should be kept secret # dh1024.pem 1024 Substitute 2048 for 1024 if you are using 2048 bit keys. dh {{openvpn_keydir}}/dh{{openvpn_key_size}}.pem -# Client configuration directory. {% if openvpn_client_config_dir is defined -%} +# Client configuration directory. client-config-dir {{ openvpn_client_config_dir }} {% endif %} @@ -72,7 +72,7 @@ ifconfig-pool-persist {{openvpn_ifconfig_pool_persist}} # The keepalive directive causes ping-like messages to be sent back and forth # over the link so that each side knows when the other side has gone down. Ping # every 10 seconds, assume that remote peer is down if no ping received during -# a 120 second time period. +# a 30 second time period. keepalive {{ openvpn_keepalive }} # Enable compression on the VPN link. If you enable it here, you must also @@ -128,8 +128,11 @@ group nogroup client-to-client {% endif %} +{% if openvpn_float %} +float +{% endif %} + {% if openvpn_use_pam %} -client-cert-not-required plugin {{openvpn_use_pam_plugin|default(openvpn_use_pam_plugin_distribution)}} openvpn {% endif %} @@ -137,6 +140,10 @@ plugin {{openvpn_use_pam_plugin|default(openvpn_use_pam_plugin_distribution)}} o plugin {{ openvpn_use_ldap_plugin | default(openvpn_use_ldap_plugin_distribution) }} "/etc/openvpn/auth-ldap.conf" {% endif %} +{% if openvpn_disable_cert %} +client-cert-not-required +{% endif %} + {% for option in openvpn_server_options %} {{option}} {% endfor %} @@ -144,3 +151,24 @@ plugin {{ openvpn_use_ldap_plugin | default(openvpn_use_ldap_plugin_distribution {% if openvpn_clients_revoke|length > 0 or crl_pem_file.stat.exists %} crl-verify {{openvpn_keydir}}/crl.pem {% endif %} + +{% for key, value in interfaces.iteritems() | sort %} +{% if key != 'eth1' %} +#push "route {{ value.ip4_address | ipaddr('network') }} {{ value.ip4_address | ipaddr('netmask') }}" +{% endif %} +{% endfor %} +{% for network in dc_networks %} +push "route {{ network | ipaddr('network') }} {{ network | ipaddr('netmask') }}" +{% endfor %} + +{% for item in dns_servers_consul %} +#push "dhcp-option DNS {{ item }}" +{% endfor %} +push "dhcp-option DNS 10.1.3.10" + +push "dhcp-option DOMAIN cs.consul" +push "dhcp-option SEARCH {{ domain }}" +push "dhcp-option SEARCH consul" +push "dhcp-option SEARCH cs.consul" +push "dhcp-option SEARCH node.cs.consul" +push "dhcp-option SEARCH service.cs.consul"