Bulk update

Signed-off-by: Georg Pfuetzenreuter <georg@lysergic.dev>
This commit is contained in:
Georg Pfuetzenreuter 2022-02-13 16:56:12 +01:00
parent 9f8f61a0ab
commit 2ce8450b89
Signed by: Georg
GPG Key ID: 68206CD7890A7675
23 changed files with 266 additions and 17 deletions

View File

@ -8,5 +8,6 @@ templates/generated/
variables/deploy-variables.yml variables/deploy-variables.yml
inventory.yml inventory.yml
*.bak *.bak
*.example
*.old *.old
*.tgz *.tgz

View File

@ -74,7 +74,7 @@
block: block:
- import_tasks: "../tasks/netbox_query_ip.yml" - import_tasks: "../tasks/netbox_query_ip.yml"
- import_tasks: "../tasks/netbox_evaluate_ip.yml" - import_tasks: "../tasks/netbox_evaluate_ip.yml"
#no_log: true no_log: true
- name: Provision virtual machine - name: Provision virtual machine
import_tasks: "../tasks/configure_libvirt.yml" import_tasks: "../tasks/configure_libvirt.yml"
@ -93,7 +93,7 @@
- import_tasks: "../tasks/netbox_init_interface.yml" - import_tasks: "../tasks/netbox_init_interface.yml"
- import_tasks: "../tasks/netbox_query_interface.yml" - import_tasks: "../tasks/netbox_query_interface.yml"
- import_tasks: "../tasks/netbox_evaluate_interface.yml" - import_tasks: "../tasks/netbox_evaluate_interface.yml"
#no_log: true no_log: true
- name: Define IP address object in NetBox - name: Define IP address object in NetBox
block: block:
@ -103,8 +103,14 @@
- name: Start VM and attach console - name: Start VM and attach console
import_tasks: "../tasks/init_vm_console.yml" import_tasks: "../tasks/init_vm_console.yml"
# - name: Wait for guest OS installation - name: Initialize SSH CA
# import_tasks: "../tasks/wait.yml" import_tasks: "../tasks/init_ssh.yml"
- name: Wait for guest OS installation
import_tasks: "../tasks/wait.yml"
- name: Configure SSH
import_tasks: "../tasks/configure_ssh.yml"
always: always:

View File

@ -0,0 +1,79 @@
#!/bin/sh
#
# Deploys SSH client configuration for nodes with CA signed host certificates and CA based user authentication. Standalone nodes may not use this script.
# Currently only designed for systemd based GNU/Linux distributions and OpenBSD. To-Do: support Sys-V init and Lukem RC based systems. To-Do 2: port this to Ansible deployment_poc.
#
# Author: Georg Pfuetzenreuter <georg@lysergic.dev>
# Last edit: 13/02/2022
PUBKEY="$1"
get_ip_address () {
case $KERNEL in
"OpenBSD" ) ifconfig | grep -E 'inet.[0-9]' | grep -v '127.0.0.1' | awk '{ print $2}' | head -n1
;;
"Linux" ) ip addr show eth0 | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}'
;;
esac
}
HOSTNAME=$(hostname -s)
KERNEL=$(uname)
IP_ADDRESS="$(get_ip_address)"
if [ "$KERNEL" = "OpenBSD" ] || [ "$KERNEL" = "Linux" ]; then
if [ -f /etc/ssh/$HOSTNAME ] && [ -f /etc/ssh/$HOSTNAME-cert.pub ]; then
if [ ! -d /etc/ssh/old ]; then
mkdir /etc/ssh/old
fi
if [ -f /etc/ssh/ssh_known_hosts ]; then
mv /etc/ssh/ssh_known_hosts /etc/ssh/old/
fi
#if compgen -G "/etc/ssh/ssh_host_*" > /dev/null; then
#mv /etc/ssh/ssh_host_* /etc/ssh/old/
#fi
if [ -f /etc/ssh/ssh_host_rsa_key ]; then
mv /etc/ssh/ssh_host_* /etc/ssh/old/
fi
mv /etc/ssh/sshd_config /etc/ssh/old/
if [ -f /etc/ssh/ssh_config ]; then
mv /etc/ssh/ssh_config /etc/ssh/old/
fi
cat <<'EOF_SSHD_CONFIG' >/etc/ssh/sshd_config
ListenAddress %%IP_ADDRESS%%
Protocol 2
SyslogFacility AUTH
LogLevel FATAL
HostKey /etc/ssh/%%HOSTNAME%%
HostCertificate /etc/ssh/%%HOSTNAME%%-cert.pub
TrustedUserCAKeys /etc/ssh/user_ca
PasswordAuthentication no
ChallengeResponseAuthentication no
AuthenticationMethods publickey
LoginGraceTime 1m
PermitRootLogin no
StrictModes yes
MaxAuthTries 1
MaxSessions 3
X11Forwarding no
PrintMotd yes
PrintLastLog yes
EOF_SSHD_CONFIG
sed -i -e "s/%%IP_ADDRESS%%/$IP_ADDRESS/" -e "s/%%HOSTNAME%%/$HOSTNAME/" /etc/ssh/sshd_config
echo "$PUBKEY" > /etc/ssh/user_ca
case $KERNEL in
"OpenBSD" ) rcctl reload sshd
;;
"Linux" ) systemctl reload sshd
;;
esac
echo "OK"
else
echo "Missing host certificate and public key, copy them to /etc/ssh/ for me."
fi
else
echo "Unsupported operating system, please configure sshd manually."
fi

