diff --git a/.gitignore b/.gitignore index 2b15661..c32c404 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,8 @@ operations/variable-scripts/variable.json ### ANSIBLE -*.retry \ No newline at end of file +*.retry + +### OTHER +*.env +.env diff --git a/applications/roles/authsec.pihole/LICENSE b/applications/roles/authsec.pihole/LICENSE new file mode 100644 index 0000000..f30cbee --- /dev/null +++ b/applications/roles/authsec.pihole/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Jens Frey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/applications/roles/authsec.pihole/README.md b/applications/roles/authsec.pihole/README.md new file mode 100644 index 0000000..3fe19ea --- /dev/null +++ b/applications/roles/authsec.pihole/README.md @@ -0,0 +1,241 @@ +# Pihole + + +Pi-hole role. This will install [Pi-hole®: A black hole for Internet +advertisements – A black hole for Internet +advertisements](https://pi-hole.net/) for you. + +It also helps you administering Pi-Hole using a simple CSV file that you can +edit with your favourite editor. + +## Requirements + +A host running Ubuntu/Debian/Photon OS or e.g. a raspberry pi running Raspberry +Pi OS (Lite). + +If you run into problems, a look into the [Pi-hole +documentation](https://docs.pi-hole.net/docker/dhcp/) may help. + +### Host CSV File + +Pi-hole configuration is done via a csv file. This gives you a nice overview +and makes it easy to manage your environment. + +The role includes a full example CSV file in the `files` folder for you to +review. + +The following lines do show `dhcp-option` settings that will be written into +the dnsmasq configuration file. The lines tag one IP address as the vm based +DNS server and the raspberry pi based DNS server running on an actual raspberry +pi. + +#### Set DHCP Options + +``` csv +hostname,domainname,ip_address,static,mac_address,dhcp_option,type,comment +,,,,,"tag:vm-dns,option:dns-server,192.168.30.253","<>","Sets value of dhcp-option configuration option, here which DNS server to use" +,,,,,"tag:pi-dns,option:dns-server,192.168.30.254","<>","Sets value of dhcp-option configuration option, here which DNS server to use" +``` + +**Note:** If you are setting up multiple DNS servers here, you probably do want +to set the `riv_pihole_dns_default_tag` option when configuring your setup to set a default DNS server +for clients without a specific configuration. + +#### Setup IP/Host mapping + +The configuration below configures the host with the name `slash` to receive an +IP address of `192.168.128.2` if that address is still available. If a DHCP +lease was already handed out to another machine, a new IP address will be +assigned. It also identifies the machine as a physical host. + +``` csv +hostname,domainname,ip_address,static,mac_address,dhcp_option,type,comment +slash,example.net,192.168.128.2,true,,,"<>","ESXi Host"" +``` + +#### Setup static IP address + +If you want to make sure that the IP address is assigned to a specific hostname +only, you can set the `static` field to `true` to achieve that. Setting this +option will instruct dnsmasq to ignore DHCP requests from any host named +`vmhole` as shown in the example below. The type is also identified as a virtual machine. + +``` csv +hostname,domainname,ip_address,static,mac_address,dhcp_option,type,comment +vmhole,example.net,192.168.128.253,true,,,"<>","Pi-hole Virtual machine DNS server" +``` + +#### Setup Mac address/IP address mapping + +To assign a specific IP address and hostname to a special device using the mac +address of the device, use the following entry in the csv configuration +database. + +``` csv +hostname,domainname,ip_address,static,mac_address,dhcp_option,type,comment +blib,example.net,192.168.128.18,,00:0c:29:43:37:dc,,"<>","Pi-hole Virtual machine DNS server" +``` + +#### Set different DNS server + +Setting up a special DNS server for some devices can be achieved by supplying +the appropriate DHCP option when defining the mapping. The below example shows +how to set the `vm-dns` DNS server for the photon host. + +``` csv +hostname,domainname,ip_address,static,mac_address,dhcp_option,type,comment +photon,example.net,192.168.128.19,,00:0c:29:51:80:1f,"vm-dns","<>","Proxy server VM based on a docker image, using vm-dns server" +``` + +## Role Variables + +The role uses the following variables: + +| Variable | Default | Description | +| ------------------------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| riv_pihole_admin_password_generated | {{ lookup('password', '/dev/null length=15 chars=ascii_letters') }} | This variable sets the password for the web user interface. If no password is set, it will be auto-generated. The password value is shown in plain text in the last step if the variable `riv_pihole_show_summary` is set to `true`. | +| riv_pihole_dns_default_tag | | This variable sets a DHCP tag that lets you specify a default DNS server for hosts not listed in the configuration csv file. | +| riv_pihole_show_summary | false | If set `true` the last step will show the (generated) password in plain text along with some useful information like the IP address and name of the host pihole was installed on. | +| riv_pihole_docker_network | host | The network to which docker connects. If you want to use DHCP, you need to connect to the host network. | +| riv_pihole_docker_purge_networks | yes | Remove the created network when the docker container is shut down. | +| riv_pihole_dhcp_active | false | Enable or disable the built-in DHCP server. If you want to use Pi-hole as DHCP server, you need to turn this on. | +| riv_pihole_dhcp_leasetime | 24h | The default lease time to set when handing out a client IP address | +| riv_pihole_dhcp_start | 192.168.1.2 | The starting range of the built-in DHCP server. | +| riv_pihole_dhcp_end | 192.168.1.253 | The last address of the built-in DHCP server. | +| riv_pihole_dhcp_router | 192.168.1.1 | The router which should be advertised to clients getting an IP address. | +| riv_pihole_domain | example.net | The domain of your local network. | +| riv_pihole_interface | eth0 | The interface processes inside Pi-hole will bind to | +| riv_pihole_dhcp_ipv6 | false | Enable IPv6 support on DHCP. | +| riv_pihole_dhcp_rapid_commit | false | Control switch for the rapid commit option. | +| riv_pihole_dnsmasq_listening | all | The interface dnsmasq should listen on. | +| riv_pihole_query_logging | true | Log DNS queries. | +| riv_pihole_install_web_server | true | Install the built in Web-Server | +| riv_pihole_install_web_interface | true | Install the Web-Interface. | +| riv_pihole_lighttpd_enabled | | Enable lighttpd | +| riv_pihole_ipv4_address | {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] \| default(ansible_host) }} | The IPv4 address you want Pi-Hole to listen on. | +| riv_pihole_ipv6_address | | The IPv6 address you want Pi-Hole to listen on. | +| riv_pihole_dns_bogus_priv | | Control bogus private reverse lookups | +| riv_pihole_dns_fqdn_required | | Controls if the unqualified name is put into DNS as well | +| riv_pihole_dnssec | | Control DNSSEC | +| riv_pihole_rev_server_enabled | | Enable DNS conditional forwarding for device name resolution. | +| riv_pihole_rev_server_cidr | | If conditional forwarding is enabled, set the reverse DNS zone (e.g. 192.168.0.0/24) | +| riv_pihole_rev_server_domain | | If conditional forwarding is enabled, set the domain of the local network router (e.g example.net). | +| riv_pihole_rev_server_target | | If conditional forwarding is enabled, set the IP of the local network router. | +| riv_pihole_docker_image | pihole/pihole:latest | Which docker image to pull. You can e.g. specify a version. | +| riv_pihole_configuration_base_folder | /opt/pihole | Where do you want your configuration to live on the target host. | +| riv_pihole_etc_pihole_folder | {{ riv_pihole_configuration_base_folder }}/pihole | Control position of pihole folder. | +| riv_pihole_etc_dnsmasq_folder | {{ riv_pihole_configuration_base_folder }}/dnsmasq.d | Control position of dnsmasq.d folder. | +| riv_pihole_sys_dns_server1 | 127.0.0.1 | System DNS servers for Pi-hole. The first one HAS TO BE 127.0.0.1 | +| riv_pihole_sys_dns_server2 | 8.8.8.8 | System DNS server for Pi-hole | +| riv_pihole_dns_server1 | 1.1.1.1 | DNS Server used inside the docker container | +| riv_pihole_dns_server2 | 8.8.8.8 | DNS Server used inside the docker container | +| riv_pihole_serverip | {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] \| default(ansible_host) }} | The IP address of the Pi-hole host | +| riv_pihole_timezone | Europe/Berlin | Your timezone | +| riv_pihole_open_firewall_ports | true | Set to false if you don't want the role to open required firewall ports. | +| riv_pihole_dns_db_configuration_file | {{ role_path }}/files/mappings.csv | The location of the DNS configuration file. The default file pointed to should be copied and adopted appropriately. | + +## Example Playbook + +The example below shows a playbook you can use to configure pi-hole on a Photon +OS based virtual machine which is reflected in the inventory file. + +### Folder structure + +The folder structure is as follows (the roles folder will be created automatically later): + +``` +|-- dns-db.csv +|-- inventory +|-- pihole-vm.yml +`-- roles + `-- authsec.pihole + |-- defaults + | `-- main.yml + |-- files + | `-- mappings.csv + |-- LICENSE + |-- meta + | `-- main.yml + |-- README.md + |-- tasks + | |-- checkssh-photonos.yml + | |-- checkssh.yml + | |-- firewall-iptables.yml + | |-- install-apt.yml + | |-- install-photonos.yml + | `-- main.yml + `-- templates + |-- 02-pihole-dhcp.conf.j2 + |-- 10-pihole-custom-static.conf.j2 + `-- setupVars.conf.j2 +``` + +### Import Role + +You can import the role into your project using: + +``` bash +#> ansible-galaxy install -p roles authsec.pihole +``` + +### Create database + +This is a copy of the example database in `roles/authsec.pihole/files`. + +**dns-db.csv:** + +``` csv +hostname,domainname,ip_address,static,mac_address,dhcp_option,comment +,,,,,"tag:vm-dns,option:dns-server,192.168.128.253","Sets value of dhcp-option configuration option" +,,,,,"tag:pi-dns,option:dns-server,192.168.128.254","Sets value of dhcp-option configuration option" +slash,example.net,192.168.128.2,,,,"ESXi Host" +mohh,example.net,192.168.128.5,,,,"The Brain (vCenter Server)" +blib,example.net,192.168.128.18,,00:0c:29:43:37:dc,"pi-dns","VM using Raspberry Pi based DNS (and DHCP) server" +photon,example.net,192.168.128.19,,00:0c:29:51:80:1f,"vm-dns","VM using VM based DNS server" +vmhole,example.net,192.168.128.253,true,,,"Pi-hole Virtual machine DNS server" +pihole,example.net,192.168.128.254,,,,"Raspberry Pi backed Pi-Hole DNS and DHCP server for this network, docker based and ansible managed" +``` + +**inventory:** + +``` +[dns_vms] +vmhole.example.net ansible_host=192.168.128.253 ansible_user=pihole ansible_become_method='su' ansible_become_password='kevin.is.dead' ansible_python_interpreter=/usr/bin/python3 +``` + +**pihole-vm.yml:** + +``` yaml +--- +# Configure a machine to run pi-hole inside a docker container +- hosts: dns_vms + gather_facts: yes + become: yes + tasks: + - include_role: + name: authsec.pihole + vars: + # true|false + riv_pihole_admin_password: "secure.me" + riv_pihole_dhcp_active: "false" + riv_pihole_dhcp_start: "192.168.128.8" + riv_pihole_dhcp_end: "192.168.128.252" + riv_pihole_dhcp_router: "192.168.128.1" + riv_pihole_domain: "example.net" + riv_pihole_show_summary: true + riv_pihole_dns_db_configuration_file: "dns-db.csv" +``` + +### Run ansible + +Once everything is configured, you can run `ansible` to setup pi-hole on the +system configured in the `inventory`. + +``` bash +#> ansible-playbook -i inventory pihole-vm.yml +``` + +License +------- + +MIT diff --git a/applications/roles/authsec.pihole/defaults/main.yml b/applications/roles/authsec.pihole/defaults/main.yml new file mode 100644 index 0000000..3240dab --- /dev/null +++ b/applications/roles/authsec.pihole/defaults/main.yml @@ -0,0 +1,65 @@ +--- +# tasks file for pihole + +# Generate a secure default password +riv_pihole_admin_password_generated: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}" +riv_pihole_docker_network: "host" +riv_pihole_docker_purge_networks: "yes" + +# If you are using tags to assign multiple DNS servers to an IP address, +# you can use this option to set a default, where you do not want to define +# a specific IP address to name mapping. +riv_pihole_dns_default_tag: "" + +riv_pihole_show_summary: false + +riv_pihole_dhcp_active: "false" +# 1 day lease +riv_pihole_dhcp_leasetime: "24h" +riv_pihole_dhcp_start: "192.168.1.2" +riv_pihole_dhcp_end: "192.168.1.253" +riv_pihole_dhcp_router: "192.168.1.1" +riv_pihole_domain: "example.net" +riv_pihole_interface: "eth0" + +riv_pihole_dhcp_ipv6: "false" +riv_pihole_dhcp_rapid_commit: "false" +riv_pihole_dnsmasq_listening: "all" +riv_pihole_query_logging: "true" +riv_pihole_install_web_server: "true" +riv_pihole_install_web_interface: "true" +riv_pihole_lighttpd_enabled: "" +riv_pihole_ipv4_address: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] | default(ansible_host) }}" +riv_pihole_ipv6_address: "" +riv_pihole_dns_bogus_priv: "false" +riv_pihole_dns_fqdn_required: "false" +riv_pihole_dnssec: "false" +riv_pihole_rev_server_enabled: "false" # previously conditional forwarding (riv_pihole_conditional_forwarding) +riv_pihole_rev_server_cidr: "" # previously conditional forwarding IP (riv_pihole_conditional_forwarding_ip) +riv_pihole_rev_server_domain: "" # previously conditional forwarding domain (riv_pihole_conditional_forwarding_domain) +riv_pihole_rev_server_target: "" # previously conditional forwarding host (riv_pihole_conditional_forwarding_reverse) + +riv_pihole_docker_image: "pihole/pihole:latest" + +riv_pihole_configuration_base_folder: "/opt/pihole" +riv_pihole_etc_pihole_folder: "{{ riv_pihole_configuration_base_folder }}/pihole" +riv_pihole_etc_dnsmasq_folder: "{{ riv_pihole_configuration_base_folder }}/dnsmasq.d" + +# These are the DNS servers for the docker system +# The first one MUST be 127.0.0.1 +riv_pihole_sys_dns_server1: "127.0.0.1" +riv_pihole_sys_dns_server2: "8.8.8.8" + +# These are the DNS servers that Pi-hole uses to resolve +riv_pihole_dns_server1: "1.1.1.1" +riv_pihole_dns_server2: "8.8.8.8" + +riv_pihole_serverip: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] | default(ansible_host) }}" + +riv_pihole_timezone: "Europe/Berlin" + +# Photon OS e.g. has the firewall locked by default, if this is enabled +# the necessary ports will be opened +riv_pihole_open_firewall_ports: true + +riv_pihole_dns_db_configuration_file: "{{ role_path }}/files/mappings.csv" \ No newline at end of file diff --git a/applications/roles/authsec.pihole/files/mappings.csv b/applications/roles/authsec.pihole/files/mappings.csv new file mode 100755 index 0000000..2b13024 --- /dev/null +++ b/applications/roles/authsec.pihole/files/mappings.csv @@ -0,0 +1,11 @@ +hostname,domainname,ip_address,static,mac_address,dhcp_option,type,comment +,,,,,"tag:vm-dns,option:dns-server,192.168.128.253","<>","Sets value of dhcp-option configuration option, here which DNS server to use" +,,,,,"tag:pi-dns,option:dns-server,192.168.128.254","<>","Sets value of dhcp-option configuration option, here which DNS server to use" +slash,example.net,192.168.128.2,true,f4:02:70:b6:17:d2,,"<>","ESXi Host" +dudu,example.net,192.168.128.3,true,,,"<>","dudu node" +mohh,example.net,192.168.128.5,true,,,"<>","vCenter installation" +ku,example.net,192.168.128.250,true,,"pi-dns","<>","Control node" +proxy,example.net,192.168.128.252,true,,"vm-dns","<>","Proxy server VM based on a docker image" +wpad,example.net,192.168.128.252,,,,"<>","Proxy autodiscovery alias" +vmhole,example.net,192.168.128.253,true,,,"<>","Pi-hole based VM DNS server with statically assigned IP (static prevents DHCP from handing out that IP/DNS name combination)" +opihi,example.net,192.168.128.254,,b8:27:eb:24:32:1b,,"<>","Raspberry Pi backed Pi-Hole DNS and DHCP server for this network, docker based and ansible managed" diff --git a/applications/roles/authsec.pihole/meta/.galaxy_install_info b/applications/roles/authsec.pihole/meta/.galaxy_install_info new file mode 100644 index 0000000..26b130d --- /dev/null +++ b/applications/roles/authsec.pihole/meta/.galaxy_install_info @@ -0,0 +1,2 @@ +install_date: Mon Jun 13 19:57:14 2022 +version: master diff --git a/applications/roles/authsec.pihole/meta/main.yml b/applications/roles/authsec.pihole/meta/main.yml new file mode 100644 index 0000000..c3c71bd --- /dev/null +++ b/applications/roles/authsec.pihole/meta/main.yml @@ -0,0 +1,26 @@ +galaxy_info: + role_name: pihole + author: Jens Frey + description: Install, run and configure Pi-Hole using docker and a CSV file where you can map your hosts to IP addresses. + license: MIT + + min_ansible_version: 2.9 + + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + platforms: + - name: Debian + versions: + - buster + - name: Ubuntu + versions: + - focal + + galaxy_tags: + - pihole + - raspberry + - raspberrypi + - rpi + - photonos + +dependencies: [] \ No newline at end of file diff --git a/applications/roles/authsec.pihole/tasks/checkssh-photonos.yml b/applications/roles/authsec.pihole/tasks/checkssh-photonos.yml new file mode 100644 index 0000000..8ea881d --- /dev/null +++ b/applications/roles/authsec.pihole/tasks/checkssh-photonos.yml @@ -0,0 +1,5 @@ +- name: Make sure ssh is enabled, not just started + systemd: + name: sshd.service + enabled: true + state: started \ No newline at end of file diff --git a/applications/roles/authsec.pihole/tasks/checkssh.yml b/applications/roles/authsec.pihole/tasks/checkssh.yml new file mode 100644 index 0000000..9b20139 --- /dev/null +++ b/applications/roles/authsec.pihole/tasks/checkssh.yml @@ -0,0 +1,5 @@ +- name: Make sure ssh is enabled, not just started + systemd: + name: ssh.service + enabled: true + state: started \ No newline at end of file diff --git a/applications/roles/authsec.pihole/tasks/firewall-iptables.yml b/applications/roles/authsec.pihole/tasks/firewall-iptables.yml new file mode 100644 index 0000000..e83b155 --- /dev/null +++ b/applications/roles/authsec.pihole/tasks/firewall-iptables.yml @@ -0,0 +1,41 @@ +- name: Allow ping + iptables: + chain: INPUT + jump: ACCEPT + protocol: icmp + +- name: Allow DHCP + iptables: + chain: INPUT + protocol: udp + destination_port: "67" + jump: ACCEPT + when: riv_pihole_dhcp_active|bool + +- name: Allow HTTP + iptables: + chain: INPUT + protocol: tcp + destination_port: "80" + jump: ACCEPT + +- name: Allow HTTPS + iptables: + chain: INPUT + protocol: tcp + destination_port: "443" + jump: ACCEPT + +- name: Allow UDP DNS queries + iptables: + chain: INPUT + protocol: udp + destination_port: "53" + jump: ACCEPT + +- name: Allow TCP DNS queries + iptables: + chain: INPUT + protocol: tcp + destination_port: "53" + jump: ACCEPT \ No newline at end of file diff --git a/applications/roles/authsec.pihole/tasks/install-apt.yml b/applications/roles/authsec.pihole/tasks/install-apt.yml new file mode 100644 index 0000000..618a14a --- /dev/null +++ b/applications/roles/authsec.pihole/tasks/install-apt.yml @@ -0,0 +1,6 @@ +- name: Install docker and pip3 + apt: + pkg: + - docker.io + - python3-pip + state: present \ No newline at end of file diff --git a/applications/roles/authsec.pihole/tasks/install-photonos.yml b/applications/roles/authsec.pihole/tasks/install-photonos.yml new file mode 100644 index 0000000..5317862 --- /dev/null +++ b/applications/roles/authsec.pihole/tasks/install-photonos.yml @@ -0,0 +1,5 @@ +- name: Install docker and pip3 + command: tdnf -y install docker python3-pip + register: result + changed_when: + - '"Complete!" in result.stdout' \ No newline at end of file diff --git a/applications/roles/authsec.pihole/tasks/main.yml b/applications/roles/authsec.pihole/tasks/main.yml new file mode 100644 index 0000000..ccc8d52 --- /dev/null +++ b/applications/roles/authsec.pihole/tasks/main.yml @@ -0,0 +1,159 @@ +--- +- name: Setting or generating password for web interface + set_fact: + riv_pihole_admin_password: "{{ riv_pihole_admin_password_generated }}" + when: riv_pihole_admin_password is undefined +- name: Ensure resolv.conf absent + file: + path: /etc/resolv.conf + state: absent +- name: Ensure we do have DNS available for the installation. + lineinfile: + path: /etc/resolv.conf + insertbefore: '^{{ item.property | regex_escape() }} ' + line: '{{ item.property }} {{ item.value }}' + create: true + with_items: + - { property: 'nameserver', value: '127.0.0.1'} + - { property: 'nameserver', value: '9.9.9.9'} + - { property: 'search', value: "{{ riv_pihole_domain }}" } +- name: Running apt install environment + include_tasks: + file: install-apt.yml + when: + - (ansible_facts['distribution'] == 'Debian') or (ansible_facts['distribution'] == 'Ubuntu') +- name: Running photon os install environment + include_tasks: + file: install-photonos.yml + when: + - ansible_facts['distribution'] == 'VMware Photon OS' +- name: Install python docker support + pip: + name: docker + state: present +- name: Ensure docker is up + systemd: + name: docker + enabled: true + state: started +- name: Pull Pi-hole image before resolved is shut down + docker_image: + name: "{{ riv_pihole_docker_image }}" + force_source: yes + source: pull +- name: Running general SSH check + include_tasks: + file: checkssh.yml + when: + - ansible_facts['distribution'] != 'VMware Photon OS' +- name: Running Photon OS SSH check + include_tasks: + file: checkssh-photonos.yml + when: + - ansible_facts['distribution'] == 'VMware Photon OS' +- name: Make sure default resolved service is stopped + systemd: + name: systemd-resolved.service + enabled: false + state: stopped +- name: Read configuration data + read_csv: + path: "{{ riv_pihole_dns_db_configuration_file }}" + delimiter: ',' + register: mappings + delegate_to: localhost + become: no +- name: Ensure pihole folder is present + file: + path: "{{ riv_pihole_etc_pihole_folder }}" + state: directory + mode: '0775' +- name: Ensure dnsmasq.d folder is present + file: + path: "{{ riv_pihole_etc_dnsmasq_folder }}" + state: directory + mode: '0755' +- name: Generate encoded Pi-hole WEBPASSWORD + shell: set -o pipefail && echo -n $(echo -n "{{ riv_pihole_admin_password }}" | sha256sum | sed 's/\s.*$//') | sha256sum | sed 's/\s.*$//' + args: + executable: /bin/bash + register: riv_pihole_admin_password_encoded + changed_when: false +- name: Provision Pihole config + template: + src: setupVars.conf.j2 + dest: "{{ riv_pihole_etc_pihole_folder }}/setupVars.conf" + mode: '0644' + register: riv_pihole_config +- name: Provision DNS configuration + template: + src: 10-pihole-custom-static.conf.j2 + dest: "{{ riv_pihole_etc_dnsmasq_folder }}/10-pihole-custom-static.conf" + owner: root + group: root + mode: '0644' + register: riv_pihole_dns_config + vars: + mappings: mappings +- name: Provision DHCP configuration + template: + src: 02-pihole-dhcp.conf.j2 + dest: "{{ riv_pihole_etc_dnsmasq_folder }}/02-pihole-dhcp.conf" + owner: root + group: root + mode: '0644' + register: riv_pihole_dhcp_config +- name: Provisioning host aliases + template: + src: ansible-managed.hosts.j2 + dest: "{{ riv_pihole_etc_pihole_folder }}/ansible-managed.hosts" + owner: root + group: root + mode: '0644' + register: riv_pihole_dns_alias_config + vars: + mappings: mappings +- name: Setting up firewall + include_tasks: + file: firewall-iptables.yml + when: riv_pihole_open_firewall_ports +- name: Ensure pihole docker container is running + docker_container: + name: pihole + image: "{{ riv_pihole_docker_image }}" + state: started + restart: "{{ riv_pihole_config.changed or riv_pihole_dns_config.changed or riv_pihole_dhcp_config.changed }}" + restart_policy: unless-stopped + networks_cli_compatible: yes + network_mode: host + networks: + - name: "{{ riv_pihole_docker_network }}" + capabilities: + - NET_ADMIN + dns_servers: + - "{{ riv_pihole_sys_dns_server1 }}" + - "{{ riv_pihole_sys_dns_server2 }}" + volumes: + - "{{ riv_pihole_etc_pihole_folder }}:/etc/pihole/" + - "{{ riv_pihole_etc_dnsmasq_folder }}:/etc/dnsmasq.d/" + env: + TZ: '{{ riv_pihole_timezone }}' + DNS1: '{{ riv_pihole_dns_server1 }}' + DNS2: '{{ riv_pihole_dns_server2 }}' + WEBPASSWORD: "{{ riv_pihole_admin_password }}" + ServerIP: "{{ riv_pihole_serverip }}" + REV_SERVER: "{{ riv_pihole_rev_server_enabled }}" + REV_SERVER_CIDR: "{{ riv_pihole_rev_server_cidr }}" + REV_SERVER_DOMAIN: "{{ riv_pihole_rev_server_domain }}" + REV_SERVER_TARGET: "{{ riv_pihole_rev_server_target }}" +- name: DNS/DHCP server summary + pause: + seconds: 1 + prompt: | + Pi-Hole web PASSWORD: "{{ riv_pihole_admin_password }}" + Pi-Hole Server IP: "{{ riv_pihole_serverip }}" + Pi-Hole Server Name: "{{ inventory_hostname }}" + Pi-Hole DHCP server active: "{{ riv_pihole_dhcp_active }}" + changed_when: false + when: riv_pihole_show_summary + delegate_to: localhost diff --git a/applications/roles/authsec.pihole/templates/02-pihole-dhcp.conf.j2 b/applications/roles/authsec.pihole/templates/02-pihole-dhcp.conf.j2 new file mode 100644 index 0000000..df91fd0 --- /dev/null +++ b/applications/roles/authsec.pihole/templates/02-pihole-dhcp.conf.j2 @@ -0,0 +1,11 @@ +############################################################################### +# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. # +# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE # +############################################################################### +dhcp-authoritative +dhcp-range={% if riv_pihole_dns_default_tag is defined and riv_pihole_dns_default_tag|length >0%}set:{{ riv_pihole_dns_default_tag }},{% endif %}{{ riv_pihole_dhcp_start }},{{ riv_pihole_dhcp_end }},{{ riv_pihole_dhcp_leasetime }} +dhcp-option=option:router,{{ riv_pihole_dhcp_router }} +dhcp-leasefile=/etc/pihole/dhcp.leases +#quiet-dhcp + +domain={{ riv_pihole_domain }} \ No newline at end of file diff --git a/applications/roles/authsec.pihole/templates/10-pihole-custom-static.conf.j2 b/applications/roles/authsec.pihole/templates/10-pihole-custom-static.conf.j2 new file mode 100644 index 0000000..56676aa --- /dev/null +++ b/applications/roles/authsec.pihole/templates/10-pihole-custom-static.conf.j2 @@ -0,0 +1,18 @@ +# {{ ansible_managed }} + +# Change dhcp-option to dhcp-option-force if you need PXELinux support +{% for item in mappings.list %} +{% if item.type=="<>" %} +dhcp-option={{ item.dhcp_option }} +{% elif item.type=="<>" or item.type=="<>" %} + +# {{ item.comment }} +address=/{{ item.hostname }}.{{ item.domainname }}/{{ item.ip_address }} +ptr-record={{ (item.ip_address.split('.'))[::-1]|join('.') }}.in-addr.arpa,{{ item.hostname }}.{{ item.domainname }} +dhcp-host={% if item.mac_address is defined and item.mac_address|length %}{{ item.mac_address }},{% endif %}{% if item.dhcp_option is defined and item.dhcp_option|length >0%}set:{{ item.dhcp_option }},{% endif %}{{ item.ip_address }},{{ item.hostname }}{% if item.static is defined and item.static|length%},ignore{% endif %} + +{% endif %} +{% endfor %} + +# Include ansible managed static hosts +addn-hosts=/etc/pihole/ansible-managed.hosts diff --git a/applications/roles/authsec.pihole/templates/ansible-managed.hosts.j2 b/applications/roles/authsec.pihole/templates/ansible-managed.hosts.j2 new file mode 100644 index 0000000..d22ee66 --- /dev/null +++ b/applications/roles/authsec.pihole/templates/ansible-managed.hosts.j2 @@ -0,0 +1,9 @@ +# {{ ansible_managed }} + +{% for item in mappings.list %} +{% if item.type=="<>" %} +# {{ item.comment }} +{{ item.ip_address }} {{ item.hostname }} {{ item.hostname }}.{{ item.domainname }} + +{% endif %} +{% endfor %} \ No newline at end of file diff --git a/applications/roles/authsec.pihole/templates/setupVars.conf.j2 b/applications/roles/authsec.pihole/templates/setupVars.conf.j2 new file mode 100644 index 0000000..cc6b41e --- /dev/null +++ b/applications/roles/authsec.pihole/templates/setupVars.conf.j2 @@ -0,0 +1,33 @@ +# {{ ansible_managed }} + +BLOCKING_ENABLED=true +DHCP_ACTIVE={{ riv_pihole_dhcp_active }} +DHCP_START={{ riv_pihole_dhcp_start }} +DHCP_END={{ riv_pihole_dhcp_end }} +DHCP_ROUTER={{ riv_pihole_dhcp_router }} +DHCP_LEASETIME={{ riv_pihole_dhcp_leasetime }} +PIHOLE_DOMAIN={{ riv_pihole_domain }} +DHCP_IPv6={{ riv_pihole_dhcp_ipv6 }} +DHCP_rapid_commit={{ riv_pihole_dhcp_rapid_commit }} +DNSMASQ_LISTENING={{ riv_pihole_dnsmasq_listening }} +PIHOLE_DNS_1={{ riv_pihole_dns_server1 }} +PIHOLE_DNS_2={{ riv_pihole_dns_server2 }} +WEBPASSWORD={{ riv_pihole_admin_password_encoded.stdout }} +QUERY_LOGGING={{ riv_pihole_query_logging }} +INSTALL_WEB_SERVER={{ riv_pihole_install_web_server }} +INSTALL_WEB_INTERFACE={{ riv_pihole_install_web_interface }} +LIGHTTPD_ENABLED={{ riv_pihole_lighttpd_enabled }} +IPV4_ADDRESS={{ riv_pihole_ipv4_address }} +IPV6_ADDRESS={{ riv_pihole_ipv6_address }} +DNS_BOGUS_PRIV={{ riv_pihole_dns_bogus_priv }} +DNS_FQDN_REQUIRED={{ riv_pihole_dns_fqdn_required }} +DNSSEC={{ riv_pihole_dnssec }} +REV_SERVER={{ riv_pihole_rev_server_enabled }} +REV_SERVER_CIDR={{ riv_pihole_rev_server_cidr }} +REV_SERVER_DOMAIN={{ riv_pihole_rev_server_domain }} +REV_SERVER_TARGET={{ riv_pihole_rev_server_target }} +CONDITIONAL_FORWARDING= +CONDITIONAL_FORWARDING_IP= +CONDITIONAL_FORWARDING_DOMAIN= +CONDITIONAL_FORWARDING_REVERSE= +PIHOLE_INTERFACE={{ riv_pihole_interface }} diff --git a/applications/roles/home-apps/files/tandoor.env b/applications/roles/home-apps/files/tandoor.env deleted file mode 100644 index f1bdd35..0000000 --- a/applications/roles/home-apps/files/tandoor.env +++ /dev/null @@ -1,161 +0,0 @@ -# only set this to true when testing/debugging -# when unset: 1 (true) - dont unset this, just for development -DEBUG=0 -SQL_DEBUG=0 - -# HTTP port to bind to -# TANDOOR_PORT=8080 - -# hosts the application can run under e.g. recipes.mydomain.com,cooking.mydomain.com,... -ALLOWED_HOSTS=* - -# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one -# ---------------------------- REQUIRED ------------------------- -SECRET_KEY=optbkabNw9HYUMh2juHfCd45/Oe+MvSjZIn67Gs5CGkSg36j/D -# --------------------------------------------------------------- - -# your default timezone See https://timezonedb.com/time-zones for a list of timezones -TIMEZONE=America/New_York - -# add only a database password if you want to run with the default postgres, otherwise change settings accordingly -DB_ENGINE=django.db.backends.postgresql -# DB_OPTIONS= {} # e.g. {"sslmode":"require"} to enable ssl -POSTGRES_HOST=db_recipes -POSTGRES_PORT=5432 -POSTGRES_USER=djangouser -# ---------------------------- REQUIRED ------------------------- -POSTGRES_PASSWORD=tandoor -# --------------------------------------------------------------- -POSTGRES_DB=djangodb - -# database connection string, when used overrides other database settings. -# format might vary depending on backend -# DATABASE_URL = engine://username:password@host:port/dbname - -# the default value for the user preference 'fractions' (enable/disable fraction support) -# default: disabled=0 -FRACTION_PREF_DEFAULT=0 - -# the default value for the user preference 'comments' (enable/disable commenting system) -# default comments enabled=1 -COMMENT_PREF_DEFAULT=1 - -# Users can set a amount of time after which the shopping list is refreshed when they are in viewing mode -# This is the minimum interval users can set. Setting this to low will allow users to refresh very frequently which -# might cause high load on the server. (Technically they can obviously refresh as often as they want with their own scripts) -SHOPPING_MIN_AUTOSYNC_INTERVAL=5 - -# Default for user setting sticky navbar -# STICKY_NAV_PREF_DEFAULT=1 - -# If base URL is something other than just / (you are serving a subfolder in your proxy for instance http://recipe_app/recipes/) -# Be sure to not have a trailing slash: e.g. '/recipes' instead of '/recipes/' -# SCRIPT_NAME=/recipes - -# If staticfiles are stored at a different location uncomment and change accordingly, MUST END IN / -# this is not required if you are just using a subfolder -# This can either be a relative path from the applications base path or the url of an external host -# STATIC_URL=/static/ - -# If mediafiles are stored at a different location uncomment and change accordingly, MUST END IN / -# this is not required if you are just using a subfolder -# This can either be a relative path from the applications base path or the url of an external host -# MEDIA_URL=/media/ - -# Serve mediafiles directly using gunicorn. Basically everyone recommends not doing this. Please use any of the examples -# provided that include an additional nxginx container to handle media file serving. -# If you know what you are doing turn this back on (1) to serve media files using djangos serve() method. -# when unset: 1 (true) - this is temporary until an appropriate amount of time has passed for everyone to migrate -GUNICORN_MEDIA=0 - -# S3 Media settings: store mediafiles in s3 or any compatible storage backend (e.g. minio) -# as long as S3_ACCESS_KEY is not set S3 features are disabled -# S3_ACCESS_KEY= -# S3_SECRET_ACCESS_KEY= -# S3_BUCKET_NAME= -# S3_REGION_NAME= # default none, set your region might be required -# S3_QUERYSTRING_AUTH=1 # default true, set to 0 to serve media from a public bucket without signed urls -# S3_QUERYSTRING_EXPIRE=3600 # number of seconds querystring are valid for -# S3_ENDPOINT_URL= # when using a custom endpoint like minio - -# Email Settings, see https://docs.djangoproject.com/en/3.2/ref/settings/#email-host -# Required for email confirmation and password reset (automatically activates if host is set) -# EMAIL_HOST= -# EMAIL_PORT= -# EMAIL_HOST_USER= -# EMAIL_HOST_PASSWORD= -# EMAIL_USE_TLS=0 -# EMAIL_USE_SSL=0 -# email sender address (default 'webmaster@localhost') -# DEFAULT_FROM_EMAIL= -# prefix used for account related emails (default "[Tandoor Recipes] ") -# ACCOUNT_EMAIL_SUBJECT_PREFIX= - -# allow authentication via reverse proxy (e.g. authelia), leave off if you dont know what you are doing -# see docs for more information https://vabene1111.github.io/recipes/features/authentication/ -# when unset: 0 (false) -REVERSE_PROXY_AUTH=0 - -# Default settings for spaces, apply per space and can be changed in the admin view -# SPACE_DEFAULT_MAX_RECIPES=0 # 0=unlimited recipes -# SPACE_DEFAULT_MAX_USERS=0 # 0=unlimited users per space -# SPACE_DEFAULT_MAX_FILES=0 # Maximum file storage for space in MB. 0 for unlimited, -1 to disable file upload. -# SPACE_DEFAULT_ALLOW_SHARING=1 # Allow users to share recipes with public links - -# allow people to create accounts on your application instance (without an invite link) -# when unset: 0 (false) -# ENABLE_SIGNUP=0 - -# If signup is enabled you might want to add a captcha to it to prevent spam -# HCAPTCHA_SITEKEY= -# HCAPTCHA_SECRET= - -# if signup is enabled you might want to provide urls to data protection policies or terms and conditions -# TERMS_URL= -# PRIVACY_URL= -# IMPRINT_URL= - -# enable serving of prometheus metrics under the /metrics path -# ATTENTION: view is not secured (as per the prometheus default way) so make sure to secure it -# trough your web server (or leave it open of you dont care if the stats are exposed) -# ENABLE_METRICS=0 - -# allows you to setup OAuth providers -# see docs for more information https://vabene1111.github.io/recipes/features/authentication/ -# SOCIAL_PROVIDERS = allauth.socialaccount.providers.github, allauth.socialaccount.providers.nextcloud, - -# Should a newly created user from a social provider get assigned to the default space and given permission by default ? -# ATTENTION: This feature might be deprecated in favor of a space join and public viewing system in the future -# default 0 (false), when 1 (true) users will be assigned space and group -# SOCIAL_DEFAULT_ACCESS = 1 - -# if SOCIAL_DEFAULT_ACCESS is used, which group should be added -# SOCIAL_DEFAULT_GROUP=guest - -# Django session cookie settings. Can be changed to allow a single django application to authenticate several applications -# when running under the same database -# SESSION_COOKIE_DOMAIN=.example.com -# SESSION_COOKIE_NAME=sessionid # use this only to not interfere with non unified django applications under the same top level domain - -# by default SORT_TREE_BY_NAME is disabled this will store all Keywords and Food in the order they are created -# enabling this setting makes saving new keywords and foods very slow, which doesn't matter in most usecases. -# however, when doing large imports of recipes that will create new objects, can increase total run time by 10-15x -# Keywords and Food can be manually sorted by name in Admin -# This value can also be temporarily changed in Admin, it will revert the next time the application is started -# This will be fixed/changed in the future by changing the implementation or finding a better workaround for sorting -# SORT_TREE_BY_NAME=0 -# LDAP authentication -# default 0 (false), when 1 (true) list of allowed users will be fetched from LDAP server -#LDAP_AUTH= -#AUTH_LDAP_SERVER_URI= -#AUTH_LDAP_BIND_DN= -#AUTH_LDAP_BIND_PASSWORD= -#AUTH_LDAP_USER_SEARCH_BASE_DN= -#AUTH_LDAP_TLS_CACERTFILE= - -# Enables exporting PDF (see export docs) -# Disabled by default, uncomment to enable -# ENABLE_PDF_EXPORT=1 - -# Recipe exports are cached for a certain time by default, adjust time if needed -# EXPORT_FILE_CACHE_DURATION=600 diff --git a/applications/roles/home-apps/tasks/main.yml b/applications/roles/home-apps/tasks/main.yml index b76bfed..12176a9 100644 --- a/applications/roles/home-apps/tasks/main.yml +++ b/applications/roles/home-apps/tasks/main.yml @@ -17,3 +17,41 @@ community.docker.docker_compose: definition: tandoor-compose.yml recreate: always + +- name: Deploy Heimdall + community.docker.docker_container: + name: heimdall + image: lscr.io/linuxserver/heimdall:latest + restart_policy: unless-stopped + env: + - "TZ={{ TZ }}" + - "PUID={{ PUID }}" + - "PGID={{ PGID }}" + volumes: + - "{{ CONFIG_FOLDER }}/heimdall/config:/config" + ports: + - 80:8500 + - 443:8501 + +- name: Deploy Uptime Kuma + community.docker.docker_container: + name: uptime-kuma + image: louislam/uptime-kuma:1 + restart_policy: always + volumes: + - "{{ CONFIG_FOLDER }}/uptime-kuma/config:/app/data" + ports: + - 3001:3001 + +- name: Deploy Nginx Proxy Manager + community.docker.docker_container: + name: nginx-proxy-manager + image: jc21/nginx-proxy-manager:latest + restart_policy: always + volumes: + - "{{ CONFIG_FOLDER }}/nginx-proxy-manager/config:/data" + - "{{ CONFIG_FOLDER }}/nginx-proxy-manager/letsencrypt:/etc/letsencrypt" + ports: + - 8080:80 + - 8081:81 + - 4443:443 diff --git a/applications/roles/media-manager/tasks/main.yml b/applications/roles/media-manager/tasks/main.yml index c4d5721..483713c 100644 --- a/applications/roles/media-manager/tasks/main.yml +++ b/applications/roles/media-manager/tasks/main.yml @@ -172,6 +172,7 @@ ports: - 5055:5055 +# Discord Bot for Media Requests - name: Deploy Requestrr community.docker.docker_container: name: requestrr