diff --git a/ansible/roles/docker-swarm-app-caddy/assets/Caddyfile b/ansible/roles/docker-swarm-app-caddy/assets/Caddyfile index 951463e..8bef47a 100644 --- a/ansible/roles/docker-swarm-app-caddy/assets/Caddyfile +++ b/ansible/roles/docker-swarm-app-caddy/assets/Caddyfile @@ -1,7 +1,42 @@ { - # Global options block. Entirely optional, https is on by default - # Optional email key for lets encrypt - email youremail@domain.com - # Optional staging lets encrypt for testing. Comment out for production. - acme_ca https://acme-staging-v02.api.letsencrypt.org/directory + http_port 80 + https_port 443 + debug + + order authenticate before respond + order authorize before basicauth + + security { + oauth identity provider github {env.GITHUB_CLIENT_ID} {env.GITHUB_CLIENT_SECRET} + + authentication portal myportal { + crypto default token lifetime 3600 + crypto key sign-verify {env.JWT_SHARED_KEY} + cookie domain {{domain}} + enable identity provider github + ui { + links { + "My Identity" "/whoami" icon "las la-user" + } + } + + transform user { + match realm github + match sub github.com/{{github_org}} + action add role authp/admin + } + } + + authorization policy mypolicy { + set auth url https://auth.{{domain}}:443/oauth2/github + crypto key verify {env.JWT_SHARED_KEY} + allow roles authp/admin authp/user + validate bearer header + inject headers with claims + } + } +} + +auth.{{domain}} { + authenticate with myportal } diff --git a/ansible/roles/docker-swarm-app-caddy/assets/Dockerfile b/ansible/roles/docker-swarm-app-caddy/assets/Dockerfile index 5c624b7..81262ea 100644 --- a/ansible/roles/docker-swarm-app-caddy/assets/Dockerfile +++ b/ansible/roles/docker-swarm-app-caddy/assets/Dockerfile @@ -10,4 +10,7 @@ FROM caddy:${CADDY_VERSION}-alpine COPY --from=builder /usr/bin/caddy /usr/bin/caddy +COPY docker-entrypoint.sh /usr/local/bin/ + +ENTRYPOINT ["docker-entrypoint.sh"] CMD ["caddy", "docker-proxy"] diff --git a/ansible/roles/docker-swarm-app-caddy/assets/caddy-stack.yml b/ansible/roles/docker-swarm-app-caddy/assets/caddy-stack.yml index b88c961..046f266 100644 --- a/ansible/roles/docker-swarm-app-caddy/assets/caddy-stack.yml +++ b/ansible/roles/docker-swarm-app-caddy/assets/caddy-stack.yml @@ -21,7 +21,13 @@ services: - caddy_data:/data - caddy_config:/config secrets: - - caddy_github_auth + - caddy_github_client_id + - caddy_github_client_secret + - caddy_jwt_shared_key + environment: + GITHUB_CLIENT_ID_FILE: /run/secrets/caddy_github_client_id + GITHUB_CLIENT_SECRET_FILE: /run/secrets/caddy_github_client_secret + JWT_SHARED_KEY_FILE: /run/secrets/caddy_jwt_shared_key deploy: placement: constraints: @@ -41,9 +47,10 @@ services: - caddy deploy: labels: - caddy: whoami.nokwebspace.ovh + caddy: whoami.{{domain}} # this include escape for ansible caddy.reverse_proxy: "{{ '{{' }}upstreams 80{{ '}}' }}" + caddy.authenticate: with myportal volumes: caddy_data: @@ -54,5 +61,9 @@ networks: attachable: true secrets: - caddy_github_auth: + caddy_github_client_id: + external: true + caddy_github_client_secret: + external: true + caddy_jwt_shared_key: external: true diff --git a/ansible/roles/docker-swarm-app-caddy/assets/caddy_github_auth b/ansible/roles/docker-swarm-app-caddy/assets/caddy_github_auth deleted file mode 100644 index 806dea4..0000000 --- a/ansible/roles/docker-swarm-app-caddy/assets/caddy_github_auth +++ /dev/null @@ -1,3 +0,0 @@ -GITHUB_CLIENT_ID={{ github_client_id }} -GITHUB_CLIENT_SECRET={{ github_client_secret }} -JWT_SHARED_KEY={{ jwt_shared_key }} \ No newline at end of file diff --git a/ansible/roles/docker-swarm-app-caddy/assets/docker-entrypoint.sh b/ansible/roles/docker-swarm-app-caddy/assets/docker-entrypoint.sh new file mode 100644 index 0000000..89d3e2a --- /dev/null +++ b/ansible/roles/docker-swarm-app-caddy/assets/docker-entrypoint.sh @@ -0,0 +1,32 @@ +# docker-entrypoint.sh + +#!/bin/bash + +set -e + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + if [ -n "${varValue}" ]; then + export "$var"="${varValue}" + elif [ -n "${fileVarValue}" ]; then + export "$var"="$(cat "${fileVarValue}")" + elif [ -n "${def}" ]; then + export "$var"="$def" + fi + unset "$fileVar" +} + +env | grep "_FILE" | while read -r line ; do + echo "Processing ${line%_FILE*}" + file_env "${line%_FILE*}" +done + +exec "$@" \ No newline at end of file diff --git a/ansible/roles/docker-swarm-app-caddy/defaults/main.yaml b/ansible/roles/docker-swarm-app-caddy/defaults/main.yaml index 894f8df..c4aa9ee 100644 --- a/ansible/roles/docker-swarm-app-caddy/defaults/main.yaml +++ b/ansible/roles/docker-swarm-app-caddy/defaults/main.yaml @@ -1,3 +1,4 @@ caddy_dir: /var/data/caddy +email: nokwebspace@gmail.com domain: nokwebspace.ovh github_org: xnok diff --git a/ansible/roles/docker-swarm-app-caddy/tasks/main.yaml b/ansible/roles/docker-swarm-app-caddy/tasks/main.yaml index f66a2ff..16dbabc 100644 --- a/ansible/roles/docker-swarm-app-caddy/tasks/main.yaml +++ b/ansible/roles/docker-swarm-app-caddy/tasks/main.yaml @@ -26,26 +26,15 @@ ### # Create Caddy Pre-requisits ### -- name: Create Secret file - template: - src: "{{ role_path }}/assets/caddy_github_auth" - dest: "{{ caddy_dir }}/caddy_github_auth" - mode: '0644' - vars: - github_client_id: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_ID') }}" - github_client_secret: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_SECRET') }}" - jwt_shared_key: "{{ lookup('env', 'CADDY_JWT_SHARED_KEY') | replace('\n', '\\n') }}" - - name: Create secret for github auth docker_secret: - name: caddy_github_auth - data: "{{ caddy_dir }}/caddy_github_auth" + name: "{{ item.name }}" + data: "{{ item.value }}" state: present - -- name: Remove secrets file - ansible.builtin.file: - path: "{{ caddy_dir }}/caddy_github_auth" - state: absent + loop: + - {name: 'caddy_github_client_id', value: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_ID') }}"} + - {name: 'caddy_github_client_secret', value: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_SECRET') }}"} + - {name: 'caddy_jwt_shared_key', value: "{{ lookup('env', 'CADDY_JWT_SHARED_KEY') | replace('\n', '\\n') }}"} ### # Start Container diff --git a/ansible/roles/docker-swarm-app-portainer/assets/portainer-agent-stack.yml.j2 b/ansible/roles/docker-swarm-app-portainer/assets/portainer-agent-stack.yml.j2 index 642aae5..8e64673 100644 --- a/ansible/roles/docker-swarm-app-portainer/assets/portainer-agent-stack.yml.j2 +++ b/ansible/roles/docker-swarm-app-portainer/assets/portainer-agent-stack.yml.j2 @@ -2,7 +2,7 @@ version: '3.2' services: agent: - image: portainer/agent:2.11.1 + image: portainer/agent:2.19.4 volumes: - /var/run/docker.sock:/var/run/docker.sock - /var/lib/docker/volumes:/var/lib/docker/volumes @@ -14,7 +14,7 @@ services: constraints: [node.platform.os == linux] portainer: - image: portainer/portainer-ce:2.11.1 + image: portainer/portainer-ce:2.19.4 command: -H tcp://tasks.agent:9001 --tlsskipverify {% if not caddy %} ports: @@ -34,6 +34,12 @@ services: replicas: 1 placement: constraints: [node.role == manager] +{% if caddy %} + labels: + caddy: portainer.{{domain}} + # this include escape for ansible + caddy.reverse_proxy: "{{ '{{' }}upstreams 9000{{ '}}' }}" +{% endif %} networks: agent_network: