From 7897bebbafbf5f3daa1f575d175c9a85796dc237 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Tue, 23 Jan 2024 16:02:26 +0100 Subject: [PATCH 01/25] Current state of rework --- .gitignore | 4 +- README.md | 20 +++++++ ansible.cfg | 9 +++ ansible/README.md | 21 ------- ansible/ansible.cfg | 5 -- ansible/dodger_deploy.yml | 17 ------ ansible/inventory.yml | 8 --- {ansible/defaults => defaults}/main.yml | 0 dodger_deploy.yml | 18 ++++++ inventory.yml | 32 +++++++++++ jenkins/README.md | 21 ------- jenkins/docker-compose.yml | 26 --------- portainer/.env | 1 - portainer/README.md | 33 ----------- portainer/docker-compose.yaml | 30 ---------- ansible/requirements.txt => requirements.txt | 0 ansible/requirements.yml => requirements.yml | 0 resilio-sync/.env | 1 - resilio-sync/README.md | 17 ------ resilio-sync/docker-compose.yaml | 27 --------- {blog => roles/blog}/.env | 0 {blog => roles/blog}/.gitignore | 0 {blog => roles/blog}/README.md | 0 .../blog/templates}/docker-compose.yaml | 0 roles/crowdsec/defaults/main.yml | 10 ++++ roles/crowdsec/files/config.yaml | 50 ++++++++++++++++ roles/crowdsec/files/traefik.yml | 4 ++ roles/crowdsec/files/whitelist-de.yml | 6 ++ roles/crowdsec/handlers/main.yml | 5 ++ roles/crowdsec/tasks/firewall_bouncer.yml | 57 +++++++++++++++++++ roles/crowdsec/tasks/main.yml | 49 ++++++++++++++++ .../roles => roles}/default/defaults/main.yml | 0 .../default/tasks/hardening.yml | 0 .../roles => roles}/default/tasks/main.yml | 0 {ansible/roles => roles}/docker/LICENSE | 0 .../roles => roles}/docker/defaults/main.yml | 0 .../roles => roles}/docker/tasks/main.yml | 0 {gitlab => roles/gitlab}/.env | 0 {gitlab => roles/gitlab}/README.md | 0 {gitlab => roles/gitlab}/docker-compose.yaml | 0 .../gitlab}/gitlab-runner-register.sh | 0 {homer => roles/homer}/.env | 0 {homer => roles/homer}/README.md | 0 {homer => roles/homer}/docker-compose.yaml | 0 {hugo => roles/hugo}/.env | 0 {hugo => roles/hugo}/README.md | 0 {hugo => roles/hugo}/docker-compose.yml | 0 {matrix => roles/matrix}/.env | 0 {matrix => roles/matrix}/README.md | 0 .../matrix}/docker-compose.signal.yaml | 0 .../matrix}/docker-compose.telegram.yaml | 0 .../matrix}/docker-compose.whatsapp.yaml | 0 {matrix => roles/matrix}/docker-compose.yaml | 0 .../matrix}/files/homeserver.yaml | 0 .../matrix}/files/matrix.log.config | 0 {matrix => roles/matrix}/nginx/matrix.conf | 0 .../nginx/www/.well-known/matrix/client | 0 .../nginx/www/.well-known/matrix/server | 0 {nextcloud => roles/nextcloud}/.env | 0 {nextcloud => roles/nextcloud}/README.md | 0 .../nextcloud}/coturn/README.md | 0 .../nextcloud}/coturn/docker-compose.yaml | 0 .../nextcloud}/coturn/turnserver.conf | 0 .../nextcloud}/docker-compose.yaml | 0 {openldap => roles/openldap}/.env | 0 {openldap => roles/openldap}/README.md | 0 .../openldap}/docker-compose.yaml | 0 {seafile => roles/seafile}/.env | 0 {seafile => roles/seafile}/README.md | 0 .../seafile}/docker-compose.yaml | 0 {traefik => roles/traefik}/.env | 0 {traefik => roles/traefik}/README.md | 0 .../traefik}/docker-compose.yaml | 0 .../traefik}/letsencrypt/acme.json | 0 {wazuh => roles/wazuh}/.env | 0 {wazuh => roles/wazuh}/README.md | 0 .../wazuh}/docker-compose.yml.diff | 0 {ansible/vars => vars}/users.yml | 0 78 files changed, 263 insertions(+), 208 deletions(-) create mode 100644 ansible.cfg delete mode 100644 ansible/README.md delete mode 100644 ansible/ansible.cfg delete mode 100644 ansible/dodger_deploy.yml delete mode 100644 ansible/inventory.yml rename {ansible/defaults => defaults}/main.yml (100%) create mode 100644 dodger_deploy.yml create mode 100644 inventory.yml delete mode 100644 jenkins/README.md delete mode 100644 jenkins/docker-compose.yml delete mode 100644 portainer/.env delete mode 100644 portainer/README.md delete mode 100644 portainer/docker-compose.yaml rename ansible/requirements.txt => requirements.txt (100%) rename ansible/requirements.yml => requirements.yml (100%) delete mode 100644 resilio-sync/.env delete mode 100644 resilio-sync/README.md delete mode 100644 resilio-sync/docker-compose.yaml rename {blog => roles/blog}/.env (100%) rename {blog => roles/blog}/.gitignore (100%) rename {blog => roles/blog}/README.md (100%) rename {blog => roles/blog/templates}/docker-compose.yaml (100%) create mode 100644 roles/crowdsec/defaults/main.yml create mode 100644 roles/crowdsec/files/config.yaml create mode 100644 roles/crowdsec/files/traefik.yml create mode 100644 roles/crowdsec/files/whitelist-de.yml create mode 100644 roles/crowdsec/handlers/main.yml create mode 100644 roles/crowdsec/tasks/firewall_bouncer.yml create mode 100644 roles/crowdsec/tasks/main.yml rename {ansible/roles => roles}/default/defaults/main.yml (100%) rename {ansible/roles => roles}/default/tasks/hardening.yml (100%) rename {ansible/roles => roles}/default/tasks/main.yml (100%) rename {ansible/roles => roles}/docker/LICENSE (100%) rename {ansible/roles => roles}/docker/defaults/main.yml (100%) rename {ansible/roles => roles}/docker/tasks/main.yml (100%) rename {gitlab => roles/gitlab}/.env (100%) rename {gitlab => roles/gitlab}/README.md (100%) rename {gitlab => roles/gitlab}/docker-compose.yaml (100%) rename {gitlab => roles/gitlab}/gitlab-runner-register.sh (100%) rename {homer => roles/homer}/.env (100%) rename {homer => roles/homer}/README.md (100%) rename {homer => roles/homer}/docker-compose.yaml (100%) rename {hugo => roles/hugo}/.env (100%) rename {hugo => roles/hugo}/README.md (100%) rename {hugo => roles/hugo}/docker-compose.yml (100%) rename {matrix => roles/matrix}/.env (100%) rename {matrix => roles/matrix}/README.md (100%) rename {matrix => roles/matrix}/docker-compose.signal.yaml (100%) rename {matrix => roles/matrix}/docker-compose.telegram.yaml (100%) rename {matrix => roles/matrix}/docker-compose.whatsapp.yaml (100%) rename {matrix => roles/matrix}/docker-compose.yaml (100%) rename {matrix => roles/matrix}/files/homeserver.yaml (100%) rename {matrix => roles/matrix}/files/matrix.log.config (100%) rename {matrix => roles/matrix}/nginx/matrix.conf (100%) rename {matrix => roles/matrix}/nginx/www/.well-known/matrix/client (100%) rename {matrix => roles/matrix}/nginx/www/.well-known/matrix/server (100%) rename {nextcloud => roles/nextcloud}/.env (100%) rename {nextcloud => roles/nextcloud}/README.md (100%) rename {nextcloud => roles/nextcloud}/coturn/README.md (100%) rename {nextcloud => roles/nextcloud}/coturn/docker-compose.yaml (100%) rename {nextcloud => roles/nextcloud}/coturn/turnserver.conf (100%) rename {nextcloud => roles/nextcloud}/docker-compose.yaml (100%) rename {openldap => roles/openldap}/.env (100%) rename {openldap => roles/openldap}/README.md (100%) rename {openldap => roles/openldap}/docker-compose.yaml (100%) rename {seafile => roles/seafile}/.env (100%) rename {seafile => roles/seafile}/README.md (100%) rename {seafile => roles/seafile}/docker-compose.yaml (100%) rename {traefik => roles/traefik}/.env (100%) rename {traefik => roles/traefik}/README.md (100%) rename {traefik => roles/traefik}/docker-compose.yaml (100%) rename {traefik => roles/traefik}/letsencrypt/acme.json (100%) rename {wazuh => roles/wazuh}/.env (100%) rename {wazuh => roles/wazuh}/README.md (100%) rename {wazuh => roles/wazuh}/docker-compose.yml.diff (100%) rename {ansible/vars => vars}/users.yml (100%) diff --git a/.gitignore b/.gitignore index 16665d8..8e39822 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ db wordpress ./**/.venv .venv -.vscode \ No newline at end of file +.vscode +.DS_Store +pw_vault.txt \ No newline at end of file diff --git a/README.md b/README.md index 799e820..d48fdae 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,23 @@ In case you want to run applications individually, please make sure your Docker docker network create proxy ``` +## Ansible + +Deploying made simple by applying Ansible Playbooks including hardening, installs and more! + +### Getting Started + +Create Python virtualenv and install requirements: + +```bash +python -m venv .venv +source .venv/bin/activate + +pip install -r requirements.txt +``` + +Replace your IP address in the `inventory.yml` and run the provided Ansible playbook: + +```bash +ansible-playbook dodger_deploy.yml +``` diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..07a47d6 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,9 @@ +[defaults] +nocows = True +forks = 10 +allow_world_readable_tmpfiles=true +inventory = ./inventory.yml +vault_password_file = pw_vault.txt + +[ssh_connection] +ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o ServerAliveInterval=50 -o ServerAliveCountMax=999 diff --git a/ansible/README.md b/ansible/README.md deleted file mode 100644 index 04fa6de..0000000 --- a/ansible/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Ansible - -Deploying made simple by applying Ansible Playbooks including hardening, installs and more! - -## Getting Started - -Create Python virtualenv and install requirements: - -```bash -python -m venv .venv -source .venv/bin/activate - -pip install -r requirements.txt -``` - -Replace your IP address in the `inventory.yml` and run the provided Ansible playbook: - -```bash -ansible-playbook dodger_deploy.yml -``` - diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg deleted file mode 100644 index f892a6f..0000000 --- a/ansible/ansible.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[defaults] -nocows = True -forks = 10 -allow_world_readable_tmpfiles=true -inventory = ./inventory.yml diff --git a/ansible/dodger_deploy.yml b/ansible/dodger_deploy.yml deleted file mode 100644 index bbb0358..0000000 --- a/ansible/dodger_deploy.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Setup dodger - hosts: dodger - become: true - gather_facts: true - vars_files: - - "users.yml" - roles: - - name: gantsign.oh-my-zsh - - name: default - - name: robertdebock.update - - name: docker - tasks: - - name: Clone repository - ansible.builtin.git: - repo: https://github.com/stefanDeveloper/dodger.git - dest: /srv/dodger diff --git a/ansible/inventory.yml b/ansible/inventory.yml deleted file mode 100644 index 64a8816..0000000 --- a/ansible/inventory.yml +++ /dev/null @@ -1,8 +0,0 @@ -all: - children: - dodger: - hosts: - hypervisor: - ansible_host: smachmeier - ansible_port: 22 - ansible_user: stefan diff --git a/ansible/defaults/main.yml b/defaults/main.yml similarity index 100% rename from ansible/defaults/main.yml rename to defaults/main.yml diff --git a/dodger_deploy.yml b/dodger_deploy.yml new file mode 100644 index 0000000..e40dc6f --- /dev/null +++ b/dodger_deploy.yml @@ -0,0 +1,18 @@ +--- +- name: Setup dodger + hosts: dodger + become: true + gather_facts: true + vars_files: + - "users.yml" + roles: + # - name: gantsign.oh-my-zsh + # - name: default + # - name: robertdebock.update + # - name: docker + - name: crowdsec + # tasks: + # - name: Clone repository + # ansible.builtin.git: + # repo: https://github.com/stefanDeveloper/dodger.git + # dest: /srv/dodger diff --git a/inventory.yml b/inventory.yml new file mode 100644 index 0000000..f84b11f --- /dev/null +++ b/inventory.yml @@ -0,0 +1,32 @@ +all: + children: + dodger: + hosts: + hypervisor: + ansible_host: smachmeier + ansible_port: 22 + ansible_user: stefan + + lapi_port: 8090 + install_firewall_bouncer: true + fw_bouncer_apikey: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 64633635656432346362383736623465326565336531623364396537303931323831333465373564 + 6138316362653561323033616363663163343161643539330a366237643463626265353634313662 + 64353630356666613865626665616166623362306130393537303262316566653132653339636538 + 3362323933623162650a646361383631383631316566666636626665373633633838363739636633 + 36346162363562343732303332616164363664336264636332633935316536616332633464613262 + 63613033326235633865633339623637326236356330353730303365343363636230363032623936 + 316362396564653034643964333434363936 + crowdsec: + version: latest + collections: crowdsecurity/traefik crowdsecurity/nextcloud + acquis: + - traefik.yml + log_mounts: + # - /var/log/nginx:/logs/nginx:ro + - /var/log/traefik/:/logs/traefik:ro + - /var/log/syslog:/var/logs/syslog:ro + - /var/log/auth.log:/var/log/auth.log:ro + whitelist: + - /srv/docker/crowdsec/whitelist-de.yml:/etc/crowdsec/parsers/s02-enrich/whitelist-de.yml diff --git a/jenkins/README.md b/jenkins/README.md deleted file mode 100644 index 94f19a1..0000000 --- a/jenkins/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Jenkins - -> Jenkins is a CI/CD tool. I use it to automize certain tasks. - -## Usage - -Set the following environment variables: - -```bash -DOMAIN= -``` - -and change the volume to your corresponding folder if you want to run docker commands in this folder. It can be useful when you want to create automatic backups. - -Finally you can start the application (without detach mode to get the token): - -```bash -docker-compose up -``` - -Now you have to wait until Jenkins is up, next step is to unlock the session by the key you will see in the logs. However, it is easier to link the [documentation](https://hub.docker.com/_/jenkins) diff --git a/jenkins/docker-compose.yml b/jenkins/docker-compose.yml deleted file mode 100644 index d813260..0000000 --- a/jenkins/docker-compose.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: '3.3' -services: - jenkins: - image: jenkins/jenkins:lts - container_name: jenkins - volumes: - - ./jenkins_data:/var/jenkins_home - - /var/run/docker.sock:/var/run/docker.sock - - /usr/bin/docker:/usr/bin/docker - privileged: true - user: root - labels: - - "traefik.enable=true" - - "traefik.http.routers.jenkins.rule=Host(`jenkins.${DOMAIN}`)" - - "traefik.http.routers.jenkins.entrypoints=websecure" - - "traefik.http.routers.jenkins.tls.certresolver=mytlschallenge" - - "traefik.http.services.jenkins.loadbalancer.server.port=8080" - environment: - # you can set your preferred time zone - - "TZ= Europe/Berlin" - - "JAVA_OPTS=-Dhudson.footerURL=https://jenkins.${DOMAIN}" - networks: - - proxy -networks: - proxy: - external: true \ No newline at end of file diff --git a/portainer/.env b/portainer/.env deleted file mode 100644 index b1516b1..0000000 --- a/portainer/.env +++ /dev/null @@ -1 +0,0 @@ -DOMAIN= \ No newline at end of file diff --git a/portainer/README.md b/portainer/README.md deleted file mode 100644 index 45b3f76..0000000 --- a/portainer/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Portainer - -## Usage - -Set the following environment variables: - -```env -DOMAIN= -``` - -And then run - -```sh -docker-compose up -d -``` - -## Generate the admin password - -For this example, we'll use the password `superpassword`. - -Use the following command to generate a hash for the password: - -```sh -docker run --rm httpd:2.4-alpine htpasswd -nbB admin 'superpassword' | cut -d ":" -f 2 -``` - -If you try to use the hashed password in this form directly in your Compose file, the following error will be raised: - -`ERROR: Invalid interpolation format for "command" option in service "portainer": --admin-password 'SUPER_HASH'"` - -You need to escape each `$` character inside the hashed password with another `$`: - -`$$2y$$05$$dsada24rds.dsadasdw43tsdsda` \ No newline at end of file diff --git a/portainer/docker-compose.yaml b/portainer/docker-compose.yaml deleted file mode 100644 index e95bac9..0000000 --- a/portainer/docker-compose.yaml +++ /dev/null @@ -1,30 +0,0 @@ -version: '3.3' - -services: - frontend: - image: portainer/portainer-ce:latest - container_name: portainer - volumes: - - "/var/run/docker.sock:/var/run/docker.sock" - - "./data:/data" - networks: - - proxy - labels: - - "traefik.enable=true" - # Frontend - - "traefik.http.routers.frontend.rule=Host(`portainer.${DOMAIN}`)" - - "traefik.http.routers.frontend.entrypoints=websecure" - - "traefik.http.services.frontend.loadbalancer.server.port=9000" - - "traefik.http.routers.frontend.service=frontend" - - "traefik.http.routers.frontend.tls.certresolver=mytlschallenge" - # Edge - - "traefik.http.routers.edge.rule=Host(`edge.${DOMAIN}`)" - - "traefik.http.routers.edge.entrypoints=websecure" - - "traefik.http.services.edge.loadbalancer.server.port=8000" - - "traefik.http.routers.edge.service=edge" - - "traefik.http.routers.edge.tls.certresolver=mytlschallenge" - restart: unless-stopped - -networks: - proxy: - external: true \ No newline at end of file diff --git a/ansible/requirements.txt b/requirements.txt similarity index 100% rename from ansible/requirements.txt rename to requirements.txt diff --git a/ansible/requirements.yml b/requirements.yml similarity index 100% rename from ansible/requirements.yml rename to requirements.yml diff --git a/resilio-sync/.env b/resilio-sync/.env deleted file mode 100644 index b1516b1..0000000 --- a/resilio-sync/.env +++ /dev/null @@ -1 +0,0 @@ -DOMAIN= \ No newline at end of file diff --git a/resilio-sync/README.md b/resilio-sync/README.md deleted file mode 100644 index dbb424e..0000000 --- a/resilio-sync/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Resilio - -Application to sync your files with other devices, helpful to create easy backups - -## Usage - -Set the following environment variables: - -```env -DOMAIN= -``` - -And then run - -```sh -docker-compose up -d -``` diff --git a/resilio-sync/docker-compose.yaml b/resilio-sync/docker-compose.yaml deleted file mode 100644 index d852f86..0000000 --- a/resilio-sync/docker-compose.yaml +++ /dev/null @@ -1,27 +0,0 @@ -version: '3.3' -services: - resilio: - image: ghcr.io/linuxserver/resilio-sync - container_name: resilio - volumes: - - ./resilio/config:/config - - ./resilio/downloads:/downloads - - /srv/docker_data/sync:/sync - ports: - - 55555:55555 - labels: - - "traefik.enable=true" - - "traefik.http.routers.resilio.rule=Host(`resilio.${DOMAIN}`)" - - "traefik.http.routers.resilio.entrypoints=websecure" - - "traefik.http.routers.resilio.tls.certresolver=mytlschallenge" - - "traefik.http.services.resilio.loadbalancer.server.port=8888" - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Berlin - restart: unless-stopped - networks: - - proxy -networks: - proxy: - external: true diff --git a/blog/.env b/roles/blog/.env similarity index 100% rename from blog/.env rename to roles/blog/.env diff --git a/blog/.gitignore b/roles/blog/.gitignore similarity index 100% rename from blog/.gitignore rename to roles/blog/.gitignore diff --git a/blog/README.md b/roles/blog/README.md similarity index 100% rename from blog/README.md rename to roles/blog/README.md diff --git a/blog/docker-compose.yaml b/roles/blog/templates/docker-compose.yaml similarity index 100% rename from blog/docker-compose.yaml rename to roles/blog/templates/docker-compose.yaml diff --git a/roles/crowdsec/defaults/main.yml b/roles/crowdsec/defaults/main.yml new file mode 100644 index 0000000..c2400f9 --- /dev/null +++ b/roles/crowdsec/defaults/main.yml @@ -0,0 +1,10 @@ +--- +crowdsec_docker_path: /srv/docker/crowdsec + +crowdsec_default_mounts: + - crowdsec_config:/etc/crowdsec + - crowdsec_data:/var/lib/crowdsec/data + # - "{{ crowdsec_docker_path }}/config.yaml:/etc/crowdsec/config.yaml" # This is not necessary + - "{{ crowdsec_docker_path }}/acquis.d:/etc/crowdsec/acquis.d" + +install_firewall_bouncer: false diff --git a/roles/crowdsec/files/config.yaml b/roles/crowdsec/files/config.yaml new file mode 100644 index 0000000..7eff6f1 --- /dev/null +++ b/roles/crowdsec/files/config.yaml @@ -0,0 +1,50 @@ +common: + daemonize: false + log_media: stdout + log_level: info + log_dir: /var/log/ + working_dir: . +config_paths: + config_dir: /etc/crowdsec/ + data_dir: /var/lib/crowdsec/data/ + simulation_path: /etc/crowdsec/simulation.yaml + hub_dir: /etc/crowdsec/hub/ + index_path: /etc/crowdsec/hub/.index.json + notification_dir: /etc/crowdsec/notifications/ + plugin_dir: /usr/local/lib/crowdsec/plugins/ +crowdsec_service: + acquisition_path: /etc/crowdsec/acquis.yaml + acquisition_dir: /etc/crowdsec/acquis.d + parser_routines: 1 +plugin_config: + user: nobody + group: nobody +cscli: + output: human +db_config: + log_level: info + type: sqlite + db_path: /var/lib/crowdsec/data/crowdsec.db + flush: + max_items: 5000 + max_age: 7d + use_wal: true +api: + client: + insecure_skip_verify: false + credentials_path: /etc/crowdsec/local_api_credentials.yaml + server: + log_level: info + listen_uri: 0.0.0.0:8080 + profiles_path: /etc/crowdsec/profiles.yaml + trusted_ips: # IP ranges, or IPs which can have admin API access + - 127.0.0.1 + - ::1 + online_client: # Central API credentials (to push signals and receive bad IPs) + credentials_path: /etc/crowdsec/online_api_credentials.yaml + enable: true +prometheus: + enabled: true + level: full + listen_addr: 0.0.0.0 + listen_port: 6060 \ No newline at end of file diff --git a/roles/crowdsec/files/traefik.yml b/roles/crowdsec/files/traefik.yml new file mode 100644 index 0000000..589559b --- /dev/null +++ b/roles/crowdsec/files/traefik.yml @@ -0,0 +1,4 @@ +filenames: + - /logs/traefik/*.log +labels: + type: traefik \ No newline at end of file diff --git a/roles/crowdsec/files/whitelist-de.yml b/roles/crowdsec/files/whitelist-de.yml new file mode 100644 index 0000000..1126ace --- /dev/null +++ b/roles/crowdsec/files/whitelist-de.yml @@ -0,0 +1,6 @@ +name: smachmeier/whitelist-de +description: Whitelist all IPs from Germany +whitelist: + reason: Whitelisted country + expression: + - evt.Enriched.IsoCode == 'DE' diff --git a/roles/crowdsec/handlers/main.yml b/roles/crowdsec/handlers/main.yml new file mode 100644 index 0000000..0669942 --- /dev/null +++ b/roles/crowdsec/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart Firewall-Bouncer-IPtables + ansible.builtin.service: + name: crowdsec-firewall-bouncer + state: restarted diff --git a/roles/crowdsec/tasks/firewall_bouncer.yml b/roles/crowdsec/tasks/firewall_bouncer.yml new file mode 100644 index 0000000..ef4d162 --- /dev/null +++ b/roles/crowdsec/tasks/firewall_bouncer.yml @@ -0,0 +1,57 @@ +--- +- name: Get CrowdSec signing key + ansible.builtin.get_url: + url: https://packagecloud.io/crowdsec/crowdsec/gpgkey + dest: /etc/apt/trusted.gpg.d/crowdsec.asc + mode: '0644' + force: true + +- name: Install CrowdSec repos + ansible.builtin.apt_repository: + repo: "{{ item }}" + filename: crowdsec_crowdsec + loop: + - deb [signed-by=/etc/apt/trusted.gpg.d/crowdsec.asc] https://packagecloud.io/crowdsec/crowdsec/debian bookworm main + - deb-src [signed-by=/etc/apt/trusted.gpg.d/crowdsec.asc] https://packagecloud.io/crowdsec/crowdsec/debian bookworm main + +- name: Install Firewall Bouncer IPtables + ansible.builtin.package: + name: crowdsec-firewall-bouncer-iptables + state: present + +- name: Set CrowdSec api-key + ansible.builtin.lineinfile: + path: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml + line: "api_key: {{ fw_bouncer_apikey }}" + search_string: api_key + notify: Restart Firewall-Bouncer-IPtables + +- name: Disable IPv6 + ansible.builtin.lineinfile: + path: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml + line: "disable_ipv6: true" + search_string: disable_ipv6 + notify: Restart Firewall-Bouncer-IPtables + +- name: Set LAPI-url + ansible.builtin.lineinfile: + path: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml + line: "api_url: http://127.0.0.1:{{ lapi_port }}/" + search_string: api_url + notify: Restart Firewall-Bouncer-IPtables + +- name: Enable chains + ansible.builtin.lineinfile: + path: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml + line: " - {{ item }}" # yes these leading spaces are required + search_string: "{{ item }}" + loop: + - FORWARD + - DOCKER-USER + notify: Restart Firewall-Bouncer-IPtables + +- name: Start Firewall Bouncer + ansible.builtin.service: + name: crowdsec-firewall-bouncer + state: started + enabled: true diff --git a/roles/crowdsec/tasks/main.yml b/roles/crowdsec/tasks/main.yml new file mode 100644 index 0000000..8ce4a12 --- /dev/null +++ b/roles/crowdsec/tasks/main.yml @@ -0,0 +1,49 @@ +--- +- name: Create {{ crowdsec_docker_path }}/ and subdirectories + ansible.builtin.file: + state: directory + path: "{{ item }}" + mode: '0700' + loop: + - "{{ crowdsec_docker_path }}/" + - "{{ crowdsec_docker_path }}/acquis.d/" + +- name: Copy crowdsec config + ansible.builtin.copy: + src: config.yaml + dest: "{{ crowdsec_docker_path }}/config.yaml" + mode: '0600' + +- name: Copy acquisition configs + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ crowdsec_docker_path }}/acquis.d/{{ item }}" + mode: '0600' + loop: "{{ crowdsec.acquis }}" + +- name: Copy de-whitelist + ansible.builtin.copy: + src: whitelist-de.yml + dest: /srv/docker/crowdsec/whitelist-de.yml + mode: '0600' + +- name: Start CrowdSec Engine Container + community.docker.docker_container: + image: crowdsecurity/crowdsec:{{ crowdsec.version }} + pull: true + name: crowdsec + recreate: true + restart_policy: unless-stopped + ports: + - 127.0.0.1:{{ lapi_port }}:8080 + - 6060:6060 + env: + COLLECTIONS: "{{ crowdsec.collections }}" + BOUNCER_KEY_firewall: "{{ fw_bouncer_apikey }}" + volumes: "{{ crowdsec_default_mounts + crowdsec.log_mounts }}" + tags: update-container + +- name: Install Firewall-Bouncer-IPtables + ansible.builtin.include_tasks: + file: firewall_bouncer.yml + when: install_firewall_bouncer diff --git a/ansible/roles/default/defaults/main.yml b/roles/default/defaults/main.yml similarity index 100% rename from ansible/roles/default/defaults/main.yml rename to roles/default/defaults/main.yml diff --git a/ansible/roles/default/tasks/hardening.yml b/roles/default/tasks/hardening.yml similarity index 100% rename from ansible/roles/default/tasks/hardening.yml rename to roles/default/tasks/hardening.yml diff --git a/ansible/roles/default/tasks/main.yml b/roles/default/tasks/main.yml similarity index 100% rename from ansible/roles/default/tasks/main.yml rename to roles/default/tasks/main.yml diff --git a/ansible/roles/docker/LICENSE b/roles/docker/LICENSE similarity index 100% rename from ansible/roles/docker/LICENSE rename to roles/docker/LICENSE diff --git a/ansible/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml similarity index 100% rename from ansible/roles/docker/defaults/main.yml rename to roles/docker/defaults/main.yml diff --git a/ansible/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml similarity index 100% rename from ansible/roles/docker/tasks/main.yml rename to roles/docker/tasks/main.yml diff --git a/gitlab/.env b/roles/gitlab/.env similarity index 100% rename from gitlab/.env rename to roles/gitlab/.env diff --git a/gitlab/README.md b/roles/gitlab/README.md similarity index 100% rename from gitlab/README.md rename to roles/gitlab/README.md diff --git a/gitlab/docker-compose.yaml b/roles/gitlab/docker-compose.yaml similarity index 100% rename from gitlab/docker-compose.yaml rename to roles/gitlab/docker-compose.yaml diff --git a/gitlab/gitlab-runner-register.sh b/roles/gitlab/gitlab-runner-register.sh similarity index 100% rename from gitlab/gitlab-runner-register.sh rename to roles/gitlab/gitlab-runner-register.sh diff --git a/homer/.env b/roles/homer/.env similarity index 100% rename from homer/.env rename to roles/homer/.env diff --git a/homer/README.md b/roles/homer/README.md similarity index 100% rename from homer/README.md rename to roles/homer/README.md diff --git a/homer/docker-compose.yaml b/roles/homer/docker-compose.yaml similarity index 100% rename from homer/docker-compose.yaml rename to roles/homer/docker-compose.yaml diff --git a/hugo/.env b/roles/hugo/.env similarity index 100% rename from hugo/.env rename to roles/hugo/.env diff --git a/hugo/README.md b/roles/hugo/README.md similarity index 100% rename from hugo/README.md rename to roles/hugo/README.md diff --git a/hugo/docker-compose.yml b/roles/hugo/docker-compose.yml similarity index 100% rename from hugo/docker-compose.yml rename to roles/hugo/docker-compose.yml diff --git a/matrix/.env b/roles/matrix/.env similarity index 100% rename from matrix/.env rename to roles/matrix/.env diff --git a/matrix/README.md b/roles/matrix/README.md similarity index 100% rename from matrix/README.md rename to roles/matrix/README.md diff --git a/matrix/docker-compose.signal.yaml b/roles/matrix/docker-compose.signal.yaml similarity index 100% rename from matrix/docker-compose.signal.yaml rename to roles/matrix/docker-compose.signal.yaml diff --git a/matrix/docker-compose.telegram.yaml b/roles/matrix/docker-compose.telegram.yaml similarity index 100% rename from matrix/docker-compose.telegram.yaml rename to roles/matrix/docker-compose.telegram.yaml diff --git a/matrix/docker-compose.whatsapp.yaml b/roles/matrix/docker-compose.whatsapp.yaml similarity index 100% rename from matrix/docker-compose.whatsapp.yaml rename to roles/matrix/docker-compose.whatsapp.yaml diff --git a/matrix/docker-compose.yaml b/roles/matrix/docker-compose.yaml similarity index 100% rename from matrix/docker-compose.yaml rename to roles/matrix/docker-compose.yaml diff --git a/matrix/files/homeserver.yaml b/roles/matrix/files/homeserver.yaml similarity index 100% rename from matrix/files/homeserver.yaml rename to roles/matrix/files/homeserver.yaml diff --git a/matrix/files/matrix.log.config b/roles/matrix/files/matrix.log.config similarity index 100% rename from matrix/files/matrix.log.config rename to roles/matrix/files/matrix.log.config diff --git a/matrix/nginx/matrix.conf b/roles/matrix/nginx/matrix.conf similarity index 100% rename from matrix/nginx/matrix.conf rename to roles/matrix/nginx/matrix.conf diff --git a/matrix/nginx/www/.well-known/matrix/client b/roles/matrix/nginx/www/.well-known/matrix/client similarity index 100% rename from matrix/nginx/www/.well-known/matrix/client rename to roles/matrix/nginx/www/.well-known/matrix/client diff --git a/matrix/nginx/www/.well-known/matrix/server b/roles/matrix/nginx/www/.well-known/matrix/server similarity index 100% rename from matrix/nginx/www/.well-known/matrix/server rename to roles/matrix/nginx/www/.well-known/matrix/server diff --git a/nextcloud/.env b/roles/nextcloud/.env similarity index 100% rename from nextcloud/.env rename to roles/nextcloud/.env diff --git a/nextcloud/README.md b/roles/nextcloud/README.md similarity index 100% rename from nextcloud/README.md rename to roles/nextcloud/README.md diff --git a/nextcloud/coturn/README.md b/roles/nextcloud/coturn/README.md similarity index 100% rename from nextcloud/coturn/README.md rename to roles/nextcloud/coturn/README.md diff --git a/nextcloud/coturn/docker-compose.yaml b/roles/nextcloud/coturn/docker-compose.yaml similarity index 100% rename from nextcloud/coturn/docker-compose.yaml rename to roles/nextcloud/coturn/docker-compose.yaml diff --git a/nextcloud/coturn/turnserver.conf b/roles/nextcloud/coturn/turnserver.conf similarity index 100% rename from nextcloud/coturn/turnserver.conf rename to roles/nextcloud/coturn/turnserver.conf diff --git a/nextcloud/docker-compose.yaml b/roles/nextcloud/docker-compose.yaml similarity index 100% rename from nextcloud/docker-compose.yaml rename to roles/nextcloud/docker-compose.yaml diff --git a/openldap/.env b/roles/openldap/.env similarity index 100% rename from openldap/.env rename to roles/openldap/.env diff --git a/openldap/README.md b/roles/openldap/README.md similarity index 100% rename from openldap/README.md rename to roles/openldap/README.md diff --git a/openldap/docker-compose.yaml b/roles/openldap/docker-compose.yaml similarity index 100% rename from openldap/docker-compose.yaml rename to roles/openldap/docker-compose.yaml diff --git a/seafile/.env b/roles/seafile/.env similarity index 100% rename from seafile/.env rename to roles/seafile/.env diff --git a/seafile/README.md b/roles/seafile/README.md similarity index 100% rename from seafile/README.md rename to roles/seafile/README.md diff --git a/seafile/docker-compose.yaml b/roles/seafile/docker-compose.yaml similarity index 100% rename from seafile/docker-compose.yaml rename to roles/seafile/docker-compose.yaml diff --git a/traefik/.env b/roles/traefik/.env similarity index 100% rename from traefik/.env rename to roles/traefik/.env diff --git a/traefik/README.md b/roles/traefik/README.md similarity index 100% rename from traefik/README.md rename to roles/traefik/README.md diff --git a/traefik/docker-compose.yaml b/roles/traefik/docker-compose.yaml similarity index 100% rename from traefik/docker-compose.yaml rename to roles/traefik/docker-compose.yaml diff --git a/traefik/letsencrypt/acme.json b/roles/traefik/letsencrypt/acme.json similarity index 100% rename from traefik/letsencrypt/acme.json rename to roles/traefik/letsencrypt/acme.json diff --git a/wazuh/.env b/roles/wazuh/.env similarity index 100% rename from wazuh/.env rename to roles/wazuh/.env diff --git a/wazuh/README.md b/roles/wazuh/README.md similarity index 100% rename from wazuh/README.md rename to roles/wazuh/README.md diff --git a/wazuh/docker-compose.yml.diff b/roles/wazuh/docker-compose.yml.diff similarity index 100% rename from wazuh/docker-compose.yml.diff rename to roles/wazuh/docker-compose.yml.diff diff --git a/ansible/vars/users.yml b/vars/users.yml similarity index 100% rename from ansible/vars/users.yml rename to vars/users.yml From 07c7be8cbf4d07e4b18217f799a338400a6f7d21 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Tue, 23 Jan 2024 16:04:01 +0100 Subject: [PATCH 02/25] Add linting --- .github/workflows/ansible-lint.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/ansible-lint.yml diff --git a/.github/workflows/ansible-lint.yml b/.github/workflows/ansible-lint.yml new file mode 100644 index 0000000..99b2775 --- /dev/null +++ b/.github/workflows/ansible-lint.yml @@ -0,0 +1,12 @@ +name: ansible-lint +on: + pull_request: + branches: ["main", "stable", "release/v*"] +jobs: + build: + name: Ansible Lint # Naming the build is important to use it as a status check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run ansible-lint + uses: ansible/ansible-lint@main # or version tag instead of 'main' \ No newline at end of file From 33e18074011bf0e1c0bdf82ceb937ef4e69e59ca Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Thu, 25 Jan 2024 10:38:05 +0100 Subject: [PATCH 03/25] Update configuration --- roles/blog/.env | 5 - roles/blog/.gitignore | 2 - roles/blog/README.md | 21 --- roles/blog/templates/docker-compose.yaml | 43 ----- roles/crowdsec/LICENSE | 190 +++++++++++++++++++++++ roles/crowdsec/tasks/main.yml | 2 +- roles/default/LICENSE | 190 +++++++++++++++++++++++ roles/seafile/.env | 3 - roles/seafile/README.md | 19 --- roles/seafile/docker-compose.yaml | 25 --- 10 files changed, 381 insertions(+), 119 deletions(-) delete mode 100644 roles/blog/.env delete mode 100644 roles/blog/.gitignore delete mode 100644 roles/blog/README.md delete mode 100644 roles/blog/templates/docker-compose.yaml create mode 100644 roles/crowdsec/LICENSE create mode 100644 roles/default/LICENSE delete mode 100644 roles/seafile/.env delete mode 100644 roles/seafile/README.md delete mode 100644 roles/seafile/docker-compose.yaml diff --git a/roles/blog/.env b/roles/blog/.env deleted file mode 100644 index 5a738f0..0000000 --- a/roles/blog/.env +++ /dev/null @@ -1,5 +0,0 @@ -MYSQL_ROOT_PASSWORD= -MYSQL_USER= -MYSQL_PASSWORD= -MYSQL_DATABASE= -DOMAIN= \ No newline at end of file diff --git a/roles/blog/.gitignore b/roles/blog/.gitignore deleted file mode 100644 index 62dec58..0000000 --- a/roles/blog/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/db/* -/wordpress/* \ No newline at end of file diff --git a/roles/blog/README.md b/roles/blog/README.md deleted file mode 100644 index 2e36b8d..0000000 --- a/roles/blog/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Wordpress Blog - -To run docker-compose up you have to adapt `.env` and run the `docker-compose` file. - -## Usage - -Set the following environment variables: - -```env -MYSQL_ROOT_PASSWORD= -MYSQL_USER= -MYSQL_PASSWORD= -MYSQL_DATABASE= -DOMAIN= -``` - -And then run - -```sh -docker-compose up -d -``` diff --git a/roles/blog/templates/docker-compose.yaml b/roles/blog/templates/docker-compose.yaml deleted file mode 100644 index bdbb6d2..0000000 --- a/roles/blog/templates/docker-compose.yaml +++ /dev/null @@ -1,43 +0,0 @@ -version: '3.3' - -services: - db: - image: mariadb - container_name: db - restart: unless-stopped - env_file: .env - networks: - - proxy - environment: - - MYSQL_DATABASE=$MYSQL_DATABASE - volumes: - - ./db:/var/lib/mysql - command: '--default-authentication-plugin=mysql_native_password' - wordpress: - links: - - db - depends_on: - - db - - image: wordpress - container_name: wordpress - restart: unless-stopped - env_file: .env - environment: - - WORDPRESS_DB_HOST=db:3306 - - WORDPRESS_DB_USER=${MYSQL_USER} - - WORDPRESS_DB_PASSWORD=${MYSQL_PASSWOR} - - WORDPRESS_DB_NAME=${MYSQL_DATABASE} - volumes: - - ./config/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini - - ./wordpress:/var/www/html - labels: - - "traefik.enable=true" - - "traefik.http.routers.me.rule=Host(`me.${DOMAIN}`)" - - "traefik.http.routers.me.entrypoints=websecure" - - "traefik.http.routers.me.tls.certresolver=mytlschallenge" - networks: - - proxy -networks: - proxy: - external: true diff --git a/roles/crowdsec/LICENSE b/roles/crowdsec/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/crowdsec/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/crowdsec/tasks/main.yml b/roles/crowdsec/tasks/main.yml index 8ce4a12..8e96616 100644 --- a/roles/crowdsec/tasks/main.yml +++ b/roles/crowdsec/tasks/main.yml @@ -40,7 +40,7 @@ env: COLLECTIONS: "{{ crowdsec.collections }}" BOUNCER_KEY_firewall: "{{ fw_bouncer_apikey }}" - volumes: "{{ crowdsec_default_mounts + crowdsec.log_mounts }}" + volumes: "{{ crowdsec_default_mounts + crowdsec.log_mounts + crowdsec.whitelist}}" tags: update-container - name: Install Firewall-Bouncer-IPtables diff --git a/roles/default/LICENSE b/roles/default/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/default/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/seafile/.env b/roles/seafile/.env deleted file mode 100644 index eae8c06..0000000 --- a/roles/seafile/.env +++ /dev/null @@ -1,3 +0,0 @@ -SEAFILE_ADMIN_MAIL= -SEAFILE_ADMIN_PASSWORD= -DOMAIN= \ No newline at end of file diff --git a/roles/seafile/README.md b/roles/seafile/README.md deleted file mode 100644 index 99781e0..0000000 --- a/roles/seafile/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Seafile - -To run docker-compose up you have to adapt `.env` - -## Usage - -Set the following environment variables: - -```env -SEAFILE_ADMIN_MAIL= -SEAFILE_ADMIN_PASSWORD= -DOMAIN= -``` - -And then run - -```sh -docker-compose up -d -``` diff --git a/roles/seafile/docker-compose.yaml b/roles/seafile/docker-compose.yaml deleted file mode 100644 index e446b4b..0000000 --- a/roles/seafile/docker-compose.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: '3.3' - -services: - seafile: - image: seafileltd/seafile:latest - container_name: seafile - restart: unless-stopped - environment: - - SEAFILE_SERVER_HOSTNAME=https://seafile.${DOMAIN} - - SEAFILE_ADMIN_EMAIL=${SEAFILE_ADMIN_MAIL} - - SEAFILE_ADMIN_PASSWORD=${SEAFILE_ADMIN_PASSWORD} - - SEAFILE_SERVER_LETSENCRYPT=false - - SEAFILE_SERVER_HOSTNAME=seafile.${DOMAIN} - volumes: - - ./seafile-data:/shared - labels: - - "traefik.enable=true" - - "traefik.http.routers.seafile.rule=Host(`seafile.${DOMAIN}`)" - - "traefik.http.routers.seafile.entrypoints=websecure" - - "traefik.http.routers.seafile.tls.certresolver=mytlschallenge" - networks: - - proxy -networks: - proxy: - external: true \ No newline at end of file From 5c894f2c03c4d15682f308f52edce2882899ba7b Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Thu, 25 Jan 2024 14:27:35 +0100 Subject: [PATCH 04/25] Update configuration --- roles/crowdsec/defaults/main.yml | 2 +- roles/crowdsec/handlers/main.yml | 2 + roles/crowdsec/tasks/firewall_bouncer.yml | 6 +- roles/crowdsec/tasks/main.yml | 8 +- roles/default/defaults/main.yml | 2 + roles/default/tasks/hardening.yml | 2 + roles/default/tasks/main.yml | 2 + roles/watchtower/LICENSE | 190 ++++++++++++++++++++++ roles/watchtower/tasks/main.yml | 11 ++ 9 files changed, 219 insertions(+), 6 deletions(-) create mode 100644 roles/watchtower/LICENSE create mode 100644 roles/watchtower/tasks/main.yml diff --git a/roles/crowdsec/defaults/main.yml b/roles/crowdsec/defaults/main.yml index c2400f9..94f5d68 100644 --- a/roles/crowdsec/defaults/main.yml +++ b/roles/crowdsec/defaults/main.yml @@ -7,4 +7,4 @@ crowdsec_default_mounts: # - "{{ crowdsec_docker_path }}/config.yaml:/etc/crowdsec/config.yaml" # This is not necessary - "{{ crowdsec_docker_path }}/acquis.d:/etc/crowdsec/acquis.d" -install_firewall_bouncer: false +crowdsec_install_firewall_bouncer: false diff --git a/roles/crowdsec/handlers/main.yml b/roles/crowdsec/handlers/main.yml index 0669942..2028998 100644 --- a/roles/crowdsec/handlers/main.yml +++ b/roles/crowdsec/handlers/main.yml @@ -3,3 +3,5 @@ ansible.builtin.service: name: crowdsec-firewall-bouncer state: restarted + +# code: language=ansible diff --git a/roles/crowdsec/tasks/firewall_bouncer.yml b/roles/crowdsec/tasks/firewall_bouncer.yml index ef4d162..30d44eb 100644 --- a/roles/crowdsec/tasks/firewall_bouncer.yml +++ b/roles/crowdsec/tasks/firewall_bouncer.yml @@ -22,7 +22,7 @@ - name: Set CrowdSec api-key ansible.builtin.lineinfile: path: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml - line: "api_key: {{ fw_bouncer_apikey }}" + line: "api_key: {{ crowdsec_fw_bouncer_apikey }}" search_string: api_key notify: Restart Firewall-Bouncer-IPtables @@ -36,7 +36,7 @@ - name: Set LAPI-url ansible.builtin.lineinfile: path: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml - line: "api_url: http://127.0.0.1:{{ lapi_port }}/" + line: "api_url: http://127.0.0.1:{{ crowdsec_lapi_port }}/" search_string: api_url notify: Restart Firewall-Bouncer-IPtables @@ -55,3 +55,5 @@ name: crowdsec-firewall-bouncer state: started enabled: true + +# code: language=ansible diff --git a/roles/crowdsec/tasks/main.yml b/roles/crowdsec/tasks/main.yml index 8e96616..6e39eba 100644 --- a/roles/crowdsec/tasks/main.yml +++ b/roles/crowdsec/tasks/main.yml @@ -35,15 +35,17 @@ recreate: true restart_policy: unless-stopped ports: - - 127.0.0.1:{{ lapi_port }}:8080 + - 127.0.0.1:{{ crowdsec_lapi_port }}:8080 - 6060:6060 env: COLLECTIONS: "{{ crowdsec.collections }}" - BOUNCER_KEY_firewall: "{{ fw_bouncer_apikey }}" + BOUNCER_KEY_firewall: "{{ crowdsec_fw_bouncer_apikey }}" volumes: "{{ crowdsec_default_mounts + crowdsec.log_mounts + crowdsec.whitelist}}" tags: update-container - name: Install Firewall-Bouncer-IPtables ansible.builtin.include_tasks: file: firewall_bouncer.yml - when: install_firewall_bouncer + when: crowdsec_install_firewall_bouncer + +# code: language=ansible diff --git a/roles/default/defaults/main.yml b/roles/default/defaults/main.yml index ed97d53..d426851 100644 --- a/roles/default/defaults/main.yml +++ b/roles/default/defaults/main.yml @@ -1 +1,3 @@ --- + +# code: language=ansible diff --git a/roles/default/tasks/hardening.yml b/roles/default/tasks/hardening.yml index eb76fba..5c76aaf 100644 --- a/roles/default/tasks/hardening.yml +++ b/roles/default/tasks/hardening.yml @@ -18,3 +18,5 @@ name: devsec.hardening.ssh_hardening vars: ssh_banner: true + +# code: language=ansible diff --git a/roles/default/tasks/main.yml b/roles/default/tasks/main.yml index fc1af4b..f45a524 100644 --- a/roles/default/tasks/main.yml +++ b/roles/default/tasks/main.yml @@ -33,3 +33,5 @@ when: "item.username != 'root'" with_items: - "{{ users }}" + +# code: language=ansible diff --git a/roles/watchtower/LICENSE b/roles/watchtower/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/watchtower/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/watchtower/tasks/main.yml b/roles/watchtower/tasks/main.yml new file mode 100644 index 0000000..083ed62 --- /dev/null +++ b/roles/watchtower/tasks/main.yml @@ -0,0 +1,11 @@ +--- + +- name: Start watchtower + community.docker.docker_container: + name: watchtower + image: "containrrr/watchtower" + restart_policy: "unless_stopped" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + +# code: language=ansible From 27c06b0fcac0cc7e892a2a954ba0bf252dc85c9d Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Thu, 25 Jan 2024 14:48:45 +0100 Subject: [PATCH 05/25] ADd openldap implementation --- roles/openldap/.env | 5 - roles/openldap/LICENSE | 190 +++++++++++++++++++++++++++++ roles/openldap/README.md | 21 ---- roles/openldap/defaults/main.yml | 5 + roles/openldap/docker-compose.yaml | 59 --------- roles/openldap/tasks/main.yml | 59 +++++++++ 6 files changed, 254 insertions(+), 85 deletions(-) delete mode 100644 roles/openldap/.env create mode 100644 roles/openldap/LICENSE delete mode 100644 roles/openldap/README.md create mode 100644 roles/openldap/defaults/main.yml delete mode 100644 roles/openldap/docker-compose.yaml create mode 100644 roles/openldap/tasks/main.yml diff --git a/roles/openldap/.env b/roles/openldap/.env deleted file mode 100644 index 2ea9249..0000000 --- a/roles/openldap/.env +++ /dev/null @@ -1,5 +0,0 @@ -PASSWORD= -DOMAIN= -DASHBOARD_PASSWORD= -NAME= -BASE_DN= \ No newline at end of file diff --git a/roles/openldap/LICENSE b/roles/openldap/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/openldap/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/openldap/README.md b/roles/openldap/README.md deleted file mode 100644 index 4d55226..0000000 --- a/roles/openldap/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# OpenLDAP - -To run docker-compose up you have to adapt `.env` - -## Usage - -Set the following environment variables: - -```sh -PASSWORD= -DOMAIN= -DASHBOARD_PASSWORD= -NAME= -BASE_DN= -``` - -And then run - -```sh -docker-compose up -d -``` diff --git a/roles/openldap/defaults/main.yml b/roles/openldap/defaults/main.yml new file mode 100644 index 0000000..9e4bb18 --- /dev/null +++ b/roles/openldap/defaults/main.yml @@ -0,0 +1,5 @@ +--- + +openldap_docker_path: "/srv/docker/openldap" + +# code: language=ansible diff --git a/roles/openldap/docker-compose.yaml b/roles/openldap/docker-compose.yaml deleted file mode 100644 index 2bc94ba..0000000 --- a/roles/openldap/docker-compose.yaml +++ /dev/null @@ -1,59 +0,0 @@ -version: '3.3' -services: - openldap: - image: osixia/openldap:latest - container_name: "openldap" - restart: unless-stopped - environment: - - LDAP_BASE_DN=${BASE_DN} - - LDAP_ORGANISATION=${NAME} - - LDAP_DOMAIN=${DOMAIN} - - LDAP_ADMIN_PASSWORD=${PASSWORD} - - LDAP_REPLICATION=false - - LDAP_READONLY_USER=false - - LDAP_TLS_VERIFY_CLIENT=never - - LDAP_RFC2307BIS_SCHEMA=true - - LDAP_REMOVE_CONFIG_AFTER_SETUP=true - volumes: - - ./openldap_data:/var/lib/ldap - - ./slapd_data:/etc/ldap/slapd.d - networks: - - proxy - - ldapmanager: - image: wheelybird/ldap-user-manager:latest - restart: unless-stopped - environment: - LDAP_REQUIRE_STARTTLS: "false" - LDAP_TLS_VERIFY_CLIENT: never - LDAP_URI: "ldaps://openldap" - LDAP_BASE_DN: "${BASE_DN}" - LDAP_ADMINS_GROUP: "admins" - LDAP_ADMIN_BIND_PWD: "${PASSWORD}" - LDAP_ADMIN_BIND_DN: "cn=admin,${BASE_DN}" - SITE_NAME: "Machmeier-IT" - SERVER_HOSTNAME: "https://ldap.${DOMAIN}" - NO_HTTPS: "true" - - SMTP_HOSTNAME: "smtp.office365.com" - SMTP_HOST_PORT: "587" - SMTP_USERNAME: "" - SMTP_PASSWORD: "" - SMTP_USE_TLS: "true" - EMAIL_FROM_ADDRESS: "" - EMAIL_FROM_NAME: "" - - labels: - - "traefik.enable=true" - - "traefik.http.routers.ldapmanager.rule=Host(`ldap.${DOMAIN}`)" - - "traefik.http.routers.ldapmanager.entrypoints=websecure" - - "traefik.http.routers.ldapmanager.tls.certresolver=mytlschallenge" - - "traefik.http.services.ldapmanager.loadbalancer.server.port=80" - - "traefik.http.routers.ldapmanager.middlewares=ldapmanager-auth" - - "traefik.http.middlewares.ldapmanager-auth.basicauth.users=admin:{SHA}${DASHBOARD_PASSWORD}" - networks: - - proxy - -networks: - proxy: - external: true diff --git a/roles/openldap/tasks/main.yml b/roles/openldap/tasks/main.yml new file mode 100644 index 0000000..ecfe3cb --- /dev/null +++ b/roles/openldap/tasks/main.yml @@ -0,0 +1,59 @@ +--- + +- name: Create OpenLDAP container + community.docker.docker_container: + name: openldap + image: "osixia/openldap:latest" + restart_policy: "unless-stopped" + env: + LDAP_BASE_DN: "{{ openldap_base_dn }}" + LDAP_ORGANISATION: "Machmeier-IT" + LDAP_DOMAIN: "{{ openldap_domain }}" + LDAP_ADMIN_PASSWORD: "{{ openldap_password }}" + LDAP_REPLICATION: false + LDAP_READONLY_USER: false + LDAP_TLS_VERIFY_CLIENT: never + LDAP_RFC2307BIS_SCHEMA: true + LDAP_REMOVE_CONFIG_AFTER_SETUP: true + volumes: + - "{{ openldap_docker_path }}/openldap_data:/var/lib/ldap" + - "{{ openldap_docker_path }}/slapd_data:/etc/ldap/slapd.d" + networks: + - name: proxy + +- name: Create OpenLDAP Manager container + community.docker.docker_container: + name: openldap-manager + image: wheelybird/ldap-user-manager:latest + restart_policy: "unless-stopped" + env: + LDAP_REQUIRE_STARTTLS: "false" + LDAP_TLS_VERIFY_CLIENT: never + LDAP_URI: "ldaps://{{ openldap_hostname }}" + LDAP_BASE_DN: "{{ openldap_base_dn }}" + LDAP_ADMINS_GROUP: "admins" + LDAP_ADMIN_BIND_PWD: "{{ openldap_password }}" + LDAP_ADMIN_BIND_DN: "cn=admin,{{ openldap_base_dn }}" + SITE_NAME: "Machmeier-IT" + SERVER_HOSTNAME: "https://{{ openldap_domain }}" + NO_HTTPS: "true" + + SMTP_HOSTNAME: "{{ gitlab_smtp_address }}" + SMTP_HOST_PORT: "{{ gitlab_smtp_port }}" + SMTP_USERNAME: "{{ gitlab_smtp_mail }}" + SMTP_PASSWORD: "{{ gitlab_smtp_password }}" + SMTP_USE_TLS: "true" + EMAIL_FROM_ADDRESS: "{{ gitlab_smtp_mail }}" + EMAIL_FROM_NAME: "OpenLDAP Machmeier-IT" + labels: + traefik.enable: true" + traefik.http.routers.ldapmanager.rule: Host(`{{ openldap_domain }}`) + traefik.http.routers.ldapmanager.entrypoints: websecure + traefik.http.routers.ldapmanager.tls.certresolver: mytlschallenge + traefik.http.services.ldapmanager.loadbalancer.server.port: 80 + traefik.http.routers.ldapmanager.middlewares: ldapmanager-auth + traefik.http.middlewares.ldapmanager-auth.basicauth.users: admin:{SHA}${DASHBOARD_PASSWORD} + networks: + - name: proxy + +# code: language=ansible From 6924b3cfc978083ca7f6e0dc7fcb5668e85763d9 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Thu, 25 Jan 2024 14:56:38 +0100 Subject: [PATCH 06/25] Add traefik --- roles/gitlab/.env | 5 - roles/gitlab/LICENSE | 190 +++++++++++++++++++ roles/gitlab/defaults/main.yml | 4 + roles/gitlab/docker-compose.yaml | 94 --------- roles/gitlab/tasks/install_gitlab_runner.yml | 13 ++ roles/gitlab/tasks/main.yml | 102 ++++++++++ roles/openldap/tasks/main.yml | 2 +- roles/traefik/.env | 2 - roles/traefik/LICENSE | 190 +++++++++++++++++++ roles/traefik/defaults/main.yml | 5 + roles/traefik/docker-compose.yaml | 60 ------ roles/traefik/letsencrypt/acme.json | 0 roles/traefik/tasks/main.yml | 58 ++++++ 13 files changed, 563 insertions(+), 162 deletions(-) delete mode 100644 roles/gitlab/.env create mode 100644 roles/gitlab/LICENSE create mode 100644 roles/gitlab/defaults/main.yml delete mode 100644 roles/gitlab/docker-compose.yaml create mode 100644 roles/gitlab/tasks/install_gitlab_runner.yml create mode 100644 roles/gitlab/tasks/main.yml delete mode 100644 roles/traefik/.env create mode 100644 roles/traefik/LICENSE create mode 100644 roles/traefik/defaults/main.yml delete mode 100644 roles/traefik/docker-compose.yaml delete mode 100644 roles/traefik/letsencrypt/acme.json create mode 100644 roles/traefik/tasks/main.yml diff --git a/roles/gitlab/.env b/roles/gitlab/.env deleted file mode 100644 index d0ed40c..0000000 --- a/roles/gitlab/.env +++ /dev/null @@ -1,5 +0,0 @@ -DOMAIN= -SMTP_MAIL= -SMTP_PASSWORD= -LDAP_PASSWORD= -BASE_DN= \ No newline at end of file diff --git a/roles/gitlab/LICENSE b/roles/gitlab/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/gitlab/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/gitlab/defaults/main.yml b/roles/gitlab/defaults/main.yml new file mode 100644 index 0000000..f167c85 --- /dev/null +++ b/roles/gitlab/defaults/main.yml @@ -0,0 +1,4 @@ +--- +gitlab_docker_path: "/srv/docker/gitlab" + +# code: language=ansible diff --git a/roles/gitlab/docker-compose.yaml b/roles/gitlab/docker-compose.yaml deleted file mode 100644 index df283d4..0000000 --- a/roles/gitlab/docker-compose.yaml +++ /dev/null @@ -1,94 +0,0 @@ -version: "3.3" - -services: - gitlab: - image: "gitlab/gitlab-ce:latest" - container_name: "gitlab" - restart: unless-stopped - ports: - - "30022:22" - environment: - GITLAB_SHELL_SSH_PORT: 30022 - GITLAB_OMNIBUS_CONFIG: | - external_url 'https://git.${DOMAIN}' - nginx['listen_https'] = false - nginx['listen_port'] = 80 - nginx['proxy_set_headers'] = { - 'X-Forwarded-Proto' => 'https', - 'X-Forwarded-Ssl' => 'on' - } - - gitlab_rails['backup_upload_remote_directory'] = 's3-backup-bucket' - gitlab_rails['gitlab_shell_ssh_port'] = 22 - - gitlab_rails['smtp_enable'] = true - gitlab_rails['smtp_address'] = "smtp.office365.com" - gitlab_rails['smtp_port'] = 587 - gitlab_rails['smtp_user_name'] = "${SMTP_MAIL}" - gitlab_rails['smtp_password'] = "${SMTP_PASSWORD}" - gitlab_rails['smtp_domain'] = "outlook.com" - gitlab_rails['gitlab_email_from'] = "${SMTP_MAIL}" - gitlab_rails['gitlab_email_reply_to'] = "noreply@smachmeier.de" - gitlab_rails['smtp_authentication'] = "login" - gitlab_rails['smtp_enable_starttls_auto'] = true - gitlab_rails['smtp_openssl_verify_mode'] = "peer" - - gitlab_rails['ldap_enabled'] = true - gitlab_rails['ldap_servers'] = { - 'main' => { - 'label' => 'OpenLDAP', - 'host' => 'openldap', - 'port' => 389, - 'uid' => 'uid', - 'encryption' => 'plain', - 'verify_certificates' => false, - 'bind_dn' => 'cn=admin,${BASE_DN}', - 'password' => '${LDAP_PASSWORD}', - 'active_directory' => false, - 'base' => '${BASE_DN}', - 'group_base' => 'ou=groups,${BASE_DN}', - 'admin_group' => 'admins', - 'attributes' => { 'username' => ['uid'], 'email' => ['mail', 'email'] }, - } - } - - volumes: - - "./config:/etc/gitlab:Z" - - "./logs:/var/log/gitlab:Z" - - "./data:/var/opt/gitlab:Z" - - "/etc/localtime:/etc/localtime:ro" - hostname: git.${DOMAIN} - labels: - - "traefik.enable=true" - - "traefik.http.routers.gitlab.rule=Host(`git.${DOMAIN}`)" - - "traefik.http.routers.gitlab.entrypoints=websecure" - - "traefik.http.routers.gitlab.tls.certresolver=mytlschallenge" - - "traefik.http.routers.gitlab.middlewares=gitlab-headers" - - "traefik.http.routers.gitlab.service=gitlab" - - - "traefik.http.middlewares.gitlab-headers.headers.customrequestheaders.X_FORWARDED_PROTO=https" - - "traefik.http.middlewares.gitlab-headers.headers.customrequestheaders.X_Forwarded-Ssl=on" - - "traefik.http.middlewares.gitlab-headers.headers.customresponseheaders.X_FORWARDED_PROTO=https" - - "traefik.http.middlewares.gitlab-headers.headers.customresponseheaders.X_Forwarded-Ssl=on" - - "traefik.http.services.gitlab.loadbalancer.server.port=80" - - - "traefik.http.routers.gitlab-registry.rule=Host(`registry.${DOMAIN}`)" - - "traefik.http.routers.gitlab-registry.entrypoints=websecure" - - "traefik.http.routers.gitlab-registry.tls.certresolver=mytlschallenge" - - "traefik.http.routers.gitlab-registry.service=gitlab-registry" - - "traefik.http.services.gitlab-registry.loadbalancer.server.port=8500" - cap_add: - - SYS_ADMIN - networks: - - proxy - gitlab-runner: - image: "gitlab/gitlab-runner:latest" - container_name: "gitlab-runner" - volumes: - - "./gitlab-runner/config:/etc/gitlab-runner" - - "/var/run/docker.sock:/var/run/docker.sock" - restart: always -networks: - proxy: - external: true - diff --git a/roles/gitlab/tasks/install_gitlab_runner.yml b/roles/gitlab/tasks/install_gitlab_runner.yml new file mode 100644 index 0000000..f99a025 --- /dev/null +++ b/roles/gitlab/tasks/install_gitlab_runner.yml @@ -0,0 +1,13 @@ +--- +- name: Install GitLab Runner + community.docker.docker_container: + name: "gitlab_runner" + image: "gitlab/gitlab-runner:latest" + restart_policy: "unless-stopped" + networks: + - name: gitlab + volumes: + - "{{ gitlab_docker_path }}/gitlab-runner/config:/etc/gitlab-runner" + - "/var/run/docker.sock:/var/run/docker.sock" + +# code: language=ansible diff --git a/roles/gitlab/tasks/main.yml b/roles/gitlab/tasks/main.yml new file mode 100644 index 0000000..cb6328e --- /dev/null +++ b/roles/gitlab/tasks/main.yml @@ -0,0 +1,102 @@ +--- +- name: Create Docker Network for GitLab + community.docker.docker_network: + name: "gitlab" + ipam_config: + - subnet: 172.28.0.0/24 + +- name: Run GitLab Docker container + community.docker.docker_container: + image: "gitlab/gitlab-ce:latest" + name: "gitlab" + restart_policy: "unless-stopped" + recreate: true + ports: + - "{{ gitlab_shell_ssh_port }}:22" + networks: + - name: gitlab + - name: proxy + volumes: + - "{{ gitlab_docker_path }}/config:/etc/gitlab:Z" + - "{{ gitlab_docker_path }}/logs:/var/log/gitlab:Z" + - "{{ gitlab_docker_path }}/data:/var/opt/gitlab:Z" + - "/etc/localtime:/etc/localtime:ro" + hostname: "{{ gitlab_domain }}" + labels: + traefik.enable: "true" + traefik.http.routers.gitlab.rule: "Host(`{{ gitlab_domain }}`)" + traefik.http.routers.gitlab.entrypoints: "websecure" + traefik.http.routers.gitlab.tls.certresolver: "mytlschallenge" + traefik.http.routers.gitlab.middlewares: "gitlab-headers" + traefik.http.routers.gitlab.service: "gitlab" + + traefik.http.middlewares.gitlab-headers.headers.customrequestheaders.X_FORWARDED_PROTO: "https" + traefik.http.middlewares.gitlab-headers.headers.customrequestheaders.X_Forwarded-Ssl: "on" + traefik.http.middlewares.gitlab-headers.headers.customresponseheaders.X_FORWARDED_PROTO: "https" + traefik.http.middlewares.gitlab-headers.headers.customresponseheaders.X_Forwarded-Ssl: "on" + traefik.http.services.gitlab.loadbalancer.server.port: "80" + + traefik.http.routers.gitlab-registry.rule: "Host(`{{ gitlab_registry_domain }}`)" + traefik.http.routers.gitlab-registry.entrypoints: "websecure" + traefik.http.routers.gitlab-registry.tls.certresolver: "mytlschallenge" + traefik.http.routers.gitlab-registry.service: "gitlab-registry" + traefik.http.services.gitlab-registry.loadbalancer.server.port: "8500" + capabilities: + - SYS_ADMIN + env: + GITLAB_SHELL_SSH_PORT: "30022" + GITLAB_OMNIBUS_CONFIG: > + external_url 'https://{{ gitlab_domain }}' + nginx['listen_https'] = false + nginx['listen_port'] = 80 + nginx['proxy_set_headers'] = { + 'X-Forwarded-Proto' => 'https', + 'X-Forwarded-Ssl' => 'on' + } + + gitlab_rails['backup_upload_remote_directory'] = 's3-backup-bucket' + gitlab_rails['gitlab_shell_ssh_port'] = 22 + + gitlab_rails['smtp_enable'] = true + gitlab_rails['smtp_address'] = "{{ gitlab_smtp_address }}" + gitlab_rails['smtp_port'] = {{ gitlab_smtp_port }} + gitlab_rails['smtp_user_name'] = "{{ gitlab_smtp_mail }}" + gitlab_rails['smtp_password'] = "{{ gitlab_smtp_password}}" + gitlab_rails['smtp_domain'] = "{{ gitlab_smtp_domain }}" + gitlab_rails['gitlab_email_from'] = "{{ gitlab_smtp_mail_from }}" + gitlab_rails['gitlab_email_reply_to'] = "{{ gitlab_smtp_mail_to }}" + gitlab_rails['smtp_authentication'] = "login" + gitlab_rails['smtp_enable_starttls_auto'] = true + gitlab_rails['smtp_openssl_verify_mode'] = "peer" + + gitlab_rails['ldap_enabled'] = true + gitlab_rails['ldap_servers'] = { + 'main' => { + 'label' => 'OpenLDAP', + 'host' => '{{ openldap_hostname }}', + 'port' => {{ openldap_port }}, + 'uid' => 'uid', + 'encryption' => 'plain', + 'verify_certificates' => false, + 'bind_dn' => 'cn=admin,{{ openldap_base_dn }}', + 'password' => '{{ openldap_password }}', + 'active_directory' => false, + 'base' => '{{ openldap_base_dn }}', + 'group_base' => 'ou=groups,{{ openldap_base_dn }}', + 'admin_group' => 'admins', + 'attributes' => { 'username' => ['uid'], 'email' => ['mail', 'email'] }, + } + } + +# - name: Run Gitlab reconfigure to assure correct file permissions +# community.docker.docker_container_exec: +# container: "gitlab" +# command: gitlab-ctl reconfigure +# changed_when: false + +- name: Install Gitlab Runner + when: gitlab_runner_enabled + ansible.builtin.include_tasks: + file: "install_gitlab_runner.yml" + +# code: language=ansible diff --git a/roles/openldap/tasks/main.yml b/roles/openldap/tasks/main.yml index ecfe3cb..83f9f0d 100644 --- a/roles/openldap/tasks/main.yml +++ b/roles/openldap/tasks/main.yml @@ -52,7 +52,7 @@ traefik.http.routers.ldapmanager.tls.certresolver: mytlschallenge traefik.http.services.ldapmanager.loadbalancer.server.port: 80 traefik.http.routers.ldapmanager.middlewares: ldapmanager-auth - traefik.http.middlewares.ldapmanager-auth.basicauth.users: admin:{SHA}${DASHBOARD_PASSWORD} + traefik.http.middlewares.ldapmanager-auth.basicauth.users: admin:{SHA}${{ traefik_dashboard_password }} networks: - name: proxy diff --git a/roles/traefik/.env b/roles/traefik/.env deleted file mode 100644 index 36236be..0000000 --- a/roles/traefik/.env +++ /dev/null @@ -1,2 +0,0 @@ -DOMAIN= -DASHBOARD_PASSWORD= \ No newline at end of file diff --git a/roles/traefik/LICENSE b/roles/traefik/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/traefik/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/traefik/defaults/main.yml b/roles/traefik/defaults/main.yml new file mode 100644 index 0000000..52771a4 --- /dev/null +++ b/roles/traefik/defaults/main.yml @@ -0,0 +1,5 @@ +--- + +traefik_docker_path: "/srv/docker/traefik" + +# code: language=ansible diff --git a/roles/traefik/docker-compose.yaml b/roles/traefik/docker-compose.yaml deleted file mode 100644 index d97d832..0000000 --- a/roles/traefik/docker-compose.yaml +++ /dev/null @@ -1,60 +0,0 @@ -version: '3.3' - -services: - reverse-proxy: - # The official v2.0 Traefik docker image - image: traefik:latest - container_name: "traefik" - restart: always - # Enables the web UI and tells Traefik to listen to docker - command: - - "--api=true" - - "--accesslog=true" - - "--api.dashboard=true" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - - "--entrypoints.websecure.address=:443" - - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true" - - "--certificatesresolvers.mytlschallenge.acme.email=YOUR_EMAIL" - - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json" - - "--certificatesresolvers.mytlschallenge.acme.keytype=EC384" - - "--certificatesresolvers.mytlschallenge.acme.preferredchain='ISRG Root X1'" - ports: - # The HTTP port - - "80:80" - # The Web UI (enabled by --api.insecure=true) - - "443:443" - volumes: - - "./letsencrypt:/letsencrypt" - - "/var/run/docker.sock:/var/run/docker.sock:ro" - labels: - - "traefik.enable=true" - # Dashboard - - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" - - "traefik.http.routers.traefik.service=api@internal" - - "traefik.http.routers.traefik.tls.certresolver=mytlschallenge" - - "traefik.http.routers.traefik.entrypoints=websecure" - - "traefik.http.routers.traefik.middlewares=dashboardauth" - - "traefik.http.middlewares.dashboardauth.basicauth.users=admin:{SHA}${DASHBOARD_PASSWORD}" - - # Global redirection: http to https - - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:(www.)?.+}`)" - - "traefik.http.routers.http-catchall.entrypoints=web" - - "traefik.http.routers.http-catchall.middlewares=wwwtohttps" - - # Global redirection: https (www.) to https - - "traefik.http.routers.wwwsecure-catchall.rule=HostRegexp(`{host:(www.).+}`)" - - "traefik.http.routers.wwwsecure-catchall.entrypoints=websecure" - - "traefik.http.routers.wwwsecure-catchall.tls=true" - - "traefik.http.routers.wwwsecure-catchall.middlewares=wwwtohttps" - - # middleware: http(s)://(www.) to https:// - - "traefik.http.middlewares.wwwtohttps.redirectregex.regex=^https?://(?:www.)?(.+)" - - "traefik.http.middlewares.wwwtohttps.redirectregex.replacement=https://$${1}" - - "traefik.http.middlewares.wwwtohttps.redirectregex.permanent=true" - networks: - - proxy -networks: - proxy: - external: true \ No newline at end of file diff --git a/roles/traefik/letsencrypt/acme.json b/roles/traefik/letsencrypt/acme.json deleted file mode 100644 index e69de29..0000000 diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml new file mode 100644 index 0000000..f2290ae --- /dev/null +++ b/roles/traefik/tasks/main.yml @@ -0,0 +1,58 @@ +--- +- name: Start Traefik + community.docker.docker_container: + name: traefik + hostname: traefik + image: "traefik/latest" + command: + - "--api=true" + - "--accesslog=true" + - "--pilot.token=be0ef0ec-7558-40a6-bb46-0297f6d402fa" + - "--accesslog.filepath=/var/log/traefik/traefik.log" + - "--api.dashboard=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true" + - "--certificatesresolvers.mytlschallenge.acme.email=YOUR_EMAIL" + - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.mytlschallenge.acme.keytype=EC384" + - "--certificatesresolvers.mytlschallenge.acme.preferredchain='ISRG Root X1'" + ports: + # The HTTP port + - "80:80" + # The Web UI (enabled by --api.insecure=true) + - "443:443" + volumes: + - "{{ traefik_docker_path }}/letsencrypt:/letsencrypt" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + labels: + - traefik.enable: true + # Dashboard + - traefik.http.routers.traefik.rule: Host(`{{ traefik_domain }}`) + - traefik.http.routers.traefik.service: api@internal + - traefik.http.routers.traefik.tls.certresolver: mytlschallenge + - traefik.http.routers.traefik.entrypoints: websecure + - traefik.http.routers.traefik.middlewares: dashboardauth + - traefik.http.middlewares.dashboardauth.basicauth.users: admin:{SHA}${{ traefik_dashboard_password }} + + # Global redirection: http to https + - traefik.http.routers.http-catchall.rule: HostRegexp(`{host:(www.)?.+}`) + - traefik.http.routers.http-catchall.entrypoints: web + - traefik.http.routers.http-catchall.middlewares: wwwtohttps + + # Global redirection: https (www.) to https + - traefik.http.routers.wwwsecure-catchall.rule: HostRegexp(`{host:(www.).+}`) + - traefik.http.routers.wwwsecure-catchall.entrypoints: websecure + - traefik.http.routers.wwwsecure-catchall.tls: true + - traefik.http.routers.wwwsecure-catchall.middlewares: wwwtohttps + + # middleware: http(s)://(www.) to https:// + - traefik.http.middlewares.wwwtohttps.redirectregex.regex: ^https?://(?:www.)?(.+) + - traefik.http.middlewares.wwwtohttps.redirectregex.replacement: https://$${1} + - traefik.http.middlewares.wwwtohttps.redirectregex.permanent: true + networks: + - name: proxy + +# code: language=ansible From b9c38769154bda0621dbc7618dbc509b8b6d665a Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 07:05:05 +0100 Subject: [PATCH 07/25] Update gitlab config --- roles/gitlab/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/gitlab/tasks/main.yml b/roles/gitlab/tasks/main.yml index cb6328e..059958e 100644 --- a/roles/gitlab/tasks/main.yml +++ b/roles/gitlab/tasks/main.yml @@ -45,7 +45,7 @@ - SYS_ADMIN env: GITLAB_SHELL_SSH_PORT: "30022" - GITLAB_OMNIBUS_CONFIG: > + GITLAB_OMNIBUS_CONFIG: |- external_url 'https://{{ gitlab_domain }}' nginx['listen_https'] = false nginx['listen_port'] = 80 From 0879bb398c8ef2b9eb4f385d5bcc770838878155 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 10:46:03 +0100 Subject: [PATCH 08/25] Add homer --- roles/crowdsec/tasks/main.yml | 4 +- roles/gitlab/defaults/main.yml | 1 + roles/homer/.env | 2 - roles/homer/LICENSE | 190 ++++++++++++++++++++++++++++ roles/homer/README.md | 20 --- roles/homer/defaults/main.yml | 5 + roles/homer/docker-compose.yaml | 24 ---- roles/homer/tasks/main.yml | 34 +++++ roles/homer/templates/config.yml.j2 | 86 +++++++++++++ 9 files changed, 318 insertions(+), 48 deletions(-) delete mode 100644 roles/homer/.env create mode 100644 roles/homer/LICENSE delete mode 100644 roles/homer/README.md create mode 100644 roles/homer/defaults/main.yml delete mode 100644 roles/homer/docker-compose.yaml create mode 100644 roles/homer/tasks/main.yml create mode 100644 roles/homer/templates/config.yml.j2 diff --git a/roles/crowdsec/tasks/main.yml b/roles/crowdsec/tasks/main.yml index 6e39eba..03d81f8 100644 --- a/roles/crowdsec/tasks/main.yml +++ b/roles/crowdsec/tasks/main.yml @@ -32,8 +32,8 @@ image: crowdsecurity/crowdsec:{{ crowdsec.version }} pull: true name: crowdsec - recreate: true - restart_policy: unless-stopped + healthcheck: + test: ["CMD", "cscli", "version"] ports: - 127.0.0.1:{{ crowdsec_lapi_port }}:8080 - 6060:6060 diff --git a/roles/gitlab/defaults/main.yml b/roles/gitlab/defaults/main.yml index f167c85..27387b1 100644 --- a/roles/gitlab/defaults/main.yml +++ b/roles/gitlab/defaults/main.yml @@ -1,4 +1,5 @@ --- + gitlab_docker_path: "/srv/docker/gitlab" # code: language=ansible diff --git a/roles/homer/.env b/roles/homer/.env deleted file mode 100644 index 36236be..0000000 --- a/roles/homer/.env +++ /dev/null @@ -1,2 +0,0 @@ -DOMAIN= -DASHBOARD_PASSWORD= \ No newline at end of file diff --git a/roles/homer/LICENSE b/roles/homer/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/homer/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/homer/README.md b/roles/homer/README.md deleted file mode 100644 index 94faa43..0000000 --- a/roles/homer/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Homer - -> A simple static Homepage for quick access to our applications. For further information, please check out [Homer](https://github.com/bastienwirtz/homer) - -## Usage - -Set the following environment variables: - -```env -DOMAIN= -DASHBOARD_PASSWORD= -``` - -(Traefik takes care for the authentication, in my case I just reused the password of Traefik Dashboard) - -And then run - -```sh -docker-compose up -d -``` diff --git a/roles/homer/defaults/main.yml b/roles/homer/defaults/main.yml new file mode 100644 index 0000000..3e5aa1d --- /dev/null +++ b/roles/homer/defaults/main.yml @@ -0,0 +1,5 @@ +--- + +homer_docker_path: "/srv/docker/homer" + +# code: language=ansible diff --git a/roles/homer/docker-compose.yaml b/roles/homer/docker-compose.yaml deleted file mode 100644 index 81f0ddd..0000000 --- a/roles/homer/docker-compose.yaml +++ /dev/null @@ -1,24 +0,0 @@ -version: '3.3' -services: - homer: - image: b4bz/homer - container_name: homer - volumes: - - ./data:/www/assets - labels: - - "traefik.enable=true" - - "traefik.http.routers.homer.rule=Host(`${DOMAIN}`)" - - "traefik.http.routers.homer.entrypoints=websecure" - - "traefik.http.routers.homer.tls.certresolver=mytlschallenge" - - "traefik.http.services.homer.loadbalancer.server.port=8080" - - "traefik.http.routers.homer.middlewares=homer-auth" - - "traefik.http.middlewares.homer-auth.basicauth.users=admin:{SHA}${DASHBOARD_PASSWORD}" - environment: - - UID=1000 - - GID=1000 - restart: unless-stopped - networks: - - proxy -networks: - proxy: - external: true diff --git a/roles/homer/tasks/main.yml b/roles/homer/tasks/main.yml new file mode 100644 index 0000000..7118433 --- /dev/null +++ b/roles/homer/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: Create folder for homer + ansible.builtin.file: + path: "{{ homer_docker_path }}" + state: directory + mode: 700 + +- name: Set homer config + ansible.builtin.template: + src: config.yml.j2 + dest: "{{ homer_docker_path }}/config.yml" + +- name: Install homer Docker Container + community.docker.docker_container: + name: "homer" + hostname: "homer" + image: b4bz/homer + volumes: + - "{{ homer_docker_path }}:/www/assets:ro" + labels: + - traefik.enable: true + - traefik.http.routers.homer.rule: Host(`{{ homer_domain }}`) + - traefik.http.routers.homer.entrypoints: websecure + - traefik.http.routers.homer.tls.certresolver: mytlschallenge + - traefik.http.services.homer.loadbalancer.server.port: 8080 + - traefik.http.routers.homer.middlewares: homer-auth + - traefik.http.middlewares.homer-auth.basicauth.users: admin:{SHA}{{ traefik_dashboard_password }} + env: + - UID: 1000 + - GID: 1000 + networks: + - name: "{{ traefik_network }}" + +# code: language=ansible diff --git a/roles/homer/templates/config.yml.j2 b/roles/homer/templates/config.yml.j2 new file mode 100644 index 0000000..88188b7 --- /dev/null +++ b/roles/homer/templates/config.yml.j2 @@ -0,0 +1,86 @@ +# Homepage configuration +# See https://fontawesome.com/icons for icons options + +title: "Dashboard" +subtitle: "Machmeier" + +header: true +footer: '

