From 255bc9cb4b6221032ba9dd3e7e34a87653ce569d Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Mon, 2 May 2022 19:40:38 -0400 Subject: [PATCH] git selinux fixes, added pihole container --- ansible/inventories/home/hosts.yml | 7 +- ansible/roles/git/handlers/main.yml | 9 +++ ansible/roles/git/tasks/main.yml | 1 + ansible/roles/git/tasks/selinux.yml | 14 ++++ ansible/roles/podman/defaults/main.yml | 1 + .../podman/tasks/configuration-nginx-http.yml | 4 +- .../roles/podman/tasks/container-pihole.yml | 54 +++++++++++++ ansible/roles/podman/tasks/firewall.yml | 2 + ansible/roles/podman/tasks/main.yml | 3 +- ansible/roles/podman/tasks/podman.yml | 2 +- .../roles/podman/tasks/systemd-generate.yml | 4 +- .../nginx/sites/pi.bdebyl.net.conf.j2 | 71 ++++++------------ ansible/vars/vault.yml | Bin 5496 -> 5690 bytes 13 files changed, 112 insertions(+), 60 deletions(-) create mode 100644 ansible/roles/git/tasks/selinux.yml create mode 100644 ansible/roles/podman/tasks/container-pihole.yml diff --git a/ansible/inventories/home/hosts.yml b/ansible/inventories/home/hosts.yml index d9ed16b..51a3845 100644 --- a/ansible/inventories/home/hosts.yml +++ b/ansible/inventories/home/hosts.yml @@ -2,9 +2,4 @@ all: hosts: home.bdebyl.net: - ansible_user: ansible - children: - newhome: - hosts: - galactica.lan: - ansible_user: fedora + ansible_user: fedora diff --git a/ansible/roles/git/handlers/main.yml b/ansible/roles/git/handlers/main.yml index d43327e..755ef76 100644 --- a/ansible/roles/git/handlers/main.yml +++ b/ansible/roles/git/handlers/main.yml @@ -6,3 +6,12 @@ state: started enabled: true daemon_reload: true + tags: git + +- name: restorecon git + become: true + ansible.builtin.command: | + restorecon -Frv {{ git_home }} + tags: + - git + - selinux diff --git a/ansible/roles/git/tasks/main.yml b/ansible/roles/git/tasks/main.yml index 36bc3dd..bbcd0c2 100644 --- a/ansible/roles/git/tasks/main.yml +++ b/ansible/roles/git/tasks/main.yml @@ -1,3 +1,4 @@ --- - import_tasks: user.yml - import_tasks: systemd.yml +- import_tasks: selinux.yml diff --git a/ansible/roles/git/tasks/selinux.yml b/ansible/roles/git/tasks/selinux.yml new file mode 100644 index 0000000..7c3037c --- /dev/null +++ b/ansible/roles/git/tasks/selinux.yml @@ -0,0 +1,14 @@ +--- +- name: configure selinux git directories + become: true + community.general.sefcontext: + target: "{{ item.target }}(/.*)?" + setype: "{{ item.setype }}" + state: present + notify: restorecon git + loop: + - { target: "{{ git_home }}", setype: "user_home_dir_t" } + - { target: "{{ git_home }}/.ssh", setype: "ssh_home_t" } + tags: + - git + - selinux diff --git a/ansible/roles/podman/defaults/main.yml b/ansible/roles/podman/defaults/main.yml index 8c03e71..8f60c5d 100644 --- a/ansible/roles/podman/defaults/main.yml +++ b/ansible/roles/podman/defaults/main.yml @@ -4,6 +4,7 @@ graylog_path: "{{ podman_volumes }}/graylog" hass_path: "{{ podman_volumes }}/hass" nginx_path: "{{ podman_volumes }}/nginx" partkeepr_path: "{{ podman_volumes }}/partkeepr" +pihole_path: "{{ podman_volumes }}/pihole" drone_server_proto: "https" drone_runner_capacity: "4" diff --git a/ansible/roles/podman/tasks/configuration-nginx-http.yml b/ansible/roles/podman/tasks/configuration-nginx-http.yml index 157ac26..7f2f72b 100644 --- a/ansible/roles/podman/tasks/configuration-nginx-http.yml +++ b/ansible/roles/podman/tasks/configuration-nginx-http.yml @@ -62,7 +62,7 @@ mode: 0644 loop: - "{{ ci_server_name }}.http.conf" - # - "{{ pi_server_name }}.conf" + - "{{ pi_server_name }}.conf" - "{{ home_server_name }}.conf" - "{{ assistant_server_name }}.conf" - "{{ video_server_name }}.conf" @@ -83,7 +83,7 @@ state: link loop: - "{{ ci_server_name }}.http.conf" - # - "{{ pi_server_name }}.conf" + - "{{ pi_server_name }}.conf" - "{{ parts_server_name }}.conf" - "{{ home_server_name }}.conf" - "{{ assistant_server_name }}.conf" diff --git a/ansible/roles/podman/tasks/container-pihole.yml b/ansible/roles/podman/tasks/container-pihole.yml new file mode 100644 index 0000000..eca4f06 --- /dev/null +++ b/ansible/roles/podman/tasks/container-pihole.yml @@ -0,0 +1,54 @@ +--- +- name: create required pihole volumes + become: true + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ podman_user }}" + group: "{{ podman_user }}" + mode: 0755 + notify: restorecon podman + loop: + - "{{ pihole_path }}/config" + - "{{ pihole_path }}/dnsmasq" + tags: pihole + +- name: flush handlers + ansible.builtin.meta: flush_handlers + tags: pihole + +- name: create pihole container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: pihole + image: docker.io/pihole/pihole:2022.04.3 + recreate: false + restart: true + restart_policy: on-failure + log_driver: journald + cap_add: + - CAP_NET_BIND_SERVICE + - NET_ADMIN + network: + - host + env: + DNSMASQ_USER: "root" + PIHOLE_UID: 0 + TZ: "America/New_York" + WEBPASSWORD: "{{ pihole_password }}" + WEB_PORT: 8082 + volumes: + - "{{ pihole_path }}/config:/etc/pihole" + - "{{ pihole_path }}/dnsmasq:/etc/dnsmasq.d" + ports: + - 53:53/udp + - 53:53/tcp + - 8082:80 + tags: pihole + +- name: create systemd startup job for pihole + include_tasks: systemd-generate.yml + vars: + container_name: pihole + tags: pihole diff --git a/ansible/roles/podman/tasks/firewall.yml b/ansible/roles/podman/tasks/firewall.yml index 56a46d4..bfda749 100644 --- a/ansible/roles/podman/tasks/firewall.yml +++ b/ansible/roles/podman/tasks/firewall.yml @@ -6,6 +6,8 @@ permanent: true state: enabled loop: + - 53/tcp + - 53/udp - 80/tcp - 443/tcp - "{{ syslog_udp_default }}/udp" diff --git a/ansible/roles/podman/tasks/main.yml b/ansible/roles/podman/tasks/main.yml index 25ab71e..22d9974 100644 --- a/ansible/roles/podman/tasks/main.yml +++ b/ansible/roles/podman/tasks/main.yml @@ -6,5 +6,6 @@ - import_tasks: container-drone.yml - import_tasks: container-hass.yml - import_tasks: container-partkeepr.yml -- import_tasks: container-nginx.yml - import_tasks: container-graylog.yml +- import_tasks: container-pihole.yml +- import_tasks: container-nginx.yml diff --git a/ansible/roles/podman/tasks/podman.yml b/ansible/roles/podman/tasks/podman.yml index 6d97c72..18c22af 100644 --- a/ansible/roles/podman/tasks/podman.yml +++ b/ansible/roles/podman/tasks/podman.yml @@ -91,7 +91,7 @@ become: true ansible.posix.sysctl: name: net.ipv4.ip_unprivileged_port_start - value: "80" + value: "53" sysctl_set: true state: present reload: true diff --git a/ansible/roles/podman/tasks/systemd-generate.yml b/ansible/roles/podman/tasks/systemd-generate.yml index 6562c34..d123593 100644 --- a/ansible/roles/podman/tasks/systemd-generate.yml +++ b/ansible/roles/podman/tasks/systemd-generate.yml @@ -5,7 +5,7 @@ changed_when: false ansible.builtin.shell: | podman generate systemd --name {{ container_name }} > {{ podman_home }}/.config/systemd/user/{{ container_name }}.service - tags: systemd + tags: always - name: enable systemd startup job for {{ container_name }} become: true @@ -21,4 +21,4 @@ delay: 1 until: result is not failed ignore_errors: true - tags: systemd + tags: always diff --git a/ansible/roles/podman/templates/nginx/sites/pi.bdebyl.net.conf.j2 b/ansible/roles/podman/templates/nginx/sites/pi.bdebyl.net.conf.j2 index 1bd518e..0659c94 100644 --- a/ansible/roles/podman/templates/nginx/sites/pi.bdebyl.net.conf.j2 +++ b/ansible/roles/podman/templates/nginx/sites/pi.bdebyl.net.conf.j2 @@ -1,57 +1,32 @@ -# -# /etc/nginx/conf.d/pihole.conf -# -# https://github.com/pi-hole/pi-hole/wiki/Nginx-Configuration -# +upstream pihole { + server 127.0.0.1:8082; +} + +geo $local_access { + default 0; + 192.168.1.0/24 1; +} server { modsecurity on; modsecurity_rules_file /etc/nginx/modsec_includes.conf; - listen 80; + listen 80; + server_name {{ pi_server_name }}; - root /srv/http/pihole; - server_name {{ pi_server_name }}; - autoindex off; + location / { + if ($local_access = 1) { + access_log off; + } + allow 192.168.1.0/24; + allow 127.0.0.1; + deny all; - proxy_intercept_errors on; - error_page 404 /pihole/index.php; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; - index pihole/index.php index.php index.html index.htm; - - allow 192.168.1.0/24; - allow 127.0.0.1; - deny all; - - location / { - expires max; - try_files $uri $uri/ =404; - add_header X-Pi-hole "A black hole for Internet advertisements"; - } - - location ~ \.php$ { - include fastcgi.conf; - fastcgi_intercept_errors on; - fastcgi_pass unix:/run/php-fpm/php-fpm.sock; - fastcgi_param VIRTUAL_HOST open_basedir="/srv/http/pihole:run/pihole-ftl/pihole-FTL.port:run/log/pihole/pihole.log:run/log/pihole-ftl/pihole-FTL.log:etc/pihole:etc/hosts:etc/hostname:etc/dnsmasq.d/02-pihole-dhcp.conf:etc/dnsmasq.d/03-pihole-wildcard.conf:etc/dnsmasq.d/04-pihole-static-dhcp.conf:var/log/lighttpd/error.log:proc/meminfo:proc/cpuinfo:sys/class/thermal/thermal_zone0/temp:tmp"; - } - - location /admin { - root /srv/http/pihole; - index index.php index.html index.htm; - add_header X-Pi-hole "The Pi-hole Web interface is working!"; - add_header X-Frame-Options "DENY"; - } - - location ~ /\.ttf { - add_header Access-Control-Allow-Origin "*"; - } - - location ~ /admin/\. { - deny all; - } - - location ~ /\.ht { - deny all; - } + proxy_buffering off; + proxy_pass http://pihole; + } } \ No newline at end of file diff --git a/ansible/vars/vault.yml b/ansible/vars/vault.yml index 036950b1d01ecda779e9b0aa2446e030b55c910d..666a1309f44960d2199e9cf57def27c2c1971bf3 100644 GIT binary patch literal 5690 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 z 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