Solved oauth2 bugs and deactivated health-csp role temporary

This commit is contained in:
Kevin Veen-Birkenbach 2025-05-13 14:34:16 +02:00
parent 687f9b0703
commit dc4964eda1
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
14 changed files with 38 additions and 82 deletions

View File

@ -33,6 +33,26 @@ def get_csp_flags(applications, application_id: str, directive: str) -> list:
tokens.append("'unsafe-inline'") tokens.append("'unsafe-inline'")
return tokens return tokens
def get_docker_compose(path_docker_compose_instances: str, application_id: str) -> dict:
"""
Build the docker_compose dict based on
path_docker_compose_instances and application_id.
"""
base = f"{path_docker_compose_instances}{application_id}/"
return {
'directories': {
'instance': base,
'env': f"{base}.env/",
'services': f"{base}services/",
'volumes': f"{base}volumes/",
'config': f"{base}config/",
},
'files': {
'env': f"{base}.env/env",
'docker_compose': f"{base}docker-compose.yml",
}
}
class FilterModule(object): class FilterModule(object):
def filters(self): def filters(self):
@ -40,4 +60,5 @@ class FilterModule(object):
'is_feature_enabled': is_feature_enabled, 'is_feature_enabled': is_feature_enabled,
'get_csp_whitelist': get_csp_whitelist, 'get_csp_whitelist': get_csp_whitelist,
'get_csp_flags': get_csp_flags, 'get_csp_flags': get_csp_flags,
'get_docker_compose': get_docker_compose,
} }

View File

@ -1,14 +1,2 @@
# Private variable for role. Please use docker_compose.directories.instance instead
_docker_compose_directories_instance: "{{ path_docker_compose_instances }}{{ application_id }}/"
# @See https://chatgpt.com/share/67a23d18-fb54-800f-983c-d6d00752b0b4 # @See https://chatgpt.com/share/67a23d18-fb54-800f-983c-d6d00752b0b4
docker_compose: docker_compose: "{{ path_docker_compose_instances | get_docker_compose(application_id) }}"
directories:
instance: "{{_docker_compose_directories_instance}}" # Folder for docker-compose.yml file
env: "{{_docker_compose_directories_instance}}.env/" # Folder for env files
services: "{{_docker_compose_directories_instance}}services/" # Folder for services
volumes: "{{_docker_compose_directories_instance}}volumes/" # Folder for volumes
config: "{{_docker_compose_directories_instance}}config/" # Folder for configuration files
files:
env: "{{_docker_compose_directories_instance}}.env/env" # General env file
docker_compose: "{{_docker_compose_directories_instance}}docker-compose.yml" # Docker Compose file

View File

@ -1,6 +1,6 @@
- name: "Transfering oauth2-proxy-keycloak.cfg.j2 to {{docker_compose.directories.volumes}}" - name: "Transfering oauth2-proxy-keycloak.cfg.j2 to {{(path_docker_compose_instances | get_docker_compose(oauth2_proxy_application_id)).directories.volumes}}"
template: template:
src: oauth2-proxy-keycloak.cfg.j2 src: oauth2-proxy-keycloak.cfg.j2
dest: "{{docker_compose.directories.volumes}}{{applications[application_id].configuration_file}}" dest: "{{(path_docker_compose_instances | get_docker_compose(oauth2_proxy_application_id)).directories.volumes}}{{applications[application_id].configuration_file}}"
notify: notify:
- docker compose project setup - docker compose project setup

View File

@ -1,11 +1,11 @@
{% if applications | is_feature_enabled('oauth2',application_id) %} {% if applications | is_feature_enabled('oauth2',application_id) %}
oauth2-proxy: oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:{{applications.oauth2_proxy.version}} image: quay.io/oauth2-proxy/oauth2-proxy:{{applications['oauth2-proxy'].version}}
restart: {{docker_restart_policy}} restart: {{docker_restart_policy}}
command: --config /oauth2-proxy.cfg command: --config /oauth2-proxy.cfg
hostname: oauth2-proxy hostname: oauth2-proxy
ports: ports:
- {{ports.localhost.oauth2_proxy[application_id]}}:4180/tcp - {{ports.localhost.oauth2_proxy[application_id]}}:4180/tcp
volumes: volumes:
- "{{docker_compose.directories.volumes}}{{applications.oauth2_proxy.configuration_file}}:/oauth2-proxy.cfg" - "{{docker_compose.directories.volumes}}{{applications['oauth2-proxy'].configuration_file}}:/oauth2-proxy.cfg"
{% endif %} {% endif %}

View File

@ -3,18 +3,18 @@ cookie_secret = "{{ applications[oauth2_proxy_application_id].creden
email_domains = "{{ primary_domain }}" email_domains = "{{ primary_domain }}"
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[oauth2_proxy_application_id].oauth2_proxy.application }}:{{ applications[oauth2_proxy_application_id].oauth2_proxy.port }}" upstreams = "http://{{ applications[oauth2_proxy_application_id].oauth2_proxy.application }}:{{ applications[oauth2_proxy_application_id].oauth2_proxy.port }}"
cookie_domains = ["{{ domain }}", "{{ domains.keycloak }}"] # Required so cookie can be read on all subdomains. cookie_domains = ["{{ domains[oauth2_proxy_application_id] }}", "{{ domains.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.
# keycloak provider # keycloak provider
client_secret = "{{ oidc.client.secret }}" client_secret = "{{ oidc.client.secret }}"
client_id = "{{ oidc.client.id }}" client_id = "{{ oidc.client.id }}"
redirect_url = "{{ web_protocol }}://{{domain}}/oauth2/callback" redirect_url = "{{ web_protocol }}://{{domains[oauth2_proxy_application_id]}}/oauth2/callback"
oidc_issuer_url = "{{ oidc.client.issuer_url }}" oidc_issuer_url = "{{ oidc.client.issuer_url }}"
provider = "oidc" provider = "oidc"
provider_display_name = "Keycloak" provider_display_name = "Keycloak"
# role restrictions # role restrictions
#cookie_roles = "realm_access.roles" #cookie_roles = "realm_access.roles"
#allowed_groups = "{{ applications[oauth2_proxy_application_id].allowed_roles }}" # This is not correct here. needs to be placed in applications @todo move there when implementing #allowed_groups = "{{ applications[application_id].allowed_roles }}" # This is not correct here. needs to be placed in applications @todo move there when implementing
# @see https://chatgpt.com/share/67f42607-bf68-800f-b587-bd56fe9067b5 # @see https://chatgpt.com/share/67f42607-bf68-800f-b587-bd56fe9067b5

View File

@ -31,7 +31,7 @@ Set the following variables to customize behavior:
```yaml ```yaml
health_csp_crawler_folder: "{{ path_administrator_scripts }}health-csp/" health_csp_crawler_folder: "{{ path_administrator_scripts }}health-csp/"
on_calendar_health_csp_crawler: "daily" on_calendar_health_csp_crawler: "daily"
```` ```
## License ## License

View File

@ -1,43 +0,0 @@
const puppeteer = require('puppeteer');
const domains = process.argv.slice(2);
(async () => {
let errorCounter = 0;
const browser = await puppeteer.launch({ headless: 'new' });
for (const domain of domains) {
const page = await browser.newPage();
const blockedResources = [];
page.on('requestfailed', request => {
const reason = request.failure()?.errorText || '';
if (reason.includes('blocked')) {
blockedResources.push({ url: request.url(), reason });
}
});
try {
const url = `https://${domain}`;
await page.goto(url, { waitUntil: 'networkidle2', timeout: 20000 });
} catch (e) {
console.error(`${domain}: ERROR visiting site - ${e.message}`);
errorCounter++;
continue;
}
if (blockedResources.length > 0) {
console.warn(`${domain}: Blocked resources detected:`);
blockedResources.forEach(r =>
console.log(` BLOCKED by CSP: ${r.url} (${r.reason})`)
);
errorCounter++;
} else {
console.log(`${domain}: ✅ No CSP blocks detected.`);
}
await page.close();
}
await browser.close();
process.exit(errorCounter);
})();

View File

@ -32,7 +32,7 @@ def run_node_checker(script_path, domains):
""" """
try: try:
result = subprocess.run( result = subprocess.run(
["/usr/bin/node", script_path] + domains, ["node", script_path] + domains,
check=True check=True
) )
return result.returncode return result.returncode

View File

@ -17,9 +17,9 @@
register: puppeteer_check register: puppeteer_check
failed_when: puppeteer_check.rc != 0 failed_when: puppeteer_check.rc != 0
- name: copy health_csp.py - name: copy health-csp.py
copy: copy:
src: health_csp.py src: health-csp.py
dest: "{{ health_csp_crawler_script }}" dest: "{{ health_csp_crawler_script }}"
mode: 0755 mode: 0755

View File

@ -1,3 +1,3 @@
health_csp_crawler_folder: "{{ path_administrator_scripts }}health-csp/" health_csp_crawler_folder: "{{ path_administrator_scripts }}health-csp/"
health_csp_crawler_script: "{{ health_csp_crawler_folder }}health_csp.py" health_csp_crawler_script: "{{ health_csp_crawler_folder }}health-csp.py"
health_csp_crawler_node: "{{ health_csp_crawler_folder }}health-csp.js" health_csp_crawler_node: "{{ health_csp_crawler_folder }}health-csp.js"

View File

@ -1,3 +1,3 @@
dependencies: dependencies:
- health-nginx - health-nginx
- health-csp # - health-csp

View File

@ -13,16 +13,6 @@ Optimized for Archlinux and Debian-based systems, this role ensures the presence
- **Node.js Installation:** Installs the latest Node.js version available via the system's package manager. - **Node.js Installation:** Installs the latest Node.js version available via the system's package manager.
- **Idempotent Execution:** Ensures Node.js is only installed when missing. - **Idempotent Execution:** Ensures Node.js is only installed when missing.
## Usage
Include this role before running any tasks or roles that depend on Node.js:
```yaml
- name: Ensure Node.js is available
roles:
- nodejs
````
## License ## License
CyMaIS NonCommercial License (CNCL) CyMaIS NonCommercial License (CNCL)

View File

@ -2,9 +2,9 @@
# Better load the repositories into /opt/docker/[servicename]/services, build them there and then use a docker-compose file for customizing # Better load the repositories into /opt/docker/[servicename]/services, build them there and then use a docker-compose file for customizing
# @todo Refactor\Remove # @todo Refactor\Remove
# @deprecated # @deprecated
- name: "Merge detached_files with applications.oauth2_proxy.configuration_file" - name: "Merge detached_files with applications['oauth2-proxy'].configuration_file"
ansible.builtin.set_fact: ansible.builtin.set_fact:
merged_detached_files: "{{ detached_files + [applications.oauth2_proxy.configuration_file] }}" merged_detached_files: "{{ detached_files + [applications['oauth2-proxy'].configuration_file] }}"
when: applications[application_id].get('features', {}).get('oauth2', False) | bool when: applications[application_id].get('features', {}).get('oauth2', False) | bool
- name: "backup detached files" - name: "backup detached files"