Refactored OAuth2 Proxy and PhpLDAPAdmin

This commit is contained in:
2025-11-27 00:21:22 +01:00
parent 4b2c7eef88
commit d97d34a822
15 changed files with 103 additions and 87 deletions

View File

@@ -17,7 +17,7 @@ server
{% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %} {% include 'roles/sys-svc-letsencrypt/templates/ssl_header.j2' %}
{% if applications | get_app_conf(application_id, 'features.oauth2', False) %} {% if applications | get_app_conf(application_id, 'features.oauth2', False) %}
{% set acl = applications | get_app_conf(application_id, 'oauth2_proxy.acl', False, {}) %} {% set acl = applications | get_app_conf(application_id, 'docker.services.oauth2_proxy.acl', False, {}) %}
{% if acl.blacklist is defined %} {% if acl.blacklist is defined %}
{# 1. Expose everything by default, then protect blacklisted paths #} {# 1. Expose everything by default, then protect blacklisted paths #}

View File

@@ -23,13 +23,14 @@ server:
unsafe-eval: true unsafe-eval: true
style-src-attr: style-src-attr:
unsafe-inline: true unsafe-inline: true
oauth2_proxy:
application: "application"
port: "80"
addons: addons:
keycloakpassword: {} keycloakpassword: {}
ldapauth: {} ldapauth: {}
docker: docker:
services: services:
database: database:
enabled: true enabled: true
oauth2_proxy:
origin:
host: "application"
port: "80"

View File

@@ -12,6 +12,13 @@ docker:
enabled: true enabled: true
database: database:
enabled: true enabled: true
oauth2_proxy:
origin:
host: "front"
port: "80"
acl:
blacklist:
- "/login"
features: features:
matomo: true matomo: true
css: false css: false
@@ -32,9 +39,3 @@ server:
whitelist: whitelist:
font-src: font-src:
- "data:" - "data:"
oauth2_proxy:
application: "front"
port: "80"
acl:
blacklist:
- "/login"

View File

@@ -13,12 +13,7 @@ features:
oauth2: true oauth2: true
oidc: false # Deactivated because users aren't auto-created. oidc: false # Deactivated because users aren't auto-created.
logout: true logout: true
oauth2_proxy:
application: "application"
port: "<< defaults_applications[web-app-gitea].docker.services.gitea.port >>"
acl:
blacklist:
- "/user/login"
server: server:
csp: csp:
flags: flags:
@@ -59,5 +54,12 @@ docker:
mem_reservation: 0.2g mem_reservation: 0.2g
mem_limit: 0.3g mem_limit: 0.3g
pids_limit: 512 pids_limit: 512
oauth2_proxy:
origin:
host: "application"
port: "<< defaults_applications[web-app-gitea].docker.services.gitea.port >>"
acl:
blacklist:
- "/user/login"
volumes: volumes:
data: "gitea_data" data: "gitea_data"

View File

@@ -1,13 +1,14 @@
docker: docker:
services: services:
lam: lam:
image: ghcr.io/ldapaccountmanager/lam image: ghcr.io/ldapaccountmanager/lam
version: latest version: latest
oauth2_proxy: oauth2_proxy:
application: application origin:
port: 80 host: application
allowed_groups: port: 80
- "{{ [RBAC.GROUP.NAME, 'web-app-lam-administrator'] | path_join }}" allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-lam-administrator'] | path_join }}"
features: features:
matomo: true matomo: true
css: true css: true

View File

@@ -1,7 +1,7 @@
http_address = "0.0.0.0:4180" http_address = "0.0.0.0:4180"
cookie_secret = "{{ applications | get_app_conf(oauth2_proxy_application_id, 'credentials.oauth2_proxy_cookie_secret', True) }}" cookie_secret = "{{ applications | get_app_conf(oauth2_proxy_application_id, 'credentials.oauth2_proxy_cookie_secret', True) }}"
cookie_secure = "true" # True is necessary to force the cookie set via https cookie_secure = "true" # True is necessary to force the cookie set via https
upstreams = "http://{{ applications | get_app_conf(oauth2_proxy_application_id, 'oauth2_proxy.application', True) }}:{{ applications | get_app_conf(oauth2_proxy_application_id, 'oauth2_proxy.port', True) }}" upstreams = "http://{{ applications | get_app_conf(oauth2_proxy_application_id, 'docker.services.oauth2_proxy.origin.host') }}:{{ applications | get_app_conf(oauth2_proxy_application_id, 'docker.services.oauth2_proxy.origin.port') }}"
cookie_domains = ["{{ domains | get_domain(oauth2_proxy_application_id) }}", "{{ domains | get_domain('web-app-keycloak') }}"] # Required so cookie can be read on all subdomains. cookie_domains = ["{{ domains | get_domain(oauth2_proxy_application_id) }}", "{{ domains | get_domain('web-app-keycloak') }}"] # Required so cookie can be read on all subdomains.
whitelist_domains = [".{{ PRIMARY_DOMAIN }}"] # Required to allow redirection back to original requested target. whitelist_domains = [".{{ PRIMARY_DOMAIN }}"] # Required to allow redirection back to original requested target.
@@ -13,11 +13,11 @@ oidc_issuer_url = "{{ OIDC.CLIENT.ISSUER_URL }}"
provider = "oidc" provider = "oidc"
provider_display_name = "{{ OIDC.BUTTON_TEXT }}" provider_display_name = "{{ OIDC.BUTTON_TEXT }}"
{% if applications | get_app_conf(oauth2_proxy_application_id, 'oauth2_proxy.allowed_groups', False) %} {% if applications | get_app_conf(oauth2_proxy_application_id, 'docker.services.oauth2_proxy.allowed_groups', False) %}
{# role based restrictions #} {# role based restrictions #}
scope = "openid email profile {{ RBAC.GROUP.CLAIM }}" scope = "openid email profile {{ RBAC.GROUP.CLAIM }}"
oidc_groups_claim = "{{ RBAC.GROUP.CLAIM }}" oidc_groups_claim = "{{ RBAC.GROUP.CLAIM }}"
allowed_groups = {{ applications | get_app_conf(oauth2_proxy_application_id, 'oauth2_proxy.allowed_groups', True) | to_json }} allowed_groups = {{ applications | get_app_conf(oauth2_proxy_application_id, 'docker.services.oauth2_proxy.allowed_groups') | to_json }}
email_domains = ["*"] email_domains = ["*"]
{% else %} {% else %}
email_domains = "{{ PRIMARY_DOMAIN }}" email_domains = "{{ PRIMARY_DOMAIN }}"

View File

@@ -1,11 +1,3 @@
oauth2_proxy:
application: "proxy"
port: "80"
acl:
whitelist:
- "/users/me" # Necessary for Nextcloud Plugin to work
- "/api/" # Necessary for Nextcloud Plugin to work
- "/oauth/token" # Necessary for Nextcloud Plugin to work
ldap: ldap:
filters: filters:
administrators: False # Set true to filter administrators administrators: False # Set true to filter administrators
@@ -78,6 +70,14 @@ docker:
mem_reservation: "512m" mem_reservation: "512m"
mem_limit: "512m" mem_limit: "512m"
pids_limit: 256 pids_limit: 256
oauth2_proxy:
origin:
host: "proxy"
port: "80"
acl:
whitelist:
- "/users/me" # Necessary for Nextcloud Plugin to work
- "/api/" # Necessary for Nextcloud Plugin to work
- "/oauth/token" # Necessary for Nextcloud Plugin to work
volumes: volumes:
data: "openproject_data" data: "openproject_data"

View File

@@ -1,11 +1,6 @@
version: "latest" version: "latest"
server_mode: False # If true then the preconfigured database file is loaded. Recommended False. True is a security risk. server_mode: False # If true then the preconfigured database file is loaded. Recommended False. True is a security risk.
master_password_required: True # Master password is required. Recommended True. False is a security risk. master_password_required: True # Master password is required. Recommended True. False is a security risk.
oauth2_proxy:
application: "application"
port: "80"
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-pgadmin-administrator'] | path_join }}"
features: features:
matomo: true matomo: true
css: true css: true
@@ -31,3 +26,9 @@ docker:
services: services:
database: database:
enabled: true enabled: true
oauth2_proxy:
origin:
host: "application"
port: "80"
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-pgadmin-administrator'] | path_join }}"

View File

@@ -1,18 +1,23 @@
version: "2.0.0-dev"
oauth2_proxy:
application: application # Needs to be the same as webinterface
port: 8080 # application port
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-phpldapadmin-administrator'] | path_join }}"
features: features:
matomo: true matomo: true
css: true css: true
desktop: true desktop: true
ldap: true ldap: true
oauth2: true oauth2: true
logout: true logout: true
server: server:
domains: domains:
canonical: canonical:
- phpldapadmin.{{ PRIMARY_DOMAIN }} - phpldapadmin.{{ PRIMARY_DOMAIN }}
aliases: [] aliases: []
docker:
services:
phpldapadmin:
image: leenooks/phpldapadmin
version: "2.0.0-dev"
oauth2_proxy:
origin:
host: application # Needs to be the same as webinterface
port: 8080 # application port
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-phpldapadmin-administrator'] | path_join }}"

View File

@@ -2,7 +2,7 @@
application: application:
container_name: {{ application_id }} container_name: {{ application_id }}
image: leenooks/phpldapadmin:{{ applications | get_app_conf(application_id, 'version', True)}} image: {{ PHPLDAPADMIN_IMAGE }}:{{ PHPLDAPADMIN_VERSION }}
ports: ports:
- 127.0.0.1:{{ ports.localhost.http[application_id] }}:8080 - 127.0.0.1:{{ ports.localhost.http[application_id] }}:8080
{% include 'roles/docker-container/templates/base.yml.j2' %} {% include 'roles/docker-container/templates/base.yml.j2' %}

View File

@@ -1 +1,5 @@
application_id: "web-app-phpldapadmin" application_id: "web-app-phpldapadmin"
entity_name: "{{ application_id | get_entity_name }}"
PHPLDAPADMIN_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.image' )}}"
PHPLDAPADMIN_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.' ~ entity_name ~ '.version' )}}"

View File

@@ -1,13 +1,8 @@
autologin: false # This is a high security risk. Just activate this option if you know what you're doing autologin: false # This is a high security risk. Just activate this option if you know what you're doing
oauth2_proxy:
port: "80"
application: "application"
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-phpmyadmin-administrator'] | path_join }}"
features: features:
matomo: true matomo: true
css: false css: false
desktop: false # Opens itself in a new window, when it's loaded in an iframe. desktop: false # Opens itself in a new window, when it's loaded in an iframe.
# it's anyhow not so enduser relevant, so it can be kept like this # it's anyhow not so enduser relevant, so it can be kept like this
central_database: true central_database: true
oauth2: true oauth2: true
@@ -30,4 +25,9 @@ docker:
phpmyadmin: phpmyadmin:
version: "latest" # Use the latest phpmyadmin version version: "latest" # Use the latest phpmyadmin version
name: "phpmyadmin" name: "phpmyadmin"
image: phpmyadmin/phpmyadmin image: "phpmyadmin/phpmyadmin"
oauth2_proxy:
port: "80"
application: "application"
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-phpmyadmin-administrator'] | path_join }}"

View File

@@ -1,11 +1,11 @@
features: features:
matomo: true matomo: true
css: false css: false
desktop: true desktop: true
central_database: true central_database: true
ldap: true ldap: true
oauth2: true oauth2: true
logout: true logout: true
server: server:
domains: domains:
canonical: canonical:
@@ -23,12 +23,6 @@ server:
whitelist: whitelist:
font-src: font-src:
- "data:" - "data:"
oauth2_proxy:
application: "application"
port: "80"
acl:
blacklist:
- "/login"
docker: docker:
services: services:
redis: redis:
@@ -39,6 +33,12 @@ docker:
version: "latest" version: "latest"
name: "snipe-it" name: "snipe-it"
image: "grokability/snipe-it" image: "grokability/snipe-it"
oauth2_proxy:
application: "application"
port: "80"
acl:
blacklist:
- "/login"
volumes: volumes:
data: "snipe-it_data" data: "snipe-it_data"

View File

@@ -1,11 +1,3 @@
oauth2_proxy:
application: "application"
port: "80"
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-yourls-administrator'] | path_join }}"
acl:
blacklist:
- "<< defaults_applications[web-app-yourls].server.locations.admin >>" # Protects the admin area
features: features:
matomo: true matomo: true
css: true css: true
@@ -38,3 +30,11 @@ docker:
version: "latest" version: "latest"
name: "yourls" name: "yourls"
image: "yourls" image: "yourls"
oauth2_proxy:
application: "application"
port: "80"
allowed_groups:
- "{{ [RBAC.GROUP.NAME, 'web-app-yourls-administrator'] | path_join }}"
acl:
blacklist:
- "<< defaults_applications[web-app-yourls].server.locations.admin >>" # Protects the admin area

View File

@@ -22,7 +22,8 @@ class TestOauth2AclMutualExclusion(unittest.TestCase):
failures.append(f"{role_path.name}: failed to parse YAML ({e})") failures.append(f"{role_path.name}: failed to parse YAML ({e})")
continue continue
oauth2 = data.get("oauth2_proxy", {}) services = data.get("services", {})
oauth2 = services.get("oauth2_proxy", {})
acl = oauth2.get("acl", None) acl = oauth2.get("acl", None)
if acl is None: if acl is None:
continue continue
@@ -37,7 +38,7 @@ class TestOauth2AclMutualExclusion(unittest.TestCase):
if failures: if failures:
self.fail( self.fail(
"The following roles define both whitelist and blacklist under oauth2_proxy.acl:\n" "The following roles define both whitelist and blacklist under docker.services.oauth2_proxy.acl:\n"
+ "\n".join(failures) + "\n".join(failures)
) )