aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbinary <me@rgoncalves.se>2020-11-10 20:46:04 +0100
committerbinary <me@rgoncalves.se>2020-11-10 20:46:04 +0100
commit0a673e300800b91342499cec9cd482b5d2d9c603 (patch)
tree752309b2f30928063340afefe39682679491a451
parent89c7516b1f9ec4ce7ce2947f98f2070c242f4459 (diff)
downloadinfrastructure-0a673e300800b91342499cec9cd482b5d2d9c603.tar.gz
Fully working init for alpine vm
-rw-r--r--playbooks/network.yml8
-rw-r--r--roles/pf/tasks/main.yml19
-rw-r--r--roles/serial/files/serial_macro.py14
-rw-r--r--roles/serial/tasks/main.yml12
-rw-r--r--roles/ssh/tasks/main.yml19
-rw-r--r--roles/ssh/templates/sshd_config.j293
-rw-r--r--roles/vmm/files/init_vm_alpine.yml (renamed from roles/vmm/files/init_vm_serial.py)105
-rw-r--r--roles/vmm/tasks/init_vm_alpine.yml (renamed from roles/vmm/tasks/init_vm.yml)38
8 files changed, 255 insertions, 53 deletions
diff --git a/playbooks/network.yml b/playbooks/network.yml
index 7d59334..c3bb76f 100644
--- a/playbooks/network.yml
+++ b/playbooks/network.yml
@@ -2,6 +2,14 @@
# site.yml
# Deploy configuration to all servers.
+---
+
+- hosts: localhost
+ tasks:
+ - include_role:
+ name: ssh
+ tasks_from: generate_dns.yml
+
- hosts: openbsd
roles:
- ssh
diff --git a/roles/pf/tasks/main.yml b/roles/pf/tasks/main.yml
index c47a721..51471c5 100644
--- a/roles/pf/tasks/main.yml
+++ b/roles/pf/tasks/main.yml
@@ -11,5 +11,24 @@
group: "{{ group_root }}"
mode: "0600"
+- name: Enable pf
+ shell: /sbin/pfctl -e
+ ignore_errors: true
+
- name: Restart pf
shell: /sbin/pfctl -f /etc/pf.conf
+
+- name: Test ssh connection on new pf rule
+ wait_for:
+ port: 22
+ delay: 2
+ state: started
+
+- name: Add cron job for pf
+ cron:
+ cron_file: /etc/crontab
+ name: "Reload pf configuration"
+ user: root
+ job: "/sbin/pfctl -f /etc/pf.conf > /dev/nul 2>&1"
+ minute: "*"
+
diff --git a/roles/serial/files/serial_macro.py b/roles/serial/files/serial_macro.py
new file mode 100644
index 0000000..eb47226
--- /dev/null
+++ b/roles/serial/files/serial_macro.py
@@ -0,0 +1,14 @@
+#!/bin/python3
+
+import serial
+import time
+
+
+def send_cmd(ser, delay, cmd):
+ ser.write(f"{cmd}\n".encode("utf-8"))
+ time.sleep(delay)
+
+def send_cmds(ser, cmds):
+ for cmd in cmds:
+ send_cmd(ser, cmd[0], cmd[1])
+
diff --git a/roles/serial/tasks/main.yml b/roles/serial/tasks/main.yml
index 95a8ff5..2db546d 100644
--- a/roles/serial/tasks/main.yml
+++ b/roles/serial/tasks/main.yml
@@ -5,3 +5,15 @@
- name: Check pyserial installation
command: python3 -m pip install pyserial
+
+- name: Ensure python scripts directory exists
+ file:
+ path: /data/python
+ recurse: true
+ state: directory
+
+- name: Copy custom serial library
+ copy:
+ src: serial_macro.py
+ dest: /data/python/serial_macro.py
+
diff --git a/roles/ssh/tasks/main.yml b/roles/ssh/tasks/main.yml
index 38300df..0fc2dee 100644
--- a/roles/ssh/tasks/main.yml
+++ b/roles/ssh/tasks/main.yml
@@ -3,4 +3,21 @@
---
-- include: generate_dns.yml
+- name: Generate sshd configuration
+ template:
+ src: templates/sshd_config.j2
+ dest: /etc/ssh/sshd_config
+ owner: root
+ group: "{{ group_root }}"
+ mode: "0644"
+
+- name: Restart sshd
+ service:
+ name: sshd
+ state: restarted
+
+- name: Check ssh connection
+ wait_for:
+ port: 22
+ delay: 1
+ state: started
diff --git a/roles/ssh/templates/sshd_config.j2 b/roles/ssh/templates/sshd_config.j2
new file mode 100644
index 0000000..4f7f608
--- /dev/null
+++ b/roles/ssh/templates/sshd_config.j2
@@ -0,0 +1,93 @@
+# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
+
+# This is the sshd server system-wide configuration file. See
+# sshd_config(5) for more information.
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented. Uncommented options override the
+# default value.
+
+#Port 22
+#AddressFamily any
+#ListenAddress 0.0.0.0
+#ListenAddress ::
+
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_ecdsa_key
+#HostKey /etc/ssh/ssh_host_ed25519_key
+
+# Ciphers and keying
+#RekeyLimit default none
+
+# Logging
+#SyslogFacility AUTH
+#LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 2m
+PermitRootLogin yes
+#StrictModes yes
+#MaxAuthTries 6
+#MaxSessions 10
+
+#PubkeyAuthentication yes
+
+# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
+# but this is overridden so installations will only check .ssh/authorized_keys
+AuthorizedKeysFile .ssh/authorized_keys
+
+#AuthorizedPrincipalsFile none
+
+#AuthorizedKeysCommand none
+#AuthorizedKeysCommandUser nobody
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# HostbasedAuthentication
+#IgnoreUserKnownHosts no
+# Don't read the user's ~/.rhosts and ~/.shosts files
+#IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+PasswordAuthentication no
+PermitEmptyPasswords no
+
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
+
+#AllowAgentForwarding yes
+#AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+#PermitTTY yes
+#PrintMotd yes
+#PrintLastLog yes
+#TCPKeepAlive yes
+#PermitUserEnvironment no
+#Compression delayed
+ClientAliveInterval 180
+#ClientAliveCountMax 3
+#UseDNS no
+#PidFile /var/run/sshd.pid
+#MaxStartups 10:30:100
+#PermitTunnel no
+#ChrootDirectory none
+#VersionAddendum none
+
+# no default banner path
+#Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/libexec/sftp-server
+
+# Example of overriding settings on a per-user basis
+#Match User anoncvs
+# X11Forwarding no
+# AllowTcpForwarding no
+# PermitTTY no
+# ForceCommand cvs server
diff --git a/roles/vmm/files/init_vm_serial.py b/roles/vmm/files/init_vm_alpine.yml
index 46e34d7..d9dc0d5 100644
--- a/roles/vmm/files/init_vm_serial.py
+++ b/roles/vmm/files/init_vm_alpine.yml
@@ -5,23 +5,67 @@ import subprocess
import sys
import os
-import time
-
+from serial_macro import *
USAGE = f"USAGE: {sys.argv[0]} vm_guest gate ip mask ssh_key"
+def init_network():
+ send_cmds(ser, [
+ [1, "setup-interfaces"],
+ [1, ""],
+ [1, f"{IP}"],
+ [1, f"{MASK}"],
+ [1, f"{GATE}"],
+ [1, "no"],
+ [1, "ifdown -a"],
+ [10, "ifup -a"],
+ [1, "rc-update add networking"]
+ ])
-def send_cmd(ser, delay, cmd):
- ser.write(f"{cmd}\n".encode("utf-8"))
- time.sleep(delay)
-def send_cmds(ser, cmds):
- for cmd in cmds:
- send_cmd(ser, cmd[0], cmd[1])
+def init_dns():
+ send_cmds(ser, [
+ [1, f"setup-dns"],
+ [1, ""],
+ [1, f"{DNS}"],
+ ])
+
+
+def init_disk():
+ send_cmds(ser, [
+ [10, "apk add e2fsprogs sfdisk syslinux"],
+ [1, "setup-disk"],
+ [1, ""],
+ [10, "sys"],
+ [30, "y"],
+ ])
+
+
+def init_ssh():
+ send_cmds(ser, [
+ [5, "apk add openssh"],
+ [1, "mkdir /root/.ssh"],
+ [1, f"echo '{SSHKEY}' > /root/.ssh/authorized_keys"],
+ [1, f"echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config"],
+ [1, "/etc/init.d/sshd restart"]
+ ])
+
+def init_packages():
+ send_cmds(ser, [
+ [1, "echo https://mirror.ungleich.ch/mirror/packages/alpine/latest-stable/main/ > /etc/apk/repositories "],
+ [5, "apk update"]
+ ])
def main():
+ global ser
+ global IP
+ global GATE
+ global MASK
+ global DNS
+ global SSHKEY
+
COM = "/dev/"
BAUD = 115200
TIMEOUT = 1
@@ -48,40 +92,23 @@ def main():
SSHKEY = sys.argv[6]
ser = serial.Serial(COM, BAUD, timeout=TIMEOUT)
-
send_cmd(ser, 1, "root")
-
- # virtual interface
- send_cmds(ser, [
- [1, "setup-interfaces"],
- [1, ""],
- [1, f"{IP}"],
- [1, f"{MASK}"],
- [1, f"{GATE}"],
- [1, "no"],
- [1, "ifdown -a"],
- [10, "ifup -a"]
- ])
-
- # dns
- send_cmds(ser, [
- [1, "setup-dns"],
- [1, f"{HOST}"],
- [1, f"{DNS}"]
- ])
-
- # ssh
- send_cmds(ser, [
- [5, "apk add openssh"],
- [1, "mkdir /root/.ssh"],
- [1, f"echo '{SSHKEY}' > /root/.ssh/authorized_keys"],
- [1, f"echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config"],
- [1, "/etc/init.d/sshd restart"]
- ])
-
+ # first boot :: live
+ init_network()
+ init_dns()
+ init_packages()
+ init_disk()
+ send_cmd(ser, 70, "reboot")
ser.close()
- print(COM)
+ ser = serial.Serial(COM, BAUD, timeout=TIMEOUT)
+ send_cmd(ser, 1, "root")
+ # second boot :: disk
+ init_network()
+ init_dns()
+ init_ssh()
+ init_packages()
+ ser.close()
if __name__ == "__main__":
diff --git a/roles/vmm/tasks/init_vm.yml b/roles/vmm/tasks/init_vm_alpine.yml
index 6b5cf4d..0c66a44 100644
--- a/roles/vmm/tasks/init_vm.yml
+++ b/roles/vmm/tasks/init_vm_alpine.yml
@@ -1,23 +1,38 @@
-# vmm ~~ tasks/init_vm.yml
+# vmm ~~ tasks/init_vm_alpine.yml
---
+- set_fact:
+ iso: "{{ vms | selectattr('name', 'equalto', guest) | map(attribute='iso') | first }}"
+
+- include: set_facts.yml
+
+- name: Check for existing drive
+ stat:
+ path: "{{ disk_file }}"
+ register: st_disk
+
+- fail:
+ msg: "No empty disk detected ! You need to generated disks via hypervisor playbook"
+ when: not st_disk.stat.exists
+
+- fail:
+ msg: "Existing installation detected ! Manual action on host required"
+ when: st_disk.stat.size > 500000
+
- include_role:
name: serial
+- name: Copy vm init script
+ copy:
+ src: init_vm_alpine.py
+ dest: /data/python/init_vm_alpine.py
+
- name: Stop vm if running
shell: vmctl stop "{{ guest }}" ; vmctl stop vm-tmp
ignore_errors: true
-- set_fact:
- iso: "{{ vms | selectattr('name', 'equalto', guest) | map(attribute='iso') | first }}"
-
-- debug:
- var: iso
-
-- include: set_facts.yml
-
- name: Start temporary vm
shell: vmctl start -r {{ iso_latest }} -d {{ disk_file }} -n {{ vmm.switch.name }} -m 1G vm-tmp
@@ -26,13 +41,10 @@
seconds: 30
- name: Init vm via script
- script: init_vm_serial.py \
+ command: python3 /data/python/init_vm_alpine.py \
{{ guest }} \
{{ hostvars[guest].ip.out }} \
{{ hypervisor.gateway }} \
{{ hypervisor.mask }} \
{{ _i.dns[0] }} \
"{{ lookup('file', inventory_dir + '/files/pubkeys/rgoncalves.pub') }}"
- args:
- executable: "/usr/local/bin/python3"
-
remember that computers suck.