feat(users): Add user creation and refine provision #6
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
vault
|
||||
.vault_pass
|
19
Makefile
19
Makefile
@ -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
|
||||
|
70
README.md
70
README.md
@ -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
29
bootstrap.yml
Normal 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
|
24
init.yml
24
init.yml
@ -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
|
||||
|
@ -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
|
||||
|
36
inventory/hosts.template.yml
Normal file
36
inventory/hosts.template.yml
Normal 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
|
@ -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
2
inventory/vars/main.yml
Normal file
@ -0,0 +1,2 @@
|
||||
ansible_ssh_private_key_file: ~/.ssh/atmen
|
||||
ansible_user: atmen
|
5
inventory/vars/unprovisioned.yml
Normal file
5
inventory/vars/unprovisioned.yml
Normal 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
|
1
inventory/vars/vagrant.yml
Normal file
1
inventory/vars/vagrant.yml
Normal file
@ -0,0 +1 @@
|
||||
vagrant: true
|
@ -1 +1 @@
|
||||
Subproject commit fe3df5c836fa93e0a7de3a588a07095112833bbb
|
||||
Subproject commit 9c8ba5c1555944f02f7ffadc3b0839530b2782f7
|
@ -1,4 +0,0 @@
|
||||
---
|
||||
# defaults file for misc
|
||||
ansible_default_user: autositos
|
||||
ssh_key_filename: id_autositos_rsa
|
@ -1,2 +0,0 @@
|
||||
---
|
||||
# handlers file for misc
|
@ -1,2 +0,0 @@
|
||||
---
|
||||
# tasks file for misc
|
@ -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"
|
||||
|
@ -1,2 +0,0 @@
|
||||
localhost
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- misc
|
@ -1,2 +0,0 @@
|
||||
---
|
||||
# vars file for misc
|
@ -1,2 +0,0 @@
|
||||
---
|
||||
# defaults file for node-configuration
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -1,2 +0,0 @@
|
||||
localhost
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- node-configuration
|
@ -1,2 +0,0 @@
|
||||
---
|
||||
# vars file for node-configuration
|
@ -1,3 +0,0 @@
|
||||
---
|
||||
maintainer_user: joe
|
||||
maintainer_password: testing # To be stored in vault
|
8
user-provision/handlers/main.yml
Normal file
8
user-provision/handlers/main.yml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Restart sshd service
|
||||
ansible.builtin.service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
listen: "restart sshd"
|
||||
ignore_errors: yes
|
||||
become: yes
|
@ -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
|
60
user-provision/tasks/main.yml
Normal file
60
user-provision/tasks/main.yml
Normal 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
|
3
user-provision/vars/main.yml
Normal file
3
user-provision/vars/main.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
atmen_ssh_key_host_path: ~/.ssh/atmen.pub
|
||||
maintainer_ssh_key_host_path: ~/.ssh/maintainer.pub
|
Loading…
Reference in New Issue
Block a user