From 5f06a966aace15fd95f766e8d9c9fdb5e879fc41 Mon Sep 17 00:00:00 2001 From: counterweight Date: Tue, 1 Jul 2025 10:39:01 +0200 Subject: [PATCH] wip --- .gitignore | 1 + 01_infra_setup.md | 28 +++++++++ README.md | 39 ++++++++++++ infra/example.inventory.ini | 2 + infra/playbook.yml | 121 ++++++++++++++++++++++++++++++++++++ infra/vars.yml | 3 + 6 files changed, 194 insertions(+) create mode 100644 .gitignore create mode 100644 01_infra_setup.md create mode 100644 infra/example.inventory.ini create mode 100644 infra/playbook.yml create mode 100644 infra/vars.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c13bb9b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +inventory.ini \ No newline at end of file diff --git a/01_infra_setup.md b/01_infra_setup.md new file mode 100644 index 0000000..7599746 --- /dev/null +++ b/01_infra_setup.md @@ -0,0 +1,28 @@ +# 01. Infra Setup + +This describes how to prepare each machine before deploying services on them. + +## 01.01 First steps + +* Create an ssh key or pick an existing one. We'll refer to it as the `personal_ssh_key`. +* The guide assumes the laptop (Lapy) has `ansible` installed. If not, do `sudo apt install -y ansible` and `ansible --version` to check. + +## 01.02 Prepare the VPS (Vipy) + +### 01.02.01 Source the VPS + +* The guide is agnostic to which provider you pick, but has been tested with VMs from https://lnvps.net. +* The expectations are that the VPS ticks the following boxes: + + Runs Debian 12 bookworm. + + Has a public IP4 and starts out with SSH listening on port 22. + + Boots with one of your SSH keys already authorized. +* Move on once your VPS is running. + +### 01.02.02 Prepare Ansible vars + +* You have an example `infra/example.inventory.ini`. Copy it with `cp example.inventory.ini inventory.ini` and fill in with the vars for your VPS. + +### 01.02.03 First steps with Ansible + +* cd into `infra` +* Run `ansible-playbook playbook.yml` diff --git a/README.md b/README.md index e69de29..23be743 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,39 @@ +# Personal infra + +My repo documenting my personal infra, along with artifacts, scripts, etc. + +## Overview + +### Services + +* Reverse Proxy + + Deployed on Vipy + + Caddy + + Plan install + + File based config + + Crossbackup to Desky via rsync +* Uptime Kuma + + Deployed on Vipy + + Crossbackup to Desky via rsync +* Vaultwarden + + Deployed on Desky + + Crossbackup to Vipy via rsync +* Gitea + + Deployed on Desky + + Crossbackup to Vipy via rsync +* Immich + + Deployed on Desky +* VPN + + All set up on Vipy +* Bitcoin Knots + + Deployed on Desky +* electrs +* Synapse Server +* Phoenix D + LNBits +* Backups + +## Infra + +* Laptop (Lapy) +* One beefy desktop (Desky) +* One VPS (Vipy) diff --git a/infra/example.inventory.ini b/infra/example.inventory.ini new file mode 100644 index 0000000..30f75b0 --- /dev/null +++ b/infra/example.inventory.ini @@ -0,0 +1,2 @@ +[vipy] +your.vps.ip.here ansible_user=debian ansible_port=22 \ No newline at end of file diff --git a/infra/playbook.yml b/infra/playbook.yml new file mode 100644 index 0000000..991fe81 --- /dev/null +++ b/infra/playbook.yml @@ -0,0 +1,121 @@ +- name: Secure Debian VPS + hosts: vipy + vars_files: + - vars.yml + become: true + + tasks: + - name: Update and upgrade apt packages + apt: + update_cache: yes + upgrade: full + autoremove: yes + + - name: Create new user + user: + name: "{{ new_user }}" + groups: sudo + shell: /bin/bash + state: present + create_home: yes + + - name: Set up SSH directory for new user + file: + path: "/home/{{ new_user }}/.ssh" + state: directory + mode: "0700" + owner: "{{ new_user }}" + group: "{{ new_user }}" + + - name: Change SSH port and disable root login + lineinfile: + path: /etc/ssh/sshd_config + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + backrefs: yes + loop: + - { regexp: "^#?Port .*", line: "Port {{ ssh_port }}" } + - { regexp: "^#?PermitRootLogin .*", line: "PermitRootLogin no" } + - { + regexp: "^#?PasswordAuthentication .*", + line: "PasswordAuthentication no", + } + + - name: Restart SSH + service: + name: ssh + state: restarted + + - name: Set SSH port to new port + set_fact: + ansible_port: "{{ ssh_port }}" + + - name: Install UFW + apt: + name: ufw + state: present + + - name: Turn UFW off + ufw: + state: disabled + + - name: Configure UFW default rules + ufw: + policy: deny + direction: incoming + + - name: Allow outgoing traffic + ufw: + rule: allow + direction: outgoing + + - name: Allow SSH port through UFW + ufw: + rule: allow + port: "{{ ssh_port }}" + proto: tcp + from_ip: "{{ allow_ssh_from if allow_ssh_from != 'any' else omit }}" + + - name: Turn UFW on + ufw: + state: enabled + + - name: Install fail2ban + apt: + name: fail2ban + state: present + + - name: Ensure fail2ban is running + service: + name: fail2ban + enabled: yes + state: started + + - name: Remove unnecessary services + apt: + name: "{{ item }}" + state: absent + purge: yes + loop: + - exim4 + - apache2 + - cups + - rpcbind + - nfs-common + - telnet + - ftp + - samba + + - name: Install auditd + apt: + name: + - auditd + - audispd-plugins + state: present + + - name: Enable and start auditd + service: + name: auditd + enabled: yes + state: started diff --git a/infra/vars.yml b/infra/vars.yml new file mode 100644 index 0000000..193ccf4 --- /dev/null +++ b/infra/vars.yml @@ -0,0 +1,3 @@ +new_user: counterweight +ssh_port: 2222 +allow_ssh_from: "any"