Created with ❤️ with bulma, vuejs & font awesome // Fork me on

' # set false if you want to hide it. + +# Optional theme customization +theme: default +colors: + light: + highlight-primary: "#ff6d3e" + highlight-secondary: "#4285f4" + highlight-hover: "#5a95f5" + background: "#f5f5f5" + card-background: "#ffffff" + text: "#363636" + text-header: "#ffffff" + text-title: "#303030" + text-subtitle: "#424242" + card-shadow: rgba(0, 0, 0, 0.1) + link-hover: "#363636" + dark: + highlight-primary: "#ff6d3e" + highlight-secondary: "#4285f4" + highlight-hover: "#5a95f5" + background: "#131313" + card-background: "#2b2b2b" + text: "#eaeaea" + text-header: "#ffffff" + text-title: "#fafafa" + text-subtitle: "#f5f5f5" + card-shadow: rgba(0, 0, 0, 0.4) + link-hover: "#ffdd57" + +# Optional message +message: + #url: https://b4bz.io + style: "is-dark" # See https://bulma.io/documentation/components/message/#colors for styling options. + title: "Tips & Tricks" + icon: "fa fa-grin" + content: "This is a quick link page to all runing applications.
" + +# Optional navbar +# links: [] # Allows for navbar (dark mode, layout, and search) without any links +links: + - name: "Contribute" + icon: "fab fa-github" + url: "https://github.com/stefanDeveloper" + target: "_blank" # optional html a tag target attribute + +# Services +# First level array represent a group. +# Leave only a "items" key if not using group (group name, icon & tagstyle are optional, section separation will not be displayed). +services: + - name: "Cloud" + icon: "fas fa-cloud" + items: + - name: "NextCloud" + subtitle: "Cloud like OneDrive, supports chats and video calls" + tag: "cloud" + url: "https://{{ nextcloud_domain }}" + target: "_blank" + - name: "Monitoring" + icon: "fas fa-server" + items: + - name: "GitLab" + subtitle: "Git repository with runner" + tag: "git" + url: "https://{{ gitlab_domain }}/" + target: "_blank" + - name: "Monitoring" + icon: "fas fa-cloud" + items: + - name: "Traefik" + subtitle: "Reverse proxy" + tag: "reverse-proxy" + url: "https://{{ traefik_domain }}/" + target: "_blank" + - name: "Wazuh" + subtitle: "Docker container maintaining and monitoring" + tag: "docker" + url: "https://{{ wazuh_domain }}/" + target: "_blank" From 3bcad3dfcb13c1da4f258f408197e5e290066e8f Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 10:46:16 +0100 Subject: [PATCH 09/25] Update traefik config --- roles/traefik/README.md | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/roles/traefik/README.md b/roles/traefik/README.md index 9c1d59c..85bd818 100644 --- a/roles/traefik/README.md +++ b/roles/traefik/README.md @@ -3,33 +3,3 @@ ## Prerequisite > Traefik is reverse proxy. It automically fetchs certificates from LetsEncrypt with EC384 encryption. This is just a default setting and can be adjusted anytime. - -To run docker-compose up you have to adapt `.env` and run - -```sh -sudo chmod 600 -R ./letsencrypt -``` - -and change the following strings inside the `docker-compose`: - -```yaml -# Change email -- "--certificatesresolvers.mytlschallenge.acme.email=YOUR_EMAIL" -``` - -(I wasn't able to resolve it with a `.env` file, please feel free to contribute) - -## Usage - -Set the following environment variables: - -```env -DOMAIN= -DASHBOARD_PASSWORD= -``` - -For the password you can use [htpasswd](https://hostingcanada.org/htpasswd-generator/). And then run - -```sh -docker-compose up -d -``` From 0254b3d6d4a2d5b5cd14d6b4f3a14107ba764203 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 10:46:34 +0100 Subject: [PATCH 10/25] Update watchtower --- roles/watchtower/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/watchtower/tasks/main.yml b/roles/watchtower/tasks/main.yml index 083ed62..7eed47a 100644 --- a/roles/watchtower/tasks/main.yml +++ b/roles/watchtower/tasks/main.yml @@ -4,7 +4,7 @@ community.docker.docker_container: name: watchtower image: "containrrr/watchtower" - restart_policy: "unless_stopped" + restart_policy: "unless-stopped" volumes: - "/var/run/docker.sock:/var/run/docker.sock" From 16b5751c7b3c03d729bd9f6808ef354cc554c7a5 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 10:51:23 +0100 Subject: [PATCH 11/25] Update homer --- roles/homer/tasks/main.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/roles/homer/tasks/main.yml b/roles/homer/tasks/main.yml index 7118433..d1e19b1 100644 --- a/roles/homer/tasks/main.yml +++ b/roles/homer/tasks/main.yml @@ -18,16 +18,16 @@ volumes: - "{{ homer_docker_path }}:/www/assets:ro" labels: - - traefik.enable: true - - traefik.http.routers.homer.rule: Host(`{{ homer_domain }}`) - - traefik.http.routers.homer.entrypoints: websecure - - traefik.http.routers.homer.tls.certresolver: mytlschallenge - - traefik.http.services.homer.loadbalancer.server.port: 8080 - - traefik.http.routers.homer.middlewares: homer-auth - - traefik.http.middlewares.homer-auth.basicauth.users: admin:{SHA}{{ traefik_dashboard_password }} - env: - - UID: 1000 - - GID: 1000 + traefik.enable: "true" + traefik.http.routers.homer.rule: "Host(`{{ homer_domain }}`)" + traefik.http.routers.homer.entrypoints: "websecure" + traefik.http.routers.homer.tls.certresolver: "mytlschallenge" + traefik.http.services.homer.loadbalancer.server.port: "8080" + traefik.http.routers.homer.middlewares: "homer-auth" + traefik.http.middlewares.homer-auth.basicauth.users: "admin:{SHA}{{ traefik_dashboard_password }}" + # env: + # UID: "1000" + # GID: "1000" networks: - name: "{{ traefik_network }}" From 9c2aac31f558a7e2eb01ce2ae5acd038215c0a23 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 11:04:53 +0100 Subject: [PATCH 12/25] Fix homer --- roles/homer/tasks/main.yml | 17 ++++++++++++----- roles/homer/templates/config.yml.j2 | 3 --- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/roles/homer/tasks/main.yml b/roles/homer/tasks/main.yml index d1e19b1..4b22448 100644 --- a/roles/homer/tasks/main.yml +++ b/roles/homer/tasks/main.yml @@ -3,20 +3,26 @@ ansible.builtin.file: path: "{{ homer_docker_path }}" state: directory - mode: 700 + mode: 0700 + owner: stefan + group: stefan - name: Set homer config ansible.builtin.template: src: config.yml.j2 dest: "{{ homer_docker_path }}/config.yml" + mode: 0700 + owner: stefan + group: stefan - name: Install homer Docker Container community.docker.docker_container: name: "homer" hostname: "homer" image: b4bz/homer + restart_policy: unless-stopped volumes: - - "{{ homer_docker_path }}:/www/assets:ro" + - "{{ homer_docker_path }}/config.yml:/www/assets/config.yml:ro" labels: traefik.enable: "true" traefik.http.routers.homer.rule: "Host(`{{ homer_domain }}`)" @@ -25,9 +31,10 @@ traefik.http.services.homer.loadbalancer.server.port: "8080" traefik.http.routers.homer.middlewares: "homer-auth" traefik.http.middlewares.homer-auth.basicauth.users: "admin:{SHA}{{ traefik_dashboard_password }}" - # env: - # UID: "1000" - # GID: "1000" + env: + UID: "1000" + GID: "1000" + INIT_ASSETS: "1" networks: - name: "{{ traefik_network }}" diff --git a/roles/homer/templates/config.yml.j2 b/roles/homer/templates/config.yml.j2 index 88188b7..59bd5b5 100644 --- a/roles/homer/templates/config.yml.j2 +++ b/roles/homer/templates/config.yml.j2 @@ -44,7 +44,6 @@ message: content: "This is a quick link page to all runing applications.
" # Optional navbar -# links: [] # Allows for navbar (dark mode, layout, and search) without any links links: - name: "Contribute" icon: "fab fa-github" @@ -52,8 +51,6 @@ links: target: "_blank" # optional html a tag target attribute # Services -# First level array represent a group. -# Leave only a "items" key if not using group (group name, icon & tagstyle are optional, section separation will not be displayed). services: - name: "Cloud" icon: "fas fa-cloud" From c293d7c517fa18352325682d9c246ae56316a9ac Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 15:55:44 +0100 Subject: [PATCH 13/25] Update docker compose --- roles/gitlab/tasks/install_gitlab_runner.yml | 2 +- roles/gitlab/tasks/main.yml | 6 +- roles/nextcloud/.env | 4 - roles/nextcloud/LICENSE | 190 +++++++++++++++++++ roles/nextcloud/README.md | 10 - roles/nextcloud/coturn/README.md | 5 - roles/nextcloud/coturn/docker-compose.yaml | 20 -- roles/nextcloud/coturn/turnserver.conf | 9 - roles/nextcloud/defaults/main.yml | 8 + roles/nextcloud/docker-compose.yaml | 79 -------- roles/nextcloud/tasks/main.yml | 90 +++++++++ roles/openldap/tasks/main.yml | 48 +++-- roles/traefik/tasks/main.yml | 9 +- 13 files changed, 331 insertions(+), 149 deletions(-) delete mode 100644 roles/nextcloud/.env create mode 100644 roles/nextcloud/LICENSE delete mode 100644 roles/nextcloud/coturn/README.md delete mode 100644 roles/nextcloud/coturn/docker-compose.yaml delete mode 100644 roles/nextcloud/coturn/turnserver.conf create mode 100644 roles/nextcloud/defaults/main.yml delete mode 100644 roles/nextcloud/docker-compose.yaml create mode 100644 roles/nextcloud/tasks/main.yml diff --git a/roles/gitlab/tasks/install_gitlab_runner.yml b/roles/gitlab/tasks/install_gitlab_runner.yml index f99a025..3c5ca67 100644 --- a/roles/gitlab/tasks/install_gitlab_runner.yml +++ b/roles/gitlab/tasks/install_gitlab_runner.yml @@ -5,7 +5,7 @@ image: "gitlab/gitlab-runner:latest" restart_policy: "unless-stopped" networks: - - name: gitlab + - name: proxy volumes: - "{{ gitlab_docker_path }}/gitlab-runner/config:/etc/gitlab-runner" - "/var/run/docker.sock:/var/run/docker.sock" diff --git a/roles/gitlab/tasks/main.yml b/roles/gitlab/tasks/main.yml index 059958e..f77fd44 100644 --- a/roles/gitlab/tasks/main.yml +++ b/roles/gitlab/tasks/main.yml @@ -2,6 +2,8 @@ - name: Create Docker Network for GitLab community.docker.docker_network: name: "gitlab" + driver: bridge + ipam_driver: default ipam_config: - subnet: 172.28.0.0/24 @@ -10,11 +12,11 @@ image: "gitlab/gitlab-ce:latest" name: "gitlab" restart_policy: "unless-stopped" - recreate: true ports: - "{{ gitlab_shell_ssh_port }}:22" networks: - - name: gitlab + # - name: gitlab + # - name: openldap - name: proxy volumes: - "{{ gitlab_docker_path }}/config:/etc/gitlab:Z" diff --git a/roles/nextcloud/.env b/roles/nextcloud/.env deleted file mode 100644 index 35c3f04..0000000 --- a/roles/nextcloud/.env +++ /dev/null @@ -1,4 +0,0 @@ -POSTGRES_PW= -REDIS_PW= -POSTGRES_PW= -DOMAIN= \ No newline at end of file diff --git a/roles/nextcloud/LICENSE b/roles/nextcloud/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/nextcloud/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/nextcloud/README.md b/roles/nextcloud/README.md index f9f1285..4a833d7 100644 --- a/roles/nextcloud/README.md +++ b/roles/nextcloud/README.md @@ -37,13 +37,3 @@ tar -czvg PATH_TO_YOUR_NEXTCLOUD/snapshot.file -f PATH_TO_YOUR_NEXTCLOUD/nextclo # Set maintenance mode off docker exec --user www-data nextcloud_nextcloud_1 php occ maintenance:mode --off ``` - -### Run Cron - -```sh -docker exec -u www-data CONTAINER_NAME php cron.php -``` - -## CoTURN - -Helps to integrate Nextcloud Talks, however, this part is still under investigation. Go to our CoTURN[documentation](./coturn/README.md) to get the latest information. diff --git a/roles/nextcloud/coturn/README.md b/roles/nextcloud/coturn/README.md deleted file mode 100644 index 23ed53d..0000000 --- a/roles/nextcloud/coturn/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# CoTURN - -> Further information check out the official [documentation](https://nextcloud-talk.readthedocs.io/en/latest/TURN/) - -Adapt `.env` file before running container. diff --git a/roles/nextcloud/coturn/docker-compose.yaml b/roles/nextcloud/coturn/docker-compose.yaml deleted file mode 100644 index b6f706f..0000000 --- a/roles/nextcloud/coturn/docker-compose.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '3.3' -services: - homer: - image: instrumentisto/coturn - container_name: coturn - labels: - - "--log-file=stdout" - - "--min-port=49160" - - "--max-port=49200" - restart: unless-stopped - volumes: - - "./turnserver.conf:/etc/coturn/turnserver.conf" - ports: - - 3478:3478 - - 49160-49200:49160-49200 - networks: - - proxy -networks: - proxy: - external: true diff --git a/roles/nextcloud/coturn/turnserver.conf b/roles/nextcloud/coturn/turnserver.conf deleted file mode 100644 index 7b45191..0000000 --- a/roles/nextcloud/coturn/turnserver.conf +++ /dev/null @@ -1,9 +0,0 @@ -listening-port=3478 -fingerprint=1 -use-auth-secret=1 -static-auth-secret= -realm=DOMAIN -total-quota=0 -bps-capacity=0 -stale-nonce=1 -no-multicast-peers=1 diff --git a/roles/nextcloud/defaults/main.yml b/roles/nextcloud/defaults/main.yml new file mode 100644 index 0000000..3f497ac --- /dev/null +++ b/roles/nextcloud/defaults/main.yml @@ -0,0 +1,8 @@ +--- + +nextcloud_docker_path: "/srv/docker/nextcloud" + +nextcloud_postgres_username: nextcloud +nextcloud_postgres_db: nextcloud + +# code: language=ansible diff --git a/roles/nextcloud/docker-compose.yaml b/roles/nextcloud/docker-compose.yaml deleted file mode 100644 index 4df46fe..0000000 --- a/roles/nextcloud/docker-compose.yaml +++ /dev/null @@ -1,79 +0,0 @@ -version: '3.3' -services: - db: - restart: always - image: postgres:13 - container_name: "nextcloud_postgres" - networks: - - proxy - environment: - - POSTGRES_USER=nextcloud - - POSTGRES_PASSWORD=${POSTGRES_PW} - - POSTGRES_DB=nextcloud - volumes: - - ./nextcloud-db:/var/lib/postgresql/data - redis: - image: redis:latest - container_name: "nextcloud_redis" - restart: always - command: redis-server --requirepass ${REDIS_PW} - networks: - - proxy - volumes: - - ./redis:/var/lib/redis - - clamav: - image: "clamav/clamav:stable_base" - container_name: "clamav" - networks: - - proxy - volumes: - # Socket - # - /usr/sbin/:/var/run/clamav/ - # Virus DB - - /var/docker/clamav/virus_db/:/var/lib/clamav/ - ports: - - 3310:3310 - restart: unless-stopped - - nextcloud: - image: nextcloud:latest - restart: always - container_name: "nextcloud" - hostname: nextcloud.${DOMAIN} - networks: - - proxy - depends_on: - - redis - - db - labels: - - traefik.enable=true - - traefik.http.routers.nextcloud.middlewares=nextcloud,nextcloud-dav - - traefik.http.routers.nextcloud.tls.certresolver=mytlschallenge - - traefik.http.routers.nextcloud.rule=Host(`nextcloud.${DOMAIN}`) - - traefik.http.middlewares.nextcloud.headers.customFrameOptionsValue=ALLOW-FROM https://${DOMAIN} - - traefik.http.middlewares.nextcloud.headers.contentSecurityPolicy=frame-ancestors 'self' ${DOMAIN} *.${DOMAIN} - - traefik.http.middlewares.nextcloud.headers.customresponseheaders.X-Frame-Options=SAMEORIGIN - - traefik.http.middlewares.nextcloud.headers.stsSeconds=155520011 - - traefik.http.middlewares.nextcloud.headers.stsIncludeSubdomains=true - - traefik.http.middlewares.nextcloud.headers.stsPreload=true - - "traefik.http.middlewares.nextcloud-dav.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav" - - "traefik.http.middlewares.nextcloud-dav.redirectregex.replacement=https://$${1}/remote.php/dav/" - environment: - - POSTGRES_DB=nextcloud - - POSTGRES_USER=nextcloud - - POSTGRES_PASSWORD=${NEXTCLOUD_PW} - - POSTGRES_HOST=db - - NEXTCLOUD_ADMIN_USER=admin - - NEXTCLOUD_ADMIN_PASSWORD=${POSTGRES_PW} - - REDIS_HOST=redis - - REDIS_HOST_PASSWORD=${REDIS_PW} - - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.${DOMAIN} - - TRUSTED_PROXIES=172.18.0.0/16 - - OVERWRITEPROTOCOL=https - volumes: - - ./nextcloud-www:/var/www/html - -networks: - proxy: - external: true \ No newline at end of file diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml new file mode 100644 index 0000000..a9a94d6 --- /dev/null +++ b/roles/nextcloud/tasks/main.yml @@ -0,0 +1,90 @@ +--- +- name: Create Nextcloud network + community.docker.docker_network: + name: nextcloud + driver: bridge + ipam_driver: default + ipam_config: + - subnet: 172.30.0.0/24 + +- name: Create Postgres DB Container + community.docker.docker_container: + name: nextcloud_postgres + hostname: nextcloud_postgres + image: postgres:13 + restart_policy: unless-stopped + tty: true + interactive: true + command: "postgres -c 'max_connections=200'" + networks: + - name: proxy + env: + POSTGRES_USER: "{{ nextcloud_postgres_username }}" + POSTGRES_PASSWORD: "{{ nextcloud_postgres_password }}" + POSTGRES_DB: "{{ nextcloud_postgres_db }}" + volumes: + - "{{ nextcloud_docker_path }}/nextcloud-db:/var/lib/postgresql/data" + +- name: Create Redis Container + community.docker.docker_container: + name: nextcloud_redis + hostname: nextcloud_redis + restart_policy: unless-stopped + image: redis:latest + command: "redis-server --requirepass {{ nextcloud_redis_password }}" + networks: + - name: proxy + volumes: + - "{{ nextcloud_docker_path }}/redis:/var/lib/redis" + +- name: Create ClamAV Container + community.docker.docker_container: + name: "nextcloud_clamav" + hostname: "nextcloud_clamav" + image: "clamav/clamav:stable_base" + networks: + - name: proxy + volumes: + - /var/docker/clamav/virus_db/:/var/lib/clamav/ + restart_policy: unless-stopped + +- name: Create Nextcloud container + community.docker.docker_container: + name: "nextcloud" + hostname: "nextcloud" + image: "nextcloud:latest" + restart_policy: unless-stopped + networks: + # - name: nextcloud + # - name: openldap + - name: proxy + labels: + traefik.enable: "true" + traefik.http.routers.nextcloud.middlewares: "nextcloud,nextcloud-dav" + traefik.http.routers.nextcloud.tls.certresolver: "mytlschallenge" + traefik.http.routers.nextcloud.rule: "Host(`{{ nextcloud_domain }}`)" + traefik.http.middlewares.nextcloud.headers.customFrameOptionsValue: "ALLOW-FROM https://{{ domain }}" + traefik.http.middlewares.nextcloud.headers.contentSecurityPolicy: "frame-ancestors 'self' {{ domain }} *.{{ domain }}" + traefik.http.middlewares.nextcloud.headers.customresponseheaders.X-Frame-Options: "SAMEORIGIN" + traefik.http.middlewares.nextcloud.headers.stsSeconds: "155520011" + traefik.http.middlewares.nextcloud.headers.stsIncludeSubdomains: "true" + traefik.http.middlewares.nextcloud.headers.stsPreload: "true" + + traefik.http.middlewares.nextcloud-dav.redirectregex.regex: "https://(.*)/.well-known/(card|cal)dav" + traefik.http.middlewares.nextcloud-dav.redirectregex.replacement: "https://{{ nextcloud_domain }}/remote.php/dav/" + env: + POSTGRES_DB: "{{ nextcloud_postgres_db }}" + POSTGRES_USER: "{{ nextcloud_postgres_username }}" + POSTGRES_PASSWORD: "{{ nextcloud_postgres_password }}" + POSTGRES_HOST: "nextcloud_postgres" + NEXTCLOUD_ADMIN_USER: "admin" + NEXTCLOUD_ADMIN_PASSWORD: "{{ nextcloud_admin_password }}" + REDIS_HOST: "nextcloud_redis" + REDIS_HOST_PASSWORD: "{{ nextcloud_redis_password }}" + NEXTCLOUD_TRUSTED_DOMAINS: "{{ nextcloud_domain }}" + TRUSTED_PROXIES: "172.18.0.0/16" + OVERWRITEPROTOCOL: "https" + volumes: + - "{{ nextcloud_docker_path }}/nextcloud-www:/var/www/html" + +# code: language=ansible diff --git a/roles/openldap/tasks/main.yml b/roles/openldap/tasks/main.yml index 83f9f0d..e773438 100644 --- a/roles/openldap/tasks/main.yml +++ b/roles/openldap/tasks/main.yml @@ -1,20 +1,31 @@ --- +- name: Create OpenLDAP network + community.docker.docker_network: + name: "openldap" + driver: bridge + ipam_driver: default + ipam_config: + - subnet: 172.29.0.0/24 + + - name: Create OpenLDAP container community.docker.docker_container: - name: openldap + name: "openldap" + hostname: "openldap" image: "osixia/openldap:latest" restart_policy: "unless-stopped" + recreate: true env: LDAP_BASE_DN: "{{ openldap_base_dn }}" LDAP_ORGANISATION: "Machmeier-IT" LDAP_DOMAIN: "{{ openldap_domain }}" - LDAP_ADMIN_PASSWORD: "{{ openldap_password }}" - LDAP_REPLICATION: false - LDAP_READONLY_USER: false + LDAP_ADMIN_PASSWORD: "qjRNbLEXN0sNlFCQkDbYwBjwyzuXXrR6AVz8" + LDAP_REPLICATION: "false" + LDAP_READONLY_USER: "false" LDAP_TLS_VERIFY_CLIENT: never - LDAP_RFC2307BIS_SCHEMA: true - LDAP_REMOVE_CONFIG_AFTER_SETUP: true + LDAP_RFC2307BIS_SCHEMA: "true" + LDAP_REMOVE_CONFIG_AFTER_SETUP: "true" volumes: - "{{ openldap_docker_path }}/openldap_data:/var/lib/ldap" - "{{ openldap_docker_path }}/slapd_data:/etc/ldap/slapd.d" @@ -24,36 +35,39 @@ - name: Create OpenLDAP Manager container community.docker.docker_container: name: openldap-manager + hostname: "openldap-manager" image: wheelybird/ldap-user-manager:latest restart_policy: "unless-stopped" + recreate: true env: LDAP_REQUIRE_STARTTLS: "false" - LDAP_TLS_VERIFY_CLIENT: never - LDAP_URI: "ldaps://{{ openldap_hostname }}" + LDAP_TLS_VERIFY_CLIENT: "never" + LDAP_URI: "ldap://{{ openldap_hostname }}" LDAP_BASE_DN: "{{ openldap_base_dn }}" LDAP_ADMINS_GROUP: "admins" - LDAP_ADMIN_BIND_PWD: "{{ openldap_password }}" + LDAP_ADMIN_BIND_PWD: "qjRNbLEXN0sNlFCQkDbYwBjwyzuXXrR6AVz8" LDAP_ADMIN_BIND_DN: "cn=admin,{{ openldap_base_dn }}" SITE_NAME: "Machmeier-IT" SERVER_HOSTNAME: "https://{{ openldap_domain }}" NO_HTTPS: "true" SMTP_HOSTNAME: "{{ gitlab_smtp_address }}" - SMTP_HOST_PORT: "{{ gitlab_smtp_port }}" + SMTP_HOST_PORT: "{{ gitlab_smtp_port | string }}" SMTP_USERNAME: "{{ gitlab_smtp_mail }}" SMTP_PASSWORD: "{{ gitlab_smtp_password }}" SMTP_USE_TLS: "true" EMAIL_FROM_ADDRESS: "{{ gitlab_smtp_mail }}" EMAIL_FROM_NAME: "OpenLDAP Machmeier-IT" labels: - traefik.enable: true" - traefik.http.routers.ldapmanager.rule: Host(`{{ openldap_domain }}`) - traefik.http.routers.ldapmanager.entrypoints: websecure - traefik.http.routers.ldapmanager.tls.certresolver: mytlschallenge - traefik.http.services.ldapmanager.loadbalancer.server.port: 80 - traefik.http.routers.ldapmanager.middlewares: ldapmanager-auth - traefik.http.middlewares.ldapmanager-auth.basicauth.users: admin:{SHA}${{ traefik_dashboard_password }} + traefik.enable: "true" + traefik.http.routers.ldapmanager.rule: "Host(`{{ openldap_domain }}`)" + traefik.http.routers.ldapmanager.entrypoints: "websecure" + traefik.http.routers.ldapmanager.tls.certresolver: "mytlschallenge" + traefik.http.services.ldapmanager.loadbalancer.server.port: "80" + traefik.http.routers.ldapmanager.middlewares: "ldapmanager-auth" + traefik.http.middlewares.ldapmanager-auth.basicauth.users: "admin:{SHA}{{ traefik_dashboard_password }}" networks: + # - name: openldap - name: proxy # code: language=ansible diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml index f2290ae..86d4a98 100644 --- a/roles/traefik/tasks/main.yml +++ b/roles/traefik/tasks/main.yml @@ -1,4 +1,10 @@ --- +- name: Create Traefik network + community.docker.docker_network: + name: proxy + ipam_config: + - subnet: 172.18.0.0/16 + - name: Start Traefik community.docker.docker_container: name: traefik @@ -7,7 +13,6 @@ command: - "--api=true" - "--accesslog=true" - - "--pilot.token=be0ef0ec-7558-40a6-bb46-0297f6d402fa" - "--accesslog.filepath=/var/log/traefik/traefik.log" - "--api.dashboard=true" - "--providers.docker=true" @@ -35,7 +40,7 @@ - traefik.http.routers.traefik.tls.certresolver: mytlschallenge - traefik.http.routers.traefik.entrypoints: websecure - traefik.http.routers.traefik.middlewares: dashboardauth - - traefik.http.middlewares.dashboardauth.basicauth.users: admin:{SHA}${{ traefik_dashboard_password }} + - traefik.http.middlewares.dashboardauth.basicauth.users: admin:{SHA}{{ traefik_dashboard_password }} # Global redirection: http to https - traefik.http.routers.http-catchall.rule: HostRegexp(`{host:(www.)?.+}`) From 7e3f55118e715128171e012dde96414750fd51e1 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 15:57:25 +0100 Subject: [PATCH 14/25] Update volume in traefik --- roles/traefik/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml index 86d4a98..6bd169c 100644 --- a/roles/traefik/tasks/main.yml +++ b/roles/traefik/tasks/main.yml @@ -31,6 +31,7 @@ - "443:443" volumes: - "{{ traefik_docker_path }}/letsencrypt:/letsencrypt" + - "/var/log/traefik/:/var/log/traefik/" - "/var/run/docker.sock:/var/run/docker.sock:ro" labels: - traefik.enable: true From eb5ff00b556e8bfb05b010634f93b0777024cac3 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 16:40:42 +0100 Subject: [PATCH 15/25] Update current container --- roles/openldap/tasks/main.yml | 2 -- roles/traefik/defaults/main.yml | 11 ++++++++ roles/traefik/tasks/main.yml | 50 +++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/roles/openldap/tasks/main.yml b/roles/openldap/tasks/main.yml index e773438..7f4ebf9 100644 --- a/roles/openldap/tasks/main.yml +++ b/roles/openldap/tasks/main.yml @@ -15,7 +15,6 @@ hostname: "openldap" image: "osixia/openldap:latest" restart_policy: "unless-stopped" - recreate: true env: LDAP_BASE_DN: "{{ openldap_base_dn }}" LDAP_ORGANISATION: "Machmeier-IT" @@ -38,7 +37,6 @@ hostname: "openldap-manager" image: wheelybird/ldap-user-manager:latest restart_policy: "unless-stopped" - recreate: true env: LDAP_REQUIRE_STARTTLS: "false" LDAP_TLS_VERIFY_CLIENT: "never" diff --git a/roles/traefik/defaults/main.yml b/roles/traefik/defaults/main.yml index 52771a4..babb557 100644 --- a/roles/traefik/defaults/main.yml +++ b/roles/traefik/defaults/main.yml @@ -2,4 +2,15 @@ traefik_docker_path: "/srv/docker/traefik" +lp_logrotate_confd: + - path: traefik + conf: | + /var/log/traefik/traefik.log { + weekly + rotate 3 + size 100M + compress + delaycompress + } + # code: language=ansible diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml index 6bd169c..9f28321 100644 --- a/roles/traefik/tasks/main.yml +++ b/roles/traefik/tasks/main.yml @@ -3,13 +3,21 @@ community.docker.docker_network: name: proxy ipam_config: - - subnet: 172.18.0.0/16 - + - subnet: 172.18.0.0/16 + +- name: Create logrotate for Traefik + ansible.builtin.blockinfile: + path: "/etc/logrotate.d/{{ item.path }}" + block: "{{ item.conf }}" + create: true + loop: "{{ lp_logrotate_confd }}" + - name: Start Traefik community.docker.docker_container: name: traefik hostname: traefik - image: "traefik/latest" + image: "traefik:latest" + restart_policy: unless-stopped command: - "--api=true" - "--accesslog=true" @@ -20,7 +28,7 @@ - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true" - - "--certificatesresolvers.mytlschallenge.acme.email=YOUR_EMAIL" + - "--certificatesresolvers.mytlschallenge.acme.email={{ traefik_mail }}" - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.mytlschallenge.acme.keytype=EC384" - "--certificatesresolvers.mytlschallenge.acme.preferredchain='ISRG Root X1'" @@ -34,30 +42,30 @@ - "/var/log/traefik/:/var/log/traefik/" - "/var/run/docker.sock:/var/run/docker.sock:ro" labels: - - traefik.enable: true + traefik.enable: "true" # Dashboard - - traefik.http.routers.traefik.rule: Host(`{{ traefik_domain }}`) - - traefik.http.routers.traefik.service: api@internal - - traefik.http.routers.traefik.tls.certresolver: mytlschallenge - - traefik.http.routers.traefik.entrypoints: websecure - - traefik.http.routers.traefik.middlewares: dashboardauth - - traefik.http.middlewares.dashboardauth.basicauth.users: admin:{SHA}{{ traefik_dashboard_password }} + traefik.http.routers.traefik.rule: "Host(`{{ traefik_domain }}`)" + traefik.http.routers.traefik.service: "api@internal" + traefik.http.routers.traefik.tls.certresolver: "mytlschallenge" + traefik.http.routers.traefik.entrypoints: "websecure" + traefik.http.routers.traefik.middlewares: "dashboardauth" + traefik.http.middlewares.dashboardauth.basicauth.users: "admin:{SHA}{{ traefik_dashboard_password }}" # Global redirection: http to https - - traefik.http.routers.http-catchall.rule: HostRegexp(`{host:(www.)?.+}`) - - traefik.http.routers.http-catchall.entrypoints: web - - traefik.http.routers.http-catchall.middlewares: wwwtohttps + traefik.http.routers.http-catchall.rule: "HostRegexp(`{host:(www.)?.+}`)" + traefik.http.routers.http-catchall.entrypoints: "web" + traefik.http.routers.http-catchall.middlewares: "wwwtohttps" # Global redirection: https (www.) to https - - traefik.http.routers.wwwsecure-catchall.rule: HostRegexp(`{host:(www.).+}`) - - traefik.http.routers.wwwsecure-catchall.entrypoints: websecure - - traefik.http.routers.wwwsecure-catchall.tls: true - - traefik.http.routers.wwwsecure-catchall.middlewares: wwwtohttps + traefik.http.routers.wwwsecure-catchall.rule: "HostRegexp(`{host:(www.).+}`)" + traefik.http.routers.wwwsecure-catchall.entrypoints: "websecure" + traefik.http.routers.wwwsecure-catchall.tls: "true" + traefik.http.routers.wwwsecure-catchall.middlewares: "wwwtohttps" # middleware: http(s)://(www.) to https:// - - traefik.http.middlewares.wwwtohttps.redirectregex.regex: ^https?://(?:www.)?(.+) - - traefik.http.middlewares.wwwtohttps.redirectregex.replacement: https://$${1} - - traefik.http.middlewares.wwwtohttps.redirectregex.permanent: true + traefik.http.middlewares.wwwtohttps.redirectregex.regex: "^https?://(?:www.)?(.+)" + traefik.http.middlewares.wwwtohttps.redirectregex.replacement: "https://$${1}" + traefik.http.middlewares.wwwtohttps.redirectregex.permanent: "true" networks: - name: proxy From a236b5b62175dea79cf5b5348e4315f6db54dfbf Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 16:53:06 +0100 Subject: [PATCH 16/25] Add cron job --- roles/nextcloud/tasks/main.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml index a9a94d6..3cda256 100644 --- a/roles/nextcloud/tasks/main.yml +++ b/roles/nextcloud/tasks/main.yml @@ -87,4 +87,11 @@ volumes: - "{{ nextcloud_docker_path }}/nextcloud-www:/var/www/html" +- name: Write nextcloud background job + ansible.builtin.cron: + name: nextcloud_background_job + user: root + job: docker exec -u www-data nextcloud php /var/www/html/cron.php + minute: 5 + # code: language=ansible From 89a4ebd40bbeb67641045e366a0e0f6d25260c01 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Fri, 26 Jan 2024 16:57:09 +0100 Subject: [PATCH 17/25] Update playbook --- dodger_deploy.yml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/dodger_deploy.yml b/dodger_deploy.yml index e40dc6f..5af640e 100644 --- a/dodger_deploy.yml +++ b/dodger_deploy.yml @@ -6,13 +6,16 @@ vars_files: - "users.yml" roles: - # - name: gantsign.oh-my-zsh - # - name: default - # - name: robertdebock.update - # - name: docker + - name: gantsign.oh-my-zsh + - name: default + - name: robertdebock.update + - name: docker - name: crowdsec - # tasks: - # - name: Clone repository - # ansible.builtin.git: - # repo: https://github.com/stefanDeveloper/dodger.git - # dest: /srv/dodger + - name: traefik + - name: openldap + - name: gitlab + - name: homer + - name: nextcloud + - name: watchtower + +# code: language=ansible From 9cf0476f5d17ff60a80f54dac68c98ec0f54b96a Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Mon, 29 Jan 2024 11:16:59 +0100 Subject: [PATCH 18/25] Update readme --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index d48fdae..86a71c7 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,8 @@ This repository provides a complete Docker stack to easily set up your server wi * [Traefik](./traefik/README.md) as a reverse proxy to route your request (mandatory) * [Wordpress](./blog/README.md) just a simple Wordpress blog page * [GitLab](./gitlab/README.md) for coding -* [Portainer](./portainer/README.md) helps you to maintain your containers and images * [Nextcloud](./Nextcloud/README.md) one of my favorite private clouds :heart: * [Homer](./homer/README.md) just a landing page with links -* [Resilio](./resilio/README.md) allows you to sync your data with others, helpful to share backups -* [Seafile](./seafile/README.md) another cloud (not used by me anymore) * [OpenLDAP](./openldap/README.md) configuration for easy usage with GUI. * [Matrix](./matrix/README.md) Synapse server with LDAP configuration. * [Hugo](./hugo/README.md) hugo server to deploy simple website. From 443d097af4fdf8bc598493e880177b326e77aead Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Mon, 29 Jan 2024 15:51:29 +0100 Subject: [PATCH 19/25] Add matrix --- roles/matrix/.env | 2 - roles/matrix/LICENSE | 190 ++++++++++++++++++ roles/matrix/README.md | 19 +- roles/matrix/defaults/main.yml | 17 ++ roles/matrix/docker-compose.signal.yaml | 39 ---- roles/matrix/docker-compose.telegram.yaml | 28 --- roles/matrix/docker-compose.whatsapp.yaml | 28 --- roles/matrix/docker-compose.yaml | 56 ------ roles/matrix/files/matrix.log.config | 26 --- .../nginx/www/.well-known/matrix/client | 5 - .../nginx/www/.well-known/matrix/server | 3 - roles/matrix/tasks/install_signal_bridge.yml | 41 ++++ .../matrix/tasks/install_telegram_bridge.yml | 30 +++ .../matrix/tasks/install_whatsapp_bridge.yml | 30 +++ roles/matrix/tasks/main.yml | 113 +++++++++++ .../homeserver.yaml.j2} | 32 +-- roles/matrix/templates/matrix.log.config | 78 +++++++ .../nginx/matrix.conf.j2} | 2 +- .../nginx/www/.well-known/matrix/client.j2 | 5 + .../nginx/www/.well-known/matrix/server.j2 | 3 + 20 files changed, 527 insertions(+), 220 deletions(-) delete mode 100644 roles/matrix/.env create mode 100644 roles/matrix/LICENSE create mode 100644 roles/matrix/defaults/main.yml delete mode 100644 roles/matrix/docker-compose.signal.yaml delete mode 100644 roles/matrix/docker-compose.telegram.yaml delete mode 100644 roles/matrix/docker-compose.whatsapp.yaml delete mode 100644 roles/matrix/docker-compose.yaml delete mode 100644 roles/matrix/files/matrix.log.config delete mode 100644 roles/matrix/nginx/www/.well-known/matrix/client delete mode 100644 roles/matrix/nginx/www/.well-known/matrix/server create mode 100644 roles/matrix/tasks/install_signal_bridge.yml create mode 100644 roles/matrix/tasks/install_telegram_bridge.yml create mode 100644 roles/matrix/tasks/install_whatsapp_bridge.yml create mode 100644 roles/matrix/tasks/main.yml rename roles/matrix/{files/homeserver.yaml => templates/homeserver.yaml.j2} (63%) create mode 100644 roles/matrix/templates/matrix.log.config rename roles/matrix/{nginx/matrix.conf => templates/nginx/matrix.conf.j2} (92%) create mode 100644 roles/matrix/templates/nginx/www/.well-known/matrix/client.j2 create mode 100644 roles/matrix/templates/nginx/www/.well-known/matrix/server.j2 diff --git a/roles/matrix/.env b/roles/matrix/.env deleted file mode 100644 index e571b1c..0000000 --- a/roles/matrix/.env +++ /dev/null @@ -1,2 +0,0 @@ -DOMAIN= -DB_PASSWORD= diff --git a/roles/matrix/LICENSE b/roles/matrix/LICENSE new file mode 100644 index 0000000..6d8cea4 --- /dev/null +++ b/roles/matrix/LICENSE @@ -0,0 +1,190 @@ +EUROPEAN UNION PUBLIC LICENCE v. 1.2 +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the +terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). +The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following +notice immediately following the copyright notice for the Work: + Licensed under the EUPL +or has expressed by any other means his willingness to license under the EUPL. + +1.Definitions +In this Licence, the following terms have the following meaning: +— ‘The Licence’:this Licence. +— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available +as Source Code and also as Executable Code as the case may be. +— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or +modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work +required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in +the country mentioned in Article 15. +— ‘The Work’:the Original Work or its Derivative Works. +— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and +modify. +— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by +a computer as a program. +— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence. +— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to +the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the +Licence. +— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating, +transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential +functionalities at the disposal of any other natural or legal person. + +2.Scope of the rights granted by the Licence +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for +the duration of copyright vested in the Original Work: +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display the Work or copies thereof to the public +and perform publicly, as the case may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. +Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the +applicable law permits so. +In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed +by law in order to make effective the licence of the economic rights here above listed. +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the +extent necessary to make use of the rights granted on the Work under this Licence. + +3.Communication of the Source Code +The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as +Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with +each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to +the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to +distribute or communicate the Work. + +4.Limitations on copyright +Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the +exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5.Obligations of the Licensee +The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those +obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to +the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the +Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work +to carry prominent notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this +Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless +the Original Work is expressly distributed only under this version of the Licence — for example by communicating +‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the +Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both +the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed +in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide +a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. +Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names +of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6.Chain of Authorship +The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or +licensed to him/her and that he/she has the power and authority to grant the Licence. +Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions +to the Work, under the terms of this Licence. + +7.Disclaimer of Warranty +The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work +and may therefore contain defects or ‘bugs’ inherent to this type of development. +For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind +concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or +errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this +Licence. +This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work. + +8.Disclaimer of Liability +Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be +liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the +Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss +of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However, +the Licensor will be liable under statutory product liability laws as far such laws apply to the Work. + +9.Additional agreements +While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services +consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10.Acceptance of the Licence +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window +displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms +and conditions. +Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You +by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution +or Communication by You of the Work or copies thereof. + +11.Information to the public +In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, +by offering to download the Work from a remote location) the distribution channel or media (for example, a website) +must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence +and the way it may be accessible, concluded, stored and reproduced by the Licensee. + +12.Termination of the Licence +The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms +of the Licence. +Such a termination will not terminate the licences of any person who has received the Work from the Licensee under +the Licence, provided such persons remain in full compliance with the Licence. + +13.Miscellaneous +Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the +Work. +If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or +enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid +and enforceable. +The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of +the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. +New versions of the Licence will be published with a unique version number. +All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take +advantage of the linguistic version of their choice. + +14.Jurisdiction +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising between the European Union institutions, +bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice +of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to +the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business. + +15.Applicable Law +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, +resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside +a European Union Member State. + + + Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above licences without producing +a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the +covered Source Code from exclusive appropriation. +All other changes or additions to this Appendix require the production of a new EUPL version. diff --git a/roles/matrix/README.md b/roles/matrix/README.md index 5468ac4..e20544e 100644 --- a/roles/matrix/README.md +++ b/roles/matrix/README.md @@ -1,23 +1,6 @@ # Synapse Matrix Server -To run docker-compose up you have to adapt `.env` and replace `YOUR_DOMAIN.TLD` and `YOUR_SECRET` in `nginx/` and `files`. - -## Usage - -Set the following environment variables: - -```bash -DOMAIN= -DB_PASSWORD= -``` - -And then run - -```sh -docker-compose up -d -``` - -### Bridges +## Bridges > For more information, please read the official documentation of Mautrix https://docs.mau.fi/bridges/index.html diff --git a/roles/matrix/defaults/main.yml b/roles/matrix/defaults/main.yml new file mode 100644 index 0000000..e473390 --- /dev/null +++ b/roles/matrix/defaults/main.yml @@ -0,0 +1,17 @@ +--- + +matrix_docker_path: "/srv/docker/matrix" + +matrix_db_name: "synapse" +matrix_db_user: "synapse" + +mautrix_whatsapp_db_name: "synapse" +mautrix_whatsapp_db_user: "synapse" + +mautrix_telegram_db_name: "synapse" +mautrix_telegram_db_user: "synapse" + +mautrix_signal_db_name: "mautrixsignal" +mautrix_signal_db_user: "mautrixsignal" + +# code: language=ansible diff --git a/roles/matrix/docker-compose.signal.yaml b/roles/matrix/docker-compose.signal.yaml deleted file mode 100644 index 2180b7b..0000000 --- a/roles/matrix/docker-compose.signal.yaml +++ /dev/null @@ -1,39 +0,0 @@ -version: "3.3" - -services: - mautrix-signal: - container_name: mautrix-signal - image: dock.mau.dev/mautrix/signal - restart: unless-stopped - volumes: - - ./matrix-synapse-files/bridge:/data - - ./signald:/signald - depends_on: - - signald - networks: - - proxy - - signald: - container_name: signald - image: docker.io/signald/signald - restart: unless-stopped - volumes: - - ./signald:/signald - networks: - - proxy - - mautrix-signal-db: - image: postgres:13-alpine - restart: unless-stopped - environment: - POSTGRES_USER: mautrixsignal - POSTGRES_DATABASE: mautrixsignal - POSTGRES_PASSWORD: ${DB_PASSWORD} - volumes: - - ./db:/var/lib/postgresql/data - networks: - - proxy - -networks: - proxy: - external: true \ No newline at end of file diff --git a/roles/matrix/docker-compose.telegram.yaml b/roles/matrix/docker-compose.telegram.yaml deleted file mode 100644 index eb42582..0000000 --- a/roles/matrix/docker-compose.telegram.yaml +++ /dev/null @@ -1,28 +0,0 @@ -version: "3.3" - -services: - mautrix-telegram: - container_name: mautrix-telegram - image: dock.mau.dev/mautrix/telegram:latest - restart: unless-stopped - volumes: - - ./matrix-synapse-files/matrix-telegram:/data - networks: - - proxy - - mautrix-telegram-db: - container_name: matrix-telegram-db - image: docker.io/postgres:12-alpine - environment: - - POSTGRES_DB=synapse - - POSTGRES_USER=synapse - - POSTGRES_PASSWORD=${DB_PASSWORD} - - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C - volumes: - - ./matrix-telegram-schemas:/var/lib/postgresql/data - networks: - - proxy - -networks: - proxy: - external: true \ No newline at end of file diff --git a/roles/matrix/docker-compose.whatsapp.yaml b/roles/matrix/docker-compose.whatsapp.yaml deleted file mode 100644 index ab0f105..0000000 --- a/roles/matrix/docker-compose.whatsapp.yaml +++ /dev/null @@ -1,28 +0,0 @@ -version: "3.3" - -services: - mautrix-whatsapp: - container_name: mautrix-whatsapp - image: dock.mau.dev/mautrix/whatsapp:latest - restart: unless-stopped - volumes: - - ./matrix-synapse-files/matrix-whatsapp:/data - networks: - - proxy - - mautrix-whatsapp-db: - container_name: matrix-whatsapp-db - image: docker.io/postgres:12-alpine - environment: - - POSTGRES_DB=synapse - - POSTGRES_USER=synapse - - POSTGRES_PASSWORD=${DB_PASSWORD} - - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C - volumes: - - ./matrix-whatsapp-schemas:/var/lib/postgresql/data - networks: - - proxy - -networks: - proxy: - external: true \ No newline at end of file diff --git a/roles/matrix/docker-compose.yaml b/roles/matrix/docker-compose.yaml deleted file mode 100644 index 43d440e..0000000 --- a/roles/matrix/docker-compose.yaml +++ /dev/null @@ -1,56 +0,0 @@ -version: "3.3" - -services: - matrix-synapse: - container_name: matrix-synapse - image: matrixdotorg/synapse:latest - restart: unless-stopped - environment: - - SYNAPSE_CONFIG_PATH=/data/homeserver.yaml - volumes: - - ./matrix-synapse-files:/data - depends_on: - - matrix-synapse-db - ports: - - 8448:8448/tcp - labels: - - "traefik.enable=true" - - "traefik.http.routers.synapse.rule=Host(`synapse.${DOMAIN}`)" - - "traefik.http.routers.synapse.entrypoints=websecure" - - "traefik.http.routers.synapse.tls.certresolver=mytlschallenge" - - "traefik.http.services.synapse.loadbalancer.server.port=8008" - networks: - - proxy - - matrix-synapse-nginx: - container_name: "matrix-synapse-nginx" - image: nginx:latest - restart: always - volumes: - - ./matrix-synapse-nginx/matrix.conf:/etc/nginx/conf.d/default.conf - - ./matrix-synapse-nginx/www:/var/www/ - labels: - - "traefik.enable=true" - - "traefik.http.routers.nginx.rule=Host(`matrix.${DOMAIN}`)" - - "traefik.http.routers.nginx.entrypoints=websecure" - - "traefik.http.routers.nginx.tls.certresolver=mytlschallenge" - - "traefik.http.services.nginx.loadbalancer.server.port=80" - networks: - - proxy - - matrix-synapse-db: - container_name: matrix-synapse-db - image: postgres:12-alpine - environment: - - POSTGRES_DB=synapse - - POSTGRES_USER=synapse - - POSTGRES_PASSWORD=${DB_PASSWORD} - - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C - volumes: - - ./matrix-synapse-schemas:/var/lib/postgresql/data - networks: - - proxy - -networks: - proxy: - external: true diff --git a/roles/matrix/files/matrix.log.config b/roles/matrix/files/matrix.log.config deleted file mode 100644 index 365ba64..0000000 --- a/roles/matrix/files/matrix.log.config +++ /dev/null @@ -1,26 +0,0 @@ -version: 1 - -formatters: - precise: - format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' - - -handlers: - console: - class: logging.StreamHandler - formatter: precise - file: - filename: "/data/homeserver.log" - -loggers: - synapse.storage.SQL: - # beware: increasing this to DEBUG will make synapse log sensitive - # information such as access tokens. - level: INFO - -root: - level: INFO - handlers: [console] - - -disable_existing_loggers: false \ No newline at end of file diff --git a/roles/matrix/nginx/www/.well-known/matrix/client b/roles/matrix/nginx/www/.well-known/matrix/client deleted file mode 100644 index 2710a44..0000000 --- a/roles/matrix/nginx/www/.well-known/matrix/client +++ /dev/null @@ -1,5 +0,0 @@ -{ - "m.homeserver": { - "base_url": "https://matrix.YOUR_DOMAIN.TLD" - } -} \ No newline at end of file diff --git a/roles/matrix/nginx/www/.well-known/matrix/server b/roles/matrix/nginx/www/.well-known/matrix/server deleted file mode 100644 index 6a42b74..0000000 --- a/roles/matrix/nginx/www/.well-known/matrix/server +++ /dev/null @@ -1,3 +0,0 @@ -{ - "m.server": "synapse.YOUR_DOMAIN.TLD:443" -} \ No newline at end of file diff --git a/roles/matrix/tasks/install_signal_bridge.yml b/roles/matrix/tasks/install_signal_bridge.yml new file mode 100644 index 0000000..a08de2a --- /dev/null +++ b/roles/matrix/tasks/install_signal_bridge.yml @@ -0,0 +1,41 @@ +--- + +- name: Install Mautrix Signal container + community.docker.docker_container: + name: "mautrix-signal" + hostname: "mautrix-signal" + image: "dock.mau.dev/mautrix/signal:latest" + restart_policy: unless-stopped + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-synapse-files/matrix-signal:/data" + +- name: Install Signald container + community.docker.docker_container: + name: "signald" + hostname: "signald" + image: "docker.io/signald/signald" + restart_policy: unless-stopped + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/signald:/signald" + +- name: Install Postgresql for Matrix container + community.docker.docker_container: + name: "mautrix-signal-db" + hostname: "mautrix-signal-db" + image: postgres:13-alpine + restart_policy: unless-stopped + env: + POSTGRES_DB: "{{ mautrix_signal_db_name }}" + POSTGRES_USER: "{{ mautrix_signal_db_user }}" + POSTGRES_PASSWORD: "{{ mautrix_signal_db_password }}" + POSTGRES_INITDB_ARG: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-signal-schemas:/var/lib/postgresql/data" + +# code: language=ansible diff --git a/roles/matrix/tasks/install_telegram_bridge.yml b/roles/matrix/tasks/install_telegram_bridge.yml new file mode 100644 index 0000000..fb66a30 --- /dev/null +++ b/roles/matrix/tasks/install_telegram_bridge.yml @@ -0,0 +1,30 @@ +--- + +- name: Install Mautrix Telegram container + community.docker.docker_container: + name: "mautrix-telegram" + hostname: "mautrix-telegram" + image: "dock.mau.dev/mautrix/telegram:latest" + restart_policy: unless-stopped + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-synapse-files/matrix-telegram:/data" + +- name: Install Postgresql for Matrix container + community.docker.docker_container: + name: "mautrix-telegram-db" + hostname: "mautrix-telegram-db" + image: postgres:12-alpine + restart_policy: unless-stopped + env: + POSTGRES_DB: "{{ mautrix_telegram_db_name }}" + POSTGRES_USER: "{{ mautrix_telegram_db_user }}" + POSTGRES_PASSWORD: "{{ mautrix_telegram_db_password }}" + POSTGRES_INITDB_ARG: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-telegram-schemas:/var/lib/postgresql/data" + +# code: language=ansible diff --git a/roles/matrix/tasks/install_whatsapp_bridge.yml b/roles/matrix/tasks/install_whatsapp_bridge.yml new file mode 100644 index 0000000..ccab4cb --- /dev/null +++ b/roles/matrix/tasks/install_whatsapp_bridge.yml @@ -0,0 +1,30 @@ +--- + +- name: Install Mautrix WhatsApp container + community.docker.docker_container: + name: "mautrix-whatsapp" + hostname: "mautrix-whatsapp" + image: "dock.mau.dev/mautrix/whatsapp:latest" + restart_policy: unless-stopped + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-synapse-files/matrix-whatsapp:/data" + +- name: Install Postgresql for Matrix container + community.docker.docker_container: + name: "mautrix-whatsapp-db" + hostname: "mautrix-whatsapp-db" + image: postgres:12-alpine + restart_policy: unless-stopped + env: + POSTGRES_DB: "{{ mautrix_whatsapp_db_name }}" + POSTGRES_USER: "{{ mautrix_whatsapp_db_user }}" + POSTGRES_PASSWORD: "{{ mautrix_whatsapp_db_password }}" + POSTGRES_INITDB_ARG: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-whatsapp-schemas:/var/lib/postgresql/data" + +# code: language=ansible diff --git a/roles/matrix/tasks/main.yml b/roles/matrix/tasks/main.yml new file mode 100644 index 0000000..2a18445 --- /dev/null +++ b/roles/matrix/tasks/main.yml @@ -0,0 +1,113 @@ +--- + +# - name: Create folder for Matrix +# ansible.builtin.file: +# path: "{{ item.path }}" +# state: directory +# mode: "{{ item.mode }}" +# owner: "{{ item.owner }}" +# group: "{{ item.group }}" +# recurse: true +# with_items: +# - { path: "{{ matrix_docker_path }}", group: root, owner: root, mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-synapse-files", group: "991", owner: "991", mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-synapse-schemas", group: "70", owner: "70", mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-signal-schemas", group: "70", owner: "70", mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-telegram-schemas", group: "70", owner: "70", mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-whatsapp-schemas", group: "70", owner: "70", mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-synapse-nginx", group: root, owner: root, mode: "0700" } +# - { path: "{{ matrix_docker_path }}/matrix-synapse-nginx/www", group: root, owner: root, mode: "0755" } +# - { path: "{{ matrix_docker_path }}/matrix-synapse-nginx/www/.well-known", group: root, owner: root, mode: "0755" } +# - { path: "{{ matrix_docker_path }}/matrix-synapse-nginx/www/.well-known/matrix", group: root, owner: root, mode: "0755" } + +# - name: Copy homeserver configuration +# ansible.builtin.template: +# src: homeserver.yaml.j2 +# dest: "{{ matrix_docker_path }}/matrix-synapse-files/homeserver.yaml" +# mode: 0700 +# owner: 991 +# group: 991 + +# - name: Copy NGINX configuration +# ansible.builtin.template: +# src: nginx/matrix.conf.j2 +# dest: "{{ matrix_docker_path }}/matrix-synapse-nginx/matrix.conf" +# mode: 0700 +# owner: root +# group: root + +# - name: Copy NGINX configuration +# ansible.builtin.template: +# src: nginx/www/.well-known/matrix/{{ item }}.j2 +# dest: "{{ matrix_docker_path }}/matrix-synapse-nginx/www/.well-known/matrix/{{ item }}" +# mode: 0755 +# owner: root +# group: root +# with_items: +# - client +# - server + +- name: Install Matrix container + community.docker.docker_container: + name: "matrix-synapse" + hostname: "matrix-synapse" + image: matrixdotorg/synapse:latest + restart_policy: unless-stopped + env: + SYNAPSE_CONFIG_PATH: /data/homeserver.yaml + ports: + - "8448:8448/tcp" + labels: + traefik.enable: "true" + traefik.http.routers.synapse.rule: "Host(`{{ matrix_synapse_domain }}`)" + traefik.http.routers.synapse.entrypoints: "websecure" + traefik.http.routers.synapse.tls.certresolver: "mytlschallenge" + traefik.http.services.synapse.loadbalancer.server.port: "8008" + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-synapse-files:/data" + +- name: Install NGINX container + community.docker.docker_container: + name: "matrix-synapse-nginx" + hostname: "matrix-synapse-nginx" + image: nginx:latest + restart_policy: unless-stopped + labels: + traefik.enable: "true" + traefik.http.routers.nginx.rule: "Host(`{{ matrix_domain }}`)" + traefik.http.routers.nginx.entrypoints: "websecure" + traefik.http.routers.nginx.tls.certresolver: "mytlschallenge" + traefik.http.services.nginx.loadbalancer.server.port: "80" + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-synapse-nginx/matrix.conf:/etc/nginx/conf.d/default.conf" + - "{{ matrix_docker_path }}/matrix-synapse-nginx/www:/var/www/" + +- name: Install Postgresql for Matrix container + community.docker.docker_container: + name: "matrix-synapse-db" + hostname: "matrix-synapse-db" + image: postgres:12-alpine + env: + POSTGRES_DB: "{{ matrix_db_name }}" + POSTGRES_USER: "{{ matrix_db_user }}" + POSTGRES_PASSWORD: "{{ matrix_db_password }}" + POSTGRES_INITDB_ARG: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" + networks: + - name: proxy + volumes: + - "{{ matrix_docker_path }}/matrix-synapse-schemas:/var/lib/postgresql/data" + +- name: Include bridges + ansible.builtin.include_tasks: + file: "{{ item }}" + with_items: + - "install_signal_bridge.yml" + - "install_telegram_bridge.yml" + - "install_whatsapp_bridge.yml" + + +# code: language=ansible diff --git a/roles/matrix/files/homeserver.yaml b/roles/matrix/templates/homeserver.yaml.j2 similarity index 63% rename from roles/matrix/files/homeserver.yaml rename to roles/matrix/templates/homeserver.yaml.j2 index 16e6278..e54ac04 100644 --- a/roles/matrix/files/homeserver.yaml +++ b/roles/matrix/templates/homeserver.yaml.j2 @@ -23,22 +23,26 @@ listeners: database: name: psycopg2 args: - user: synapse - password: YOUR_SECRET - database: synapse - host: matrix-db + user: {{ matrix_db_user }} + password: {{ matrix_db_password }} + database: {{ matrix_db_name }} + host: matrix-synapse-db cp_min: 5 cp_max: 10 log_config: "/data/matrix.log.config" media_store_path: /data/media_store -registration_shared_secret: "YOUR_SECRET" +registration_shared_secret: "{{ matrix_registration_shared_secret }}" report_stats: true -macaroon_secret_key: "YOUR_SECRET" -form_secret: "YOUR_SECRET" +macaroon_secret_key: "{{ matrix_macaroon_secret_key }}" +form_secret: "{{ matrix_form_secret }}" signing_key_path: "/data/matrix.signing.key" +public_baseurl: https://{{ matrix_synapse_domain }}/ +app_service_config_files: +- "/data/registration-signal.yaml" +- "/data/registration-whatsapp.yaml" +- "/data/registration-telegram.yaml" trusted_key_servers: - - server_name: "matrix.smachmeier.de" - + - server_name: "{{ matrix_domain }}" enable_search: true user_directory: @@ -49,16 +53,16 @@ modules: - module: "ldap_auth_provider.LdapAuthProviderModule" config: enabled: true - uri: "ldap://openldap:389" + uri: "ldap://{{ openldap_hostname }}:{{ openldap_port}}" start_tls: false - base: "BASE_DN" + base: "{{ openldap_base_dn }}" mode: "search" attributes: uid: "uid" mail: "mail" name: "cn" - bind_dn: "cn=admin,BASE_DN" - bind_password: "YOUR_SECRET" - filter: "(memberof=cn=matrix,ou=groups,BASE_DN)" + bind_dn: "cn=admin,{{ openldap_base_dn }}" + bind_password: "{{ openldap_password }}" + filter: "(memberof=cn=matrix,ou=groups,{{ openldap_base_dn }})" tls_options: validate: false diff --git a/roles/matrix/templates/matrix.log.config b/roles/matrix/templates/matrix.log.config new file mode 100644 index 0000000..202b5e5 --- /dev/null +++ b/roles/matrix/templates/matrix.log.config @@ -0,0 +1,78 @@ +# Log configuration for Synapse. +# +# This is a YAML file containing a standard Python logging configuration +# dictionary. See [1] for details on the valid settings. +# +# Synapse also supports structured logging for machine readable logs which can +# be ingested by ELK stacks. See [2] for details. +# +# [1]: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema +# [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html + +version: 1 + +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + +handlers: + file: + class: logging.handlers.TimedRotatingFileHandler + formatter: precise + filename: /data/homeserver.log + when: midnight + backupCount: 3 # Does not include the current log file. + encoding: utf8 + + # Default to buffering writes to log file for efficiency. + # WARNING/ERROR logs will still be flushed immediately, but there will be a + # delay (of up to `period` seconds, or until the buffer is full with + # `capacity` messages) before INFO/DEBUG logs get written. + buffer: + class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler + target: file + + # The capacity is the maximum number of log lines that are buffered + # before being written to disk. Increasing this will lead to better + # performance, at the expensive of it taking longer for log lines to + # be written to disk. + # This parameter is required. + capacity: 10 + + # Logs with a level at or above the flush level will cause the buffer to + # be flushed immediately. + # Default value: 40 (ERROR) + # Other values: 50 (CRITICAL), 30 (WARNING), 20 (INFO), 10 (DEBUG) + flushLevel: 30 # Flush immediately for WARNING logs and higher + + # The period of time, in seconds, between forced flushes. + # Messages will not be delayed for longer than this time. + # Default value: 5 seconds + period: 5 + + # A handler that writes logs to stderr. Unused by default, but can be used + # instead of "buffer" and "file" in the logger handlers. + console: + class: logging.StreamHandler + formatter: precise + +loggers: + synapse.storage.SQL: + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + level: INFO + ldap3: + level: DEBUG + ldap_auth_provider: + level: DEBUG +root: + level: DEBUG + + # Write logs to the `buffer` handler, which will buffer them together in memory, + # then write them to a file. + # + # Replace "buffer" with "console" to log to stderr instead. + # + handlers: [buffer] + +disable_existing_loggers: false \ No newline at end of file diff --git a/roles/matrix/nginx/matrix.conf b/roles/matrix/templates/nginx/matrix.conf.j2 similarity index 92% rename from roles/matrix/nginx/matrix.conf rename to roles/matrix/templates/nginx/matrix.conf.j2 index 915987a..a031793 100644 --- a/roles/matrix/nginx/matrix.conf +++ b/roles/matrix/templates/nginx/matrix.conf.j2 @@ -1,6 +1,6 @@ server { listen 80 default_server; - server_name matrix.YOUR_DOMAIN.TLD; + server_name {{ matrix_domain }}; # Traefik -> nginx -> synapse location /_matrix { diff --git a/roles/matrix/templates/nginx/www/.well-known/matrix/client.j2 b/roles/matrix/templates/nginx/www/.well-known/matrix/client.j2 new file mode 100644 index 0000000..c6d4eb6 --- /dev/null +++ b/roles/matrix/templates/nginx/www/.well-known/matrix/client.j2 @@ -0,0 +1,5 @@ +{ + "m.homeserver": { + "base_url": "https://{{ matrix_domain }}" + } +} \ No newline at end of file diff --git a/roles/matrix/templates/nginx/www/.well-known/matrix/server.j2 b/roles/matrix/templates/nginx/www/.well-known/matrix/server.j2 new file mode 100644 index 0000000..898f683 --- /dev/null +++ b/roles/matrix/templates/nginx/www/.well-known/matrix/server.j2 @@ -0,0 +1,3 @@ +{ + "m.server": "{{ matrix_synapse_domain }}:443" +} \ No newline at end of file From 8e5ddd78e4ec3156888e19c0eb110e793b794d0d Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Mon, 29 Jan 2024 15:51:48 +0100 Subject: [PATCH 20/25] Add matrix --- dodger_deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/dodger_deploy.yml b/dodger_deploy.yml index 5af640e..0977697 100644 --- a/dodger_deploy.yml +++ b/dodger_deploy.yml @@ -17,5 +17,6 @@ - name: homer - name: nextcloud - name: watchtower + - name: matrix # code: language=ansible From 52d8479228184aeb42cfa0e7f6c9adc240a05e91 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Mon, 29 Jan 2024 15:59:01 +0100 Subject: [PATCH 21/25] Add restart policy --- roles/matrix/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/matrix/tasks/main.yml b/roles/matrix/tasks/main.yml index 2a18445..7d8dd8a 100644 --- a/roles/matrix/tasks/main.yml +++ b/roles/matrix/tasks/main.yml @@ -91,6 +91,7 @@ name: "matrix-synapse-db" hostname: "matrix-synapse-db" image: postgres:12-alpine + restart_policy: unless-stopped env: POSTGRES_DB: "{{ matrix_db_name }}" POSTGRES_USER: "{{ matrix_db_user }}" From 60176197790a9e94a05e2bd0a9ff43314955a400 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Mon, 29 Jan 2024 19:16:19 +0100 Subject: [PATCH 22/25] Fix wrong restart ploicy --- roles/crowdsec/files/nginx.yml | 5 +++++ roles/crowdsec/tasks/main.yml | 1 + roles/matrix/tasks/main.yml | 1 + 3 files changed, 7 insertions(+) create mode 100644 roles/crowdsec/files/nginx.yml diff --git a/roles/crowdsec/files/nginx.yml b/roles/crowdsec/files/nginx.yml new file mode 100644 index 0000000..b566b35 --- /dev/null +++ b/roles/crowdsec/files/nginx.yml @@ -0,0 +1,5 @@ +--- +filenames: + - /logs/nginx/*.log +labels: + type: nginx \ No newline at end of file diff --git a/roles/crowdsec/tasks/main.yml b/roles/crowdsec/tasks/main.yml index 03d81f8..6ad958c 100644 --- a/roles/crowdsec/tasks/main.yml +++ b/roles/crowdsec/tasks/main.yml @@ -32,6 +32,7 @@ image: crowdsecurity/crowdsec:{{ crowdsec.version }} pull: true name: crowdsec + restart_policy: unless-stopped healthcheck: test: ["CMD", "cscli", "version"] ports: diff --git a/roles/matrix/tasks/main.yml b/roles/matrix/tasks/main.yml index 7d8dd8a..2f87be4 100644 --- a/roles/matrix/tasks/main.yml +++ b/roles/matrix/tasks/main.yml @@ -85,6 +85,7 @@ volumes: - "{{ matrix_docker_path }}/matrix-synapse-nginx/matrix.conf:/etc/nginx/conf.d/default.conf" - "{{ matrix_docker_path }}/matrix-synapse-nginx/www:/var/www/" + - "/var/log/nginx:/var/log/nginx/" - name: Install Postgresql for Matrix container community.docker.docker_container: From dcc5840a8745bdf4785bd698a037c38bbcd9c4a8 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Tue, 30 Jan 2024 09:56:34 +0100 Subject: [PATCH 23/25] Update traefik --- roles/traefik/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml index 9f28321..41a0422 100644 --- a/roles/traefik/tasks/main.yml +++ b/roles/traefik/tasks/main.yml @@ -63,7 +63,7 @@ traefik.http.routers.wwwsecure-catchall.middlewares: "wwwtohttps" # middleware: http(s)://(www.) to https:// - traefik.http.middlewares.wwwtohttps.redirectregex.regex: "^https?://(?:www.)?(.+)" + traefik.http.middlewares.wwwtohttps.redirectregex.regex: "^https?:\/\/(?:www.)?(.+)" traefik.http.middlewares.wwwtohttps.redirectregex.replacement: "https://$${1}" traefik.http.middlewares.wwwtohttps.redirectregex.permanent: "true" networks: From 3b4eba33d4711a5c38e22a7ed1f0b9df0f640995 Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Tue, 30 Jan 2024 12:45:55 +0100 Subject: [PATCH 24/25] Update readme --- README.md | 20 ++---- roles/gitlab/README.md | 17 ------ roles/matrix/README.md | 6 +- roles/nextcloud/README.md | 21 +------ roles/wazuh/.env | 3 - roles/wazuh/docker-compose.yml.diff | 94 ----------------------------- 6 files changed, 8 insertions(+), 153 deletions(-) delete mode 100644 roles/wazuh/.env delete mode 100644 roles/wazuh/docker-compose.yml.diff diff --git a/README.md b/README.md index 86a71c7..98b520c 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@

