---

- name: Install OpenVPN
  openbsd_pkg:
    name: openvpn--
  when: ansible_distribution == 'OpenBSD'

- name: Create /etc/openvpn
  file:
    dest: "/etc/openvpn"
    state: directory
    owner: root
    group: wheel
    mode: "0755"

- name: Create the shellpki user
  user:
    name: _shellpki
    system: yes
    create_home: no
    home: "/etc/shellpki"
    shell: "/sbin/nologin"

- name: Create /etc/shellpki
  file:
    dest: "/etc/shellpki"
    state: directory
    owner: _shellpki
    group: _shellpki
    mode: "0755"

- name: Copy shellpki files
  copy:
    src: "shellpki/{{ item.source }}"
    dest: "{{ item.destination }}"
    mode: "{{ item.mode }}"
    owner: "{{ item.owner }}"
    group: "{{ item.group }}"
  with_items:
     - { source: "openssl.cnf", destination: "/etc/shellpki/openssl.cnf", mode: "0640", owner: "_shellpki", group: "_shellpki" }
     - { source: "shellpki", destination: "/usr/local/sbin/shellpki", mode: "0755", owner: "root", group: "wheel" }

- name: Add sudo rights
  lineinfile:
    dest: "/etc/sudoers"
    regexp: '/usr/local/sbin/shellpki'
    line: "%_shellpki ALL = (root) /usr/local/sbin/shellpki"
    validate: 'visudo -cf %s'

- name: Deploy OpenVPN client config template
  template:
    src: "ovpn.conf.j2"
    dest: "/etc/shellpki/ovpn.conf"
    mode: "0640"
    owner: _shellpki
    group: _shellpki

- name: Generate dhparam
  openssl_dhparam:
    path: /etc/shellpki/dh2048.pem
    size: 2048

- name: Fix CRL rights in shellpki command
  lineinfile:
    dest: "/usr/local/sbin/shellpki"
    regexp: '{{ item.regexp }}'
    insertafter: "{{ item.insertafter }}"
    line: "{{ item.line }}"
  with_items:
     - { regexp: '^    chmod 604 /etc/shellpki/crl.pem$', line: "    chmod 604 /etc/shellpki/crl.pem", insertafter: '^    chmod 640 "\${CACERT}"$' }
     - { regexp: '^    chmod 751 /etc/shellpki/$', line: "    chmod 751 /etc/shellpki/", insertafter: '^    chmod 604 /etc/shellpki/crl.pem$' }

- name: Deploy OpenVPN server config
  template:
    src: "server.conf.j2"
    dest: "/etc/openvpn/server.conf"
    mode: "0600"
    owner: root
    group: wheel

- name: Configure PacketFilter
  lineinfile:
    dest: "/etc/pf.conf"
    line: "{{ item }}"
    validate: 'pfctl -nf %s'
  notify: reload packetfilter
  with_items:
     - "# OpenVPN"
     - "pass in quick on $ext_if proto udp from any to self port 1194"

- name: Create a cron to rotate the logs
  cron:
    name: "OpenVPN logs rotation"
    weekday: "6"
    hour: "4"
    minute: "0"
    job: "cp /var/log/openvpn.log /var/log/openvpn.log.$(date +\\%F) && echo \"$(date +\\%F' '\\%R) - logfile turned over via cron\" > /var/log/openvpn.log && gzip /var/log/openvpn.log.$(date +\\%F) && find /var/log/ -type f -name \"openvpn.log.*\" -mtime +365 -exec rm {} \\+"

- name: Generate a password for the management interface
  set_fact:
    management_pwd: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters,digits') }}"

- name: Set the management password
  copy:
    dest: "/etc/openvpn/management-pwd"
    content: "{{ management_pwd }}"
    mode: "0600"
    owner: root
    group: wheel

- name: Enable openvpn service
  service:
    name: openvpn
    enabled: yes

- name: Set openvpn flags
  lineinfile:
    dest: /etc/rc.conf.local
    regexp: "^openvpn_flags="
    line: "openvpn_flags=--daemon --config /etc/openvpn/server.conf"
    create: yes