View File

@ -5,6 +5,8 @@
set_fact: set_fact:
dns_fqdn: "{{ lookup('community.general.dig', dns_ip + '/PTR') }}" dns_fqdn: "{{ lookup('community.general.dig', dns_ip + '/PTR') }}"
vm_fqdn: "{{ vm_name + '.' + namespace }}" vm_fqdn: "{{ vm_name + '.' + namespace }}"
tags:
- init_ssh
- name: Gather DNS hostname and zonename - name: Gather DNS hostname and zonename
set_fact: set_fact:
@ -23,6 +25,16 @@
path: "/var/nsd/zones/master/{{ zone }}.zone" path: "/var/nsd/zones/master/{{ zone }}.zone"
when: dns_os == 'openbsd-x86_64' when: dns_os == 'openbsd-x86_64'
delegate_to: "{{ dns_host }}" delegate_to: "{{ dns_host }}"
- name: Reload DNS zone
ansible.builtin.command:
argv:
- /usr/bin/doas
- nsd-control
- reload
- "{{ zone }}"
when: dhcp_os == 'openbsd-x86_64'
delegate_to: "{{ dns_host }}"
- name: Insert DNS static host mapping - name: Insert DNS static host mapping
vyos.vyos.vyos_config: vyos.vyos.vyos_config:

View File

@ -37,9 +37,10 @@
mode: '0444' mode: '0444'
when: dp_os == 'openbsd-x86_64' when: dp_os == 'openbsd-x86_64'
- name: Generate LUKS passphrase - name: Generate LUKS passphrase #does not quite belong here
set_fact: set_fact:
luks_passphrase: "{{ lookup('password', '/dev/null', length=15, chars=hexdigits, seed=inventory_hostname) }}" luks_passphrase: "{{ lookup('password', '/dev/null', length=15, chars=hexdigits, seed=inventory_hostname) }}"
no_log: true
- name: Prepare unattended installation - name: Prepare unattended installation
ansible.builtin.template: ansible.builtin.template:

View File

@ -51,7 +51,7 @@
- name: Create domain template - name: Create domain template
ansible.builtin.template: ansible.builtin.template:
src: "../templates/libvirt-template.xml.j2" src: "../templates/libvirt-template.xml.j2"
dest: "../templates/libvirt-{{ inventory_hostname }}.xml" dest: "../templates/generated/libvirt-{{ inventory_hostname }}.xml"
group: lysergic group: lysergic
mode: '0660' mode: '0660'

View File

