diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000000000000000000000000000000000000..eecbc51a5506bb8e6e165ef0176e52dd59bce0d4 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,5 @@ +[defaults] +INVENTORY = hosts + +[ssh_connections] +pipelining = true \ No newline at end of file diff --git a/ansible/group_vars/all/vars.yml b/ansible/group_vars/all/vars.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c77a9f1fc6ed09235f0cadda0459a33cd26a626 --- /dev/null +++ b/ansible/group_vars/all/vars.yml @@ -0,0 +1,15 @@ +packages: + - nano + - exfat-fuse + - exfat-utils + - ca-certificates + - curl + - gnupg + - lsb-release + - nfs-common + - unbound + - dnsutils + +### ZSH Settings +zsh_theme: "powerlevel10k/powerlevel10k" +ohmyzsh_git_url: https://github.com/robbyrussell/oh-my-zsh \ No newline at end of file diff --git a/ansible/tasks/essential.yml b/ansible/tasks/essential.yml new file mode 100644 index 0000000000000000000000000000000000000000..0856d0db6604e4de7f02799fbc88a6b6dfff8f8e --- /dev/null +++ b/ansible/tasks/essential.yml @@ -0,0 +1,87 @@ +- name: Update packages + apt: + update_cache: yes + upgrade: yes + +- name: Install essential packages + package: + name: "{{ packages }}" + state: latest + +- name: Check if docker is installed + stat: + path: /usr/bin/docker + register: docker_status + +- name: Check if docker pgp key is installed + stat: + path: /usr/share/keyrings/docker-archive-keyring.gpg + register: docker_pgp_key_status + +- name: Download docker + shell: "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg" + when: not docker_pgp_key_status.stat.exists + +- name: Setup stable docker repository + shell: 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null' + when: not docker_status.stat.exists + +- name: Update packages + apt: + update_cache: yes + upgrade: yes + +- name: Install essential packages + package: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: latest + +- name: Add group docker + group: + name: docker + +- name: Add user to group docker + user: + name: "{{ username }}" + group: docker + +- name: Disable SSH password auth + lineinfile: + dest: /etc/ssh/sshd_config + regexp: "^#PasswordAuthentication yes" + line: "PasswordAuthentication no" + register: sshd_config + +- name: Enable passwordless sudo for "{{ username }}" + lineinfile: + dest: /etc/sudoers + regexp: "^%wheel" + line: "{{ username }} ALL=(ALL) NOPASSWD: ALL" + validate: "/usr/sbin/visudo -cf %s" + +- name: Restart SSH daemon + service: + name: sshd + state: restarted + when: sshd_config.changed + +- name: Allow SSH in UFW + community.general.ufw: + rule: allow + port: 22 + from: 192.168.2.0/24 + proto: tcp + +- name: Allow port 111 for NFS + community.general.ufw: + rule: allow + port: 111 + from: 192.168.2.0/24 + when: nfs_share is defined + +- name: Enable UFW + community.general.ufw: + state: enabled diff --git a/app-data/.gitkeep b/app-data/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apps/pi-hole/data/dnsmasq/.gitkeep b/apps/pi-hole/data/dnsmasq/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apps/pi-hole/data/pihole/.gitkeep b/apps/pi-hole/data/pihole/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apps/pi-hole/docker-compose.yml b/apps/pi-hole/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..c22849628d1af37b58917b104e6c226fe3798ddc --- /dev/null +++ b/apps/pi-hole/docker-compose.yml @@ -0,0 +1,19 @@ +version: "3.7" + +services: + server: + image: pihole/pihole + restart: on-failure + ports: + - 53:53 + - 53:53/udp + - ${APP_PI_HOLE_PORT}:80 + volumes: + - ${APP_DATA_DIR}/data/pihole:/etc/pihole/ + - ${APP_DATA_DIR}/data/dnsmasq:/etc/dnsmasq.d/ + environment: + - VIRTUAL_HOST=${APP_DOMAIN} + - WEBPASSWORD=${APP_PASSWORD} + networks: + default: + ipv4_address: $APP_PI_HOLE_IP diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..5e517a06fdfadb074f1d8e9f7503b6dc0331c5cb --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.7' + +services: + nginx-proxy: + image: 'jc21/nginx-proxy-manager:latest' + restart: unless-stopped + ports: + - '80:80' + - '81:81' + - '443:443' + volumes: + - ${PWD}/nginx:/data + - ${PWD}/letsencrypt:/etc/letsencrypt \ No newline at end of file diff --git a/letsencrypt/.gitkeep b/letsencrypt/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/nginx/.gitkeep b/nginx/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/configure.sh b/scripts/configure.sh new file mode 100644 index 0000000000000000000000000000000000000000..3d0747ad70ef512991f8350a0cf80c2da2bb0de3 --- /dev/null +++ b/scripts/configure.sh @@ -0,0 +1,76 @@ +# Constants +NETWORK_IP="10.21.21.0" +GATEWAY_IP="10.21.21.1" +NGINX_IP="10.21.21.2" +NGINX_PORT="80" +TIPI_IP="$1" +USERNAME="$(whoami)" + +# Apps +APP_PI_HOLE_PORT="8081" +APP_PI_HOLE_IP="10.21.21.20" + +# Store paths to intermediary config files +ANSIBLE_HOSTS_FILE="./templates/ansible-hosts-sample.cfg" +ENV_FILE="./templates/.env" + +# Remove intermediary config files +[[ -f "$ENV_FILE" ]] && rm -f "$ENV_FILE" +[[ -f "$ANSIBLE_HOSTS_FILE" ]] && rm -f "$ANSIBLE_HOSTS_FILE" + +# Copy template configs to intermediary configs +[[ -f "./templates/.env-sample" ]] && cp "./templates/.env-sample" "$ENV_FILE" +[[ -f "./templates/ansible-hosts-sample.cfg" ]] && cp "./templates/ansible-hosts-sample.cfg" "$ANSIBLE_HOSTS_FILE" + +# Install ansible if not installed +if ! command -v ansible > /dev/null; then + echo "Installing Ansible..." + apt-get update + apt-get install -y software-properties-common + apt-add-repository -y ppa:ansible/ansible + apt-get update + apt-get install -y ansible +fi + +# Install ssh-keygen if not installed +if ! command -v ssh-keygen > /dev/null; then + echo "Installing ssh-keygen..." + apt-get update + apt-get install -y ssh-keygen +fi + +# Generate ssh keys +if [[ ! -f "~/ssh/id_rsa_tipi" ]]; then + echo "Generating ssh keys..." + mkdir -p "~/ssh" + ssh-keygen -t rsa -b 4096 -f "~/ssh/id_rsa_tipi" -N "" +fi + +echo "Generating config files..." +for template in "${ENV_FILE}" "${ANSIBLE_HOSTS_FILE}"; do + # Umbrel + sed -i "s//${NETWORK_IP}/g" "${template}" + sed -i "s//${GATEWAY_IP}/g" "${template}" + sed -i "s//${NGINX_IP}/g" "${template}" + sed -i "s//${NGINX_PORT}/g" "${template}" + # Apps + sed -i "s//${APP_PI_HOLE_PORT}/g" "${template}" + sed -i "s//${APP_PI_HOLE_IP}/g" "${template}" + # Ansible + sed -i "s//${TIPI_IP}/g" "${template}" + sed -i "s//${USERNAME}/g" "${template}" +done + +# Copy SSH keys to ansible host +echo "Copying SSH keys to tipi server..." +ssh-copy-id -i "~/ssh/id_rsa_tipi" "${USERNAME}@${TIPI_IP}" + +mv -f "$ENV_FILE" "./.env" +mv -f "$ANSIBLE_HOSTS_FILE" "./ansible/hosts" + +echo "Configuring permissions..." +find "$UMBREL_ROOT" -path "$UMBREL_ROOT/app-data" -prune -o -exec chown 1000:1000 {} + || true + +# Run ansible playbook +echo "Running Ansible playbook..." +ansible-playbook -i "./ansible/hosts" "./ansible/playbook.yml" \ No newline at end of file diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100644 index 0000000000000000000000000000000000000000..2856a64a7ba709cb0da437d4a6d20cc85e49a8c6 --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,6 @@ +if [[ $UID != 0 ]]; then + echo "Tipi must be started as root" + echo "Please re-run this script as" + echo " sudo ./scripts/start" + exit 1 +fi \ No newline at end of file diff --git a/templates/.env-sample b/templates/.env-sample new file mode 100644 index 0000000000000000000000000000000000000000..77f460230482ebdcd307d0a64e868dd6ca89dcd8 --- /dev/null +++ b/templates/.env-sample @@ -0,0 +1,10 @@ +#Umbrel +NETWORK_IP= +GATEWAY_IP= +NGINX_IP= +NGINX_PORT= +DASHBOARD_IP= + +# Apps +APP_PI_HOLE_PORT= +APP_PI_HOLE_IP= diff --git a/templates/ansible-hosts-sample.cfg b/templates/ansible-hosts-sample.cfg new file mode 100644 index 0000000000000000000000000000000000000000..017327fbcff8284ed6b29d7bfffe464affb336ce --- /dev/null +++ b/templates/ansible-hosts-sample.cfg @@ -0,0 +1,2 @@ +[home] +homeserver ansible_host= ansible_user= ansible_connection=ssh ansible_ssh_private_key_file= \ No newline at end of file diff --git a/templates/nginx-sample.conf b/templates/nginx-sample.conf new file mode 100644 index 0000000000000000000000000000000000000000..0cdc7d22481b52886ec29dbe2926224a7466ac89 --- /dev/null +++ b/templates/nginx-sample.conf @@ -0,0 +1,31 @@ +# Warning: it's not recommended to modify these files directly. Any +# modifications you make can break the functionality of your umbrel. These files +# are automatically reset with every Umbrel update. + +user nginx; +worker_processes 1; + +error_log /dev/stdout info; + +events { + worker_connections 1024; +} + +http { + access_log /dev/stdout; + + proxy_read_timeout 600; + + default_type application/octet-stream; + + server { + listen 80; + + location / { + proxy_pass http://:3004/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + } +}