feat(users): Add user creation and refine provision

This commit is contained in:
Tanguy Herbron 2024-08-04 19:31:05 +02:00
parent 7dea909100
commit 2bd71ca206
33 changed files with 252 additions and 192 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
vault
.vault_pass

View File

@ -1,15 +1,20 @@
install:
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "init.yml" --extra-vars "enable_setup=true enable_wireguard=true enable_k3s=true"
init:
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "init.yml"
setup:
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "init.yml" --extra-vars "enable_setup=true enable_wireguard=false enable_k3s=false"
install:
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "bootstrap.yml" --extra-vars "enable_setup=true enable_wireguard=true enable_k3s=true"
wg:
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "init.yml" --extra-vars "enable_setup=false enable_wireguard=true enable_k3s=false"
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "bootstrap.yml" --extra-vars "enable_wireguard=true enable_k3s=false"
k3s:
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "init.yml" --extra-vars "enable_setup=false enable_wireguard=false enable_k3s=true"
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "bootstrap.yml" --extra-vars "enable_wireguard=false enable_k3s=true"
uninstall:
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "k3s-ansible/reset.yml"
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i "inventory/hosts.yml" "k3s-ansible/reset.yml"
ping:
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible all -i inventory/hosts.yml --extra-vars "@inventory/vars/main.yaml" -m ping
ping-unprovisioned:
ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass ANSIBLE_HOST_KEY_CHECKING=False ansible all -i inventory/unprovisioned.yml -m ping

View File

@ -1,44 +1,64 @@
# Ansible
Catalogue of Ansible playbooks and helper scripts for server management
atmen: slave, servant
## TODO
- Split user provisioning to get rid of `creator` and use `atmen` as fast as possible | This should be done using two differnt playbooks, and switch user between the two
- Add configuration for `creator` to lock the account after initial provisioning, only allowing short connection with returned message
### Disable creator
Change `~/.profile` to only contain a print message and `exit 0`
Add `.hushlogin` to remove ssh login message
## Configuration options
### SSH Ports
The ssh port can be configured in 2 steps:
1. Change the `ansible_ssh_port` variable in `inventory/group_vars/all.yml`
2. Change the `sshd_port` variable in `inventory/vars/unprovisioned.yaml`
## Node configuration process
### Setup user configuration
- Create provisioning user without password and sudo
- Create tanguy user with password
### Provisioning
- Add atmen user for provisioning
- Configure SSH key for atmen user
- Add maintainer user
- Configure SSH key for maintainer user
- Disable root login (passwd --lock root)
### SSH Setup
- Install fail2ban
- Disable SSH login for creator user
- Disable SSH password login
- Change SSH port
### SSH Setup
- Install fail2ban
### Miscellaneous
- Test if unattended-upgrade is installed
- Disable if true
- Disable unattended-upgrade is installed
- Disable IPv6
- Setup hostname
- Install open-iscsi, nfs-common, nfs-utils
### Softwares
- Install k3s with token
- Install OMV for NAS node*(s)
### OMV configuration
- Install OMV through OMV-extras
- (lab) Add Vagrant user to SSH group
- Add atmen user to sudoers
- Install openmediavault-zfs, openmediavault-s3, openmediavault-filebrowser
## Update system
- General package manager update
# Additional configuration
- Add label to output node on k3s to enable load balancer
# OMV configuration
# OMV manual configuration
## NFS configuration
- Create FS
- Enable NFS
- `subtree_check,insecure,no_root_squash,anonuid=1000,anongid=100` in NFS share extra options
# Vault
Sensitive data is stored under two files in the `vault` directory:
- `user_provisioning.yml` contains the vault password
- `vault.yml` contains the sensitive data
## user_provisioning.yml
Configure users for provisioning and manual maintenance
```yaml
vault_atmen_password: <atmen_password>
vault_maintainer_user: <your_user>
vault_maintainer_password: <maintainer_password>
```
## vault.yml
Configure k3s secrets
```yaml
ansible_become_password: <atmen_password>
token: <k3s_token>
```
To avoid pasting your vault password everytime, you can create a `.vault_pass` file in the root directory with the vault password.

29
bootstrap.yml Normal file
View File

@ -0,0 +1,29 @@
---
- hosts: all
gather_facts: no
tasks:
- name: Include vault vars
include_vars:
file: "{{ playbook_dir ~ '/vault/secrets' }}"
- name: Include vars
include_vars:
file: inventory/vars/main.yaml
- name: Wait for hosts
ansible.builtin.wait_for_connection:
timeout: 60
- name: Gathering facts
setup:
- name: Start basic node configuration
include_role:
name: node-configuration
when: enable_setup | bool
- name: Configure headscale
include_role:
name: headscale
when: enable_headscale|bool
- name: Configure wireguard
ansible.builtin.import_playbook: wireguard/wireguard.yml
when: enable_wireguard|bool
- name: Configure k3s
ansible.builtin.import_playbook: k3s-ansible/site.yml
when: enable_k3s | bool

View File