@ -0,0 +1,65 @@
---
- name: Configure SSH server
block:
- name: Switch user
set_fact:
ansible_user_original: "{{ lookup('env', 'USER') }}"
ansible_ssh_private_key_file_original: "{{ ansible_ssh_private_key_file }}"
ansible_user: install
ansible_ssh_private_key_file: "{{ installkey }}"
- name: Test 1
ansible.builtin.raw: whoami
vars:
- ansible_ssh_extra_args: '-o StrictHostKeyChecking=no'
- name: Install SSH host certificate
ansible.builtin.copy:
checksum: "{{ stat_ssh_cert.stat.checksum }}"
dest: "/etc/ssh/{{ vm_name }}"
group: root
local_follow: no
mode: 0400
owner: root
src: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}"
become: yes
become_method: sudo
become_user: root
vars:
- ansible_ssh_extra_args: '-o StrictHostKeyChecking=no'
- name: Install SSH host key
ansible.builtin.copy:
checksum: "{{ stat_ssh_spk.stat.checksum }}"
dest: "/etc/ssh/{{ vm_name }}-cert.pub"
group: root
local_follow: no
mode: 0444
owner: root
src: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}-cert.pub"
become: yes
become_method: sudo
become_user: root
vars:
- ansible_ssh_extra_args: '-o StrictHostKeyChecking=no'
- name: Install sshd configuration
ansible.builtin.script:
cmd: "../shell/configure_sshd.sh '{{ ca_pk }}'"
become: yes
become_method: sudo
become_user: root
vars:
- ansible_ssh_extra_args: '-o StrictHostKeyChecking=no'
- name: Switch user
set_fact:
ansible_user: "{{ ansible_user_original }}"
ansible_ssh_private_key_file: "{{ ansible_ssh_private_key_file_original }}"
- name: Test 2
ansible.builtin.raw: whoami
tags:
- init_ssh

View File

@ -4,4 +4,6 @@
vars: vars:
dns_ip: "{{ item }}" dns_ip: "{{ item }}"
with_items: "{{ dns_servers }}" with_items: "{{ dns_servers }}"
tags:
- init_ssh

View File

@ -6,4 +6,5 @@
with_items: "{{ deployment_servers }}" with_items: "{{ deployment_servers }}"
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -0,0 +1,53 @@
---
- name: Initialize SSH host keys
block:
- name: Generate SSH host keypair
ansible.builtin.command:
argv:
- ssh-keygen
- -f
- "{{ ssh_ca_path }}/host_keys/{{ vm_name }}"
- -t
- ed25519
- -C
- "{{ vm_fqdn }}"
- -N
- ""
creates: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}"
- name: Evaluate certificate
ansible.builtin.stat:
path: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}"
get_attributes: no
register: stat_ssh_cert
# - name: Sign SSH host key
# ansible.builtin.command:
# argv:
# - ssh-keygen
# - -s
# - "{{ ssh_ca_path }}/{{ tenant }}"
# - -I
# - "{{ ssh_ca_prefix }} - {{ vm_fqdn }}"
# - -hn
# - "{{ vm_fqdn }}"
# - "{{ ssh_ca_path }}/host_keys/{{ vm_name }}.pub"
# creates: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}-cert.pub"
- name: Sign SSH host key
ansible.builtin.expect:
command: ssh-keygen -s "{{ ssh_ca_path }}/{{ tenant }}" -I "{{ ssh_ca_prefix }} - {{ vm_fqdn }}" -hn "{{ vm_fqdn }}" "{{ ssh_ca_path }}/host_keys/{{ vm_name }}.pub"
responses:
Enter passphrase: "{{ ca_pp }}"
timeout: 3
creates: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}-cert.pub"
- name: Evaluate public key
ansible.builtin.stat:
path: "{{ ssh_ca_path }}/host_keys/{{ vm_name }}-cert.pub"
get_attributes: no
register: stat_ssh_spk
delegate_to: localhost
tags:
- init_ssh

View File

@ -35,5 +35,7 @@
- "{{ vm_name }}" - "{{ vm_name }}"
delegate_to: localhost delegate_to: localhost
tags:
- init_ssh

View File

@ -28,17 +28,23 @@
when: host_status != 'active' when: host_status != 'active'
- name: Evaluate cluster host configuration - name: Evaluate cluster host configuration
set_fact: block:
storage: "{{ host_choice.config_context.storage[0] }}" - name: Cluster derived variables 1/2
deployment_servers: "{{ host_choice.config_context.deployment_servers }}" set_fact:
dhcp_servers: "{{ host_choice.config_context.dhcp_servers }}" storage: "{{ host_choice.config_context.storage[0] }}"
dns_servers: "{{ host_choice.config_context.dns_servers }}" deployment_servers: "{{ host_choice.config_context.deployment_servers }}"
namespace: "{{ host_choice.config_context.namespace }}" dhcp_servers: "{{ host_choice.config_context.dhcp_servers }}"
gateway: "{{ host_choice.config_context.gateway }}" dns_servers: "{{ host_choice.config_context.dns_servers }}"
namespace: "{{ host_choice.config_context.namespace }}"
gateway: "{{ host_choice.config_context.gateway }}"
- name: Cluster derived variables 2/2
set_fact:
namespace_short: "{{ namespace.split('.')[0] }}"
when: host_status == 'active' when: host_status == 'active'
tags: tags:
- init_dp - init_dp
- init_ssh
rescue: rescue:
- name: Check retry counter - name: Check retry counter

