From 138dd0e3f121bdc6a488170e1827ae014690fb5d Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Tue, 20 Dec 2022 19:30:17 -0800 Subject: [PATCH] on-fire-within --- on-fire-within/README.md | 16 ++ on-fire-within/hass-io.yml | 33 ++++ on-fire-within/main.yml | 303 +++++++++++++++++++++++++++++++++++ on-fire-within/pi.yml | 44 +++++ on-fire-within/tailscale.yml | 36 +++++ 5 files changed, 432 insertions(+) create mode 100644 on-fire-within/README.md create mode 100644 on-fire-within/hass-io.yml create mode 100644 on-fire-within/main.yml create mode 100644 on-fire-within/pi.yml create mode 100644 on-fire-within/tailscale.yml diff --git a/on-fire-within/README.md b/on-fire-within/README.md new file mode 100644 index 0000000..31c91bf --- /dev/null +++ b/on-fire-within/README.md @@ -0,0 +1,16 @@ +# On Fire Within + +## Setup + +- [Installing Hass.io](https://www.home-assistant.io/hassio/installation/) + +1. `ansible-playbook playbooks/pi/bootstrap.yml` +1. `ansible-playbook on-fire-within/bootstrap.yml` +1. `curl -fsSL get.docker.com | sh` + - `sudo usermod -aG docker alpha` +1. `curl -sL "https://raw.githubusercontent.com/home-assistant/hassio-installer/master/hassio_install.sh" | bash -s -- -m raspberrypi4` +1. `ansible-playbook on-fire-within/main.yml` + +## Notes + +- `/usr/share/hassio` diff --git a/on-fire-within/hass-io.yml b/on-fire-within/hass-io.yml new file mode 100644 index 0000000..fc95122 --- /dev/null +++ b/on-fire-within/hass-io.yml @@ -0,0 +1,33 @@ +# https://www.home-assistant.io/hassio/installation/ + +- hosts: on-fire-within + become: yes + tasks: + # Forgot what I need this for... + - name: install software-properties-common + apt: name=software-properties-common + + - name: install other dependencies for hass.io + apt: + name: + - apparmor-utils + - apt-transport-https + - avahi-daemon + - ca-certificates + - curl + - dbus + - jq + - network-manager + - socat + + # https://www.home-assistant.io/integrations/bluetooth_tracker/ + - bluetooth + - libbluetooth-dev + update_cache: yes + - service: + name: ModemManager + enabled: false + + # homekit + - name: install dependenies for homekit + apt: name=libavahi-compat-libdnssd-dev diff --git a/on-fire-within/main.yml b/on-fire-within/main.yml new file mode 100644 index 0000000..bdad158 --- /dev/null +++ b/on-fire-within/main.yml @@ -0,0 +1,303 @@ +- import_playbook: pi.yml +- import_playbook: hass-io.yml + +- hosts: on-fire-within + become: yes + tasks: + + - name: Set authorized keys from GitHub + authorized_key: + user: alpha + state: present + key: https://github.com/kejadlen.keys + + - name: Install dependencies + apt: + name: + - git + - vim + + # Needed for Docker stuff + - docker-compose + - python3-pip + - python-backports-shutil-get-terminal-size + - python-backports.ssl-match-hostname + + - name: Install python docker packages + pip: + name: + - docker + - docker-compose + state: latest + + - name: Create necessary dirs + file: + path: "{{ item }}" + state: directory + with_items: + - /etc/ddclient + - /etc/minio + - /etc/mitmproxy + - /etc/traefik + - /mnt/mushu/minio + - /mnt/mushu/syncthing + + - name: Mount USB drive + mount: + path: /mnt/mushu + src: /dev/sda + fstype: ext4 + state: mounted + + - name: Configure ddclient + copy: + content: | + daemon=300 + + use=web + ssl=yes + protocol=googledomains + + {% for host in hosts %} + login={{ host.login }}, password={{ host.password }} {{ host.host }} + {% endfor %} + dest: /etc/ddclient/ddclient.conf + mode: 0600 + vars: + hosts: "{{ ddclient.hosts }}" + notify: Restart ddclient + + - name: Traefik static configuration + copy: + content: | + providers: + docker: + exposedByDefault: false + file: + filename: /etc/traefik/dynamic_conf.toml + watch: true + + entryPoints: + http: + address: ":80" + https: + address: ":443" + + certificatesResolvers: + le: + acme: + email: {{ email }} + storage: "/etc/traefik/acme.json" + httpChallenge: + entryPoint: http + + api: + insecure: true + + accessLog: {} + dest: /etc/traefik/traefik.yml + mode: 0600 + + # https://docs.syncthing.net/users/faq.html#inotify-limits + - name: Increase inotify limit for syncthing + lineinfile: + path: /etc/sysctl.conf + regexp: '^fs.inotify.max_user_watches=' + line: fs.inotify.max_user_watches=204800 + + # The docker_compose module overwrites our existing variables, so this is a + # workaround to save off ones that we need later on in the playbook. + # + # https://github.com/ansible/ansible/issues/33960 + - name: Save original host facts + set_fact: + "{{ item }}_original": "{{ lookup('vars', item) }}" + with_items: + - minio + - traefik + tags: + - debug + + # Workaround for https://github.com/pi-hole/docker-pi-hole/issues/1048 + # - https://github.com/pi-hole/docker-pi-hole/issues/1042#issuecomment-1086728157 + # - https://github.com/pi-hole/docker-pi-hole/issues/1043#issuecomment-1086936352 + - name: Work around a Docker libseccomp issue w/Pi-Hole + block: + - apt_key: + keyserver: keyserver.ubuntu.com + id: "{{ item }}" + loop: + - 04EE7237B7D453EC + - 648ACFD622F3D138 + - apt_repository: + repo: deb http://deb.debian.org/debian buster-backports main + filename: buster-backports + state: present + - shell: apt-cache policy libseccomp2 | grep buster-backports -B1 | head -n1 | sed -e 's/^\s*\**\s*\(\S*\).*/\1/' + register: libseccomp2_version + - apt: + update_cache: yes + name: libseccomp2={{ libseccomp2_version.stdout_lines[0] }} + + - name: Docker ALL the things! + docker_compose: + project_name: on-fire-within + pull: yes + definition: + version: '2' + services: + ddclient: + image: kejadlen/ddclient:latest + container_name: ddclient + volumes: + - /etc/ddclient:/etc/ddclient + restart: unless-stopped + minio: + image: kejadlen/minio:latest + container_name: minio + environment: + MINIO_ACCESS_KEY: "{{ minio.access_key }}" + MINIO_SECRET_KEY: "{{ minio.secret_key }}" + volumes: + - /etc/minio:/root/.minio + - /mnt/mushu/minio:/data + user: 0:0 # root + labels: + - traefik.enable=true + - traefik.http.routers.minio.rule=Host(`{{ traefik.host_rules.minio }}`) + - traefik.http.routers.minio.tls=true + - traefik.http.routers.minio.tls.certresolver=le + - traefik.http.services.minio.loadbalancer.server.port=9000 + # mitmproxy: + # image: mitmproxy/mitmproxy:latest-ARMv7 + # container_name: mitmproxy + # command: mitmweb --web-iface "" + # volumes: + # - /etc/mitmproxy:/home/mitmproxy/.mitmproxy + # labels: + # - traefik.enable=true + # - traefik.tcp.routers.mitmproxy.rule=HostSNI(`{{ traefik.host_rules.mitmproxy }}`) + # - traefik.tcp.routers.mitmproxy.tls.passthrough=true + # - traefik.tcp.services.mitmproxy.loadbalancer.server.port=8080 + # - traefik.http.routers.mitmproxy-web.rule=Host(`{{ traefik.host_rules.mitmproxy_web }}`) + # - traefik.http.routers.mitmproxy-web.tls.certresolver=le + # - traefik.http.services.mitmproxy-web.loadbalancer.server.port=8081 + pihole: + image: pihole/pihole:latest + container_name: pihole + ports: + - 53:53/tcp + - 53:53/udp + environment: + TZ: America/Los_Angeles + VIRTUAL_HOST: "{{ pihole.host }}" + WEBPASSWORD: "{{ pihole.password }}" + LOCAL_IPV4: "{{ ansible_default_ipv4.address }}" + volumes: + - /etc/pihole:/etc/pihole + - /etc/dnsmasq.d:/etc/dnsmasq.d + dns: + - 127.0.0.1 + - 1.1.1.1 + labels: + - traefik.enable=true + - traefik.http.routers.pihole.rule=Host(`{{ traefik.host_rules.pihole }}`) + - traefik.http.routers.pihole.tls=true + - traefik.http.routers.pihole.tls.certresolver=le + - traefik.http.services.pihole.loadbalancer.server.port=80 + restart: unless-stopped + syncthing: + image: syncthing/syncthing:latest + container_name: syncthing + ports: + - 22000:22000/tcp # TCP file transfers + - 22000:22000/udp # QUIC file transfers + - 21027:21027/udp # Receive local discovery broadcasts + volumes: + - /etc/syncthing:/var/syncthing + - /mnt/mushu/syncthing:/sync + environment: + PUID: 0 + PGID: 0 + labels: + - traefik.enable=true + - traefik.http.routers.syncthing.rule=Host(`{{ traefik.host_rules.syncthing }}`) + - traefik.http.routers.syncthing.tls=true + - traefik.http.routers.syncthing.tls.certresolver=le + - traefik.http.services.syncthing.loadbalancer.server.port=8384 + restart: unless-stopped + traefik: + image: traefik:v2.5 + container_name: traefik + ports: + - 80:80 + - 8080:8080 + - 443:443 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /etc/traefik:/etc/traefik + labels: + - traefik.enable=true + - traefik.http.middlewares.auth.basicauth.users=alpha:{{ traefik.password | password_hash("md5") | replace("$", "$$") }} + - traefik.http.routers.traefik.rule=Host(`{{ traefik.host_rules.traefik }}`) + - traefik.http.routers.traefik.tls=true + - traefik.http.routers.traefik.tls.certresolver=le + - traefik.http.routers.traefik.middlewares=auth + - traefik.http.routers.traefik.service=api@internal + restart: unless-stopped + + - name: Route Home Assistant through Traefik + block: + # - shell: ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+' | head -n 1 + - shell: docker network inspect on-fire-within_default | jq --raw-output .[0].IPAM.Config[0].Gateway + register: docker_gateway_result + - shell: docker network inspect on-fire-within_default | jq --raw-output .[0].IPAM.Config[0].Gateway + register: docker_subnet_result + - set_fact: + docker_gateway: "{{ docker_gateway_result.stdout | trim }}" + docker_subnet: "{{ docker_subnet_result.stdout | trim }}" + - copy: + content: | + [http.routers] + [http.routers.appdaemon] + rule = "Host(`{{ traefik_original.host_rules.appdaemon }}`)" + service = "appdaemon" + [http.routers.appdaemon.tls] + certResolver = "le" + [http.routers.hassio] + rule = "Host(`{{ traefik_original.host_rules.hassio }}`)" + service = "hassio" + [http.routers.hassio.tls] + certResolver = "le" + + [http.services] + [http.services.appdaemon.loadBalancer] + [[http.services.appdaemon.loadBalancer.servers]] + url = "http://{{ docker_gateway }}:5050/" + [http.services.hassio.loadBalancer] + [[http.services.hassio.loadBalancer.servers]] + url = "http://{{ docker_gateway }}:8123/" + dest: /etc/traefik/dynamic_conf.toml + mode: 0600 + notify: Restart Traefik + tags: + - debug + + handlers: + - name: Restart ddclient + docker_container: + name: ddclient + restart: yes + ignore_errors: yes + + - name: Restart Traefik + docker_container: + name: traefik + restart: yes + ignore_errors: yes + + - name: Restart Home Assistant + docker_container: + name: homeassistant + restart: yes + ignore_errors: yes diff --git a/on-fire-within/pi.yml b/on-fire-within/pi.yml new file mode 100644 index 0000000..96ac691 --- /dev/null +++ b/on-fire-within/pi.yml @@ -0,0 +1,44 @@ +# https://www.raspberrypi.org/documentation/configuration/security.md + +- hosts: on-fire-within + become: yes + tasks: + - name: disable ssh password logins + lineinfile: + path: /etc/ssh/sshd_config + regexp: '^(#\s*)?{{ item }} ' + line: "{{ item }} no" + notify: reload ssh + with_items: + - ChallengeResponseAuthentication + - PasswordAuthentication + - UsePAM + + - name: disable pi user + user: + name: pi + password: ! + + - name: install fail2ban + package: + name: fail2ban + state: present + + - name: create jail.local + copy: + content: | + [sshd] + enabled = true + dest: /etc/fail2ban/jail.local + notify: reload fail2ban + + handlers: + - name: reload ssh + service: + name: ssh + state: reloaded + + - name: reload fail2ban + service: + name: fail2ban + state: reloaded diff --git a/on-fire-within/tailscale.yml b/on-fire-within/tailscale.yml new file mode 100644 index 0000000..4d74ed5 --- /dev/null +++ b/on-fire-within/tailscale.yml @@ -0,0 +1,36 @@ +# https://tailscale.com/download/linux/rpi + +- name: Install Tailscale + hosts: on-fire-within + become: true + tasks: + + # sudo apt-get install apt-transport-https + - name: Install apt-transport-https + ansible.builtin.package: + name: apt-transport-https + state: present + + # curl -fsSL https://pkgs.tailscale.com/stable/raspbian/buster.gpg | sudo apt-key add - + - name: Add Tailscale signing key + ansible.builtin.apt_key: + url: https://pkgs.tailscale.com/stable/raspbian/buster.gpg + state: present + + # curl -fsSL https://pkgs.tailscale.com/stable/raspbian/buster.list | sudo tee /etc/apt/sources.list.d/tailscale.list + - name: Add Tailsale apt repo + ansible.builtin.apt_repository: + repo: deb https://pkgs.tailscale.com/stable/raspbian buster main + state: present + filename: tailscale + + # sudo apt-get update + - name: Update apt-get + ansible.builtin.apt: + update_cache: true + + # sudo apt-get install tailscale + - name: Install Tailscale + ansible.builtin.package: + name: tailscale + state: present