From 85012f8ba548db81b1c0f643e897e59411126395 Mon Sep 17 00:00:00 2001 From: counterweight Date: Sun, 26 Oct 2025 22:33:01 +0100 Subject: [PATCH] first steps with proxmox --- 01_infra_setup.md | 29 +++++ ansible/example.inventory.ini | 3 + .../infra/30_proxmox_bootstrap_playbook.yml | 123 ++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 ansible/infra/30_proxmox_bootstrap_playbook.yml diff --git a/01_infra_setup.md b/01_infra_setup.md index cfe44f8..db9e270 100644 --- a/01_infra_setup.md +++ b/01_infra_setup.md @@ -45,6 +45,35 @@ This describes how to prepare each machine before deploying services on them. Note that, by applying these playbooks, both the root user and the `counterweight` user will use the same SSH pubkey for auth. +## Prepare Nodito Server + +### Source the Nodito Server + +* This setup is designed for a local Nodito server running in your home environment. +* The expectations are that the Nodito server: + + Runs Proxmox VE (based on Debian). + + Has a predictable local IP address. + + Has root user with password authentication enabled (default Proxmox state). + + SSH is accessible on port 22. + +### Prepare Ansible vars for Nodito + +* Add a `[nodito]` group to your `ansible/inventory.ini` (or simply use the one you get by copying `example.inventory.ini`) and fill in with values. + +### Bootstrap SSH Key Access and Create User + +* Nodito starts with password authentication enabled and no SSH keys configured. We need to bootstrap SSH key access first. +* Run the complete setup with: `ansible-playbook -i inventory.ini infra/00_proxmox_bootstrap_playbook.yml -e 'ansible_user=root'` +* This single playbook will: + * Set up SSH key access for root + * Create the counterweight user with SSH keys + * Update and secure the system + * Disable root login and password authentication + * Test the final configuration +* For all future playbooks targeting nodito, use the default configuration (no overrides needed). + +Note that, by applying these playbooks, both the root user and the `counterweight` user will use the same SSH pubkey for auth, but root login will be disabled. + ## GPG Keys Some of the backups are stored encrypted for security. To allow this, fill in the gpg variables listed in `example.inventory.ini` under the `lapy` block. diff --git a/ansible/example.inventory.ini b/ansible/example.inventory.ini index e6aaec0..e88ddf4 100644 --- a/ansible/example.inventory.ini +++ b/ansible/example.inventory.ini @@ -4,6 +4,9 @@ your.vps.ip.here ansible_user=counterweight ansible_port=22 ansible_ssh_private_ [watchtower] your.vps.ip.here ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/your-key +[nodito] +your.proxmox.ip.here ansible_user=counterweight ansible_port=22 ansible_ssh_private_key_file=~/.ssh/your-key ansible_ssh_pass=your_root_password + # Local connection to laptop: this assumes you're running ansible commands from your personal laptop # Make sure to adjust the username [lapy] diff --git a/ansible/infra/30_proxmox_bootstrap_playbook.yml b/ansible/infra/30_proxmox_bootstrap_playbook.yml new file mode 100644 index 0000000..4abadc8 --- /dev/null +++ b/ansible/infra/30_proxmox_bootstrap_playbook.yml @@ -0,0 +1,123 @@ +- name: Bootstrap Nodito SSH Key Access + hosts: nodito + become: true + vars_files: + - ../infra_vars.yml + + tasks: + - name: Ensure SSH directory exists for root + file: + path: /root/.ssh + state: directory + mode: "0700" + owner: root + group: root + + - name: Install SSH public key for root + authorized_key: + user: root + key: "{{ lookup('file', ansible_ssh_private_key_file + '.pub') }}" + state: present + + - name: Ensure SSH key-based authentication is enabled + lineinfile: + path: /etc/ssh/sshd_config + regexp: "^#?PubkeyAuthentication" + line: "PubkeyAuthentication yes" + state: present + backrefs: yes + + - name: Ensure AuthorizedKeysFile is properly configured + lineinfile: + path: /etc/ssh/sshd_config + regexp: "^#?AuthorizedKeysFile" + line: "AuthorizedKeysFile .ssh/authorized_keys" + state: present + backrefs: yes + + - name: Restart SSH service + service: + name: ssh + state: restarted + + - name: Wait for SSH to be ready + wait_for: + port: "{{ ssh_port }}" + host: "{{ ansible_host }}" + delay: 2 + timeout: 30 + + - name: Test SSH key authentication + command: whoami + register: ssh_key_test + changed_when: false + + - name: Verify SSH key authentication works + assert: + that: + - ssh_key_test.stdout == "root" + fail_msg: "SSH key authentication failed - expected 'root', got '{{ ssh_key_test.stdout }}'" + + - 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: Install SSH public key for new user + authorized_key: + user: "{{ new_user }}" + key: "{{ lookup('file', ansible_ssh_private_key_file + '.pub') }}" + state: present + + - name: Allow new user to run sudo without password + copy: + dest: "/etc/sudoers.d/{{ new_user }}" + content: "{{ new_user }} ALL=(ALL) NOPASSWD:ALL" + owner: root + group: root + mode: "0440" + + - name: Disable root login + lineinfile: + path: /etc/ssh/sshd_config + regexp: "^#?PermitRootLogin .*" + line: "PermitRootLogin no" + state: present + backrefs: yes + + - name: Disable password authentication + lineinfile: + path: /etc/ssh/sshd_config + regexp: "^#?PasswordAuthentication .*" + line: "PasswordAuthentication no" + state: present + backrefs: yes + + - name: Restart SSH service + service: + name: ssh + state: restarted + + - name: Wait for SSH to be ready + wait_for: + port: "{{ ssh_port }}" + host: "{{ ansible_host }}" + delay: 2 + timeout: 30 + + - name: Test connection with new user + command: whoami + become_user: "{{ new_user }}" + register: new_user_test + changed_when: false