View File

@ -6,6 +6,9 @@
ip_address_type: "existing" ip_address_type: "existing"
ipid: "{{ nb_ip_1.json.results[0].id }}" ipid: "{{ nb_ip_1.json.results[0].id }}"
when: "nb_ip_1.status|int == 200 and nb_ip_1.json.count|int != 0 and (nb_ip_1.json.results[0].status is defined and nb_ip_1.json.results[0].status.value == 'active')" when: "nb_ip_1.status|int == 200 and nb_ip_1.json.count|int != 0 and (nb_ip_1.json.results[0].status is defined and nb_ip_1.json.results[0].status.value == 'active')"
tags:
- init_dp
- init_ssh
- name: Define new IP address - name: Define new IP address
set_fact: set_fact:
@ -15,3 +18,4 @@
when: "nb_ip_2.status is defined and nb_ip_2.status|int == 200" when: "nb_ip_2.status is defined and nb_ip_2.status|int == 200"
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -5,4 +5,5 @@
prefix_display: "{{ nb_prefix.json.results[0].display }}" prefix_display: "{{ nb_prefix.json.results[0].display }}"
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -4,4 +4,5 @@
site_id: "{{ nb_site.json.results[0].id }}" site_id: "{{ nb_site.json.results[0].id }}"
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -12,6 +12,7 @@
# disk: "{{ nb_vm.json.results[0].disk }}" # disk: "{{ nb_vm.json.results[0].disk }}"
tags: tags:
- init_dp - init_dp
- init_ssh
- name: Pick metadata - name: Pick metadata
set_fact: set_fact:
@ -24,4 +25,5 @@
# #tags: "{{ nb_vm.json.results[0].tags | sum(start=[]) | map(attribute='slug') }}" # #tags: "{{ nb_vm.json.results[0].tags | sum(start=[]) | map(attribute='slug') }}"
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -13,3 +13,4 @@
delegate_to: localhost delegate_to: localhost
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -11,6 +11,9 @@
Authorization: "Token {{ token }}" Authorization: "Token {{ token }}"
register: nb_ip_1 register: nb_ip_1
delegate_to: localhost delegate_to: localhost
tags:
- init_dp
- init_ssh
- name: Query available address - name: Query available address
ansible.builtin.uri: ansible.builtin.uri:
@ -27,4 +30,5 @@
when: "nb_ip_1.json.count|int == 0 or (nb_ip_1.json.results[0].status is defined and nb_ip_1.json.results[0].status.value != 'active')" when: "nb_ip_1.json.count|int == 0 or (nb_ip_1.json.results[0].status is defined and nb_ip_1.json.results[0].status.value != 'active')"
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -13,4 +13,5 @@
delegate_to: localhost delegate_to: localhost
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -13,4 +13,5 @@
delegate_to: localhost delegate_to: localhost
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -14,4 +14,5 @@
delegate_to: localhost delegate_to: localhost
tags: tags:
- init_dp - init_dp
- init_ssh

View File

@ -1,10 +1,14 @@
--- ---
- name: Wait for guest to become alive - name: Wait for guest to become alive
wait_for: wait_for:
delay: 240 #delay: 240
connect_timeout: 3 connect_timeout: 3
sleep: 15 sleep: 15
port: 22 port: 22
host: '{{ vm_fqdn }}' host: '{{ ip_address }}'
search_regex: OpenSSH search_regex: OpenSSH
connection: local timeout: 900
#connection: local
delegate_to: localhost
tags:
- init_ssh

View File

@ -1 +1,2 @@
{{ vm_name }} IN A {{ ip_address }} {{ vm_name }} IN A {{ ip_address }}
{{ vm_name }}.{{ namespace_short }} IN A {{ ip_address }}