@ -1,17 +1,15 @@
---
- hosts: all
gather_facts: no
tasks:
- name: Start basic node configuration
- name: Add unprovisioned vars
include_vars:
file: inventory/vars/unprovisioned.yaml
- name: Wait for hosts
ansible.builtin.wait_for_connection:
timeout: 60
- name: Gathering facts
setup:
- name: Provision users
include_role:
name: node-configuration
when: enable_setup | bool
- name: Configure headscale
include_role:
name: headscale
when: enable_wireguard | bool
# - name: Configure wireguard
# ansible.builtin.import_playbook: wireguard/wireguard.yml
# when: enable_wireguard|bool == true
- name: Configure k3s
ansible.builtin.import_playbook: k3s-ansible/site.yml
when: enable_k3s | bool
name: user-provision

View File

@ -1,6 +1,11 @@
---
k3s_version: "v1.29.2+k3s1"
systemd_dir: "/etc/systemd/system"
master_ip: "{{ hostvars[groups['master'][0]]['wireguard_ip'] | default(groups['master'][0]) }}"
api_endpoint: "{{ hostvars[groups['server'][0]]['wireguard_ip'] | default(groups['server'][0]) }}"
extra_server_args: "--disable traefik --advertise-address {{hostvars[inventory_hostname]['wireguard_ip']}} --flannel-iface wg0 --tls-san {{ ansible_host }} --disable servicelb {{ ['--node-label']|product(hostvars[inventory_hostname]['k3s_label'])|map('join', ' ')|join(' ') }}"
extra_agent_args: "--flannel-iface wg0 --node-external-ip {{hostvars[inventory_hostname]['wireguard_ip']}} {{ ['--node-label']|product(hostvars[inventory_hostname]['k3s_label'])|map('join', ' ')|join(' ') }}"
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_port: 22
ufw_enabled: false
wireguard_port: 51820
wireguard_mask_bits: 8

View File

@ -0,0 +1,36 @@
all:
hosts:
cp:
ansible_host: 192.168.56.101
is_nas: false
hostname: cp
wireguard_ip: 10.20.0.1
k3s_label:
- type=worker
- size=wide
vps:
ansible_host: 192.168.56.102
is_nas: false
hostname: vps
wireguard_ip: 10.20.0.2
k3s_label:
- type=outbound
children:
server:
hosts:
cp:
agent:
hosts:
vps:
k3s_cluster:
children:
server:
agent:
vars:
k3s_version: v1.28.5+k3s1
api_endpoint: "{{ hostvars[groups['server'][0]]['wireguard_ip'] | default(groups['server'][0]) }}"
extra_server_args: "--disable traefik --advertise-address {{hostvars[inventory_hostname]['wireguard_ip']}} --flannel-iface wg0 --tls-san {{hostvars[inventory_hostname]['wireguard_ip']}} --disable servicelb {{ ['--node-label']|product(hostvars[inventory_hostname]['k3s_label'])|map('join', ' ')|join(' ') }}"
extra_agent_args: "--flannel-iface wg0 --node-external-ip {{hostvars[inventory_hostname]['wireguard_ip']}} {{ ['--node-label']|product(hostvars[inventory_hostname]['k3s_label'])|map('join', ' ')|join(' ') }}"
ufw_enabled: false
wireguard_port: 51820
wireguard_mask_bits: 8

View File

@ -1,45 +1,28 @@
all:
hosts:
cp:
ansible_host: 10.10.0.64
ansible_host: 192.168.56.101
is_nas: false
hostname: cp
wireguard_ip: 10.20.0.2
outsider:
ansible_host: 51.15.60.240
is_nas: false
hostname: outsider
wireguard_ip: 10.20.0.1
k3s_label:
- type=worker
- size=wide
vps:
ansible_host: 192.168.56.102
is_nas: false
hostname: vps
wireguard_ip: 10.20.0.2
k3s_label:
- type=outbound
children:
master:
server:
hosts:
cp:
node:
agent:
hosts:
outsider:
etcd_cluster:
hosts:
cp:
outsider:
master:
hosts:
cp:
replica:
hosts:
outsider:
postgres_cluster:
children:
master:
replica:
vps:
k3s_cluster:
children:
master:
node:
vars:
ansible_ssh_private_key_file: ~/.ssh/creator
ansible_user: creator
ansible_become_password: aberation
ansible_ssh_port: 22
ufw_enabled: false
wireguard_port: 51820
wireguard_mask_bits: 8
server:
agent:

2
inventory/vars/main.yml Normal file
View File

@ -0,0 +1,2 @@
ansible_ssh_private_key_file: ~/.ssh/atmen
ansible_user: atmen

View File

@ -0,0 +1,5 @@
ansible_ssh_private_key_file: ~/.ssh/creator
ansible_user: creator
ansible_become_password: aberation
ansible_ssh_port: 22
sshd_port: 22

View File

@ -0,0 +1 @@
vagrant: true

@ -1 +1 @@
Subproject commit fe3df5c836fa93e0a7de3a588a07095112833bbb
Subproject commit 9c8ba5c1555944f02f7ffadc3b0839530b2782f7

View File

@ -1,4 +0,0 @@
---
# defaults file for misc
ansible_default_user: autositos
ssh_key_filename: id_autositos_rsa

View File

