diff --git a/.gitignore b/.gitignore index 0218305..201651b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .ansible-vaultpass +.venv/* diff --git a/Makefile b/Makefile index e54fac2..feca4c8 100644 --- a/Makefile +++ b/Makefile @@ -26,10 +26,11 @@ SSH_KEY=${HOME}/.ssh/id_rsa_home_ansible # Default to all ansible tags to run (passed via 'make deploy TAGS=sometag') TAGS?=all +SKIP_TAGS?=none TARGET?=all ${VENV}: - virtualenv -p python3 ${VENV} + python3 -m venv ${VENV} ${PIP}: ${VENV} ${ANSIBLE} ${ANSIBLE_VAULT} ${LINT_YAML} ${LINT_ANSIBLE}: ${VENV} requirements.txt @@ -51,7 +52,7 @@ SKIP_FILE=./.lint-vars.sh # Targets deploy: ${ANSIBLE} ${VAULT_FILE} - ${ANSIBLE} --diff --private-key ${SSH_KEY} -t ${TAGS} -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml + ${ANSIBLE} --diff --private-key ${SSH_KEY} -t ${TAGS} --skip-tags ${SKIP_TAGS} -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml list-tags: ${ANSIBLE} ${VAULT_FILE} ${ANSIBLE} --list-tags -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml @@ -60,7 +61,7 @@ list-tasks: ${ANSIBLE} ${VAULT_FILE} ${ANSIBLE} --list-tasks -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml check: ${ANSIBLE} ${VAULT_FILE} - ${ANSIBLE} --check --diff --private-key ${SSH_KEY} -t ${TAGS} -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml + ${ANSIBLE} --check --diff --private-key ${SSH_KEY} -t ${TAGS} --skip-tags ${SKIP_TAGS} -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml vault: ${ANSIBLE_VAULT} ${VAULT_FILE} ${ANSIBLE_VAULT} edit --vault-password-file ${VAULT_PASS_FILE} ${VAULT_FILE} diff --git a/ansible.cfg b/ansible.cfg index 82a20a5..a3a4a47 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -2,7 +2,7 @@ callback_enabled = profile_tasks # Do not gather facts by default -gathering = explicit +#gathering = explicit # Hide warnings about discovered Python interpreter interpreter_python = auto_silent diff --git a/ansible/deploy_home.yml b/ansible/deploy_home.yml index 13739ac..dbb9a1e 100644 --- a/ansible/deploy_home.yml +++ b/ansible/deploy_home.yml @@ -5,12 +5,9 @@ roles: - role: common - role: git - - role: ddns + - role: podman - role: ssl - - role: pihole - - role: http + #- role: pihole - role: drone - - role: hass - - role: motion - - role: partkeepr - role: graylog + - role: http diff --git a/ansible/inventories/home/hosts.yml b/ansible/inventories/home/hosts.yml index 64a403e..d9ed16b 100644 --- a/ansible/inventories/home/hosts.yml +++ b/ansible/inventories/home/hosts.yml @@ -3,3 +3,8 @@ all: hosts: home.bdebyl.net: ansible_user: ansible + children: + newhome: + hosts: + galactica.lan: + ansible_user: fedora diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml index b5057ad..e4cb465 100644 --- a/ansible/roles/common/defaults/main.yml +++ b/ansible/roles/common/defaults/main.yml @@ -1,12 +1,21 @@ --- -deps: [cronie, docker, fail2ban, git, logrotate, python-docker, tmux, weechat] +deps: + [ + cockpit-podman, + cronie, + docker, + fail2ban, + fail2ban-selinux, + git, + logrotate, + podman, + python-docker, + ] fail2ban_jails: [sshd.local, nginx.local] services: - - cronie + - crond - docker - fail2ban - - iptables - - nginx - systemd-timesyncd diff --git a/ansible/roles/common/files/fail2ban/jails/nginx.local b/ansible/roles/common/files/fail2ban/jails/nginx.local index 2826281..f637405 100644 --- a/ansible/roles/common/files/fail2ban/jails/nginx.local +++ b/ansible/roles/common/files/fail2ban/jails/nginx.local @@ -7,13 +7,13 @@ bantime = 1w maxretry = 8 ignoreip = 127.0.0.1/32 192.168.1.0/24 -[nginx-http-auth] -enabled = true -port = http,https -logpath = %(nginx_error_log)s -bantime = 2w -maxretry = 5 -ignoreip = 127.0.0.1/32 192.168.1.0/24 +#[nginx-http-auth] +#enabled = true +#port = http,https +#logpath = %(nginx_error_log)s +#bantime = 2w +#maxretry = 5 +#ignoreip = 127.0.0.1/32 192.168.1.0/24 [nginx-botsearch] enabled = true diff --git a/ansible/roles/common/tasks/deps.yml b/ansible/roles/common/tasks/deps.yml index ccbf5e3..43834c2 100644 --- a/ansible/roles/common/tasks/deps.yml +++ b/ansible/roles/common/tasks/deps.yml @@ -1,7 +1,7 @@ --- - name: install common dependencies become: true - community.general.pacman: + ansible.builtin.package: name: "{{ deps }}" state: present tags: deps diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml index 73a2b03..8aca606 100644 --- a/ansible/roles/common/tasks/main.yml +++ b/ansible/roles/common/tasks/main.yml @@ -2,3 +2,18 @@ - import_tasks: deps.yml - import_tasks: security.yml - import_tasks: service.yml + +- name: create the docker group + become: true + ansible.builtin.group: + name: docker + state: present + tags: common + +- name: add default user to docker group + become: true + ansible.builtin.user: + name: "{{ ansible_user }}" + groups: docker + append: true + tags: common diff --git a/ansible/roles/ddns/tasks/main.yml b/ansible/roles/ddns/tasks/main.yml deleted file mode 100644 index 4857114..0000000 --- a/ansible/roles/ddns/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- import_tasks: awsddns.yml diff --git a/ansible/roles/drone/handlers/main.yml b/ansible/roles/drone/handlers/main.yml new file mode 100644 index 0000000..2de51a2 --- /dev/null +++ b/ansible/roles/drone/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: restorecon drone + become: true + ansible.builtin.command: sh -c 'restorecon -Firv /var/lib/drone' diff --git a/ansible/roles/drone/tasks/drone.yml b/ansible/roles/drone/tasks/drone.yml index eaaf7c8..314cb46 100644 --- a/ansible/roles/drone/tasks/drone.yml +++ b/ansible/roles/drone/tasks/drone.yml @@ -4,7 +4,7 @@ community.general.docker_container: name: drone image: drone/drone:latest - recreate: true + recreate: false restart: true restart_policy: on-failure restart_retries: 3 @@ -32,7 +32,7 @@ community.general.docker_container: name: drone-runner image: drone/drone-runner-docker:latest - recreate: true + recreate: false restart: true restart_policy: on-failure restart_retries: 3 diff --git a/ansible/roles/drone/tasks/main.yml b/ansible/roles/drone/tasks/main.yml index 479cac1..c44b8ef 100644 --- a/ansible/roles/drone/tasks/main.yml +++ b/ansible/roles/drone/tasks/main.yml @@ -1,2 +1,3 @@ --- - import_tasks: drone.yml +- import_tasks: selinux.yml diff --git a/ansible/roles/drone/tasks/selinux.yml b/ansible/roles/drone/tasks/selinux.yml new file mode 100644 index 0000000..433b50d --- /dev/null +++ b/ansible/roles/drone/tasks/selinux.yml @@ -0,0 +1,9 @@ +--- +- name: selinux context for drone directory + become: true + community.general.sefcontext: + target: "/var/lib/drone(/.*)?" + setype: svirt_sandbox_file_t + state: present + notify: restorecon drone + tags: selinux diff --git a/ansible/roles/graylog/tasks/graylog.yml b/ansible/roles/graylog/tasks/graylog.yml index 73eecae..bb9ef30 100644 --- a/ansible/roles/graylog/tasks/graylog.yml +++ b/ansible/roles/graylog/tasks/graylog.yml @@ -44,9 +44,10 @@ transport.host: "localhost" network.host: "0.0.0.0" cluster.name: "graylog" - ES_JAVA_OPTS: "-Dlog4j2.formatMsgNoLookups=true -Xms512m -Xmx512m" + ES_JAVA_OPTS: "-Dlog4j2.formatMsgNoLookups=true -Xms512m -Xmx2048m" ulimits: - "memlock:-1:-1" + - "nofile:64000:64000" memory: 1G tags: graylog @@ -58,14 +59,18 @@ restart: true restart_policy: on-failure restart_retries: 3 + sysctls: + net.ipv6.conf.all.disable_ipv6: 1 + net.ipv6.conf.default.disable_ipv6: 1 networks: - name: "graylog" volumes: - graylog-conf:/usr/share/graylog/data/config + - /var/lib/docker/shared/graylog:/usr/share/graylog/bin:z env: GRAYLOG_PASSWORD_SECRET: "{{ graylog_secret }}" GRAYLOG_ROOT_PASSWORD_SHA2: "{{ graylog_root_pass_sha2 }}" - GRAYLOG_HTTP_EXTERNAL_URI: http://192.168.1.12:9000/ + GRAYLOG_HTTP_EXTERNAL_URI: http://192.168.1.10:9000/ GRAYLOG_HTTP_BIND_ADDRESS: 0.0.0.0:9000 GRAYLOG_MONGODB_URI: mongodb://graylog-mongo/graylog GRAYLOG_ELASTICSEARCH_HOSTS: http://graylog-elastic:9200 diff --git a/ansible/roles/hass/files/automations.yaml b/ansible/roles/hass/files/automations.yaml deleted file mode 100644 index 64014c1..0000000 Binary files a/ansible/roles/hass/files/automations.yaml and /dev/null differ diff --git a/ansible/roles/hass/files/configuration.yaml b/ansible/roles/hass/files/configuration.yaml deleted file mode 100644 index f9be84f..0000000 Binary files a/ansible/roles/hass/files/configuration.yaml and /dev/null differ diff --git a/ansible/roles/hass/meta/main.yml b/ansible/roles/hass/meta/main.yml deleted file mode 100644 index 258ca27..0000000 --- a/ansible/roles/hass/meta/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -dependencies: - - role: http - - role: graylog diff --git a/ansible/roles/hass/tasks/hass.yml b/ansible/roles/hass/tasks/hass.yml deleted file mode 100644 index eaf14d9..0000000 --- a/ansible/roles/hass/tasks/hass.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -- name: create home-assistant host directory volumes - become: true - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: 0640 - with_items: - - /usr/share/hass - - /usr/share/hass/media - - /var/lib/private/hass - tags: hass - -- name: copy configuration and automations - become: true - ansible.builtin.copy: - src: "files/{{ item }}" - dest: "/var/lib/private/hass/{{ item }}" - mode: 0644 - with_items: - - configuration.yaml - - automations.yaml - tags: hass - -- name: create home-assistant server container - diff: false - community.general.docker_container: - name: hass - image: ghcr.io/home-assistant/home-assistant:stable - recreate: false - restart: true - restart_policy: on-failure - restart_retries: 3 - log_driver: syslog - log_options: - syslog-address: "udp://localhost:{{ syslog_udp_default }}" - syslog-facility: daemon - tag: "docker/{{'{{'}}.Name{{'}}'}}" - volumes: - - /var/lib/hass:/config - - /usr/share/hass:/share - ports: - - "8123:8123" - tags: hass diff --git a/ansible/roles/hass/tasks/main.yml b/ansible/roles/hass/tasks/main.yml deleted file mode 100644 index 730cd64..0000000 --- a/ansible/roles/hass/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- import_tasks: hass.yml diff --git a/ansible/roles/http/defaults/main.yml b/ansible/roles/http/defaults/main.yml index 44097f8..ee251bd 100644 --- a/ansible/roles/http/defaults/main.yml +++ b/ansible/roles/http/defaults/main.yml @@ -1,6 +1,4 @@ --- -deps: [certbot, nginx, nginx-mod-modsecurity] - ci_server_name: ci.bdebyl.net pi_server_name: pi.bdebyl.net assistant_server_name: assistant.bdebyl.net diff --git a/ansible/roles/http/handlers/main.yml b/ansible/roles/http/handlers/main.yml index 4b6a498..3b65b06 100644 --- a/ansible/roles/http/handlers/main.yml +++ b/ansible/roles/http/handlers/main.yml @@ -1,6 +1,17 @@ --- - name: restart_nginx + become: true + ansible.builtin.command: docker restart nginx + +- name: restart firewalld become: true ansible.builtin.service: - name: nginx + name: firewalld state: restarted + +- name: restorecon nginx + become: true + ansible.builtin.command: restorecon -irv /etc/{{ item }} + with_items: + - nginx + - letsencrypt diff --git a/ansible/roles/http/tasks/deps.yml b/ansible/roles/http/tasks/deps.yml index aa8ae7d..6193dad 100644 --- a/ansible/roles/http/tasks/deps.yml +++ b/ansible/roles/http/tasks/deps.yml @@ -1,7 +1,7 @@ --- - name: install http dependencies become: true - pacman: + ansible.builtin.package: name: "{{ deps }}" state: present tags: deps diff --git a/ansible/roles/http/tasks/firewall.yml b/ansible/roles/http/tasks/firewall.yml new file mode 100644 index 0000000..8e7344f --- /dev/null +++ b/ansible/roles/http/tasks/firewall.yml @@ -0,0 +1,12 @@ +--- +- name: set http/https firewall rules + become: true + ansible.posix.firewalld: + service: "{{ item }}" + permanent: true + state: enabled + with_items: + - http + - https + notify: restart firewalld + tags: firewall diff --git a/ansible/roles/http/tasks/http.yml b/ansible/roles/http/tasks/http.yml index 01ad1dc..a274cb4 100644 --- a/ansible/roles/http/tasks/http.yml +++ b/ansible/roles/http/tasks/http.yml @@ -5,7 +5,7 @@ src: templates/nginx/nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root - group: http + group: nginx mode: 0644 notify: restart_nginx tags: http @@ -26,8 +26,8 @@ ansible.builtin.file: path: "{{ item }}" state: directory - owner: http - group: http + owner: nginx + group: nginx mode: 0755 loop: - /srv/http @@ -38,8 +38,8 @@ become: true ansible.builtin.file: path: /srv/http - owner: http - group: http + owner: nginx + group: nginx mode: 0755 recurse: true tags: http @@ -84,9 +84,3 @@ - "{{ logs_server_name }}.conf" notify: restart_nginx tags: http - -- name: validate nginx configurations - become: true - ansible.builtin.command: nginx -t - changed_when: false - tags: http diff --git a/ansible/roles/http/tasks/logrotate.yml b/ansible/roles/http/tasks/logrotate.yml deleted file mode 100644 index 6a2b552..0000000 --- a/ansible/roles/http/tasks/logrotate.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: template nginx log rotation - become: true - ansible.builtin.template: - src: logrotate/nginx.j2 - dest: /etc/logrotate.d/nginx - mode: 0644 - tags: - - http - - logrotate diff --git a/ansible/roles/http/tasks/main.yml b/ansible/roles/http/tasks/main.yml index fd04727..25d282d 100644 --- a/ansible/roles/http/tasks/main.yml +++ b/ansible/roles/http/tasks/main.yml @@ -1,7 +1,7 @@ --- - import_tasks: deps.yml -- import_tasks: security.yml +- import_tasks: firewall.yml - import_tasks: modsec.yml - import_tasks: http.yml - import_tasks: https.yml -- import_tasks: logrotate.yml +- import_tasks: nginx.yml diff --git a/ansible/roles/http/tasks/nginx.yml b/ansible/roles/http/tasks/nginx.yml new file mode 100644 index 0000000..8157f63 --- /dev/null +++ b/ansible/roles/http/tasks/nginx.yml @@ -0,0 +1,33 @@ +--- +- name: selinux context for nginx directories + become: true + community.general.sefcontext: + target: "/etc/{{ item }}" + setype: container_file_t + state: present + with_items: + - "nginx(/.*)?" + - "letsencrypt(/.*)?" + notify: restorecon nginx + tags: selinux + +- name: create nginx modsecurity container + community.general.docker_container: + name: nginx + image: owasp/modsecurity:nginx + entrypoint: ["nginx", "-g", "daemon off;"] + command_handling: correct + recreate: true + restart: true + restart_policy: on-failure + restart_retries: 3 + network_mode: host + log_driver: syslog + log_options: + syslog-address: "udp://localhost:{{ syslog_udp_default }}" + syslog-facility: daemon + tag: "docker/{{'{{'}}.Name{{'}}'}}" + volumes: + - /etc/nginx:/etc/nginx:ro + - /etc/letsencrypt:/etc/letsencrypt:ro + tags: nginx diff --git a/ansible/roles/http/tasks/security.yml b/ansible/roles/http/tasks/security.yml deleted file mode 100644 index ae4542e..0000000 --- a/ansible/roles/http/tasks/security.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: touch nginx logs, enable jail - become: true - ansible.builtin.file: - path: "/var/log/nginx/{{ item }}.log" - state: touch - mode: 0644 - loop: - - access - - error - notify: restart_fail2ban - tags: - - http - - security diff --git a/ansible/roles/http/templates/nginx/nginx.conf.j2 b/ansible/roles/http/templates/nginx/nginx.conf.j2 index 7964721..2000f0e 100644 --- a/ansible/roles/http/templates/nginx/nginx.conf.j2 +++ b/ansible/roles/http/templates/nginx/nginx.conf.j2 @@ -1,4 +1,4 @@ -user http; +user nginx; worker_processes 1; load_module /usr/lib/nginx/modules/ngx_http_modsecurity_module.so; diff --git a/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.http.conf.j2 b/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.http.conf.j2 index 27fb53b..dd08e19 100644 --- a/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.http.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.http.conf.j2 @@ -1,6 +1,5 @@ server { listen 80; - listen [::]:80; server_name {{ ci_server_name }}; location /.well-known { diff --git a/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 b/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 index 74509c8..23c6ce0 100644 --- a/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/ci.bdebyl.net.https.conf.j2 @@ -12,13 +12,12 @@ server { modsecurity_rules_file {{ nginx_path }}/modsec_includes.conf; listen 443 ssl http2; - listen [::]:443 ssl http2; server_name {{ ci_server_name }}; ssl_certificate /etc/letsencrypt/live/{{ ci_server_name }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ ci_server_name }}/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/{{ ci_server_name }}/fullchain.pem; - ssl_dhparam /etc/ssl/certs/dhparam.pem; + ssl_dhparam ssl/dhparam.pem; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; diff --git a/ansible/roles/http/templates/nginx/sites/home.bdebyl.net.conf.j2 b/ansible/roles/http/templates/nginx/sites/home.bdebyl.net.conf.j2 index bf48527..d470ce0 100644 --- a/ansible/roles/http/templates/nginx/sites/home.bdebyl.net.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/home.bdebyl.net.conf.j2 @@ -10,7 +10,7 @@ server { listen 80 default_server; server_name {{ home_server_name }}; if ($whitelisted = 1) { - return 302 http://pi.bdebyl.net; + return 302 http://192.168.1.12; } if ($whitelisted = 0) { diff --git a/ansible/roles/http/templates/nginx/sites/logs.bdebyl.net.conf.j2 b/ansible/roles/http/templates/nginx/sites/logs.bdebyl.net.conf.j2 index 24e0726..7d8324a 100644 --- a/ansible/roles/http/templates/nginx/sites/logs.bdebyl.net.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/logs.bdebyl.net.conf.j2 @@ -12,6 +12,7 @@ server { modsecurity_rules_file {{ nginx_path }}/modsec_includes.conf; listen 80; + listen [::]:80; server_name {{ logs_server_name }}; location / { diff --git a/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.conf.j2 b/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.conf.j2 index ed07b9c..a3d8bb5 100644 --- a/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.conf.j2 @@ -8,7 +8,6 @@ server { modsecurity_rules_file {{ nginx_path }}/modsec_includes.conf; listen 80; - listen [::]:80; server_name {{ parts_server_name }}; location /.well-known { diff --git a/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.https.conf.j2 b/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.https.conf.j2 index f6e80a3..b07b976 100644 --- a/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.https.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/parts.bdebyl.net.https.conf.j2 @@ -14,13 +14,12 @@ server { resolver 127.0.0.1 127.0.0.53 9.9.9.9 valid=60s; listen 443 ssl http2; - listen [::]:443 ssl http2; server_name {{ parts_server_name }}; ssl_certificate /etc/letsencrypt/live/{{ parts_server_name }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ parts_server_name }}/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/{{ parts_server_name }}/fullchain.pem; - ssl_dhparam /etc/ssl/certs/dhparam.pem; + ssl_dhparam ssl/dhparam.pem; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; diff --git a/ansible/roles/http/templates/nginx/sites/pi.bdebyl.net.conf.j2 b/ansible/roles/http/templates/nginx/sites/pi.bdebyl.net.conf.j2 index ca804b8..6f38147 100644 --- a/ansible/roles/http/templates/nginx/sites/pi.bdebyl.net.conf.j2 +++ b/ansible/roles/http/templates/nginx/sites/pi.bdebyl.net.conf.j2 @@ -9,7 +9,6 @@ server { modsecurity_rules_file {{ nginx_path }}/modsec_includes.conf; listen 80; - listen [::]:80; root /srv/http/pihole; server_name {{ pi_server_name }}; diff --git a/ansible/roles/motion/defaults/main.yml b/ansible/roles/motion/defaults/main.yml deleted file mode 100644 index 870fe9a..0000000 --- a/ansible/roles/motion/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -deps: ["cifs-utils"] diff --git a/ansible/roles/motion/handlers/main.yml b/ansible/roles/motion/handlers/main.yml deleted file mode 100644 index 5a31071..0000000 --- a/ansible/roles/motion/handlers/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: restart_motion - become: true - ansible.builtin.service: - name: motion - state: restarted diff --git a/ansible/roles/motion/meta/main.yml b/ansible/roles/motion/meta/main.yml deleted file mode 100644 index 258ca27..0000000 --- a/ansible/roles/motion/meta/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -dependencies: - - role: http - - role: graylog diff --git a/ansible/roles/motion/tasks/deps.yml b/ansible/roles/motion/tasks/deps.yml deleted file mode 100644 index dc6a57c..0000000 --- a/ansible/roles/motion/tasks/deps.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: install shinobi dependencies - become: true - community.general.pacman: - name: "{{ deps }}" - state: present - tags: - - deps - - motion diff --git a/ansible/roles/motion/tasks/main.yml b/ansible/roles/motion/tasks/main.yml deleted file mode 100644 index be6c254..0000000 --- a/ansible/roles/motion/tasks/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- import_tasks: deps.yml -- import_tasks: motion.yml diff --git a/ansible/roles/motion/tasks/motion.yml b/ansible/roles/motion/tasks/motion.yml deleted file mode 100644 index 6967354..0000000 --- a/ansible/roles/motion/tasks/motion.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- -- name: create shinobi user - become: true - ansible.builtin.user: - name: "{{ motion_user }}" - shell: /bin/nologin - tags: motion - -- name: mount shinob videos folder - become: true - ansible.builtin.file: - path: /mnt/shinobi - state: directory - owner: "{{ motion_user }}" - group: "{{ motion_user }}" - mode: 0755 - tags: motion - -- name: mount smb via cifs - become: true - ansible.posix.mount: - path: /mnt/shinobi - src: "//{{ motion_hostname }}/share/GardenCamera" - fstype: cifs - # yamllint disable-line rule:line-length - opts: "username={{ motion_user }},password={{ motion_pass }},workgroup=workgroup,iocharset=utf8,uid={{ motion_user }},gid={{ motion_user }}" - state: mounted - tags: motion - -- name: create shinobi data volume - become: true - community.general.docker_volume: - name: shinobi_data - tags: motion - -- name: create shinobi server container - diff: false - community.general.docker_container: - name: shinobi - image: migoller/shinobidocker:latest - recreate: false - restart: true - restart_policy: on-failure - restart_retries: 3 - log_driver: syslog - log_options: - syslog-address: "udp://localhost:{{ syslog_udp_default }}" - syslog-facility: daemon - tag: "docker/{{'{{'}} .Name {{'}}'}}" - volumes: - - "shinobi_data:/var/lib/mysql" - - "/mnt/shinobi:/opt/shinobi/videos" - ports: - - "8085:8080" - tags: motion diff --git a/ansible/roles/partkeepr/meta/main.yml b/ansible/roles/partkeepr/meta/main.yml deleted file mode 100644 index 258ca27..0000000 --- a/ansible/roles/partkeepr/meta/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -dependencies: - - role: http - - role: graylog diff --git a/ansible/roles/partkeepr/tasks/main.yml b/ansible/roles/partkeepr/tasks/main.yml deleted file mode 100644 index 0274d3d..0000000 --- a/ansible/roles/partkeepr/tasks/main.yml +++ /dev/null @@ -1,87 +0,0 @@ ---- -- name: create required partkeepr volumes - community.general.docker_volume: - name: "{{ item }}" - with_items: - - partkeepr-web-vol - - partkeepr-conf-vol - - partkeepr-data-vol - - partkeepr-db-vol - tags: partkeepr - -- name: create partkeepr network - community.general.docker_network: - name: "partkeepr" - tags: partkeepr - -- name: create partkeepr-db container - diff: false - community.general.docker_container: - name: partkeepr-db - image: mariadb:10.0 - recreate: false - restart: true - restart_policy: unless-stopped - restart_retries: 3 - log_driver: syslog - log_options: - syslog-address: "udp://localhost:{{ syslog_udp_default }}" - syslog-facility: daemon - tag: "docker/{{'{{'}}.Name{{'}}'}}" - networks: - - name: "partkeepr" - env: - MYSQL_RANDOM_ROOT_PASSWORD: "yes" - MYSQL_DATABASE: partkeepr - MYSQL_USER: partkeepr - MYSQL_PASSWORD: partkeepr - volumes: - - partkeepr-db-vol:/var/lib/mysql - tags: partkeepr - -- name: create partkeepr container - diff: false - community.general.docker_container: - name: partkeepr - image: mhubig/partkeepr:latest - recreate: false - restart: true - restart_policy: unless-stopped - restart_retries: 3 - log_driver: syslog - log_options: - syslog-address: "udp://localhost:{{ syslog_udp_default }}" - syslog-facility: daemon - tag: "docker/{{'{{'}}.Name{{'}}'}}" - networks: - - name: "partkeepr" - ports: - - "8081:80" - volumes: - - partkeepr-db-conf-vol:/var/www/html/app/config - - partkeepr-db-data-vol:/var/www/html/data - - partkeepr-db-web-vol:/var/www/html/web - tags: partkeepr - -- name: create partkeepr-cron container - diff: false - community.general.docker_container: - name: partkeepr-cron - image: mhubig/partkeepr:latest - command_handling: correct - entrypoint: [] - command: bash -c "crontab /etc/cron.d/partkeepr && cron -f" - recreate: false - restart: true - restart_policy: unless-stopped - restart_retries: 3 - log_driver: syslog - log_options: - syslog-address: "udp://localhost:{{ syslog_udp_default }}" - syslog-facility: daemon - tag: "docker/{{'{{'}}.Name{{'}}'}}" - volumes: - - partkeepr-db-conf-vol:/var/www/html/app/config:ro - - partkeepr-db-data-vol:/var/www/html/data - - partkeepr-db-web-vol:/var/www/html/web - tags: partkeepr diff --git a/ansible/roles/pihole/tasks/deps.yml b/ansible/roles/pihole/tasks/deps.yml index 173a697..f2fe91d 100644 --- a/ansible/roles/pihole/tasks/deps.yml +++ b/ansible/roles/pihole/tasks/deps.yml @@ -6,6 +6,6 @@ - name: install pi-hole-server dependencies become: true - community.general.pacman: + ansible.builtin.package: name: "{{ deps }}" state: present diff --git a/ansible/roles/podman/defaults/main.yml b/ansible/roles/podman/defaults/main.yml new file mode 100644 index 0000000..16de3a6 --- /dev/null +++ b/ansible/roles/podman/defaults/main.yml @@ -0,0 +1,3 @@ +--- +partkeepr_path: "{{ podman_volumes }}/partkeepr" +hass_path: "{{ podman_volumes }}/hass" diff --git a/ansible/roles/podman/files/automations.yaml b/ansible/roles/podman/files/automations.yaml new file mode 100644 index 0000000..085a664 --- /dev/null +++ b/ansible/roles/podman/files/automations.yaml @@ -0,0 +1,41 @@ +- id: '1649042254031' + alias: Office Lights Morning + description: '' + trigger: + - platform: time + at: '10:30:00' + condition: [] + action: + - type: turn_on + device_id: 04a5b4bea0caafe63bca3fb31c49091b + entity_id: light.bastian_s_office_lights + domain: light + brightness_pct: 100 + mode: single +- id: '1649042299713' + alias: Office Lights Evening + description: '' + trigger: + - platform: time + at: '17:00:00' + condition: [] + action: + - type: turn_on + device_id: 04a5b4bea0caafe63bca3fb31c49091b + entity_id: light.bastian_s_office_lights + domain: light + brightness_pct: 1 + mode: single +- id: '1649042328061' + alias: Office Lights Off + description: '' + trigger: + - platform: time + at: '20:00:00' + condition: [] + action: + - type: turn_off + device_id: 04a5b4bea0caafe63bca3fb31c49091b + entity_id: light.bastian_s_office_lights + domain: light + mode: single diff --git a/ansible/roles/podman/files/configuration.yaml b/ansible/roles/podman/files/configuration.yaml new file mode 100644 index 0000000..ab82bfd --- /dev/null +++ b/ansible/roles/podman/files/configuration.yaml @@ -0,0 +1,19 @@ +# Configure a default setup of Home Assistant (frontend, api, etc) +default_config: + +# Text to speech +tts: + - platform: google_translate +api: +http: + use_x_forwarded_for: true + trusted_proxies: + - 127.0.0.1 + - 172.0.0.0/8 + +homeassistant: + time_zone: America/New_York + media_dirs: + media: /share + +automation: !include automations.yaml diff --git a/ansible/roles/podman/handlers/main.yml b/ansible/roles/podman/handlers/main.yml new file mode 100644 index 0000000..38bba51 --- /dev/null +++ b/ansible/roles/podman/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: restorecon podman + become: true + ansible.builtin.command: | + restorecon -Frv {{ podman_home }} + tags: + - podman + - selinux diff --git a/ansible/roles/ddns/meta/main.yml b/ansible/roles/podman/meta/main.yml similarity index 100% rename from ansible/roles/ddns/meta/main.yml rename to ansible/roles/podman/meta/main.yml diff --git a/ansible/roles/ddns/tasks/awsddns.yml b/ansible/roles/podman/tasks/container-awsddns.yml similarity index 56% rename from ansible/roles/ddns/tasks/awsddns.yml rename to ansible/roles/podman/tasks/container-awsddns.yml index 5c31708..e87cf08 100644 --- a/ansible/roles/ddns/tasks/awsddns.yml +++ b/ansible/roles/podman/tasks/container-awsddns.yml @@ -1,14 +1,15 @@ --- - name: create awsddns server container + become: true + become_user: "{{ podman_user }}" diff: false - docker_container: + containers.podman.podman_container: name: awsddns - image: bdebyl/awsddns - pull: true - recreate: true + image: docker.io/bdebyl/awsddns + recreate: false restart: true restart_policy: on-failure - restart_retries: 3 + log_driver: journald env: AWS_ZONE_ID: "{{ aws_zone_id }}" AWS_ZONE_HOSTNAME: "{{ aws_zone_hostname }}" @@ -16,3 +17,9 @@ AWS_SECRET_ACCESS_KEY: "{{ aws_secret_access_key }}" AWS_DEFAULT_REGION: "{{ aws_default_region }}" tags: ddns + +- name: create systemd startup job for awsddns + include_tasks: systemd-generate.yml + vars: + container_name: awsddns + tags: ddns diff --git a/ansible/roles/podman/tasks/container-hass.yml b/ansible/roles/podman/tasks/container-hass.yml new file mode 100644 index 0000000..ff47807 --- /dev/null +++ b/ansible/roles/podman/tasks/container-hass.yml @@ -0,0 +1,57 @@ +--- +- name: create home-assistant host directory volumes + become: true + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ podman_user }}" + group: "{{ podman_user }}" + mode: 0755 + notify: restorecon podman + with_items: + - "{{ hass_path }}/media" + - "{{ hass_path }}/config" + tags: hass + +- name: copy configuration and automations + become: true + ansible.builtin.copy: + src: "files/{{ item }}" + dest: "{{ hass_path }}/config/{{ item }}" + owner: "{{ podman_user }}" + group: "{{ podman_user }}" + mode: 0644 + notify: restorecon podman + with_items: + - configuration.yaml + - automations.yaml + tags: hass + +- meta: flush_handlers + tags: hass + +- name: create home-assistant server container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: hass + image: ghcr.io/home-assistant/home-assistant:stable + recreate: false + restart: true + restart_policy: on-failure + log_driver: journald + cap_add: + - CAP_NET_RAW + - CAP_NET_BIND_SERVICE + volumes: + - "{{ hass_path }}/config:/config" + - "{{ hass_path }}/media:/share" + ports: + - "8123:8123" + tags: hass + +- name: create systemd startup job for hass + include_tasks: systemd-generate.yml + vars: + container_name: hass + tags: hass diff --git a/ansible/roles/podman/tasks/container-partkeepr.yml b/ansible/roles/podman/tasks/container-partkeepr.yml new file mode 100644 index 0000000..58dd122 --- /dev/null +++ b/ansible/roles/podman/tasks/container-partkeepr.yml @@ -0,0 +1,95 @@ +--- +- name: create required partkeepr volumes + become: true + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ podman_user }}" + group: "{{ podman_user }}" + mode: 0755 + notify: restorecon podman + with_items: + - "{{ partkeepr_path }}/mysql" + tags: partkeepr + +- meta: flush_handlers + tags: partkeepr + +- name: create partkeepr network + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_network: + name: partkeepr + tags: partkeepr + +- name: create partkeepr-db container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: partkeepr-db + image: docker.io/mariadb:10.0 + recreate: false + restart: false + restart_policy: on-failure + log_driver: journald + network: + - partkeepr + env: + MYSQL_RANDOM_ROOT_PASSWORD: "yes" + MYSQL_DATABASE: partkeepr + MYSQL_USER: partkeepr + MYSQL_PASSWORD: "{{ partkeepr_mysql_password }}" + volumes: + - "{{ partkeepr_path }}/mysql:/var/lib/mysql" + tags: partkeepr + +- name: create systemd startup job for partkeepr-db + include_tasks: systemd-generate.yml + vars: + container_name: partkeepr-db + tags: partkeepr + +- name: create partkeepr container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: partkeepr + image: docker.io/mhubig/partkeepr:latest + recreate: false + restart: false + restart_policy: on-failure + log_driver: journald + network: + - partkeepr + ports: + - "8081:80" + tags: partkeepr + +- name: create systemd startup job for partkeepr + include_tasks: systemd-generate.yml + vars: + container_name: partkeepr + tags: partkeepr + +- name: create partkeepr-cron container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: partkeepr-cron + image: docker.io/mhubig/partkeepr:latest + entrypoint: "" + command: > + bash -c "crontab /etc/cron.d/partkeepr && cron -f" + recreate: false + restart: true + restart_policy: on-failure + log_driver: journald + network: + - partkeepr + tags: partkeepr + +- name: create systemd startup job for partkeepr-cron + include_tasks: systemd-generate.yml + vars: + container_name: partkeepr-cron + tags: partkeepr diff --git a/ansible/roles/podman/tasks/main.yml b/ansible/roles/podman/tasks/main.yml new file mode 100644 index 0000000..1f0468a --- /dev/null +++ b/ansible/roles/podman/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- import_tasks: podman.yml +- import_tasks: container-awsddns.yml +- import_tasks: container-partkeepr.yml +- import_tasks: container-hass.yml diff --git a/ansible/roles/podman/tasks/podman.yml b/ansible/roles/podman/tasks/podman.yml new file mode 100644 index 0000000..85a76d7 --- /dev/null +++ b/ansible/roles/podman/tasks/podman.yml @@ -0,0 +1,58 @@ +--- +- name: create podman user + become: true + ansible.builtin.user: + name: "{{ podman_user }}" + comment: Rootless podman user + shell: /sbin/nologin + home: "{{ podman_home }}" + tags: podman + +- name: check if podman user lingering enabled + become: true + ansible.builtin.stat: + path: "/var/lib/systemd/linger/{{ podman_user }}" + register: user_lingering + tags: podman + +- name: enable podman user lingering + become: true + become_user: "{{ podman_user }}" + ansible.builtin.command: | + loginctl enable-linger {{ podman_user }} + when: + - not user_lingering.stat.exists + tags: podman + +- name: selinux context for podman directories + become: true + community.general.sefcontext: + target: "{{ item.target }}(/.*)?" + setype: "{{ item.setype }}" + state: present + notify: restorecon podman + with_items: + - { target: "{{ podman_home }}", setype: "user_home_dir_t" } + - { target: "{{ podman_path }}", setype: "container_file_t" } + tags: + - podman + - selinux + +- name: create podman system directories + become: true + become_user: "{{ podman_user }}" + ansible.builtin.file: + path: "{{ podman_home }}/{{ item }}" + state: directory + owner: "{{ podman_user }}" + group: "{{ podman_user }}" + mode: 0755 + notify: restorecon podman + with_items: + - ".config/systemd/user" + - "{{ podman_containers }}" + - "{{ podman_volumes }}" + tags: podman + +- meta: flush_handlers + tags: podman diff --git a/ansible/roles/podman/tasks/systemd-generate.yml b/ansible/roles/podman/tasks/systemd-generate.yml new file mode 100644 index 0000000..f86c062 --- /dev/null +++ b/ansible/roles/podman/tasks/systemd-generate.yml @@ -0,0 +1,17 @@ +--- +- name: create systemd startup job for {{ container_name }} + become: true + become_user: "{{ podman_user }}" + ansible.builtin.shell: | + podman generate systemd {{ container_name }} > {{ podman_home}}/.config/systemd/user/{{ container_name }}.service + tags: systemd + +- name: enable systemd startup job for {{ container_name }} + become: true + become_user: "{{ podman_user }}" + ansible.builtin.systemd: + name: "{{ container_name }}.service" + daemon_reload: true + enabled: true + scope: user + tags: systemd diff --git a/ansible/roles/ssl/defaults/main.yml b/ansible/roles/ssl/defaults/main.yml new file mode 100644 index 0000000..6b91523 --- /dev/null +++ b/ansible/roles/ssl/defaults/main.yml @@ -0,0 +1,2 @@ +--- +deps: [certbot] diff --git a/ansible/roles/ssl/tasks/certbot.yml b/ansible/roles/ssl/tasks/certbot.yml index ebda748..02ae53d 100644 --- a/ansible/roles/ssl/tasks/certbot.yml +++ b/ansible/roles/ssl/tasks/certbot.yml @@ -1,18 +1,28 @@ --- +- name: create nginx ssl directory + become: true + ansible.builtin.file: + path: /etc/nginx/ssl + owner: root + group: root + mode: 0644 + state: directory + tags: ssl + - name: stat dhparam become: true ansible.builtin.stat: - path: /etc/ssl/certs/dhparam.pem + path: /etc/nginx/ssl/dhparam.pem register: dhparam tags: ssl - name: generate openssl dhparam for nginx become: true ansible.builtin.command: | - openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 when: not dhparam.stat.exists args: - creates: /etc/ssl/certs/dhparam.pem + creates: /etc/nginx/ssl/dhparam.pem tags: ssl - name: create ssl certificate for ci server diff --git a/ansible/roles/ssl/tasks/deps.yml b/ansible/roles/ssl/tasks/deps.yml new file mode 100644 index 0000000..d712c92 --- /dev/null +++ b/ansible/roles/ssl/tasks/deps.yml @@ -0,0 +1,7 @@ +--- +- name: install ssl dependencies + become: true + ansible.builtin.package: + name: "{{ deps }}" + state: present + tags: deps diff --git a/ansible/vars/vault.yml b/ansible/vars/vault.yml index be66e12..036950b 100644 Binary files a/ansible/vars/vault.yml and b/ansible/vars/vault.yml differ