Be sure to :star: my configuration repo so you can keep up to date on any daily progress!

- - - + + +

@@ -18,7 +18,7 @@ This repository provides a complete Docker stack to easily set up your server wi ## Supported Applications * [Traefik](./traefik/README.md) as a reverse proxy to route your request (mandatory) -* [Wordpress](./blog/README.md) just a simple Wordpress blog page +* [Crowdsec](./Crowdsec/README.md) just the best firewall handler * [GitLab](./gitlab/README.md) for coding * [Nextcloud](./Nextcloud/README.md) one of my favorite private clouds :heart: * [Homer](./homer/README.md) just a landing page with links @@ -35,20 +35,8 @@ Just clone this repository and follow each guideline inside the corresponding ap git clone https://github.com/stefanDeveloper/dodger.git ``` -In each of these folders you will find a `docker-compose.yml`, a `.env` file, as well as a `README.md` that describes some basics about this application. - -In case you want to run applications individually, please make sure your Docker environment has a network called `proxy`. If this is not the case, please run: - -```sh -docker network create proxy -``` - -## Ansible - Deploying made simple by applying Ansible Playbooks including hardening, installs and more! -### Getting Started - Create Python virtualenv and install requirements: ```bash diff --git a/roles/gitlab/README.md b/roles/gitlab/README.md index 4b4c786..add1e12 100644 --- a/roles/gitlab/README.md +++ b/roles/gitlab/README.md @@ -1,22 +1,5 @@ # Gitlab -To run docker-compose up you have to adapt `.env` - -## Usage - -Set the following environment variables: - -```env -DOMAIN= -SMTP_PASSWORD= -``` - -And then run - -```sh -docker-compose up -d -``` - ## Gitlab Runner If you want to add a GitLab runner, go to your Runner Configuration (/admin/runners) in Gitlab and replace the registration inside the [script](./gitlab-runner-register.sh) diff --git a/roles/matrix/README.md b/roles/matrix/README.md index e20544e..651aade 100644 --- a/roles/matrix/README.md +++ b/roles/matrix/README.md @@ -6,6 +6,6 @@ Supported bridges in this setting -- [Signal](docker-compose.signal.yaml) -- [Telegram](docker-compose.telegram.yaml) -- [WhatsApp](docker-compose.whatsapp.yaml) +- [Signal](tasks/install_signal_bridge.yml) +- [Telegram](tasks/install_telegram_bridge.yml) +- [WhatsApp](tasks/install_whatsapp_bridge.yml) diff --git a/roles/nextcloud/README.md b/roles/nextcloud/README.md index 4a833d7..2a13ca9 100644 --- a/roles/nextcloud/README.md +++ b/roles/nextcloud/README.md @@ -1,23 +1,4 @@ -# NextCloud - -To run docker-compose up you have to adapt `.env` - -## Usage - -Set the following environment variables: - -```env -POSTGRES_PW= -REDIS_PW= -POSTGRES_PW= -DOMAIN= -``` - -And then run - -```sh -docker-compose up -d -``` +# Nextcloud ## Useful diff --git a/roles/wazuh/.env b/roles/wazuh/.env deleted file mode 100644 index 25cf4ff..0000000 --- a/roles/wazuh/.env +++ /dev/null @@ -1,3 +0,0 @@ -INDEX_PASSWORD= -DASHBOARD_PASSWORD= -DOMAIN= \ No newline at end of file diff --git a/roles/wazuh/docker-compose.yml.diff b/roles/wazuh/docker-compose.yml.diff deleted file mode 100644 index 5d88345..0000000 --- a/roles/wazuh/docker-compose.yml.diff +++ /dev/null @@ -1,94 +0,0 @@ -diff --git a/single-node/docker-compose.yml b/single-node/docker-compose.yml -index 3f066fd..a9f3e30 100644 ---- a/single-node/docker-compose.yml -+++ b/single-node/docker-compose.yml -@@ -6,6 +6,9 @@ services: - image: wazuh/wazuh-manager:4.5.0 - hostname: wazuh.manager - restart: always -+ networks: -+ proxy: -+ ipv4_address: 172.18.0.22 - ulimits: - memlock: - soft: -1 -@@ -14,14 +17,14 @@ services: - soft: 655360 - hard: 655360 - ports: -- - "1514:1514" -- - "1515:1515" -- - "514:514/udp" -- - "55000:55000" -+ - "127.0.0.1:1514:1514" -+ - "127.0.0.1:1515:1515" -+ - "127.0.0.1:514:514/udp" -+ - "127.0.0.1:55000:55000" - environment: - - INDEXER_URL=https://wazuh.indexer:9200 - - INDEXER_USERNAME=admin -- - INDEXER_PASSWORD=SecretPassword -+ - INDEXER_PASSWORD=${INDEX_PASSWORD} - - FILEBEAT_SSL_VERIFICATION_MODE=full - - SSL_CERTIFICATE_AUTHORITIES=/etc/ssl/root-ca.pem - - SSL_CERTIFICATE=/etc/ssl/filebeat.pem -@@ -44,13 +47,12 @@ services: - - ./config/wazuh_indexer_ssl_certs/wazuh.manager.pem:/etc/ssl/filebeat.pem - - ./config/wazuh_indexer_ssl_certs/wazuh.manager-key.pem:/etc/ssl/filebeat.key - - ./config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf -- - wazuh.indexer: - image: wazuh/wazuh-indexer:4.5.0 - hostname: wazuh.indexer - restart: always - ports: -- - "9200:9200" -+ - "127.0.0.1:9200:9200" - environment: - - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" - ulimits: -@@ -69,19 +71,26 @@ services: - - ./config/wazuh_indexer_ssl_certs/admin-key.pem:/usr/share/wazuh-indexer/certs/admin-key.pem - - ./config/wazuh_indexer/wazuh.indexer.yml:/usr/share/wazuh-indexer/opensearch.yml - - ./config/wazuh_indexer/internal_users.yml:/usr/share/wazuh-indexer/opensearch-security/internal_users.yml -- -+ networks: -+ - proxy - wazuh.dashboard: - image: wazuh/wazuh-dashboard:4.5.0 - hostname: wazuh.dashboard - restart: always -- ports: -- - 443:5601 -+ labels: -+ - "traefik.enable=true" -+ - "traefik.http.routers.wazuh.rule=Host(`wazuh.${DOMAIN}`)" -+ - "traefik.http.routers.wazuh.entrypoints=websecure" -+ - "traefik.http.routers.wazuh.tls.certresolver=mytlschallenge" -+ - "traefik.http.services.wazuh.loadbalancer.server.port=5601" -+ #ports: -+ #- 443:5601 - environment: - - INDEXER_USERNAME=admin -- - INDEXER_PASSWORD=SecretPassword -+ - INDEXER_PASSWORD=${INDEX_PASSWORD} - - WAZUH_API_URL=https://wazuh.manager - - DASHBOARD_USERNAME=kibanaserver -- - DASHBOARD_PASSWORD=kibanaserver -+ - DASHBOARD_PASSWORD=${DASHBOARD_PASSWORD} - - API_USERNAME=wazuh-wui - - API_PASSWORD=MyS3cr37P450r.*- - volumes: -@@ -95,7 +104,11 @@ services: - links: - - wazuh.indexer:wazuh.indexer - - wazuh.manager:wazuh.manager -- -+ networks: -+ - proxy -+networks: -+ proxy: -+ external: true - volumes: - wazuh_api_configuration: - wazuh_etc: \ No newline at end of file From 06c40d66591a3417fb7aed35843f42c4d175a21a Mon Sep 17 00:00:00 2001 From: Stefan Machmeier Date: Tue, 30 Jan 2024 13:02:08 +0100 Subject: [PATCH 25/25] Update readme --- README.md | 3 ++- assets/dodger_logo.png | Bin 0 -> 27761 bytes assets/dodger_logo.svg | 53 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 assets/dodger_logo.png create mode 100644 assets/dodger_logo.svg diff --git a/README.md b/README.md index 98b520c..0df3b86 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@