@ -1,2 +0,0 @@
---
# handlers file for misc

View File

@ -1,2 +0,0 @@
---
# tasks file for misc

View File

@ -1,32 +0,0 @@
---
- name: Create provisioning user
hosts: all
become: true
gather_facts: false
tasks:
- name: Create user
ansible.builtin.user:
name: "{{ ansible_default_user }}"
comment: Automation user for ansible
state: present
append: yes
system: True
create_home: True
- name: Generate master SSH key
community.crypto.openssh_keypair:
path: "/home/{{ ansible_default_user }}/.ssh/{{ ssh_key_filename }}"
type: rsa
size: 4096
state: present
force: no
tags:
- init
- name: Deploy SSH public key
ansible.posix.authorized_key:
user: "{{ ansible_default_user }}"
state: present
key: "{{ lookup('file', '/home/{{ ansible_default_user }}/.ssh/{{ ssh_key_filename }}.pub') }}"
when: "'init' not in ansible_run_tags"

View File

@ -1,2 +0,0 @@
localhost

View File

@ -1,5 +0,0 @@
---
- hosts: localhost
remote_user: root
roles:
- misc

View File

@ -1,2 +0,0 @@
---
# vars file for misc

View File

@ -1,2 +0,0 @@
---
# defaults file for node-configuration

View File

@ -1,9 +1,4 @@
---
# tasks file for node-configuration
- name: Setup user configuration
import_tasks: ./users.yml
become: yes
- name: Configure and harden SSH
import_tasks: ./ssh.yml
become: yes

View File

@ -16,12 +16,13 @@
- name: Install OMV-extras
ansible.builtin.shell: /tmp/omv-extras.install -n -f >> /tmp/omv-extras.log
# TODO: Only enable this within Homelab configuration
# Check for vagrant variable, indicating we are running in a lab environment
- name: Add Vagrant user to ssh group
ansible.builtin.user:
name: vagrant
groups: ssh
append: yes
when: vagrant | default(false)
- name: Add Ansible user to ssh group
ansible.builtin.user:

View File

@ -19,18 +19,3 @@
ansible.builtin.package:
name: fail2ban
state: present
- name: Disable password login
lineinfile:
dest: "/etc/ssh/sshd_config"
regexp: '^(#\s*)?PasswordAuthentication '
line: "PasswordAuthentication no"
notify: restart sshd
- name: Change SSH port
lineinfile:
dest: "/etc/ssh/sshd_config"
regexp: "^Port "
line: "Port {{ sshd_port }}"
notify: restart sshd
when: 0 > 1

View File

@ -1,2 +0,0 @@
localhost

View File

@ -1,5 +0,0 @@
---
- hosts: localhost
remote_user: root
roles:
- node-configuration

View File

@ -1,2 +0,0 @@
---
# vars file for node-configuration

View File

@ -1,3 +0,0 @@
---
maintainer_user: joe
maintainer_password: testing # To be stored in vault

View File

@ -0,0 +1,8 @@
---
- name: Restart sshd service
ansible.builtin.service:
name: sshd
state: restarted
listen: "restart sshd"
ignore_errors: yes
become: yes

View File

@ -21,24 +21,6 @@ galaxy_info:
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to

View File

@ -0,0 +1,60 @@
- block:
- include_vars: "{{ playbook_dir ~ '/vault/user_provisioning' }}"
# Atmen : slave, servant
- name: Add provisioning user "atmen" for ansible
ansible.builtin.user:
name: atmen
comment: Ansible provisioner
groups: sudo
append: yes
shell: /bin/bash
password: "{{ vault_atmen_password | password_hash('sha512') }}"
- name: Set authorized key for atmen
ansible.posix.authorized_key:
user: atmen
state: present
key: "{{ lookup('file', atmen_ssh_key_host_path) }}"
- name: Add maintainer user
ansible.builtin.user:
name: "{{ vault_maintainer_user }}"
comment: Maintainer user
groups: sudo
append: yes
shell: /bin/bash
password: "{{ vault_maintainer_password | password_hash('sha512') }}"
- name: Set authorized key for maintainer user
ansible.posix.authorized_key:
user: "{{ vault_maintainer_user }}"
state: present
key: "{{ lookup('file', maintainer_ssh_key_host_path) }}"
- name: Disable root login
ansible.builtin.user:
name: root
password: '*'
- name: Disable SSH login for creator
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
line: DenyUsers creator
state: present
- name: Disable password login
lineinfile:
dest: "/etc/ssh/sshd_config"
regexp: '^(#\s*)?PasswordAuthentication '
line: "PasswordAuthentication no"
notify: restart sshd
- name: Change SSH port
lineinfile:
dest: "/etc/ssh/sshd_config"
regexp: "^Port "
line: "Port {{ sshd_port }}"
notify: restart sshd
changed_when: true
become: yes

View File

@ -0,0 +1,3 @@
printf "Node already provisioned, this user has been disabled.\n\n"
exit 0

View File

@ -0,0 +1,3 @@
---
atmen_ssh_key_host_path: ~/.ssh/atmen.pub
maintainer_ssh_key_host_path: ~/.ssh/therbron.pub