diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..15f981d --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - var-naming \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9c584bd..bb1b570 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,8 @@ inventory/ cache/ # Ignore Testplaybook -playbooks/global/testserver.yml \ No newline at end of file +playbooks/global/testserver.yml + +# Ignore unneccessary Files +.vscode +.ansible \ No newline at end of file diff --git a/ansible.cfg b/ansible.cfg index 0fd6374..e75e998 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -2,6 +2,7 @@ inventory = ./inventory/ host_key_checking = False retry_files_enabled = False +private_key_file = ~/.ssh/ansible_key # Caching-Einstellungen gathering = smart @@ -10,7 +11,7 @@ fact_caching_connection = ./cache fact_caching_timeout = 86400 # Rollen-Pfade -roles_path = ./roles/global:./roles/custom +roles_path = ./roles/ # Vault-Einstellungen vault_password_file = ./vault.secret @@ -26,4 +27,4 @@ become_ask_pass = False [ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=60s -pipelining = True +pipelining = True \ No newline at end of file diff --git a/playbooks/heyer.systems/all.yml b/playbooks/heyer.systems/all.yml new file mode 100644 index 0000000..7747a93 --- /dev/null +++ b/playbooks/heyer.systems/all.yml @@ -0,0 +1,5 @@ +--- +- name: Configure all servers + hosts: all + roles: + - server_install_ssh diff --git a/playbooks/heyer.systems/calibre.yml b/playbooks/heyer.systems/calibre.yml new file mode 100644 index 0000000..35433d7 --- /dev/null +++ b/playbooks/heyer.systems/calibre.yml @@ -0,0 +1,7 @@ +--- +- name: Configure calibre + hosts: calibre + roles: + - server_install_ssh + - server_install_fail2ban + - server_install_syslog diff --git a/playbooks/heyer.systems/docker1.yml b/playbooks/heyer.systems/docker1.yml new file mode 100644 index 0000000..7db4be9 --- /dev/null +++ b/playbooks/heyer.systems/docker1.yml @@ -0,0 +1,28 @@ +--- +- name: Configure docker1 + hosts: docker1 + roles: + - role: server_install_ssh + tags: + - ssh + - system + + - role: server_install_fail2ban + tags: + - fail2ban + - system + + - role: server_install_syslog + tags: + - syslog + - system + + - role: deploy_container_traefik + tags: + - traefik + - docker-container + + - role: deploy_container_homepage + tags: + - homepage + - docker-container diff --git a/playbooks/heyer.systems/minecraft.yml b/playbooks/heyer.systems/minecraft.yml new file mode 100644 index 0000000..40f1497 --- /dev/null +++ b/playbooks/heyer.systems/minecraft.yml @@ -0,0 +1,7 @@ +--- +- name: Configure Gaming Server + hosts: minecraft + roles: + - server_install_ssh + - server_install_fail2ban + - server_install_syslog diff --git a/playbooks/heyer.systems/pihole.yml b/playbooks/heyer.systems/pihole.yml new file mode 100644 index 0000000..78f08e3 --- /dev/null +++ b/playbooks/heyer.systems/pihole.yml @@ -0,0 +1,7 @@ +--- +- name: Configure pihole + hosts: pihole + roles: + - server_install_ssh + - server_install_fail2ban + - server_install_syslog diff --git a/playbooks/heyer.systems/pve1.yml b/playbooks/heyer.systems/pve1.yml new file mode 100644 index 0000000..c9b9139 --- /dev/null +++ b/playbooks/heyer.systems/pve1.yml @@ -0,0 +1,6 @@ +--- +- name: Configure pve1 + hosts: pve1 + roles: + - server_install_ssh + - server_install_fail2ban diff --git a/playbooks/heyer.systems/pve2.yml b/playbooks/heyer.systems/pve2.yml new file mode 100644 index 0000000..5886f60 --- /dev/null +++ b/playbooks/heyer.systems/pve2.yml @@ -0,0 +1,6 @@ +--- +- name: Configure pve2 + hosts: pve2 + roles: + - server_install_ssh + - server_install_fail2ban diff --git a/playbooks/heyer.systems/pve3.yml b/playbooks/heyer.systems/pve3.yml new file mode 100644 index 0000000..90f4c1e --- /dev/null +++ b/playbooks/heyer.systems/pve3.yml @@ -0,0 +1,6 @@ +--- +- name: Configure pve3 + hosts: pve3 + roles: + - server_install_ssh + - server_install_fail2ban diff --git a/roles/deploy_container_homepage/README.md b/roles/deploy_container_homepage/README.md new file mode 100644 index 0000000..952fea0 --- /dev/null +++ b/roles/deploy_container_homepage/README.md @@ -0,0 +1,112 @@ +Hier ist ein passendes **README.md**, das deine Anforderungen erfΓΌllt: + +--- + +# πŸ“¦ Ansible Role: Container Homepage + +This role deploys a tenant-specific instance of the **homepage container** (e.g. [gethomepage.dev](https://gethomepage.dev)) +It uses Docker Compose and copies custom configuration files per host. + +--- + +## πŸš€ **Getting Started** + +### 1️⃣ **Prepare tenant-specific config files** + +All example config files are located in: + +``` +roles/container_homepage/files/ +``` + +πŸ‘‰ Copy these files to your inventory directory under the following structure: + +``` +inventory/[TENANT]/host_files/[HOST]/container_homepage_config_files/ +``` + +Example: + +``` +inventory/tenant1/host_files/docker1/container_homepage_config_files/bookmarks.yaml +inventory/tenant1/host_files/docker1/container_homepage_config_files/settings.yaml +... +``` + +⚠️ **Customize these files** before deploying, according to the requirements of your tenant and host. + +--- + +## βš™οΈ **Default Variables** + +These are defined in `defaults/main.yml`: + +```yaml +container_homepage_version: latest +container_homepage_domain: dashboard.example.com +container_homepage_directory: /opt/docker/homepage +container_homepage_config_files: + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/bookmarks.yaml" + dest: "bookmarks.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/settings.yaml" + dest: "settings.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/custom.css" + dest: "custom.css" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/custom.js" + dest: "custom.js" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/docker.yaml" + dest: "docker.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/kubernetes.yaml" + dest: "kubernetes.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/services.yaml" + dest: "services.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/widgets.yaml" + dest: "widgets.yaml" +``` + +--- + +## πŸ“‚ **Inventory example** + +``` +inventory/ +└── tenant1/ + β”œβ”€β”€ hosts.yml + └── host_files/ + └── docker1/ + └── container_homepage_config_files/ + β”œβ”€β”€ bookmarks.yaml + β”œβ”€β”€ settings.yaml + β”œβ”€β”€ custom.css + β”œβ”€β”€ custom.js + β”œβ”€β”€ docker.yaml + β”œβ”€β”€ kubernetes.yaml + β”œβ”€β”€ services.yaml + └── widgets.yaml +``` + +--- + +## πŸ“ **Usage** + +Run your playbook as usual: + +```bash +ansible-playbook -i inventory/tenant1/inventory.yml playbooks/playbook.yml +``` + +The role will: +βœ… Ensure directories exist +βœ… Deploy Docker Compose and environment files +βœ… Copy the tenant-specific configuration files +βœ… Start or update the container + +--- + +## πŸ’‘ Notes + +* The role expects Docker (with compose v2 plugin) to be installed on the target host. +* The docker-compose and .env files should be templated or provided by your playbook or role. +* Make sure the `container_homepage_directory` location has correct permissions for your user/container runtime. + +--- \ No newline at end of file diff --git a/roles/deploy_container_homepage/defaults/main.yml b/roles/deploy_container_homepage/defaults/main.yml new file mode 100644 index 0000000..0e0f29d --- /dev/null +++ b/roles/deploy_container_homepage/defaults/main.yml @@ -0,0 +1,20 @@ +container_homepage_version: latest +container_homepage_domain: dashboard.example.com +container_homepage_directory: /opt/docker/homepage +container_homepage_config_files: + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/bookmarks.yaml" + dest: "bookmarks.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/settings.yaml" + dest: "settings.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/custom.css" + dest: "custom.css" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/custom.js" + dest: "custom.js" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/docker.yaml" + dest: "docker.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/kubernetes.yaml" + dest: "kubernetes.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/services.yaml" + dest: "services.yaml" + - src: "{{ inventory_dir }}/host_files/{{ inventory_hostname }}/container_homepage_config_files/widgets.yaml" + dest: "widgets.yaml" diff --git a/roles/deploy_container_homepage/files/bookmarks.yaml b/roles/deploy_container_homepage/files/bookmarks.yaml new file mode 100644 index 0000000..79c3694 --- /dev/null +++ b/roles/deploy_container_homepage/files/bookmarks.yaml @@ -0,0 +1,18 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/bookmarks + +- Developer: + - Github: + - abbr: GH + href: https://github.com/ + +- Social: + - Reddit: + - abbr: RE + href: https://reddit.com/ + +- Entertainment: + - YouTube: + - abbr: YT + href: https://youtube.com/ \ No newline at end of file diff --git a/roles/deploy_container_homepage/files/custom.css b/roles/deploy_container_homepage/files/custom.css new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_homepage/files/custom.js b/roles/deploy_container_homepage/files/custom.js new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_homepage/files/docker.yaml b/roles/deploy_container_homepage/files/docker.yaml new file mode 100644 index 0000000..725e92a --- /dev/null +++ b/roles/deploy_container_homepage/files/docker.yaml @@ -0,0 +1,10 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/docker/ + +# my-docker: +# host: 127.0.0.1 +# port: 2375 + +# my-docker: +# socket: /var/run/docker.sock \ No newline at end of file diff --git a/roles/deploy_container_homepage/files/kubernetes.yaml b/roles/deploy_container_homepage/files/kubernetes.yaml new file mode 100644 index 0000000..4d2c40b --- /dev/null +++ b/roles/deploy_container_homepage/files/kubernetes.yaml @@ -0,0 +1,2 @@ +--- +# sample kubernetes config \ No newline at end of file diff --git a/roles/deploy_container_homepage/files/proxmox.yaml b/roles/deploy_container_homepage/files/proxmox.yaml new file mode 100644 index 0000000..7196f8f --- /dev/null +++ b/roles/deploy_container_homepage/files/proxmox.yaml @@ -0,0 +1,4 @@ +--- +# url: https://proxmox.host.or.ip:8006 +# token: username@pam!Token ID +# secret: secret \ No newline at end of file diff --git a/roles/deploy_container_homepage/files/services.yaml b/roles/deploy_container_homepage/files/services.yaml new file mode 100644 index 0000000..837ce28 --- /dev/null +++ b/roles/deploy_container_homepage/files/services.yaml @@ -0,0 +1,18 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/services/ + +- My First Group: + - My First Service: + href: http://localhost/ + description: Homepage is awesome + +- My Second Group: + - My Second Service: + href: http://localhost/ + description: Homepage is the best + +- My Third Group: + - My Third Service: + href: http://localhost/ + description: Homepage is 😎 \ No newline at end of file diff --git a/roles/deploy_container_homepage/files/settings.yaml b/roles/deploy_container_homepage/files/settings.yaml new file mode 100644 index 0000000..1234d38 --- /dev/null +++ b/roles/deploy_container_homepage/files/settings.yaml @@ -0,0 +1,7 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/settings/ + +providers: + openweathermap: openweathermapapikey + weatherapi: weatherapiapikey \ No newline at end of file diff --git a/roles/deploy_container_homepage/files/widgets.yaml b/roles/deploy_container_homepage/files/widgets.yaml new file mode 100644 index 0000000..e55edec --- /dev/null +++ b/roles/deploy_container_homepage/files/widgets.yaml @@ -0,0 +1,12 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/info-widgets/ + +- resources: + cpu: true + memory: true + disk: / + +- search: + provider: duckduckgo + target: _blank \ No newline at end of file diff --git a/roles/deploy_container_homepage/handlers/main.yml b/roles/deploy_container_homepage/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_homepage/meta/main.yml b/roles/deploy_container_homepage/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_homepage/tasks/main.yml b/roles/deploy_container_homepage/tasks/main.yml new file mode 100644 index 0000000..290c0ff --- /dev/null +++ b/roles/deploy_container_homepage/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: Ensure data directories exist + ansible.builtin.file: + path: "{{ container_homepage_directory }}/data/{{ item }}" + state: directory + mode: '0755' + loop: + - "config" + become: false + +- name: Deploy Docker Compose and .env files + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ container_homepage_directory }}/{{ item.dest }}" + mode: '0644' + loop: + - { src: 'docker-compose.yml.j2', dest: 'docker-compose.yml' } + - { src: '.env.j2', dest: '.env' } + become: false + +- name: Deploy tenant-specific config files + ansible.builtin.copy: + src: "{{ item.src }}" + dest: "{{ container_homepage_directory }}/data/config/{{ item.dest }}" + mode: '0644' + loop: "{{ container_homepage_config_files }}" + become: false + +- name: Start Container + community.docker.docker_compose_v2: + project_src: "{{ container_homepage_directory }}" + pull: always + docker_host: "unix:///run/user/1000/docker.sock" + become: false diff --git a/roles/deploy_container_homepage/templates/.env.j2 b/roles/deploy_container_homepage/templates/.env.j2 new file mode 100644 index 0000000..7c71c97 --- /dev/null +++ b/roles/deploy_container_homepage/templates/.env.j2 @@ -0,0 +1,2 @@ +HOMEPAGE_VERSION={{ container_homepage_version }} +HOMEPAGE_DOMAIN={{ container_homepage_domain }} \ No newline at end of file diff --git a/roles/deploy_container_homepage/templates/docker-compose.yml.j2 b/roles/deploy_container_homepage/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..ef15321 --- /dev/null +++ b/roles/deploy_container_homepage/templates/docker-compose.yml.j2 @@ -0,0 +1,29 @@ +--- +services: + homepage: + image: ghcr.io/gethomepage/homepage:${HOMEPAGE_VERSION} + container_name: homepage + restart: always + networks: + - traefik + volumes: + - ./data/config:/app/config + - /run/user/1000/docker.sock:/var/run/docker.sock:ro + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik" + - "traefik.http.routers.homepage.entrypoints=http" + - "traefik.http.routers.homepage.rule=Host(`${HOMEPAGE_DOMAIN}`)" + - "traefik.http.middlewares.homepage-https-redirect.redirectscheme.scheme=https" + - "traefik.http.routers.homepage.middlewares=homepage-https-redirect" + - "traefik.http.routers.homepage-secure.entrypoints=https" + - "traefik.http.routers.homepage-secure.rule=Host(`${HOMEPAGE_DOMAIN}`)" + - "traefik.http.routers.homepage-secure.tls=true" + - "traefik.http.routers.homepage-secure.service=homepage" + - "traefik.http.services.homepage.loadbalancer.server.port=3000" + environment: + HOMEPAGE_ALLOWED_HOSTS: "*" + +networks: + traefik: + external: true diff --git a/roles/deploy_container_homepage/vars/main.yml b/roles/deploy_container_homepage/vars/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_traefik/defaults/main.yml b/roles/deploy_container_traefik/defaults/main.yml new file mode 100644 index 0000000..1eea22b --- /dev/null +++ b/roles/deploy_container_traefik/defaults/main.yml @@ -0,0 +1,35 @@ +--- +container_traefik_version: "latest" +container_traefik_http_port: 80 +container_traefik_https_port: 443 +container_traefik_domain: "example.com" +container_traefik_san_domains: + - "example.com" + - "example.org" +container_traefik_cloudflare_mail: "your-email@example.com" +container_traefik_cloudflare_token: "your-cloudflare-token" +container_traefik_basicauth_user: "admin" +container_traefik_basicauth_password: "yourpassword" + +# Static Traefik Routes +container_traefik_routers: + traefik: + entryPoints: + - "https" + rule: "Host(`example.example.com`)" + middlewares: + - default-headers + tls: {} + service: traefik + +container_traefik_services: + traefik: + loadBalancer: + servers: + - url: "http://127.0.0.1" + passHostHeader: true + serversTransport: insecure-https + +container_traefik_serversTransports: + insecure-https: + insecureSkipVerify: true diff --git a/roles/deploy_container_traefik/handlers/main.yml b/roles/deploy_container_traefik/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_traefik/meta/main.yml b/roles/deploy_container_traefik/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/deploy_container_traefik/tasks/main.yml b/roles/deploy_container_traefik/tasks/main.yml new file mode 100644 index 0000000..da3e7a6 --- /dev/null +++ b/roles/deploy_container_traefik/tasks/main.yml @@ -0,0 +1,57 @@ +--- +- name: Ensure data directories exist + ansible.builtin.file: + path: "{{ traefik_container_dir }}/data/{{ item }}" + state: directory + mode: '0755' + loop: + - "traefik" + - "certs" + - "logs" + - "traefik/config.d" + become: false + +- name: Ensure log files exist + ansible.builtin.file: + path: "{{ traefik_container_dir }}/data/logs/{{ item }}" + state: touch + mode: '0644' + loop: + - "traefik.log" + - "access.log" + become: false + +- name: Deploy Traefik configuration files + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ traefik_container_dir }}/data/{{ item.dest }}" + mode: '0644' + loop: + - { src: 'traefik.yml.j2', dest: 'traefik/traefik.yml' } + - { src: 'default.yml.j2', dest: 'traefik/config.d/default.yml' } + - { src: 'hosts.yml.j2', dest: 'traefik/config.d/hosts.yml' } + become: false + +- name: Deploy Docker Compose and .env files + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ traefik_container_dir }}/{{ item.dest }}" + mode: '0644' + loop: + - { src: 'docker-compose.yml.j2', dest: 'docker-compose.yml' } + - { src: '.env.j2', dest: '.env' } + become: false + +- name: Ensure Docker network exists + community.docker.docker_network: + name: traefik + state: present + docker_host: "unix:///run/user/1000/docker.sock" + become: false + +- name: Start Traefik container + community.docker.docker_compose_v2: + project_src: "{{ traefik_container_dir }}" + pull: always + docker_host: "unix:///run/user/1000/docker.sock" + become: false diff --git a/roles/deploy_container_traefik/templates/.env.j2 b/roles/deploy_container_traefik/templates/.env.j2 new file mode 100644 index 0000000..8428d72 --- /dev/null +++ b/roles/deploy_container_traefik/templates/.env.j2 @@ -0,0 +1,29 @@ +# Traefik Version +# Defines the version of Traefik to be used. By default, "latest" is used. +TRAEFIK_VERSION={{ container_traefik_version }} + +TRAEFIK_DOMAIN={{ container_traefik_domain }} + +# Ports +# Defines the ports on which Traefik will be available for HTTP and HTTPS traffic. +# By default, these are 80 (HTTP) and 443 (HTTPS). +TRAEFIK_HTTP_PORT={{ container_traefik_http_port }} +TRAEFIK_HTTPS_PORT={{ container_traefik_https_port }} + +# Cloudflare API Access +# Your Cloudflare API credentials that Traefik uses to automatically obtain TLS certificates +# via the Cloudflare DNS provider. +# Replace the following placeholders with your actual Cloudflare details: +# - CLOUDFLARE_MAIL: Your Cloudflare email address +# - CLOUDFLARE_TOKEN: Your Cloudflare API token +CLOUDFLARE_MAIL={{ container_traefik_cloudflare_mail }} +CLOUDFLARE_TOKEN={{ container_traefik_cloudflare_token }} + +# Basic Auth Configuration +# Basic authentication credentials for securing the Traefik dashboard. +# You can generate the password using the following command: +# echo $(htpasswd -nB yourusername) | sed -e s/\\$/\\$\\$/g +# Replace `yourusername` with the desired username. +# The generated value can then be placed in the `BASICAUTH_PASSWORD` variable. +TRAEFIK_BASICAUTH_USER={{ container_traefik_basicauth_user }} +TRAEFIK_BASICAUTH_PASSWORD={{ container_traefik_basicauth_password }} \ No newline at end of file diff --git a/roles/deploy_container_traefik/templates/default.yml.j2 b/roles/deploy_container_traefik/templates/default.yml.j2 new file mode 100644 index 0000000..a9485b6 --- /dev/null +++ b/roles/deploy_container_traefik/templates/default.yml.j2 @@ -0,0 +1,19 @@ +http: + middlewares: + https-redirect: + redirectScheme: + scheme: https + + default-headers: + headers: + frameDeny: true + sslRedirect: true + browserXssFilter: true + contentTypeNosniff: true + forceSTSHeader: true + stsIncludeSubdomains: true + stsPreload: true + stsSeconds: 15552000 + customFrameOptionsValue: SAMEORIGIN + customRequestHeaders: + X-Forwarded-Proto: https diff --git a/roles/deploy_container_traefik/templates/docker-compose.yml.j2 b/roles/deploy_container_traefik/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..90a5f2c --- /dev/null +++ b/roles/deploy_container_traefik/templates/docker-compose.yml.j2 @@ -0,0 +1,44 @@ +--- +services: + traefik: + image: traefik:${TRAEFIK_VERSION} + container_name: traefik + restart: always + security_opt: + - "no-new-privileges:true" + networks: + - traefik + ports: + - ${TRAEFIK_HTTP_PORT}:80 + - ${TRAEFIK_HTTPS_PORT}:443 + volumes: + - /run/user/1000/docker.sock:/var/run/docker.sock:ro + - ./data/traefik:/etc/traefik + - ./data/certs:/etc/certs:ro + - ./data/logs/traefik.log:/var/log/traefik.log + - ./data/logs/access.log:/var/log/crowdsec/traefik.log + environment: + - "CF_API_EMAIL=${CLOUDFLARE_MAIL:?error}" + - "CF_DNS_API_TOKEN=${CLOUDFLARE_TOKEN:?error}" + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.entrypoints=http" + - "traefik.http.routers.traefik.rule=Host(`${TRAEFIK_DOMAIN}`)" + - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https" + - "traefik.http.routers.traefik.middlewares=traefik-https-redirect" + - "traefik.http.routers.traefik-secure.entrypoints=https" + - "traefik.http.middlewares.basic-auth.basicauth.users=${TRAEFIK_BASICAUTH_USER}:${TRAEFIK_BASICAUTH_PASSWORD}" + - "traefik.http.routers.traefik-secure.middlewares=basic-auth" + - "traefik.http.routers.traefik-secure.rule=Host(`${TRAEFIK_DOMAIN}`)" + - "traefik.http.routers.traefik-secure.tls=true" + - "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare" +{% for domain in container_traefik_san_domains %} + - "traefik.http.routers.traefik-secure.tls.domains[{{ loop.index0 }}].main={{ domain }}" + - "traefik.http.routers.traefik-secure.tls.domains[{{ loop.index0 }}].sans=*.{{ domain }}" +{% endfor %} + - "traefik.http.routers.traefik-secure.service=api@internal" + +networks: + traefik: + external: true diff --git a/roles/deploy_container_traefik/templates/hosts.yml.j2 b/roles/deploy_container_traefik/templates/hosts.yml.j2 new file mode 100644 index 0000000..dc23f3d --- /dev/null +++ b/roles/deploy_container_traefik/templates/hosts.yml.j2 @@ -0,0 +1,42 @@ +http: + routers: +{% for router_name, router in container_traefik_routers.items() %} + {{ router_name }}: + entryPoints: +{% for ep in router.entryPoints %} + - "{{ ep }}" +{% endfor %} + rule: "{{ router.rule }}" +{% if router.middlewares is defined and router.middlewares %} + middlewares: +{% for m in router.middlewares %} + - {{ m }} +{% endfor %} +{% endif %} +{% if router.tls is defined and router.tls %} + tls: {} +{% endif %} + service: {{ router.service }} +{% endfor %} + + services: +{% for service_name, service in container_traefik_services.items() %} + {{ service_name }}: + loadBalancer: + servers: +{% for server in service.loadBalancer.servers %} + - url: "{{ server.url }}" +{% endfor %} + passHostHeader: {{ service.loadBalancer.passHostHeader | default(true) | lower }} +{% if service.loadBalancer.serversTransport is defined %} + serversTransport: {{ service.loadBalancer.serversTransport }} +{% endif %} +{% endfor %} + + serversTransports: +{% for transport_name, transport in container_traefik_serversTransports.items() %} + {{ transport_name }}: +{% for key, value in transport.items() %} + {{ key }}: {{ value | lower if value is boolean else value }} +{% endfor %} +{% endfor %} diff --git a/roles/deploy_container_traefik/templates/traefik.yml.j2 b/roles/deploy_container_traefik/templates/traefik.yml.j2 new file mode 100644 index 0000000..ea2511d --- /dev/null +++ b/roles/deploy_container_traefik/templates/traefik.yml.j2 @@ -0,0 +1,43 @@ +api: + dashboard: true + +log: + level: INFO + format: json + filePath: "/var/log/traefik.log" + +accessLog: + filePath: "/var/log/access.log" + bufferingSize: 50 + +entryPoints: + http: + address: ":80" + https: + address: ":443" + +serversTransport: + insecureSkipVerify: false + forwardingTimeouts: + dialTimeout: 10s + responseHeaderTimeout: 10s + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + watch: true + file: + directory: "/etc/traefik/config.d/" + watch: true + +certificatesResolvers: + cloudflare: + acme: + email: "{{ container_traefik_cloudflare_mail }}" + storage: acme.json + dnsChallenge: + provider: cloudflare + resolvers: + - "1.1.1.1:53" + - "1.0.0.1:53" diff --git a/roles/deploy_container_traefik/vars/main.yml b/roles/deploy_container_traefik/vars/main.yml new file mode 100644 index 0000000..fbf5ac5 --- /dev/null +++ b/roles/deploy_container_traefik/vars/main.yml @@ -0,0 +1,2 @@ +--- +traefik_container_dir: "/opt/docker/traefik" diff --git a/roles/server_install_fail2ban/defaults/main.yml b/roles/server_install_fail2ban/defaults/main.yml new file mode 100644 index 0000000..84f45e2 --- /dev/null +++ b/roles/server_install_fail2ban/defaults/main.yml @@ -0,0 +1,5 @@ +--- +fail2ban_ssh_enabled: true +fail2ban_ssh_maxretry: 5 +fail2ban_ssh_bantime: 1h +fail2ban_ssh_findtime: 1h diff --git a/roles/server_install_fail2ban/handlers/main.yml b/roles/server_install_fail2ban/handlers/main.yml new file mode 100644 index 0000000..c86a3ee --- /dev/null +++ b/roles/server_install_fail2ban/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart fail2ban + ansible.builtin.service: + name: fail2ban + state: restarted diff --git a/roles/server_install_fail2ban/meta/main.yml b/roles/server_install_fail2ban/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_fail2ban/tasks/main.yml b/roles/server_install_fail2ban/tasks/main.yml new file mode 100644 index 0000000..77d0ebf --- /dev/null +++ b/roles/server_install_fail2ban/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Update apt package index + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: Install Fail2Ban + ansible.builtin.apt: + name: fail2ban + state: present + +- name: Ensure Fail2Ban service is enabled and running + ansible.builtin.service: + name: fail2ban + enabled: true + state: started + +- name: Configure Fail2Ban for SSH + ansible.builtin.template: + src: jail.local.j2 + dest: /etc/fail2ban/jail.local + mode: '0644' + notify: Restart fail2ban diff --git a/roles/server_install_fail2ban/templates/jail.local.j2 b/roles/server_install_fail2ban/templates/jail.local.j2 new file mode 100644 index 0000000..866c49e --- /dev/null +++ b/roles/server_install_fail2ban/templates/jail.local.j2 @@ -0,0 +1,15 @@ +[DEFAULT] +# Ignore local IP addresses +ignoreip = 127.0.0.1/8 ::1 + +# Ban settings +bantime = {{ fail2ban_ssh_bantime }} +findtime = {{ fail2ban_ssh_findtime }} +maxretry = {{ fail2ban_ssh_maxretry }} + +[sshd] +enabled = {{ fail2ban_ssh_enabled | lower }} +port = ssh +filter = sshd +logpath = %(sshd_log)s +maxretry = {{ fail2ban_ssh_maxretry }} \ No newline at end of file diff --git a/roles/server_install_fail2ban/vars/main.yml b/roles/server_install_fail2ban/vars/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_ssh/defaults/main.yml b/roles/server_install_ssh/defaults/main.yml new file mode 100644 index 0000000..cf4734c --- /dev/null +++ b/roles/server_install_ssh/defaults/main.yml @@ -0,0 +1,8 @@ +# Standard-SSH-Benutzer +ssh_user: skulladmin + +# Platzhalter-Key +ssh_public_key: "" + +# SSH-Port +ssh_port: 22 diff --git a/roles/server_install_ssh/handlers/main.yml b/roles/server_install_ssh/handlers/main.yml new file mode 100644 index 0000000..d0383c6 --- /dev/null +++ b/roles/server_install_ssh/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart SSH + ansible.builtin.service: + name: ssh + state: restarted diff --git a/roles/server_install_ssh/meta/main.yml b/roles/server_install_ssh/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_ssh/tasks/main.yml b/roles/server_install_ssh/tasks/main.yml new file mode 100644 index 0000000..cb293a1 --- /dev/null +++ b/roles/server_install_ssh/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Paketlisten aktualisieren + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: OpenSSH Server installieren + ansible.builtin.apt: + name: openssh-server + state: present + +- name: Benutzer anlegen (falls nicht vorhanden) + ansible.builtin.user: + name: "{{ ssh_user }}" + shell: /bin/bash + create_home: true + +- name: SSH-Verzeichnis anlegen + ansible.builtin.file: + path: "/home/{{ ssh_user }}/.ssh" + state: directory + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: '0700' + +- name: SSH-Key eintragen + ansible.builtin.copy: + content: "{{ ssh_public_key }}" + dest: "/home/{{ ssh_user }}/.ssh/authorized_keys" + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: '0600' + +- name: SSH-Konfiguration per Template ΓΌbertragen + ansible.builtin.template: + src: sshd_config.j2 + dest: /etc/ssh/sshd_config + owner: root + group: root + mode: '0644' + notify: Restart SSH diff --git a/roles/server_install_ssh/templates/sshd_config.j2 b/roles/server_install_ssh/templates/sshd_config.j2 new file mode 100644 index 0000000..c4cded6 --- /dev/null +++ b/roles/server_install_ssh/templates/sshd_config.j2 @@ -0,0 +1,17 @@ +# OpenSSH server configuration (managed by Ansible) +Port {{ ssh_port }} +Protocol 2 +PermitRootLogin no +PasswordAuthentication no +ChallengeResponseAuthentication no +UsePAM yes +X11Forwarding no +ClientAliveInterval 300 +ClientAliveCountMax 2 +LoginGraceTime 30 +MaxAuthTries 3 +AllowTcpForwarding no +PermitEmptyPasswords no +PrintMotd no +UseDNS no +Compression no \ No newline at end of file diff --git a/roles/server_install_ssh/vars/main.yml b/roles/server_install_ssh/vars/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_syslog/defaults/main.yml b/roles/server_install_syslog/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_syslog/files/.gitkeep b/roles/server_install_syslog/files/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_syslog/handlers/main.yml b/roles/server_install_syslog/handlers/main.yml new file mode 100644 index 0000000..02b08a9 --- /dev/null +++ b/roles/server_install_syslog/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Start and enable rsyslog + ansible.builtin.service: + name: rsyslog + state: started + enabled: true diff --git a/roles/server_install_syslog/meta/main.yml b/roles/server_install_syslog/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_syslog/tasks/main.yml b/roles/server_install_syslog/tasks/main.yml new file mode 100644 index 0000000..f6d89a6 --- /dev/null +++ b/roles/server_install_syslog/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Update apt package index + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: Install rsyslog + ansible.builtin.apt: + name: rsyslog + state: present + notify: Start and enable rsyslog + +- name: Enable rsyslog + ansible.builtin.service: + name: rsyslog + state: started + enabled: true diff --git a/roles/server_install_syslog/templates/.gitkeep b/roles/server_install_syslog/templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/server_install_syslog/vars/main.yml b/roles/server_install_syslog/vars/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/defaults/main.yml b/roles/template_role/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/files/.gitkeep b/roles/template_role/files/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/handlers/main.yml b/roles/template_role/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/meta/main.yml b/roles/template_role/meta/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/tasks/main.yml b/roles/template_role/tasks/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/templates/.gitkeep b/roles/template_role/templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/template_role/vars/main.yml b/roles/template_role/vars/main.yml new file mode 100644 index 0000000..e69de29