- Dodger + + ![dodger Logo](https://github.com/stefanDeveloper/dodger/assets/18898803/baa4278f-ef46-4227-a08c-cfb8445c17a4?raw=true)

Be sure to :star: my configuration repo so you can keep up to date on any daily progress!

diff --git a/assets/dodger_logo.png b/assets/dodger_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c19f008a3446fca36fbd80a786fff37a564a5f80 GIT binary patch literal 27761 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 Z(Ku6ggKd z?t(3_;)k#YmcJTz6PnWNV*DcMVg{P5#ek zC}dcZRc&1J0O`&J)u8|ldGEm&=Lq^UW?yCB5Vh6I4(w8np}-p4D>FstkEApYm+?fb zHDdV%aA+UjVRjua})#R}YA=pD}XOJ~1qXM7jl3F!dD zj<6RTp(pJZ26;FsxN}QK;3e8J?)dC7H<`0Kc!Px|?(+f0vn7lm&dTM6!*8LHpDfCC zVAqiND=)rpE${AIkL$O^%rDa}jknP@dY-1BA*oWuXqwGU?xXLO8t4vYjOrGtL?>5N z(vD-01x@D(%fR>I?#OBB@F#ueli3di%3izCdVH|?H6fvMx!*n)f_NR>jK zlvmCf&zX-gO5P?mM;^WUH#Dw>&~J-+2#hq@Cop~rE&PrYHR}PT>P;H1z#xX|S`Mhz2(j{H)zuVBl`b2&ks&{E2nVJVfY@VVkKL&TfT9`4Er4Wg`zI2aIjWaGy zvGEIxQzvug?ND_`*KOOV_(Q=H*c=!V(D1bR9#N}?=pS78<_0&00hl3u>&-z%r!Hi; zx!ztTBvkQ3m4u<~fMYfIGdGF13IFC9y$KiYYQMCXFcBhI886# zEC%(`X-cmAs?B6pGOIW**31} z3V|BkW1J;?=bmf_3O=vpIP9)_{W=gd3Cw(zikR~e9>F^=i8F^EtTBYPh?eDQnVDc| z!%0|Cqc73@>2TmxTSv)0+gnEd!}i<2RsZwve|F&iaR=s;Pcn2-;7|AIKzu6N6#n=B b=U)Trl=Z&&SS=e__!O#>=hn(CboT!O#dqT5 literal 0 HcmV?d00001 diff --git a/assets/dodger_logo.svg b/assets/dodger_logo.svg new file mode 100644 index 0000000..8e9290e --- /dev/null +++ b/assets/dodger_logo.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + +