ansible/ManagedWeb.yml

Summary

Maintainability
Test Coverage
## YAML Template.
---
- hosts: main_web
  vars:
    app_user: "apache"
    http_host: "{{ ansible_facts['fqdn'] }}"
    ocsp_host: "{{ groups['ocsp_responder'][0] }}"
    http_conf: "{{ ansible_facts['fqdn'] }}.conf"
    http_logdir: "/var/log/httpd/"
    db_root_pw: "new_password"
    consortium: "Roaming Ex Machina"
    root_dn: "/DC=net/DC=enterprise-wifi/O={{ consortium }}/OU=Client Certificates/CN={{ consortium }} Client Root CA Gen 1"
    interm_dn: "/DC=net/DC=enterprise-wifi/O={{ consortium }}/OU=Client Certificates/CN={{ consortium }} Client Issuing CA Gen 1"
  remote_user: root
  tasks:
      - name: enable PowerTools repo
        command:
          cmd: dnf config-manager --set-enabled powertools
      - name: "make sure EPEL repo is available"
        package: 
          name: "{{ ['epel-release'] }}"
          state: latest
      - name: all packages are up to date
        package:
          name: '*'
          state: latest
      - name: install packages
        package:
          name: "{{ ['httpd', 'php', 'php-mysqlnd', 'git', 'php-gettext', 'php-openssl', 'php-devel', 'php-pear', 'php-bcmath', 'php-gd', 'php-json', 'php-mbstring', 'zip', 'openssl', 'haveged', 'python3-PyMySQL', 'wpa_supplicant', 'ImageMagick', 'ImageMagick-devel', 'make', 'mariadb-server', 'certbot', 'python3-certbot-apache'] }}"
      - name: "install composer"
        shell:
          chdir: /usr/local/bin
          cmd: curl -s https://getcomposer.org/installer | php
          creates: /usr/local/bin/composer.phar
      - name: get php-imagick
        community.general.pear:
          name: pecl/imagick
          state: present
      - name: Create directories if they don't exist
        file:
          path: "{{ item }}"
          state: directory
          owner: apache
          group: apache
          mode: 0775
          recurse: yes
        loop:
          - /var/log/CAT
      - name: Start httpd
        service:
          name: httpd
          state: started
      - name: Start MySQL/MariaDB
        service:
          name: mariadb
          state: started    
      - name: Create document root
        file:
          path: "/var/www/{{ http_host }}"
          state: directory
          owner: "{{ app_user }}"
          mode: '0755'
      - name: Set up Apache virtualHost
        template:
          src: "files/web.apache.conf.j2"
          dest: "/etc/httpd/conf.d/{{ http_conf }}"
        notify:
          - restart Apache
      - name: Get an HTTPS certificate from LetsEncrypt
        shell: "certbot run -n --apache --domains {{ http_host }} --agree-tos --email root@{{ http_host }}"
      - name: download CA management scripts
        git:
          repo: https://github.com/GEANT/RADIUS.git
          dest: /tmp/CA_MGMT/
      - name: create directory for CAs
        file: 
          path: "/CA_MGMT"
          state: "directory"
      - name: copy CA generation script to final destination
        command: "/bin/cp -Rf /tmp/CA_MGMT/eduroam-as-a-Service/Client\\ Certificates\\ CA\\ Hierarchy /CA_MGMT/"
      - name: make sure /dev/hwrng exists, even if it is only a symlink to /dev/urandom
        file:
          src: /dev/urandom
          state: link
          path: /dev/hwrng
          force: yes
      - name: adapt CRL location in openssl.conf/RSA
        lineinfile:
          path: "/CA_MGMT/Client Certificates CA Hierarchy/settings/openssl-rsa.cnf"
          line: "crlDistributionPoints=URI:http://{{ ocsp_host }}/revocation/rsa/user-root/crl.der"
          regexp: "^crlDistributionPoints="
      - name: adapt CRL location in openssl.conf/ECDSA
        lineinfile:
          path: "/CA_MGMT/Client Certificates CA Hierarchy/settings/openssl-ecdsa.cnf"
          line: "crlDistributionPoints=URI:http://{{ ocsp_host }}/revocation/ecdsa/user-root/crl.der"
          regexp: "^crlDistributionPoints="
      - name: adapt OCSP location in openssl.conf/RSA
        lineinfile:
          path: "/CA_MGMT/Client Certificates CA Hierarchy/settings/openssl-rsa.cnf"
          line: "OCSP;URI.0 = http://{{ ocsp_host }}/revocation/rsa/user-root/ocsp"
          regexp: "^OCSP;URI.0"
      - name: adapt OCSP location in openssl.conf/ECDSA
        lineinfile:
          path: "/CA_MGMT/Client Certificates CA Hierarchy/settings/openssl-ecdsa.cnf"
          line: "OCSP;URI.0 = http://{{ ocsp_host }}/revocation/ecdsa/user-root/ocsp"
          regexp: "^OCSP;URI.0"
      - name: adapt root cert location in openssl.conf/RSA
        lineinfile:
          path: "/CA_MGMT/Client Certificates CA Hierarchy/settings/openssl-rsa.cnf"
          line: "caIssuers;URI.0 = http://{{ ocsp_host }}/certstore/rsa/user-root/cacert.pem"
          regexp: "^caIssuers;URI.0"
      - name: adapt root cert location in openssl.conf/ECDSA
        lineinfile:
          path: "/CA_MGMT/Client Certificates CA Hierarchy/settings/openssl-ecdsa.cnf"
          line: "caIssuers;URI.0 = http://{{ ocsp_host }}/certstore/ecdsa/user-root/cacert.pem"
          regexp: "^caIssuers;URI.0"
      - name: create self-signed root CAs for client certs if they don't exist yet
        command: 
          argv: "{{ ['./CA.bootstrapNewRootCA', 'deploy1234', root_dn] }}"
          chdir: "/CA_MGMT/Client Certificates CA Hierarchy"
          creates: "/CA_MGMT/Client Certificates CA Hierarchy/ROOT-RSA/cacert.pem"
      - name: create intermediate issuing CAs for client certs if they don't exist yet
        command:
          argv: "{{ ['./CA.generateNewIntermediateCA', 'intermed4321', 'deploy1234', 'INTERMEDIATE', interm_dn] }}"
          chdir: "/CA_MGMT/Client Certificates CA Hierarchy"
          creates: "/CA_MGMT/Client Certificates CA Hierarchy/ROOT-RSA/certs/INTERMEDIATE/cert-rsa.pem"
      - name: get CAT including dependencies
        git:
          repo: https://github.com/GEANT/CAT.git
          dest: /var/www/{{ http_host }}/src/git/
          depth: 1
          force: no
        become: yes
        become_user: apache
      - command:
          cmd: cp -Ru /var/www/{{ http_host }}/src/git/ /var/www/{{ http_host }}/cat/
        become: yes
        become_user: apache
      - name: composer update the CAT dependencies
        shell: "/usr/local/bin/composer.phar --working-dir=/var/www/{{ http_host }}/cat/ update --no-dev"
        become: yes
        become_user: apache
      - name: create default config files (1/4)
        command: 
          cmd: "cp /var/www/{{ http_host }}/cat/config/Master-template.php /var/www/{{ http_host }}/cat/config/Master.php"
          creates: "/var/www/{{ http_host }}/cat/config/Master.php"
        become: yes
        become_user: apache
      - name: create default config files (2/4)
        command: 
          cmd: "cp /var/www/{{ http_host }}/cat/config/ConfAssistant-template.php /var/www/{{ http_host }}/cat/config/ConfAssistant.php"
          creates: "/var/www/{{ http_host }}/cat/config/ConfAssistant.php"
        become: yes
        become_user: apache
      - name: create default config files (3/4)
        command: 
          cmd: "cp /var/www/{{ http_host }}/cat/config/Diagnostics-template.php /var/www/{{ http_host }}/cat/config/Diagnostics.php"
          creates: "/var/www/{{ http_host }}/cat/config/Diagnostics.php"
        become: yes
        become_user: apache
      - name: create default config files (4/4)
        command: 
          cmd: "cp /var/www/{{ http_host }}/cat/devices/Devices-template.php /var/www/{{ http_host }}/cat/devices/Devices.php"
          creates: "/var/www/{{ http_host }}/cat/devices/Devices.php"
        become: yes
        become_user: apache
      - name: brand product with desired consortium name (1/3)
        replace:
          path: "/var/www/{{ http_host }}/cat/config/Master.php"
          regexp: "eduroam"
          replace: "{{ consortium }}"
      - name: brand product with desired consortium name (2/3)
        replace:
          path: "/var/www/{{ http_host }}/cat/config/ConfAssistant.php"
          regexp: "eduroam"
          replace: "{{ consortium }}"
      - name: brand product with desired consortium name (3/3)
        replace:
          path: "/var/www/{{ http_host }}/cat/config/Diagnostics.php"
          regexp: "eduroam"
          replace: "{{ consortium }}"
      - name: create simpleSAMLphp basic config (1/2)
        command:
          cmd: "cp /var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config-templates/config.php /var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config/"
          creates: /var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config/config.php
        become: yes
        become_user: apache
      - name: create simpleSAMLphp basic config (1/2)
        command:
          cmd: "cp /var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config-templates/authsources.php /var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config/"
          creates: /var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config/authsources.php
        become: yes
        become_user: apache
      - name: change admin password so we can actually authenticate against it
        lineinfile:
          path: "/var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/config/config.php"
          regexp: "'auth.adminpassword'"
          line: "'auth.adminpassword' => 'testing123',"
      - name: CAT authenticate against the static 'admin' password. Something to fine-tune obviously.
        lineinfile:
          path: /var/www/{{ http_host }}/cat/config/Master.php
          regexp: "'ssp-authsource'"
          line: "'ssp-authsource' => 'admin',"
      - name: set correct pointer to SSP web root
        lineinfile:
          path: /var/www/{{ http_host }}/cat/config/Master.php
          regexp: "'ssp-path-to-autoloader' => '"
          line: "'ssp-path-to-autoloader' => '/var/www/{{ http_host }}/cat/vendor/simplesamlphp/simplesamlphp/www/_include.php',"
      - name: use 'user' for the eptid so that the admin module can work
        lineinfile:
          path: /var/www/{{ http_host }}/cat/config/Master.php
          regexp: "'ssp-attrib-identifier' => '"
          line: "'ssp-attrib-identifier' => 'user',"
      - name: set correct pointer to GeoIP2
        lineinfile:
          path: /var/www/{{ http_host }}/cat/config/Master.php
          regexp: "'geoip2-path-to-autoloader' => '"
          line: "'geoip2-path-to-autoloader' => '/var/www/{{ http_host }}/cat/vendor/autoload.php',"
      - name: copy nsis3 to fixed path on system
        command:
          cmd: "cp -R /var/www/{{ http_host }}/cat/tests/nsis3 /usr/local/share/"            
      - name: use our inline test deployment of NSIS3
        lineinfile:
          path: /var/www/{{ http_host }}/cat/config/ConfAssistant.php
          regexp: "'makensis' => '"
          line: "'makensis' => '/usr/local/share/nsis3/bin/makensis',"
      - name: make sure user exists
        mysql_user:
            login_user: "root"
            host: "localhost"
            name: "kitty"
            update_password: "always"
            password: "somepass"
            priv: "cat_ansible.*:ALL"
      - name: check if DB exists
        shell: mysql -e 'SHOW DATABASES;' | grep cat_ansible
        register: dbstatus
        failed_when: dbstatus.rc == 2
      - name: install DB schema
        mysql_db:
          login_user: "kitty"
          login_password: "somepass"
          name: "cat_ansible"
          target: "/var/www/{{ http_host }}/cat/schema/schema.sql"
          state: import
        when: dbstatus.rc == 1
      - name: adapt CAT config - database name
        replace:
          path: "/var/www/{{ http_host }}/cat/config/Master.php"
          regexp: "'db' => 'cat',"
          replace: "'db' => 'cat_ansible',"
      - name: copy client cert root CA to its config location (RSA)
        command:
          cmd: "cp /CA_MGMT/Client\\ Certificates\\ CA\\ Hierarchy/ROOT-RSA/cacert.pem /var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/rootca-RSA.pem"
          creates: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/rootca-RSA.pem"
        become: yes
        become_user: apache
      - name: copy client cert root CA to its config location (ECDSA)
        command:
          cmd: "cp /CA_MGMT/Client\\ Certificates\\ CA\\ Hierarchy/ROOT-ECDSA/cacert.pem /var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/rootca-ECDSA.pem"
          creates: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/rootca-ECDSA.pem"
        become: yes
        become_user: apache
      - name: copy client cert intermediate CA to its config location (RSA)
        command:
          cmd: "cp /CA_MGMT/Client\\ Certificates\\ CA\\ Hierarchy/ROOT-RSA/certs/INTERMEDIATE/cert-rsa.pem /var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-RSA.pem"
          creates: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-RSA.pem"
      - name: establish unprotected private key for intermediate CA in config (RSA)
        command: 
          cmd: "openssl rsa -in /CA_MGMT/Client\\ Certificates\\ CA\\ Hierarchy/ROOT-RSA/certs/INTERMEDIATE/cert-srv-key.pem -passin pass:intermed4321 -out /var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-RSA.key"
          creates: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-RSA.key"         
      - name: copy client cert intermediate CA to its config location (ECDSA)
        command:
          cmd: "cp /CA_MGMT/Client\\ Certificates\\ CA\\ Hierarchy/ROOT-ECDSA/certs/INTERMEDIATE/cert-ecdsa.pem /var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-ECDSA.pem"
          creates: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-ECDSA.pem"
      - name: establish unprotected private key for intermediate CA in config (ECDSA)
        command: 
          cmd: "openssl ec -in /CA_MGMT/Client\\ Certificates\\ CA\\ Hierarchy/ROOT-ECDSA/certs/INTERMEDIATE/cert-ecsrv-key.pem -passin pass:intermed4321 -out /var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-ECDSA.key"
          creates: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/real-ECDSA.key"         
      - name: fix ownership of certificate files
        file:
          owner: apache
          group: apache
          path: "/var/www/{{ http_host }}/cat/config/SilverbulletClientCerts/{{ item }}"
        loop: 
          - real-RSA.pem
          - real-RSA.key
          - real-ECDSA.pem
          - real-ECDSA.key

  handlers:
    - name: reload Apache
      service:
        name: httpd
        state: reloaded

    - name: restart Apache
      service:
        name: httpd
        state: restarted