- name: Is NRPE installed ?
  stat:
    path: "/etc/nrpe.d/evolix.cfg"
  check_mode: no
  register: nrpe_evolix_config

- name: Install NRPE check dependencies
  openbsd_pkg:
    name: p5-Net-Telnet
  when: nrpe_evolix_config.stat.exists

- name: Install OpenVPN NRPE check
  copy:
    src: "files/check_openvpn_openbsd.pl"
    dest: "/usr/local/libexec/nagios/plugins/check_openvpn.pl"
    mode: "0755"
    owner: root
    group: wheel
  when: nrpe_evolix_config.stat.exists

- name: Configure NRPE OpenVPN check
  lineinfile:
    dest: "/etc/nrpe.d/zzz_evolix.cfg"
    regexp: '^command\[check_openvpn\]='
    line: "command[check_openvpn]=/usr/local/libexec/nagios/plugins/check_openvpn.pl -H 127.0.0.1 -p 1195 -P {{ management_pwd }}"
    create: yes
    mode: "0644"
    owner: root
    group: wheel
  notify: restart nrpe
  when: nrpe_evolix_config.stat.exists

- name: Install OpenVPN certificates NRPE check
  copy:
    src: "files/check_openvpn_certificates.sh"
    dest: "/usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh"
    mode: "0755"
    owner: root
    group: wheel
  when: nrpe_evolix_config.stat.exists

- name: Add doas rights for NRPE check
  lineinfile:
    dest: "/etc/doas.conf"
    regexp: 'check_openvpn_certificates.sh'
    line: "permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh"
    validate: 'doas -C %s'
  when: nrpe_evolix_config.stat.exists

- name: Configure NRPE certificates check
  lineinfile:
    dest: "/etc/nrpe.d/evolix.cfg"
    regexp: '^command\[check_openvpn_certificates\]='
    line: "command[check_openvpn_certificates]=doas /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh"
  notify: restart nrpe
  when: nrpe_evolix_config.stat.exists

- name: Copy script to check expirations
  copy:
    src: "shellpki/cert-expirations.sh"
    dest: "/usr/share/scripts/cert-expirations.sh"
    mode: "0700"
    owner: root
    group: wheel

- name: Install cron to warn about certificates expiration
  cron:
    name: "OpenVPN certificates expiration"
    special_time: monthly
    job: '/usr/share/scripts/cert-expirations.sh | mail -E -s "PKI VPN {{ ansible_hostname }} : recapitulatif expirations" {{ client_email }}'

- name: Generate the CA password
  set_fact:
    ca_pwd: "{{ lookup('password', '/dev/null length=25 chars=ascii_letters,digits') }}"
  check_mode: no
  changed_when: no

- name: Initialization of the CA
  shell: 'CA_PASSWORD="{{ ca_pwd }}" shellpki init --non-interactive {{ ansible_fqdn }}'

- name: Creation of the server's certificate
  shell: 'CA_PASSWORD="{{ ca_pwd }}" shellpki create --days 3650 --non-interactive {{ ansible_fqdn }}'

- name: Get the server key
  shell: 'ls -tr /etc/shellpki/private/ | tail -1'
  register: ca_key
  check_mode: no
  changed_when: no

- name: Configure the server key
  replace:
    path: /etc/openvpn/server.conf
    regexp: 'key  /etc/shellpki/private/TO_COMPLETE'
    replace: 'key  /etc/shellpki/private/{{ ca_key.stdout }}'

- name: Restart OpenVPN
  service:
    name: openvpn
    state: restarted

- name: Warn the user about manual checks
  pause:
    prompt: |
      /!\ WARNING /!\
      You must check and adjust if necessary the configuration file "/etc/openvpn/server.conf", and then restart the OpenVPN service with "rcctl restart openvpn".
      The "push" parameter may be needed to push a route to the client, so that the client can access that route through OpenVPN.

      Take note of the generated CA password and store it in your password manager : {{ ca_pwd }}
      
      Press enter to exit when it's done.

