diff --git a/provision.yml b/provision.yml index 357d54136..f670effa8 100644 --- a/provision.yml +++ b/provision.yml @@ -167,6 +167,7 @@ - { role: stepupgateway, tags: ['stepupgateway' , 'stepup'] } - { role: stepupselfservice, tags: ['stepupselfservice' , 'stepup'] } - { role: stepupra , tags: ['stepupra' , 'stepup'] } + - { role: stepupgateway , tags: ['stepupgateway' , 'stepup'] } - hosts: docker become: true diff --git a/roles/rsyslog/templates/sc_ruleset.conf.j2 b/roles/rsyslog/templates/sc_ruleset.conf.j2 index 66af2cf28..6550e5a65 100644 --- a/roles/rsyslog/templates/sc_ruleset.conf.j2 +++ b/roles/rsyslog/templates/sc_ruleset.conf.j2 @@ -50,6 +50,8 @@ if $programname == "gateway" and $msg startswith ' {"message":"Intrinsic Loa Req {% for stepupapp in stepupapps %} :programname, isequal, "stepup-{{ stepupapp }}" { action(type="omfile" DynaFile="stepup-{{ stepupapp }}-{{item.name }}") stop } +if $programname == "{{ stepupapp }}" and $msg startswith " {{ stepupapp }}" then { action(type="omfile" DynaFile="apache-{{ stepupapp }}-{{item.name }}") stop } +:programname, isequal, "{{ stepupapp }}" { action(type="omfile" DynaFile="stepup-{{ stepupapp }}-{{item.name }}") stop } :programname, isequal, "Apache-{{ stepupapp }}" { action(type="omfile" DynaFile="apache-{{ stepupapp }}-{{item.name }}") stop } if $programname == "{{ stepupapp }}" and $msg startswith " {{ stepupapp }}" then { action(type="omfile" DynaFile="apache-{{ stepupapp }}-{{item.name }}") stop } :programname, isequal, "{{ stepupapp }}" { action(type="omfile" DynaFile="stepup-{{ stepupapp }}-{{item.name }}") stop } diff --git a/roles/stepupapp/tasks/copyspcerts.yml b/roles/stepupapp/tasks/copyspcerts.yml index 7f944e1f3..0ca8b6322 100644 --- a/roles/stepupapp/tasks/copyspcerts.yml +++ b/roles/stepupapp/tasks/copyspcerts.yml @@ -5,11 +5,11 @@ dest: "{{ current_release_config_file_dir_name }}/sp.key" owner: "{{ appname}}" group: "{{ appname }}" - mode: 400 + mode: "0440" - name: Write SP certificate | {{ appname }} copy: src: "{{ inventory_dir }}/files/certs/stepup/{{ appname }}_saml_sp.crt" dest: "{{ current_release_config_file_dir_name }}/sp.crt" group: "{{ appname }}" - mode: 400 + mode: "0440" diff --git a/roles/stepupazuremfa/handlers/main.yml b/roles/stepupazuremfa/handlers/main.yml index 40eef830c..6e76d3748 100644 --- a/roles/stepupazuremfa/handlers/main.yml +++ b/roles/stepupazuremfa/handlers/main.yml @@ -6,3 +6,9 @@ service: name: php72-php-fpm state: reloaded + +- name: restart azuremfa + community.docker.docker_container: + name: azuremfa + state: started + restart: true diff --git a/roles/stepupazuremfa/tasks/main.yml b/roles/stepupazuremfa/tasks/main.yml index d76f1035f..a7935e775 100644 --- a/roles/stepupazuremfa/tasks/main.yml +++ b/roles/stepupazuremfa/tasks/main.yml @@ -1,62 +1,78 @@ -- name: Install Apache and FPM config - include_role: - name: apachefpm +- name: Include docker vars + ansible.builtin.include_vars: docker.yml -- name: Install the symfony app - include_role: - name: stepupapp +- name: Add group {{ appname }} + ansible.builtin.group: + name: "{{ appname }}" + state: present + register: azuremfa_guid + +- name: Add user {{ appname }} + ansible.builtin.user: + name: "{{ appname }}" + group: "{{ appname }}" + createhome: no + state: present + register: azuremfa_uid + +- name: Create some dirs + ansible.builtin.file: + state: directory + dest: "{{ item }}" + owner: root + group: root + mode: "0755" + with_items: + - "{{ current_release_config_dir_name }}" + - "{{ current_release_appdir }}/public/images" - name: Install images - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copyimages - name: Install the GSSP certificates - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copygsspidpcerts - name: Place parameters.yml - template: + ansible.builtin.template: src: parameters.yaml.j2 dest: "{{ current_release_config_dir_name }}/parameters.yaml" - mode: 0640 + mode: "0640" owner: root group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} + notify: restart azuremfa - name: Put institutions.yaml from environment - template: + ansible.builtin.template: src: "{{ inventory_dir }}/files/stepup-azuremfa/institutions.yaml.j2" dest: "{{ current_release_config_dir_name }}/institutions.yaml" - mode: 0640 - group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Place .env file - template: - src: env.j2 - dest: "{{ current_release_appdir }}/.env.local" - mode: 0640 + mode: "0640" owner: root group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}/" - dest: "{{ current_release_symlink }}" - state: link + notify: restart azuremfa -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall +- name: Create the container + community.docker.docker_container: + name: "{{ appname }}" + image: ghcr.io/openconext/stepup-azuremfa/stepup-azuremfa:{{ azuremfa_version }} + pull: true + restart_policy: "always" + networks: + - name: "loadbalancer" + labels: + traefik.http.routers.azuremfa.rule: "Host(`azuremfa.{{ base_domain }}`)" + traefik.http.routers.azuremfa.tls: "true" + traefik.enable: "true" + env: + APACHE_UID: "#{{ azuremfa_uid.uid }}" + APACHE_GUID: "#{{ azuremfa_guid.gid }}" + mounts: + - source: /opt/openconext/azuremfa/public/images/header-logo.png + target: /var/www/html/public/build/images/header-logo.png + type: bind + - source: /opt/openconext/azuremfa + target: /var/www/html/config/openconext + type: bind diff --git a/roles/stepupazuremfa/templates/parameters.yaml.j2 b/roles/stepupazuremfa/templates/parameters.yaml.j2 index ff19a47eb..61a49ef5e 100644 --- a/roles/stepupazuremfa/templates/parameters.yaml.j2 +++ b/roles/stepupazuremfa/templates/parameters.yaml.j2 @@ -1,16 +1,21 @@ parameters: +{% if 'docker' in group_names %} + app_env: prod + app_debug: false + app_secret: {{ azuremfa_secret }} +{% endif %} # All locales supported by the application locales: [{{ enabled_locales | join(",") }}] # SAML configuration - saml_idp_publickey: '{{ current_release_config_file_dir_name }}/cert.pem' - saml_idp_privatekey: '{{ current_release_config_file_dir_name }}/key.pem' + saml_idp_publickey: '{{ current_release_config_file_dir_name_in_config }}/cert.pem' + saml_idp_privatekey: '{{ current_release_config_file_dir_name_in_config }}/key.pem' # NOTE: same key used for metadata and response/assertion signing - saml_metadata_publickey: '{{ current_release_config_file_dir_name }}/cert.pem' - saml_metadata_privatekey: '{{ current_release_config_file_dir_name }}/key.pem' + saml_metadata_publickey: '{{ current_release_config_file_dir_name_in_config }}/cert.pem' + saml_metadata_privatekey: '{{ current_release_config_file_dir_name_in_config }}/key.pem' saml_remote_sp_entity_id: 'https://{{ gateway_vhost_name }}/gssp/azuremfa/metadata' - saml_remote_sp_certificate: '{{ current_release_config_file_dir_name }}/gateway.crt' + saml_remote_sp_certificate: '{{ current_release_config_file_dir_name_in_config }}/gateway.crt' saml_remote_sp_acs: 'https://{{ gateway_vhost_name }}/gssp/azuremfa/consume-assertion' # View parameters diff --git a/roles/stepupazuremfa/vars/docker.yml b/roles/stepupazuremfa/vars/docker.yml new file mode 100644 index 000000000..764009ac0 --- /dev/null +++ b/roles/stepupazuremfa/vars/docker.yml @@ -0,0 +1,4 @@ +current_release_appdir: /opt/openconext/azuremfa +current_release_config_file_dir_name: /opt/openconext/azuremfa +current_release_config_file_dir_name_in_config: /var/www/html/config/openconext +current_release_config_dir_name: /opt/openconext/azuremfa diff --git a/roles/stepupazuremfa/vars/main.yml b/roles/stepupazuremfa/vars/main.yml index 9ef9ade0f..fbadef306 100644 --- a/roles/stepupazuremfa/vars/main.yml +++ b/roles/stepupazuremfa/vars/main.yml @@ -7,6 +7,7 @@ stepup_gh_appname: "Azure-MFA" current_release_symlink: "/opt/openconext/OpenConext-{{ appname }}" current_release_appdir: "{{current_release_symlink }}-{{ appversion }}" current_release_config_file_dir_name: "{{ current_release_appdir }}/app/files" +#current_release_config_file_dir_name_in_config: "{{ current_release_config_file_dir_name }}" current_release_config_dir_name: "{{ current_release_appdir }}/config/packages" gssp_idp_private_key: "{{ lookup('file', inventory_dir+'/files/certs/stepup/azuremfa_idp.key') }}" fpmmemory: 128M diff --git a/roles/stepupgateway/handlers/main.yml b/roles/stepupgateway/handlers/main.yml index 40eef830c..b0afaa370 100644 --- a/roles/stepupgateway/handlers/main.yml +++ b/roles/stepupgateway/handlers/main.yml @@ -6,3 +6,6 @@ service: name: php72-php-fpm state: reloaded + +- name: restart gateway + command: docker restart gateway diff --git a/roles/stepupgateway/tasks/main.yml b/roles/stepupgateway/tasks/main.yml index 52f24b95a..c4d604fec 100644 --- a/roles/stepupgateway/tasks/main.yml +++ b/roles/stepupgateway/tasks/main.yml @@ -1,26 +1,47 @@ -- name: Install Apache and FPM config - include_role: - name: apachefpm - -- name: Install the symfony app - include_role: - name: stepupapp +--- +- name: Include docker vars + ansible.builtin.include_vars: docker.yml + +- name: Add group {{ appname }} + ansible.builtin.group: + name: "{{ appname }}" + state: present + register: gateway_guid + +- name: Add user {{ appname }} + ansible.builtin.user: + name: "{{ appname }}" + group: "{{ appname }}" + createhome: no + state: present + register: gateway_uid + +- name: Create some dirs + ansible.builtin.file: + state: directory + dest: "{{ item }}" + owner: root + group: root + mode: "0755" + with_items: + - "{{ current_release_config_dir_name }}" + - "{{ current_release_appdir }}/public/images" - name: Install images - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copyimages - name: Install second factor images - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copysfimages - name: Place config parameterfiles - template: + ansible.builtin.template: src: "{{ item }}.yml.j2" dest: "{{ current_release_config_dir_name }}/{{ item }}.yaml" - mode: 0640 + mode: "0640" owner: root group: "{{ appname }}" with_items: @@ -29,97 +50,86 @@ - samlstepupproviders_parameters - global_view_parameters notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Place .env file - template: - src: env.j2 - dest: "{{ current_release_appdir }}/.env.local" - mode: 0640 - owner: root - group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} + - restart {{ appname }} -# Writing all the SAML keys and certificates. Since the gateway is special no need to include it from other roles + # Writing all the SAML keys and certificates. Since the gateway is special no need to include it from other roles - name: Write GateWay SAML SP private key - copy: + ansible.builtin.copy: content: "{{ gateway_saml_sp_privatekey }}" dest: "{{ current_release_config_file_dir_name }}/sp.key" owner: "{{ appname }}" - mode: 0400 + mode: "0400" - name: Write SAML SP certificate - copy: + ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/stepup/gateway_saml_sp.crt" dest: "{{ current_release_config_file_dir_name }}/sp.crt" group: "{{ appname }}" - mode: 0640 + mode: "0640" - name: Write GSSP SP private key - copy: + ansible.builtin.copy: content: "{{ gateway_gssp_sp_privatekey }}" dest: "{{ current_release_config_file_dir_name }}/sp_gssp.key" owner: "{{ appname }}" - mode: 0400 + mode: "0400" - name: Write GSSP SP certificate - copy: + ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/stepup/gateway_gssp_sp.crt" dest: "{{ current_release_config_file_dir_name }}/sp_gssp.crt" group: "{{ appname }}" - mode: 0640 + mode: "0640" - name: Write SAML IdP private key - copy: + ansible.builtin.copy: content: "{{ gateway_saml_idp_privatekey }}" dest: "{{ current_release_config_file_dir_name }}/idp.key" owner: "{{ appname }}" - mode: 0400 + mode: "0400" - name: Write SAML IdP public key - copy: + ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/stepup/gateway_saml_idp.crt" dest: "{{ current_release_config_file_dir_name }}/idp.crt" group: "{{ appname }}" - mode: 0640 + mode: "0640" - name: Write GSSP IdP cert - copy: + ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/stepup/gateway_gssp_idp.crt" dest: "{{ current_release_config_file_dir_name }}/idp_gssp.crt" owner: "{{ appname }}" - mode: 0600 + mode: "0600" - name: Write GSSP IdP key - copy: + ansible.builtin.copy: content: "{{ gateway_gssp_idp_privatekey }}" dest: "{{ current_release_config_file_dir_name }}/idp_gssp.key" owner: "{{ appname }}" - mode: 0600 - -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}/" - dest: "{{ current_release_symlink }}" - state: link - -- name: Remove gateway database db_migrate script from /root/ - file: - path: "/root/01-gateway-db_migrate.sh" - state: absent - -- name: Put logout.php in public - template: - src: "logout.php.j2" - dest: "{{ current_release_appdir }}/public/logout.php" - mode: "444" - -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall + mode: "0600" + +- name: Create the container + community.docker.docker_container: + name: "{{ appname }}" + image: ghcr.io/openconext/stepup-gateway/stepup-gateway:{{ gateway_version }} + pull: true + restart_policy: "always" + networks: + - name: "loadbalancer" + labels: + traefik.http.routers.gateway.rule: "Host(`{{ gateway_vhost_name }}`)" + traefik.http.routers.gateway.tls: "true" + traefik.enable: "true" + env: + APACHE_UID: "#{{ gateway_uid.uid }}" + APACHE_GUID: "#{{ gateway_guid.gid }}" + APP_ENV: prod + HTTPD_CSP: "" + mounts: + - source: /opt/openconext/gateway/public/images/header-logo.png + target: /var/www/html/public/images/header-logo.png + type: bind + - source: /opt/openconext/gateway/ + target: /var/www/html/config/openconext + type: bind diff --git a/roles/stepupgateway/templates/parameters.yml.j2 b/roles/stepupgateway/templates/parameters.yml.j2 index 021a4e9af..29281d6cc 100644 --- a/roles/stepupgateway/templates/parameters.yml.j2 +++ b/roles/stepupgateway/templates/parameters.yml.j2 @@ -1,4 +1,10 @@ parameters: +{% if 'docker' in group_names %} + app_env: prod + app_debug: false + app_secret: {{ gateway_secret }} +{% endif %} + trusted_proxies: [ 127.0.0.1 ] database_driver: pdo_mysql @@ -57,21 +63,21 @@ parameters: # The private key and certificate that are used by the Gateway SP to sign SAML AuthnRequests # Filename of the PEM CERTIFICATE - saml_sp_publickey: {{ current_release_config_file_dir_name }}/sp.crt + saml_sp_publickey: {{ current_release_config_file_dir_name_in_config }}/sp.crt # Filename of the PEM RSA PRIVATE KEY - saml_sp_privatekey: {{ current_release_config_file_dir_name }}/sp.key + saml_sp_privatekey: {{ current_release_config_file_dir_name_in_config }}/sp.key # The private key and certificate that are used by the Gateway IdP to sign SAML Responses/Assertions # Filename of the PEM CERTIFICATE - saml_idp_publickey: {{ current_release_config_file_dir_name }}/idp.crt + saml_idp_publickey: {{ current_release_config_file_dir_name_in_config }}/idp.crt # Filename of the PEM RSA PRIVATE KEY - saml_idp_privatekey: {{ current_release_config_file_dir_name }}/idp.key + saml_idp_privatekey: {{ current_release_config_file_dir_name_in_config }}/idp.key # The certificate and private key that are used by the Gateway to sign the metadata that it publishes # Filename of the PEM CERTIFICATE - saml_metadata_publickey: {{ current_release_config_file_dir_name }}/idp.crt + saml_metadata_publickey: {{ current_release_config_file_dir_name_in_config }}/idp.crt # Filename of the PEM RSA PRIVATE KEY - saml_metadata_privatekey: {{ current_release_config_file_dir_name }}/idp.key + saml_metadata_privatekey: {{ current_release_config_file_dir_name_in_config }}/idp.key # The remote IdP (i.e. not the local IdP that is part of the Gateway) is the IdP that provides the first # factor authentication of users to the Gateway. diff --git a/roles/stepupgateway/templates/samlstepupproviders_parameters.yml.j2 b/roles/stepupgateway/templates/samlstepupproviders_parameters.yml.j2 index 86c5e267c..10ef19e7d 100644 --- a/roles/stepupgateway/templates/samlstepupproviders_parameters.yml.j2 +++ b/roles/stepupgateway/templates/samlstepupproviders_parameters.yml.j2 @@ -15,16 +15,16 @@ parameters: # Metadata URL: https:///gssp/{{ key }}/metadata # GSSP SP Proxy for authenticating with the real (i.e. external) GSSP IdP - gssp_{{ key }}_sp_publickey: {{ current_release_config_file_dir_name }}/sp_gssp.crt - gssp_{{ key }}_sp_privatekey: {{ current_release_config_file_dir_name }}/sp_gssp.key + gssp_{{ key }}_sp_publickey: {{ current_release_config_file_dir_name_in_config }}/sp_gssp.crt + gssp_{{ key }}_sp_privatekey: {{ current_release_config_file_dir_name_in_config }}/sp_gssp.key # Certificate and private key of GSSP IdP Proxy for use by RA and SS - gssp_{{ key }}_idp_publickey: {{ current_release_config_file_dir_name }}/idp_gssp.crt - gssp_{{ key }}_idp_privatekey: {{ current_release_config_file_dir_name }}/idp_gssp.key + gssp_{{ key }}_idp_publickey: {{ current_release_config_file_dir_name_in_config }}/idp_gssp.crt + gssp_{{ key }}_idp_privatekey: {{ current_release_config_file_dir_name_in_config }}/idp_gssp.key # Metadata signing cert and key for tiqr SP/IdP proxy - gssp_{{ key }}_metadata_publickey: {{ current_release_config_file_dir_name }}/idp_gssp.crt - gssp_{{ key }}_metadata_privatekey: {{ current_release_config_file_dir_name }}/idp_gssp.key + gssp_{{ key }}_metadata_publickey: {{ current_release_config_file_dir_name_in_config }}/idp_gssp.crt + gssp_{{ key }}_metadata_privatekey: {{ current_release_config_file_dir_name_in_config }}/idp_gssp.key # Real (i.e. external) GSSP IdP gssp_{{ key }}_remote_entity_id: '{{ hostvars[inventory_hostname]['gateway_' + key + '_remote_entity_id'] }}' diff --git a/roles/stepupgateway/vars/docker.yml b/roles/stepupgateway/vars/docker.yml new file mode 100644 index 000000000..3c9ed88fd --- /dev/null +++ b/roles/stepupgateway/vars/docker.yml @@ -0,0 +1,5 @@ +current_release_appdir: /opt/openconext/gateway +current_release_config_file_dir_name: /opt/openconext/gateway +current_release_config_file_dir_name_in_config: /var/www/html/config/openconext +current_release_config_dir_name: /opt/openconext/gateway/ + diff --git a/roles/stepupgateway/vars/main.yml b/roles/stepupgateway/vars/main.yml index 8f8ba95df..ca601a1d6 100644 --- a/roles/stepupgateway/vars/main.yml +++ b/roles/stepupgateway/vars/main.yml @@ -7,7 +7,8 @@ stepup_gh_appname: "Gateway" current_release_symlink: "/opt/openconext/OpenConext-{{ appname }}" current_release_appdir: "{{current_release_symlink }}-{{ appversion }}" current_release_config_file_dir_name: "{{ current_release_appdir }}/app/files" -current_release_config_dir_name: "{{ current_release_appdir }}/config/legacy" +current_release_config_dir_name: "{{ current_release_appdir }}/config/openconext" +current_release_config_file_dir_name_in_config: "{{ current_release_config_file_dir_name }}" gateway_saml_sp_privatekey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/gateway_saml_sp.key') }}" gateway_gssp_sp_privatekey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/gateway_gssp_sp.key') }}" gateway_gssp_idp_privatekey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/gateway_gssp_idp.key') }}" diff --git a/roles/stepupmiddleware/tasks/docker.yml b/roles/stepupmiddleware/tasks/docker.yml new file mode 100644 index 000000000..44861f4b1 --- /dev/null +++ b/roles/stepupmiddleware/tasks/docker.yml @@ -0,0 +1,3 @@ +--- +- name: Exiting since there is no docker support yet + meta: end_play diff --git a/roles/stepupmiddleware/tasks/main.yml b/roles/stepupmiddleware/tasks/main.yml index ceab80cb6..d55b2e516 100644 --- a/roles/stepupmiddleware/tasks/main.yml +++ b/roles/stepupmiddleware/tasks/main.yml @@ -1,133 +1,7 @@ -- name: Install Apache and FPM config - include_role: - name: apachefpm +- name: Include docker tasks when running docker + include_tasks: docker.yml + when: "'docker' in group_names" -- name: Install the symfony app - include_role: - name: stepupapp - -- name: Place parameters.yml - template: - src: parameters.yaml.j2 - dest: "{{ current_release_config_dir_name }}/parameters.yaml" - mode: 0640 - owner: root - group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}" - dest: "{{ current_release_symlink }}" - state: link - -- name: Put middleware configuration scripts in /root/ - template: - src: "{{ item }}.j2" - dest: "/root/{{ item }}" - group: "root" - owner: "root" - mode: "0500" - with_items: - - "01-middleware-db_migrate.sh" - - "06-middleware-bootstrap-sraa-users.sh" - -- name: Create /opt/scripts - file: - path: /opt/scripts - state: directory - owner: root - group: root - mode: 0750 - -- name: Put middleware config from environment in /opt/scripts - template: - src: "{{ inventory_dir }}/templates/middleware/{{ item }}.j2" - dest: "/opt/scripts/{{ item }}" - group: "{{ appname }}" - owner: "{{ appname }}" - mode: "0400" - with_items: - - "middleware-config.json" - - "middleware-whitelist.json" - - "middleware-institution.json" - tags: - - push_mw_config - - push_mw_institution - - push_mw_whitelist - -- name: Put middleware configuration scripts in /opt/scripts - template: - src: "{{ item}}.j2" - dest: "/opt/scripts/{{ item }}" - group: "{{ appname }}" - owner: root - mode: "0550" - with_items: - - "middleware-push-config.sh" - - "middleware-push-whitelist.sh" - - "middleware-push-institution.sh" - -- name: Create symlinks to middleware configuration scripts in /root - file: - src: "/opt/scripts/{{ item.key }}" - dest: "/root/{{ item.value }}" - group: "{{ appname }}" - owner: root - state: link - force: true - with_dict: - "middleware-push-config.sh": "02-middleware-config.sh" - "middleware-push-whitelist.sh": "04-middleware-whitelist.sh" - "middleware-push-institution.sh": "05-middleware-institution.sh" - -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall - -# The following push scripts have an additional conditional check on the presence of -# a tag, so these are only ran when explicitly called. - -- name: Push middleware configuration - command: /opt/scripts/middleware-push-config.sh - run_once: true - when: - - "'push_mw_config' in ansible_run_tags" - tags: - - push_mw_config - -- name: Push middleware whitelist - command: /opt/scripts/middleware-push-whitelist.sh - run_once: True - when: - - "'push_mw_whitelist' in ansible_run_tags" - tags: - - push_mw_whitelist - -- name: Push middleware institution configuration - command: /opt/scripts/middleware-push-institution.sh - run_once: True - when: - - "'push_mw_institution' in ansible_run_tags" - tags: - - push_mw_institution - - -# Middleware migrate identities from CSV - -- name: Migrate middleware identities from CSV - include_tasks: migrate_identities.yml - args: - apply: - tags: - - mw_migrate_identities - run_once: True - when: - - "'mw_migrate_identities' in ansible_run_tags" - tags: - - mw_migrate_identities +- name: Include vm tasks when running on a vm + include_tasks: vm.yml + when: "'docker' not in group_names" diff --git a/roles/stepupmiddleware/tasks/vm.yml b/roles/stepupmiddleware/tasks/vm.yml new file mode 100644 index 000000000..ceab80cb6 --- /dev/null +++ b/roles/stepupmiddleware/tasks/vm.yml @@ -0,0 +1,133 @@ +- name: Install Apache and FPM config + include_role: + name: apachefpm + +- name: Install the symfony app + include_role: + name: stepupapp + +- name: Place parameters.yml + template: + src: parameters.yaml.j2 + dest: "{{ current_release_config_dir_name }}/parameters.yaml" + mode: 0640 + owner: root + group: "{{ appname }}" + notify: + - clear cache {{ appname }} + - reload php72-fpm {{ appname }} + +- name: Activate the symlink + file: + src: "{{ current_release_appdir }}" + dest: "{{ current_release_symlink }}" + state: link + +- name: Put middleware configuration scripts in /root/ + template: + src: "{{ item }}.j2" + dest: "/root/{{ item }}" + group: "root" + owner: "root" + mode: "0500" + with_items: + - "01-middleware-db_migrate.sh" + - "06-middleware-bootstrap-sraa-users.sh" + +- name: Create /opt/scripts + file: + path: /opt/scripts + state: directory + owner: root + group: root + mode: 0750 + +- name: Put middleware config from environment in /opt/scripts + template: + src: "{{ inventory_dir }}/templates/middleware/{{ item }}.j2" + dest: "/opt/scripts/{{ item }}" + group: "{{ appname }}" + owner: "{{ appname }}" + mode: "0400" + with_items: + - "middleware-config.json" + - "middleware-whitelist.json" + - "middleware-institution.json" + tags: + - push_mw_config + - push_mw_institution + - push_mw_whitelist + +- name: Put middleware configuration scripts in /opt/scripts + template: + src: "{{ item}}.j2" + dest: "/opt/scripts/{{ item }}" + group: "{{ appname }}" + owner: root + mode: "0550" + with_items: + - "middleware-push-config.sh" + - "middleware-push-whitelist.sh" + - "middleware-push-institution.sh" + +- name: Create symlinks to middleware configuration scripts in /root + file: + src: "/opt/scripts/{{ item.key }}" + dest: "/root/{{ item.value }}" + group: "{{ appname }}" + owner: root + state: link + force: true + with_dict: + "middleware-push-config.sh": "02-middleware-config.sh" + "middleware-push-whitelist.sh": "04-middleware-whitelist.sh" + "middleware-push-institution.sh": "05-middleware-institution.sh" + +- meta: flush_handlers + +- name: Include post installation tasks + include_role: + name: stepupapp + tasks_from: postinstall + +# The following push scripts have an additional conditional check on the presence of +# a tag, so these are only ran when explicitly called. + +- name: Push middleware configuration + command: /opt/scripts/middleware-push-config.sh + run_once: true + when: + - "'push_mw_config' in ansible_run_tags" + tags: + - push_mw_config + +- name: Push middleware whitelist + command: /opt/scripts/middleware-push-whitelist.sh + run_once: True + when: + - "'push_mw_whitelist' in ansible_run_tags" + tags: + - push_mw_whitelist + +- name: Push middleware institution configuration + command: /opt/scripts/middleware-push-institution.sh + run_once: True + when: + - "'push_mw_institution' in ansible_run_tags" + tags: + - push_mw_institution + + +# Middleware migrate identities from CSV + +- name: Migrate middleware identities from CSV + include_tasks: migrate_identities.yml + args: + apply: + tags: + - mw_migrate_identities + run_once: True + when: + - "'mw_migrate_identities' in ansible_run_tags" + tags: + - mw_migrate_identities diff --git a/roles/stepupra/handlers/main.yml b/roles/stepupra/handlers/main.yml index 40eef830c..1139c576b 100644 --- a/roles/stepupra/handlers/main.yml +++ b/roles/stepupra/handlers/main.yml @@ -6,3 +6,9 @@ service: name: php72-php-fpm state: reloaded + +- name: restart ra + community.docker.docker_container: + name: ra + state: started + restart: true diff --git a/roles/stepupra/tasks/main.yml b/roles/stepupra/tasks/main.yml index e3e4e242d..db580ef93 100644 --- a/roles/stepupra/tasks/main.yml +++ b/roles/stepupra/tasks/main.yml @@ -1,36 +1,52 @@ -- name: Install Apache and FPM config - include_role: - name: apachefpm +--- +- name: Include docker vars + ansible.builtin.include_vars: docker.yml -- name: Install the symfony app - include_role: +- name: Add group {{ appname }} + ansible.builtin.group: + name: "{{ appname }}" + state: present + register: ra_guid + +- name: Add user {{ appname }} + ansible.builtin.user: + name: "{{ appname }}" + group: "{{ appname }}" + createhome: no + state: present + register: ra_uid + +- name: Create some dirs + ansible.builtin.file: + state: directory + dest: "{{ item }}" + owner: root + group: root + mode: "0755" + with_items: + - "{{ current_release_config_dir_name }}" + - "{{ current_release_appdir }}/public/images" + +- name: Install images + ansible.builtin.include_role: name: stepupapp + tasks_from: copyimages - name: Install GSSP SP key and certificates - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copygsspspcerts - name: Install SAML SP key and certificates - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copyspcerts -- name: Install images - include_role: - name: stepupapp - tasks_from: copyimages - -- name: Install second factor images - include_role: - name: stepupapp - tasks_from: copysfimages - - name: Put parameters, samlstepupproviders, samlstepupproviders_parameters and global_view_parameters YAML config - template: + ansible.builtin.template: src: "{{ item }}.yml.j2" dest: "{{ current_release_config_dir_name }}/{{ item }}.yaml" - mode: 0640 + mode: "0640" group: "{{ appname }}" with_items: - parameters @@ -38,18 +54,28 @@ - samlstepupproviders_parameters - global_view_parameters notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}/" - dest: "{{ current_release_symlink }}" - state: link + - restart {{ appname }} -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall +- name: Create the container + community.docker.docker_container: + name: "{{ appname }}" + image: ghcr.io/openconext/stepup-ra/stepup-ra:{{ ra_version }} + pull: true + restart_policy: "always" + networks: + - name: "loadbalancer" + labels: + traefik.http.routers.ra.rule: "Host(`{{ ra_vhost_name }}`)" + traefik.http.routers.ra.tls: "true" + traefik.enable: "true" + env: + APACHE_UID: "#{{ ra_uid.uid }}" + APACHE_GUID: "#{{ ra_guid.gid }}" + APP_ENV: prod + mounts: + - source: /opt/openconext/ra/public/images/header-logo.png + target: /var/www/html/public/build/images/header-logo.png + type: bind + - source: /opt/openconext/ra + target: /var/www/html/config/openconext + type: bind diff --git a/roles/stepupra/templates/parameters.yml.j2 b/roles/stepupra/templates/parameters.yml.j2 index 7df5fb0e2..f738c74fb 100644 --- a/roles/stepupra/templates/parameters.yml.j2 +++ b/roles/stepupra/templates/parameters.yml.j2 @@ -1,4 +1,10 @@ parameters: +{% if 'docker' in group_names %} + app_env: prod + app_debug: false + app_secret: {{ ra_secret }} +{% endif %} + trusted_proxies: [ {{ engine_trusted_proxy_ips|join(',') }} ] mailer_transport: smtp @@ -34,18 +40,18 @@ parameters: sms_otp_expiry_interval: {{ sms_otp_expiry_interval }} sms_maximum_otp_requests: {{ sms_maximum_otp_requests }} - saml_sp_publickey: {{ current_release_config_file_dir_name }}/sp.crt - saml_sp_privatekey: {{ current_release_config_file_dir_name }}/sp.key + saml_sp_publickey: {{ current_release_config_file_dir_name_in_config }}/sp.crt + saml_sp_privatekey: {{ current_release_config_file_dir_name_in_config }}/sp.key - saml_metadata_publickey: {{ current_release_config_file_dir_name }}/sp.crt - saml_metadata_privatekey: {{ current_release_config_file_dir_name }}/sp.key + saml_metadata_publickey: {{ current_release_config_file_dir_name_in_config }}/sp.crt + saml_metadata_privatekey: {{ current_release_config_file_dir_name_in_config }}/sp.key saml_remote_idp_entity_id: https://{{ gateway_vhost_name }}/authentication/metadata saml_remote_idp_sso_url: https://{{ gateway_vhost_name }}/authentication/single-sign-on saml_remote_idp_certificate: {{ gateway_saml_idp_publickey | depem }} # Minimum LoA required for login to the RA interface - loa_required_for_login: '{{ stepup_uri_loa3 }}' + authentication_context_class_ref: '{{ stepup_uri_loa3 }}' stepup_loa_loa1: '{{ stepup_uri_loa1 }}' stepup_loa_loa2: '{{ stepup_uri_loa2 }}' diff --git a/roles/stepupra/templates/samlstepupproviders_parameters.yml.j2 b/roles/stepupra/templates/samlstepupproviders_parameters.yml.j2 index 9ad205457..cda9e80d5 100644 --- a/roles/stepupra/templates/samlstepupproviders_parameters.yml.j2 +++ b/roles/stepupra/templates/samlstepupproviders_parameters.yml.j2 @@ -5,12 +5,12 @@ parameters: {% for key, value in stepup_enabled_generic_second_factors.items() %} # GSSP Proxy SP used to authenticate to the Real GSSP IdP though GSSP IdP proxy in the gateway - gssp_{{ key }}_sp_publickey: '{{ current_release_config_file_dir_name }}/sp_gssp.crt' - gssp_{{ key }}_sp_privatekey: '{{ current_release_config_file_dir_name }}/sp_gssp.key' + gssp_{{ key }}_sp_publickey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.crt' + gssp_{{ key }}_sp_privatekey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.key' # Certificate used to sign metadata of the GSSP Proxy SP on the gateway - gssp_{{ key }}_metadata_publickey: '{{ current_release_config_file_dir_name }}/sp_gssp.crt' - gssp_{{ key }}_metadata_privatekey: '{{ current_release_config_file_dir_name }}/sp_gssp.key' + gssp_{{ key }}_metadata_publickey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.crt' + gssp_{{ key }}_metadata_privatekey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.key' # EntityID and SSO Location of the GSSP IdP Proxy on the Gateway gssp_{{ key }}_remote_entity_id: 'https://{{ gateway_vhost_name }}/gssp/{{ key }}/metadata' diff --git a/roles/stepupra/vars/docker.yml b/roles/stepupra/vars/docker.yml new file mode 100644 index 000000000..e035e8149 --- /dev/null +++ b/roles/stepupra/vars/docker.yml @@ -0,0 +1,4 @@ +current_release_appdir: /opt/openconext/ra +current_release_config_file_dir_name: /opt/openconext/ra +current_release_config_file_dir_name_in_config: /var/www/html/config/openconext +current_release_config_dir_name: /opt/openconext/ra diff --git a/roles/stepupra/vars/main.yml b/roles/stepupra/vars/main.yml index 2fbc04ce4..996a4ff2c 100644 --- a/roles/stepupra/vars/main.yml +++ b/roles/stepupra/vars/main.yml @@ -9,6 +9,7 @@ current_release_symlink: "/opt/openconext/OpenConext-{{ appname }}" current_release_appdir: "{{ current_release_symlink }}-{{ appversion }}" current_release_config_file_dir_name: "{{ current_release_appdir }}/app/files" current_release_config_dir_name: "{{ current_release_appdir }}/config/legacy" +current_release_config_file_dir_name_in_config: "{{ current_release_config_file_dir_name }}" gssp_sp_private_key: "{{ lookup('file', inventory_dir+'/files/certs/stepup/ra_gssp_sp.key') }}" stepup_saml_sp_privatekey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/ra_saml_sp.key') }}" gateway_saml_idp_publickey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/gateway_saml_idp.crt') }}" diff --git a/roles/stepupselfservice/handlers/main.yml b/roles/stepupselfservice/handlers/main.yml index 40eef830c..007b0fc07 100644 --- a/roles/stepupselfservice/handlers/main.yml +++ b/roles/stepupselfservice/handlers/main.yml @@ -6,3 +6,9 @@ service: name: php72-php-fpm state: reloaded + +- name: restart selfservice + community.docker.docker_container: + name: selfservice + state: started + restart: true diff --git a/roles/stepupselfservice/tasks/main.yml b/roles/stepupselfservice/tasks/main.yml index c8f38280f..77855882c 100644 --- a/roles/stepupselfservice/tasks/main.yml +++ b/roles/stepupselfservice/tasks/main.yml @@ -1,36 +1,52 @@ -- name: Install Apache and FPM config - include_role: - name: apachefpm +--- +- name: Include docker vars + ansible.builtin.include_vars: docker.yml -- name: Install the symfony app - include_role: +- name: Add group {{ appname }} + ansible.builtin.group: + name: "{{ appname }}" + state: present + register: selfservice_guid + +- name: Add user {{ appname }} + ansible.builtin.user: + name: "{{ appname }}" + group: "{{ appname }}" + createhome: no + state: present + register: selfservice_uid + +- name: Create some dirs + ansible.builtin.file: + state: directory + dest: "{{ item }}" + owner: root + group: root + mode: "0755" + with_items: + - "{{ current_release_config_dir_name }}" + - "{{ current_release_appdir }}/public/images" + +- name: Install images + ansible.builtin.include_role: name: stepupapp + tasks_from: copyimages - name: Install GSSP SP key and certificates - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copygsspspcerts - name: Install SAML SP key and certificates - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copyspcerts -- name: Install images - include_role: - name: stepupapp - tasks_from: copyimages - -- name: Install images - include_role: - name: stepupapp - tasks_from: copysfimages - - name: Put parameters, samlstepupproviders, samlstepupproviders_parameters and global_view_parameters YAML config - template: + ansible.builtin.template: src: "{{ item }}.yml.j2" dest: "{{ current_release_config_dir_name }}/{{ item }}.yaml" - mode: 0640 + mode: "0640" group: "{{ appname }}" with_items: - parameters @@ -38,18 +54,30 @@ - samlstepupproviders_parameters - global_view_parameters notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}/" - dest: "{{ current_release_symlink }}" - state: link + - restart {{ appname }} -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall +- name: Create the container + community.docker.docker_container: + name: "{{ appname }}" + image: ghcr.io/openconext/stepup-selfservice/stepup-selfservice:{{ selfservice_version }} + etc_hosts: + host.docker.internal: host-gateway + pull: true + restart_policy: "always" + networks: + - name: "loadbalancer" + labels: + traefik.http.routers.selfservice.rule: "Host(`{{ selfservice_vhost_name }}`)" + traefik.http.routers.selfservice.tls: "true" + traefik.enable: "true" + env: + APACHE_UID: "#{{ selfservice_uid.uid }}" + APACHE_GUID: "#{{ selfservice_guid.gid }}" + APP_ENV: prod + mounts: + - source: /opt/openconext/selfservice/public/images/header-logo.png + target: /var/www/html/public/build/images/logo/header-logo.png + type: bind + - source: /opt/openconext/selfservice + target: /var/www/html/config/openconext + type: bind diff --git a/roles/stepupselfservice/templates/parameters.yml.j2 b/roles/stepupselfservice/templates/parameters.yml.j2 index 846847ec4..057194ad0 100644 --- a/roles/stepupselfservice/templates/parameters.yml.j2 +++ b/roles/stepupselfservice/templates/parameters.yml.j2 @@ -1,8 +1,14 @@ parameters: +{% if 'docker' in group_names %} + app_env: prod + app_debug: false + app_secret: {{ selfservice_secret }} +{% endif %} + trusted_proxies: [ {{ engine_trusted_proxy_ips|join(',') }} ] mailer_transport: smtp - mailer_host: 127.0.0.1 + mailer_host: host.docker.internal mailer_user: ~ mailer_password: ~ @@ -32,13 +38,13 @@ parameters: sms_otp_expiry_interval: {{ sms_otp_expiry_interval }} sms_maximum_otp_requests: {{ sms_maximum_otp_requests }} - saml_sp_publickey: {{ current_release_config_file_dir_name }}/sp.crt + saml_sp_publickey: {{ current_release_config_file_dir_name_in_config }}/sp.crt - saml_sp_privatekey: {{ current_release_config_file_dir_name }}/sp.key + saml_sp_privatekey: {{ current_release_config_file_dir_name_in_config }}/sp.key - saml_metadata_publickey: {{ current_release_config_file_dir_name }}/sp.crt + saml_metadata_publickey: {{ current_release_config_file_dir_name_in_config }}/sp.crt - saml_metadata_privatekey: {{ current_release_config_file_dir_name }}/sp.key + saml_metadata_privatekey: {{ current_release_config_file_dir_name_in_config }}/sp.key # Connect to remote IdP through Stepup Gateway saml_remote_idp_entity_id: https://{{ gateway_vhost_name }}/authentication/metadata @@ -91,3 +97,10 @@ parameters: # Self-asserted token registration process. recovery_method_sms_enabled: true recovery_method_safe_store_code_enabled: true + + # SAML Bundle SamlAuthenticator configuration + # The acs location that the SAML response must be posted to (used in SamlAuthenticator::supports) + acs_location_route_name: selfservice_serviceprovider_consume_assertion + # The relay state values that will cause the SamlAuthenticator from not handling the SAML response. + # Used for test and self asserted token registration authentications + rejected_relay_states: ['isTestRequest', 'isSatRequest', 'isGssfRequest'] diff --git a/roles/stepupselfservice/templates/samlstepupproviders_parameters.yml.j2 b/roles/stepupselfservice/templates/samlstepupproviders_parameters.yml.j2 index 71702288e..b2005c26b 100644 --- a/roles/stepupselfservice/templates/samlstepupproviders_parameters.yml.j2 +++ b/roles/stepupselfservice/templates/samlstepupproviders_parameters.yml.j2 @@ -5,12 +5,12 @@ parameters: {% for key, value in stepup_enabled_generic_second_factors.items() %} # GSSP Proxy SP used to authenticate to the Real GSSP IdP though GSSP IdP proxy in the gateway - gssp_{{ key }}_sp_publickey: '{{ current_release_config_file_dir_name }}/sp_gssp.crt' - gssp_{{ key }}_sp_privatekey: '{{ current_release_config_file_dir_name }}/sp_gssp.key' + gssp_{{ key }}_sp_publickey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.crt' + gssp_{{ key }}_sp_privatekey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.key' # Certificate used to sign metadata of the GSSP Proxy SP on the gateway - gssp_{{ key }}_metadata_publickey: '{{ current_release_config_file_dir_name }}/sp_gssp.crt' - gssp_{{ key }}_metadata_privatekey: '{{ current_release_config_file_dir_name }}/sp_gssp.key' + gssp_{{ key }}_metadata_publickey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.crt' + gssp_{{ key }}_metadata_privatekey: '{{ current_release_config_file_dir_name_in_config }}/sp_gssp.key' # EntityID and SSO Location of the GSSP IdP Proxy on the Gateway gssp_{{ key }}_remote_entity_id: 'https://{{ gateway_vhost_name }}/gssp/{{ key }}/metadata' diff --git a/roles/stepupselfservice/vars/docker.yml b/roles/stepupselfservice/vars/docker.yml new file mode 100644 index 000000000..008c03990 --- /dev/null +++ b/roles/stepupselfservice/vars/docker.yml @@ -0,0 +1,4 @@ +current_release_appdir: /opt/openconext/selfservice +current_release_config_file_dir_name: /opt/openconext/selfservice +current_release_config_file_dir_name_in_config: /var/www/html/config/openconext +current_release_config_dir_name: /opt/openconext/selfservice diff --git a/roles/stepupselfservice/vars/main.yml b/roles/stepupselfservice/vars/main.yml index ac19de1ea..828ec6de1 100644 --- a/roles/stepupselfservice/vars/main.yml +++ b/roles/stepupselfservice/vars/main.yml @@ -9,6 +9,7 @@ current_release_symlink: "/opt/openconext/OpenConext-{{ appname }}" current_release_appdir: "{{ current_release_symlink }}-{{ appversion }}" current_release_config_file_dir_name: "{{ current_release_appdir }}/app/files" current_release_config_dir_name: "{{ current_release_appdir }}/config/legacy" +current_release_config_file_dir_name_in_config: "{{ current_release_config_file_dir_name }}" gssp_sp_private_key: "{{ lookup('file', inventory_dir+'/files/certs/stepup/selfservice_gssp_sp.key') }}" stepup_saml_sp_privatekey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/selfservice_saml_sp.key') }}" gateway_saml_idp_publickey: "{{ lookup('file', inventory_dir+'/files/certs/stepup/gateway_saml_idp.crt') }}" diff --git a/roles/stepuptiqr/handlers/main.yml b/roles/stepuptiqr/handlers/main.yml index 40eef830c..ab79436f4 100644 --- a/roles/stepuptiqr/handlers/main.yml +++ b/roles/stepuptiqr/handlers/main.yml @@ -6,3 +6,10 @@ service: name: php72-php-fpm state: reloaded + +- name: restart tiqr + community.docker.docker_container: + name: tiqr + state: started + restart: true + diff --git a/roles/stepuptiqr/tasks/main.yml b/roles/stepuptiqr/tasks/main.yml index 81c222dfc..867585085 100644 --- a/roles/stepuptiqr/tasks/main.yml +++ b/roles/stepuptiqr/tasks/main.yml @@ -1,93 +1,87 @@ -- debug: - msg: "{{ tiqr_statestorage }}" +- name: Include docker vars + ansible.builtin.include_vars: docker.yml -- name: Install Apache and FPM config - include_role: - name: apachefpm +- name: Add group {{ appname }} + ansible.builtin.group: + name: "{{ appname }}" + state: present + register: tiqr_guid -- name: Install the symfony app - include_role: - name: stepupapp +- name: Add user {{ appname }} + ansible.builtin.user: + name: "{{ appname }}" + group: "{{ appname }}" + createhome: no + state: present + register: tiqr_uid + +- name: Create some dirs + ansible.builtin.file: + state: directory + dest: "{{ item }}" + owner: root + group: root + mode: "0755" + with_items: + - "{{ current_release_config_dir_name }}" + - "{{ current_release_appdir }}/public/images" - name: Install images - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copyimages -- name: Install the GSSP certificates - include_role: +- name: Install GSSP IdP key and certificates + ansible.builtin.include_role: name: stepupapp tasks_from: copygsspidpcerts - name: Write tiqr APNS certificate - copy: + ansible.builtin.copy: content: "{{ tiqr_apns_pemfile }}" dest: "{{ current_release_config_file_dir_name }}/apns.pem" owner: "{{ appname }}" - mode: 0400 + mode: "0400" when: tiqr_apns_pemfile is defined - name: Write tiqr Firebase service json copy: - src: "{{ inventory_dir }}/secrets/tiqr-demo.json" + src: "{{ inventory_dir }}/secrets/stepup/tiqr-demo.json" dest: "{{ current_release_config_file_dir_name }}/tiqr-demo.json" owner: "{{ appname }}" mode: 0400 when: tiqr_firebase_credentialsfile is defined - name: Place parameters.yml - template: + ansible.builtin.template: src: parameters.yaml.j2 dest: "{{ current_release_config_dir_name }}/parameters.yaml" - mode: 0640 + mode: "0640" owner: root group: "{{ appname }}" notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Place .env file - template: - src: env.j2 - dest: "{{ current_release_appdir }}/.env.local" - mode: 0640 - owner: root - group: "{{ appname }}" - notify: clear cache {{ appname }} - -- name: Install assets - command: php72 {{ current_release_appdir }}/bin/console assets:install + - restart tiqr -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}" - dest: "{{ current_release_symlink }}" - state: link - -- name: Put tiqr configuration script in /root/ - template: - src: "{{ item }}.j2" - dest: "/root/{{ item }}" - group: root - owner: root - mode: "0500" - with_items: - - "01-tiqr-db_init.sh" - -- name: Put tiqr keyserver migration script in /root/ - template: - src: "{{ item }}.j2" - dest: "/root/{{ item }}" - group: root - owner: root - mode: "500" - with_items: - - "02-tiqr-migrate-to-keyserver.php" - when: keyserver_consumerkey is defined - -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall +- name: Create the container + community.docker.docker_container: + name: "{{ appname }}" + image: ghcr.io/openconext/stepup-tiqr/stepup-tiqr:{{ tiqr_version }} + pull: true + restart_policy: "always" + networks: + - name: "loadbalancer" + labels: + traefik.http.routers.tiqr.rule: "Host(`tiqr.{{ base_domain }}`)" + traefik.http.routers.tiqr.tls: "true" + traefik.enable: "true" + env: + APACHE_UID: "#{{ tiqr_uid.uid }}" + APACHE_GUID: "#{{ tiqr_guid.gid }}" + APP_ENV: prod + mounts: + - source: /opt/openconext/tiqr/public/images/header-logo.png + target: /var/www/html/public/build/images/logo/header-logo.png + type: bind + - source: /opt/openconext/tiqr + target: /var/www/html/config/openconext + type: bind \ No newline at end of file diff --git a/roles/stepuptiqr/templates/parameters.yaml.j2 b/roles/stepuptiqr/templates/parameters.yaml.j2 index 52c0b5b4e..c6a79571c 100644 --- a/roles/stepuptiqr/templates/parameters.yaml.j2 +++ b/roles/stepuptiqr/templates/parameters.yaml.j2 @@ -1,16 +1,22 @@ parameters: +{% if 'docker' in group_names %} + app_env: prod + app_debug: false + app_secret: {{ tiqr_secret }} +{% endif %} + # All locales supported by the application locales: [{{ enabled_locales | join(",") }}] # SAML configuration - saml_idp_publickey: '{{ current_release_config_file_dir_name }}/cert.pem' - saml_idp_privatekey: '{{ current_release_config_file_dir_name }}/key.pem' + saml_idp_publickey: '{{ current_release_config_file_dir_name_in_config }}/cert.pem' + saml_idp_privatekey: '{{ current_release_config_file_dir_name_in_config }}/key.pem' # NOTE: same key used for metadata and response/assertion signing - saml_metadata_publickey: '{{ current_release_config_file_dir_name }}/cert.pem' - saml_metadata_privatekey: '{{ current_release_config_file_dir_name }}/key.pem' + saml_metadata_publickey: '{{ current_release_config_file_dir_name_in_config }}/cert.pem' + saml_metadata_privatekey: '{{ current_release_config_file_dir_name_in_config }}/key.pem' saml_remote_sp_entity_id: 'https://{{ gateway_vhost_name }}/gssp/tiqr/metadata' - saml_remote_sp_certificate: '{{ current_release_config_file_dir_name }}/gateway.crt' + saml_remote_sp_certificate: '{{ current_release_config_file_dir_name_in_config }}/gateway.crt' saml_remote_sp_acs: 'https://{{ gateway_vhost_name }}/gssp/tiqr/consume-assertion' base_url: 'https://{{ vhost_name }}' @@ -40,23 +46,16 @@ parameters: logoUrl: '%base_url%/images/header-logo.png' infoUrl: '{{ tiqr_info_url }}' library: -{% if tiqr_gcm_apikey is defined %} gcm: apikey: '{{ tiqr_gcm_apikey }}' application: 'nl.surfnet.authenticator' -{% endif %} -{% if tiqr_firebase_apikey is defined %} - firebase: - apikey: '{{ tiqr_firebase_apikey }}' -{% endif %} -{% if tiqr_firebase_credentialsFile is defined %} firebase: projectId: '{{ tiqr_firebase_projectid }}' - credentialsFile: '{{ tiqr_firebase_credentialsfile }}' - cacheTokens: '{{ tiqr_firebase_cachetokens }}' -{% endif %} + credentialsFile: '{{ current_release_config_file_dir_name_in_config }}/{{ tiqr_firebase_credentialsfile }}' + cacheTokens: {{ tiqr_firebase_cachetokens }} + tokenCacheDir: '/tmp' apns: - certificate: '{{ current_release_config_file_dir_name }}/apns.pem' + certificate: '{{ current_release_config_file_dir_name_in_config }}/apns.pem' environment: production accountblocking: maxAttempts: 5 @@ -106,4 +105,4 @@ parameters: dsn: 'mysql:host={{ tiqr_db_host }};dbname={{ database_tiqr_name }}' username: '{{ database_tiqr_user }}' password: '{{ mysql_passwords.tiqr }}' -{% endif %} +{% endif %} \ No newline at end of file diff --git a/roles/stepuptiqr/vars/docker.yml b/roles/stepuptiqr/vars/docker.yml new file mode 100644 index 000000000..f42194f3d --- /dev/null +++ b/roles/stepuptiqr/vars/docker.yml @@ -0,0 +1,5 @@ + +current_release_appdir: /opt/openconext/tiqr +current_release_config_file_dir_name: /opt/openconext/tiqr +current_release_config_file_dir_name_in_config: /var/www/html/config/openconext +current_release_config_dir_name: /opt/openconext/tiqr diff --git a/roles/stepuptiqr/vars/main.yml b/roles/stepuptiqr/vars/main.yml index 23f1e5917..18fed7cfb 100644 --- a/roles/stepuptiqr/vars/main.yml +++ b/roles/stepuptiqr/vars/main.yml @@ -9,6 +9,7 @@ current_release_symlink: "/opt/openconext/OpenConext-{{ appname }}" current_release_appdir: "{{ current_release_symlink }}-{{ appversion }}" current_release_config_file_dir_name: "{{ current_release_appdir }}/app/files" current_release_config_dir_name: "{{ current_release_appdir }}/config/legacy" +current_release_config_file_dir_name_in_config: "{{ current_release_config_file_dir_name }}" gssp_idp_private_key: "{{ lookup('file', inventory_dir+'/files/certs/stepup/tiqr_idp.key') }}" database_tiqr_user: tiqrrw database_tiqr_deploy_user: tiqrdeploy diff --git a/roles/stepupwebauthn/handlers/main.yml b/roles/stepupwebauthn/handlers/main.yml index 40eef830c..e118b593e 100644 --- a/roles/stepupwebauthn/handlers/main.yml +++ b/roles/stepupwebauthn/handlers/main.yml @@ -6,3 +6,9 @@ service: name: php72-php-fpm state: reloaded + +- name: restart webauthn + community.docker.docker_container: + name: webauthn + state: started + restart: true diff --git a/roles/stepupwebauthn/tasks/main.yml b/roles/stepupwebauthn/tasks/main.yml index cd4e8e993..ec04bc7d6 100644 --- a/roles/stepupwebauthn/tasks/main.yml +++ b/roles/stepupwebauthn/tasks/main.yml @@ -1,77 +1,121 @@ -- name: Install Apache and FPM config - include_role: - name: apachefpm +- name: Include docker vars + ansible.builtin.include_vars: docker.yml -- name: Install the symfony app - include_role: - name: stepupapp +- name: Add group {{ appname }} + ansible.builtin.group: + name: "{{ appname }}" + state: present + register: webauthn_guid + +- name: Add user {{ appname }} + ansible.builtin.user: + name: "{{ appname }}" + group: "{{ appname }}" + createhome: no + state: present + register: webauthn_uid + +- name: Create some dirs + ansible.builtin.file: + state: directory + dest: "{{ item }}" + owner: root + group: root + mode: "0755" + with_items: + - "{{ current_release_config_dir_name }}" + - "{{ current_release_appdir }}/public/images" - name: Install images - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copyimages - name: Install the GSSP certificates - include_role: + ansible.builtin.include_role: name: stepupapp tasks_from: copygsspidpcerts -- name: Create the trusted certificate dir - file: +- name: Create the metadata service dir + ansible.builtin.file: state: directory dest: "{{ item }}" + owner: root + mode: "0755" with_items: - - "{{ current_release_config_file_dir_name }}/trusted_certificates" + - "{{ current_release_config_file_dir_name }}/mds" -- name: Place parameters.yml - template: - src: parameters.yml.j2 - dest: "{{ current_release_config_dir_name }}/parameters.yml" - mode: 0640 +- name: Create and empty the metadata service cache dir + ansible.builtin.file: + state: "{{ item }}" + path: "{{ current_release_config_file_dir_name }}/var/mds/" owner: root group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} + mode: "0774" + with_items: + - absent + - directory + +- name: Download metadata service blob + ansible.builtin.get_url: + url: https://mds3.fidoalliance.org/ + dest: "{{ current_release_config_file_dir_name }}/mds/blob.jwt" + mode: '0744' + force: true -- name: Place .env file - template: - src: env.j2 - dest: "{{ current_release_appdir }}/.env.local" - mode: 0640 +- name: Download metadata service signing certificate + ansible.builtin.get_url: + url: http://secure.globalsign.com/cacert/root-r3.crt + dest: "{{ current_release_config_file_dir_name }}/mds/fido2-mds.cer" + mode: '0744' + force: true + +- name: Place parameters.yml + ansible.builtin.template: + src: parameters.yml.j2 + dest: "{{ current_release_config_dir_name }}/parameters.yaml" + mode: "0640" owner: root group: "{{ appname }}" - notify: - - clear cache {{ appname }} - - reload php72-fpm {{ appname }} - -- name: Copy trusted certificates - copy: - src: "{{ item }}" - dest: "{{ current_release_config_file_dir_name }}/trusted_certificates/" - mode: "444" - with_fileglob: - - "{{ inventory_dir }}/files/stepup-webauthn/trusted_certificates/*" + notify: restart webauthn -- name: Activate the symlink - file: - src: "{{ current_release_appdir }}" - dest: "{{ current_release_symlink }}" - state: link +# - name: Copy trusted certificates +# ansible.builtin.copy: +# src: "{{ item }}" +# dest: "{{ current_release_config_file_dir_name }}/trusted_certificates/" +# mode: "444" +# with_fileglob: +# - "{{ inventory_dir }}/files/stepup-webauthn/trusted_certificates/*" - name: Put webauthn configuration script in /root/ - template: + ansible.builtin.template: src: "{{ item }}.j2" dest: "/root/{{ item }}" - group: root - owner: root + group: root + owner: root mode: "0500" with_items: - - "01-webauthn-db_init.sh" + - "01-webauthn-db_init.sh" -- meta: flush_handlers - -- name: Include post installation tasks - include_role: - name: stepupapp - tasks_from: postinstall +- name: Create the container + community.docker.docker_container: + name: "{{ appname }}" + image: ghcr.io/openconext/stepup-webauthn/stepup-webauthn:{{ webauthn_version }} + pull: true + restart_policy: "always" + networks: + - name: "loadbalancer" + labels: + traefik.http.routers.webauthn.rule: "Host(`webauthn.{{ base_domain }}`)" + traefik.http.routers.webauthn.tls: "true" + traefik.enable: "true" + env: + APACHE_UID: "#{{ webauthn_uid.uid }}" + APACHE_GUID: "#{{ webauthn_guid.gid }}" + mounts: + - source: /opt/openconext/webauthn/public/images/header-logo.png + target: /var/www/html/public/build/images/logo/header-logo.png + type: bind + - source: /opt/openconext/webauthn + target: /var/www/html/config/openconext + type: bind diff --git a/roles/stepupwebauthn/templates/parameters.yml.j2 b/roles/stepupwebauthn/templates/parameters.yml.j2 index 221402c9e..a0a4e6cce 100644 --- a/roles/stepupwebauthn/templates/parameters.yml.j2 +++ b/roles/stepupwebauthn/templates/parameters.yml.j2 @@ -1,16 +1,22 @@ parameters: +{% if 'docker' in group_names %} + app_env: prod + app_debug: false + app_secret: {{ webauthn_secret }} + database_url: mysql://{{ database_webauthn_user }}:{{ mysql_passwords.webauthn }}@{{ webauthn_db_host }}:3306/{{ database_webauthn_name }} +{% endif %} # All locales supported by the application locales: [{{ enabled_locales | join(",") }}] # SAML configuration - saml_idp_publickey: '{{ current_release_config_file_dir_name }}/cert.pem' - saml_idp_privatekey: '{{ current_release_config_file_dir_name }}/key.pem' + saml_idp_publickey: '{{ current_release_config_file_dir_name_in_config }}/cert.pem' + saml_idp_privatekey: '{{ current_release_config_file_dir_name_in_config }}/key.pem' # NOTE: same key used for metadata and response/assertion signing - saml_metadata_publickey: '{{ current_release_config_file_dir_name }}/cert.pem' - saml_metadata_privatekey: '{{ current_release_config_file_dir_name }}/key.pem' + saml_metadata_publickey: '{{ current_release_config_file_dir_name_in_config }}/cert.pem' + saml_metadata_privatekey: '{{ current_release_config_file_dir_name_in_config }}/key.pem' saml_remote_sp_entity_id: 'https://{{ gateway_vhost_name }}/gssp/webauthn/metadata' - saml_remote_sp_certificate: '{{ current_release_config_file_dir_name }}/gateway.crt' + saml_remote_sp_certificate: '{{ current_release_config_file_dir_name_in_config }}/gateway.crt' saml_remote_sp_acs: 'https://{{ gateway_vhost_name }}/gssp/webauthn/consume-assertion' # View parameters @@ -24,4 +30,7 @@ parameters: webauthn_name: '{{ webauthn_user_display_name }}' webauthn_logo: 'https://{{ webauthn_vhost_name }}/images/header-logo.png' - trusted_certificates_directory: '{{ current_release_config_file_dir_name }}/trusted_certificates' + trusted_certificates_directory: '{{ current_release_config_file_dir_name_in_config }}/trusted_certificates' + fido2_jwt_mds_blob_file_name: '{{ current_release_config_file_dir_name_in_config }}/mds/blob.jwt' + fido2_jwt_mds_root_certificate_file_name: '{{ current_release_config_file_dir_name_in_config }}/mds/fido2-mds.cer' + fido2_mds_cache_dir: '{{ current_release_config_file_dir_name_in_config }}/var/mds/' diff --git a/roles/stepupwebauthn/vars/docker.yml b/roles/stepupwebauthn/vars/docker.yml new file mode 100644 index 000000000..c765aafa4 --- /dev/null +++ b/roles/stepupwebauthn/vars/docker.yml @@ -0,0 +1,4 @@ +current_release_appdir: /opt/openconext/webauthn +current_release_config_file_dir_name: /opt/openconext/webauthn +current_release_config_file_dir_name_in_config: /var/www/html/config/openconext +current_release_config_dir_name: /opt/openconext/webauthn diff --git a/roles/stepupwebauthn/vars/main.yml b/roles/stepupwebauthn/vars/main.yml index e16b790b8..d24106cf0 100644 --- a/roles/stepupwebauthn/vars/main.yml +++ b/roles/stepupwebauthn/vars/main.yml @@ -8,6 +8,7 @@ stepup_gh_appname: Webauthn current_release_symlink: "/opt/openconext/OpenConext-{{ appname }}" current_release_appdir: "{{ current_release_symlink }}-{{ appversion }}" current_release_config_file_dir_name: "{{ current_release_appdir }}/app/files" +current_release_config_file_dir_name_in_config: "{{ current_release_config_file_dir_name }}" current_release_config_dir_name: "{{ current_release_appdir }}/config/packages" gssp_idp_private_key: "{{ lookup('file', inventory_dir+'/files/certs/stepup/webauthn_idp.key') }}" database_webauthn_user: webauthnrw