From 9791658838cfcf0d7197088b58d04cd9fa8e1e0f Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 11 Aug 2022 12:09:43 +0200 Subject: [PATCH] Start Hydra server role implementation - Define localhost variant of Hydra parameters - Download and unpack Hydra - Create configuration file - Create certificates using mkcert --- deployment/inventory/group_vars/all.yml | 2 +- deployment/inventory/host_vars/localhost.yml | 33 +++++ .../roles/hydra_server/defaults/main.yml | 8 +- deployment/roles/hydra_server/tasks/main.yml | 119 +++++++++++++++++- .../roles/hydra_server/templates/hydra.yml.j2 | 46 +++++++ 5 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 deployment/inventory/host_vars/localhost.yml create mode 100644 deployment/roles/hydra_server/templates/hydra.yml.j2 diff --git a/deployment/inventory/group_vars/all.yml b/deployment/inventory/group_vars/all.yml index 6a325aa..1acb311 100644 --- a/deployment/inventory/group_vars/all.yml +++ b/deployment/inventory/group_vars/all.yml @@ -1,2 +1,2 @@ --- -hydra_db_password: hydra +hydra_home: /srv/hydra diff --git a/deployment/inventory/host_vars/localhost.yml b/deployment/inventory/host_vars/localhost.yml new file mode 100644 index 0000000..c5899a6 --- /dev/null +++ b/deployment/inventory/host_vars/localhost.yml @@ -0,0 +1,33 @@ +--- +# this is for a localhost deployment, database passwords for public servers +# must be different random values encrypted via ansible-vault +hydra_db_password: hydra +hydra_db_host: localhost +hydra_db_port: 5432 +hydra_version: "1.11.9" +hydra_checksum: "0e38096a45ae411f70b95beaad69a5335a16cf34c4963724beef3ebce37c283c" +hydra_tls: + cert: "{{ hydra_home }}/etc/hydra.cacert.localhost+1.pem" + key: "{{ hydra_home }}/etc/hydra.cacert.localhost+1-key.pem" +# this is for a localhost deployment, secrets for public servers must be +# different random values encrypted via ansible-vault +hydra_system_secret: "AczA+NZ25Ye9eAreglv5bo9XcND6uwBQHVUYCvPfwXo=" + +oidc_urls: + hydra_admin: + host: hydra.cacert.localhost + port: 4445 + hydra_public: + host: auth.cacert.localhost + port: 4444 + idp: + host: login.cacert.localhost + port: 3000 + demoapp: + host: app.cacert.localhost + port: 4000 + register: + host: register.cacert.localhost + port: 5000 + +use_mkcert: true diff --git a/deployment/roles/hydra_server/defaults/main.yml b/deployment/roles/hydra_server/defaults/main.yml index 357e185..6c71d8d 100644 --- a/deployment/roles/hydra_server/defaults/main.yml +++ b/deployment/roles/hydra_server/defaults/main.yml @@ -1,2 +1,8 @@ --- -# defaults file for roles/hydra_server +hydra_db_name: hydra +hydra_db_user: hydra +hydra_os_group: hydra +hydra_os_user: hydra +hydra_home: /srv/hydra + +use_mkcert: false diff --git a/deployment/roles/hydra_server/tasks/main.yml b/deployment/roles/hydra_server/tasks/main.yml index ae54d2a..f7a27a2 100644 --- a/deployment/roles/hydra_server/tasks/main.yml +++ b/deployment/roles/hydra_server/tasks/main.yml @@ -1,2 +1,119 @@ --- -# tasks file for roles/hydra_server +- name: Create Hydra group + ansible.builtin.group: + name: "{{ hydra_os_group }}" + state: present + system: true + +- name: Create Hydra user + ansible.builtin.user: + name: "{{ hydra_os_user }}" + group: "{{ hydra_os_group }}" + home: "{{ hydra_home }}" + state: present + system: true + + +- name: Create Hydra directories + ansible.builtin.file: + path: "{{hydra_home }}/{{ item.path }}" + owner: "{{ hydra_os_user }}" + group: "{{ hydra_os_group }}" + mode: "{{ item.mode }}" + state: directory + loop: + - { path: etc, mode: '0750' } + - { path: bin, mode: '0750' } + - { path: download, mode: '0750' } + + +- name: Download Hydra binary + ansible.builtin.get_url: + url: "https://github.com/ory/hydra/releases/download/v{{ hydra_version }}/hydra_{{ hydra_version }}-linux_64bit.tar.gz" + dest: "{{ hydra_home }}/download/hydra_{{ hydra_version }}-linux_64bit.tar.gz" + checksum: "sha256:{{ hydra_checksum }}" + owner: "{{ hydra_os_user }}" + group: "{{ hydra_os_group }}" + mode: '0640' + +- name: Extract Hydra binary + ansible.builtin.unarchive: + remote_src: true + src: "{{ hydra_home }}/download/hydra_{{ hydra_version }}-linux_64bit.tar.gz" + dest: "{{ hydra_home }}/bin" + owner: root + group: "{{ hydra_os_group }}" + include: 'hydra' + mode: '0750' + +- name: Create Hydra configuration + ansible.builtin.template: + src: hydra.yml.j2 + dest: "{{ hydra_home }}/etc/hydra.yml" + owner: root + group: "{{ hydra_os_group }}" + mode: '0640' + +- name: Check whether certificate exists + ansible.builtin.stat: + path: "{{ hydra_tls.cert }}" + register: hydra_cert_st + +- name: Create Hydra key and certificate with mkcert + block: + + - name: Install mkcert CA + ansible.builtin.command: + cmd: mkcert -install + + - name: Create temporary directory for Hydra key and certificate + ansible.builtin.tempfile: + prefix: "hydra-cert." + state: directory + register: hydra_cert_temp_dir + + - name: Create Hydra key and certificate + ansible.builtin.command: + cmd: "mkcert -cert-file {{ hydra_cert_temp_dir.path }}/hydra.pem -key-file {{ hydra_cert_temp_dir.path }}/hydra.key.pem {{ oidc_urls.hydra_admin.host }} {{ oidc_urls.hydra_public.host }}" + + - name: Move Hydra certificate and key to target + ansible.builtin.copy: + src: "{{ hydra_cert_temp_dir.path }}/{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: "{{ hydra_os_group }}" + mode: "{{ item.mode }}" + remote_src: true + loop: + - { src: hydra.pem, dest: "{{ hydra_tls.cert }}", mode: '0644' } + - { src: hydra.key.pem, dest: "{{ hydra_tls.key }}", mode: '0640' } + become: true + + - name: Remove temporary directory + ansible.builtin.file: + path: "{{ hydra_cert_temp_dir.path }}" + state: absent + + when: use_mkcert and not hydra_cert_st.stat.exists + become: false + +- name: Copy Hydra key and certificate from inventory + block: + + - name: Copy Hydra certificate + ansible.builtin.copy: + dest: "{{ hydra_tls.cert }}" + owner: root + group: "{{ hydra_os_group }}" + mode: '0644' + content: "{{ hydra_tls.certdata }}" + + - name: Copy Hydra key + ansible.builtin.copy: + dest: "{{ hydra_tls.key }}" + owner: root + group: "{{ hydra_os_group }}" + mode: '0640' + content: "{{ hydra_tls.keydata }}" + + when: not use_mkcert diff --git a/deployment/roles/hydra_server/templates/hydra.yml.j2 b/deployment/roles/hydra_server/templates/hydra.yml.j2 new file mode 100644 index 0000000..358aa84 --- /dev/null +++ b/deployment/roles/hydra_server/templates/hydra.yml.j2 @@ -0,0 +1,46 @@ +--- +serve: + admin: + host: {{ oidc_urls.hydra_admin.host }} + public: + host: {{ oidc_urls.hydra_public.host }} + tls: + cert: + path: {{ hydra_tls.cert }} + key: + path: {{ hydra_tls.key }} +dsn: 'postgres://{{ hydra_db_user }}:{{ hydra_db_password }}@{{ hydra_db_host }}:{{ hydra_db_port }}/{{ hydra_db_name }}' + +webfinger: + oidc_discovery: + supported_claims: + - email + - email_verified + - given_name + - family_name + - middle_name + - name + - birthdate + - zoneinfo + - locale + - https://auth.cacert.org/groups + supported_scope: + - profile + - email + +oauth2: + expose_internal_errors: false + +urls: + login: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/login + consent: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/consent + logout: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/logout + error: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/error + post_logout_redirect: https://{{ oidc_urls.idp.host }}:{{ oidc_urls.idp.port }}/logout-successful + self: + public: https://{{ oidc_urls.hydra_public.host }}:{{ oidc_urls.hydra_public.port }}/ + issuer: https://{{ oidc_urls.hydra_public.host }}:{{ oidc_urls.hydra_public.port }}/ + +secrets: + system: + - "{{ hydra_system_secret }}"