├── .gitignore ├── Makefile ├── README.md ├── ansible.cfg ├── example.interfaces.ovs ├── example.interfaces.std ├── fix-hp-ilo.sh ├── group_vars └── all │ ├── dns │ └── ssh_keys ├── includes ├── Makefile.ansible ├── Makefile.console ├── Makefile.fixvim ├── Makefile.kexec ├── Makefile.noneedrestart ├── Makefile.packages └── Makefile.ssh ├── kexec-load.service ├── kexec.yml ├── override.conf ├── proxmox.yml ├── reboot-override.conf ├── roles ├── 7to8upgrade │ └── tasks │ │ └── main.yml ├── apt-sources │ ├── files │ │ └── 10-apt-use-ipv4 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── ceph.list │ │ ├── pve-enterprise.list │ │ └── sources.list ├── dpkg-python3 │ └── tasks │ │ └── main.yml ├── filehandles │ ├── files │ │ ├── 20-nproc.conf │ │ └── 91-filehandles.conf │ ├── handlers │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── fixbash │ └── tasks │ │ └── main.yml ├── kexec │ ├── files │ │ ├── finalrd.override │ │ ├── kexec.override │ │ └── reboot.override.conf │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── kexec-load.service ├── motd │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── motd ├── proxmox-base │ ├── files │ │ ├── 10-keepalives.conf │ │ ├── 60-faster-tcp.conf │ │ ├── chrony.conf │ │ ├── etc.default.ssh │ │ ├── fix-port-8006.sh │ │ ├── grubdefault │ │ ├── rasdaemon.conf │ │ ├── sshconfig │ │ ├── tmp-0777.conf │ │ └── vimrc │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── hosts │ │ └── resolv.conf └── sshkeys │ ├── handlers │ └── main.yml │ └── tasks │ └── main.yml └── upgrade.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # These are autogenerated 2 | hosts 3 | group_vars/all/ssh_keys 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Ansible makefile for setting up a proxmox host 2 | SHELL=/bin/bash 3 | 4 | # You may need to change this if you're not xrobau 5 | OVF=VMware-ovftool-4.4.2-17901668-lin.x86_64.bundle 6 | OVFURL=https://www.dropbox.com/s/jcj1jeody1m56pi/$(OVF) 7 | 8 | # Allow xrobau, he's a nice guy. "Honest" Rob. 9 | SSHKEYS=xrobau 10 | 11 | # Base prep here 12 | TMPDIR=$(HOME)/.proxmox-ansible 13 | GROUPVARS=$(shell pwd)/group_vars 14 | 15 | ANSIBLE_HOST_KEY_CHECKING=False 16 | export ANSIBLE_HOST_KEY_CHECKING 17 | 18 | # Anything here can be automatically made by the $(MKDIRS) target below 19 | MKDIRS=$(TMPDIR) $(GROUPVARS) $(GROUPVARS)/all 20 | 21 | # Things that are always needed 22 | TOOLS += curl vim ping wget netstat 23 | PKG_ping=iputils-ping 24 | PKG_netstat=net-tools 25 | 26 | # This is first so we always have a default that is harmless (assuming 27 | # you think that 'make setup' is harmless, which I think it is!) 28 | .PHONY: halp 29 | halp: setup 30 | @echo "You probably want to run 'make proxmox' now." 31 | @echo "If you are using this to upgrade from 7 to 8, run 'make upgrade'" 32 | 33 | # Drag in any includes 34 | include $(wildcard includes/Makefile.*) 35 | 36 | # This is anything that's in TOOLS or STOOLS 37 | PKGS=$(addprefix /usr/bin/,$(TOOLS)) 38 | SPKGS=$(addprefix /usr/sbin/,$(STOOLS)) 39 | STARGETS += $(PKGS) $(SPKGS) 40 | 41 | NOIPMI=$(shell [ -e /etc/noipmi ] && echo '-e noipmi=true') 42 | PVE7TO8=$(shell [ -e /usr/bin/pve7to8 ] && echo '-e pve7to8=true') 43 | ANSIBLE=$(ANSBIN) $(NOIPMI) $(PVE7TO8) 44 | 45 | .PHONY: setup 46 | setup: $(STARGETS) 47 | 48 | # Just make anything in MKDIRS, easy DRY. 49 | $(MKDIRS): 50 | mkdir -p $@ 51 | 52 | # This installs whatever is needed in /usr/bin or /usr/sbin 53 | /usr/bin/% /usr/sbin/%: 54 | @p="$(PKG_$*)"; p=$${p:=$*}; apt-get -y install $$p || ( echo "Don't know how to install $*, add PKG_$*=dpkgname to the makefile"; exit 1 ) 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Proxmox host configurator 2 | 3 | Note this is run in TWO STAGES. 4 | 5 | # Recent Changes 6 | 7 | * 2024-08-31: Update to work with latest proxmox 8 | * 2023-02-02: Switch to 6.1 pve kernel 9 | * 2023-02-02: Increase system default filehandles 10 | 11 | ## Stage 0 (Host preparation) 12 | 13 | You will most likely need to run `apt-get -y install git make` to 14 | check out this repo. 15 | 16 | Make sure you can access the console of this machine to fix any 17 | mistakes you might make with the network configuration. If this 18 | is a server, you should be able to use `ipmitool lan print` to 19 | see the IP address of the remote console, and use that. 20 | 21 | Unless you are planning on doing GPU passthrough, make sure things 22 | like 'VT-d' and 'SR-IOV' are disabled in the BIOS of the host. 23 | 24 | ### VM/Container Networking 25 | Decide how you are going to do your networking between hosts, vms, 26 | containers, and the internet. Usually a simple bridged connection 27 | is sufficient, which is in the example configuration installed 28 | below. 29 | 30 | Network cards should _almost never_ be passed through to a client, 31 | unless that client is a dedicated router that is running DPDK or 32 | XDP itself, and you are expecting that VM to route more than 1m 33 | packets per second (Normally for that usage it would be on dedicated 34 | hardware anyway, for reliability). 35 | 36 | ## Stage 0 - Interface Example file 37 | The first time `make proxmox` is run, it will place some example 38 | interface files in /etc/network/interfaces and then exit. You can 39 | use those to prepare the host for the standard proxmox network 40 | configuration. 41 | 42 | You should copy `/etc/network/example.interfaces` into place, 43 | and configure it to match your network layout. 44 | 45 | ### Don't use OVS unless you know why you want to! 46 | There is almost no reason to use OVS for host connectivity, and is 47 | actively discouraged if you are planning on using LACP (802.3ad). 48 | It is purely provided because some people want to try it! 49 | 50 | There is an example /etc/network/example.interfaces.ovs file created, 51 | which you can use as a template to replace your current interfaces 52 | file. 53 | 54 | ### Double check console access! 55 | After you have done that, **CHECK YOU CAN GET IN VIA OUT OF BAND ACCESS** 56 | Obviously, if you're right in front of the machine, you can use the physical 57 | keyboard and monitor! 58 | 59 | ## Stage 1 - Bootstrap 60 | You can now run `make proxmox` again, and it will prepare the machine for 61 | use. It will error if `eth0` does not exist (which it should not), and you 62 | should now reboot (after configuring `/etc/network/interfaces`) the host. 63 | 64 | ## Stage 2 - Reboot 65 | If you correctly updated the interfaces file, everything should just 66 | work. Otherwise edit it again via the console and run `ifdown -a` and 67 | then `ifup -a` to reapply the network changes. 68 | 69 | ## Stage 3 - Final Configuration 70 | The second time you run `make proxmox` the rest of the machine will be 71 | configured, enabling kexec and other tweaks. 72 | 73 | There may be a slight race condition when enabling kexec - you can run 74 | `make proxmox` a second time to make sure kexec is loaded and ready, and 75 | then reboot the machine to make sure it does a kexec reboot, instead a 76 | full reboot. 77 | 78 | 79 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | retry_files_enabled = False 3 | display_skipped_hosts = False 4 | deprecation_warnings=True 5 | gathering = smart 6 | fact_caching = jsonfile 7 | fact_caching_connection = /tmp/facts_cache 8 | fact_caching_timeout = 7200 9 | forks=30 10 | inventory = hosts 11 | 12 | [ssh_connection] 13 | pipelining = True 14 | ssh_args = -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s 15 | 16 | -------------------------------------------------------------------------------- /example.interfaces.ovs: -------------------------------------------------------------------------------- 1 | # Example /etc/network/interfaces file generated by the 'proxmox-server' 2 | # Ansible playbook, using Open vSwitch for SDN configuation 3 | # 4 | # In this example, the machine has two ethernet interfaces, which 5 | # are using LACP. There are two vlans in use: 6 | # 500 - Management/Public address space 7 | # 555 - NFS Storage 8 | # 9 | # Note that this uses the standard 'eth0' 'eth1' standard, which 10 | # requires the net.ifnames=0 biosdevname=0 params on the boot 11 | # command line. See the README for instructions. 12 | 13 | source /etc/network/interfaces.d/* 14 | 15 | auto lo 16 | iface lo inet loopback 17 | 18 | auto eth0 19 | iface eth0 inet manual 20 | mtu 9000 21 | 22 | auto eth1 23 | iface eth1 inet manual 24 | mtu 9000 25 | 26 | auto vlan500 27 | iface vlan500 inet static 28 | address 123.4.5.6/26 29 | gateway 123.4.5.1 30 | ovs_type OVSIntPort 31 | ovs_bridge vmbr0 32 | ovs_mtu 1500 33 | ovs_options tag=500 34 | # If you want port 8006 to be mapped to port 443 on this 35 | # interface, uncomment this line. (The fix-port-8006 script 36 | # is in the Ansible proxmox-base role) 37 | # post-up /usr/local/bin/fix-port-8006.sh 38 | 39 | 40 | auto vlan555 41 | iface vlan555 inet static 42 | address 10.11.12.13/24 43 | ovs_type OVSIntPort 44 | ovs_bridge vmbr0 45 | ovs_mtu 9000 46 | ovs_options tag=555 47 | 48 | auto bond0 49 | iface bond0 inet manual 50 | ovs_bonds eth0 eth1 51 | ovs_type OVSBond 52 | ovs_bridge vmbr0 53 | ovs_mtu 9000 54 | # Due to an issue/bug with OVS and MLAG switches, you have to use 55 | # active-backup, and fast LACP on *both ends*. If you're not using 56 | # mlag, you PROBABLY don't need to, but if you have strange traffic 57 | # pauses on some connections/flows but not others, try it. 58 | ovs_options bond_mode=active-backup lacp=active other_config:lacp-time=fast 59 | # ovs_options bond_mode=balance-tcp lacp=active 60 | 61 | # Note that PROXMOX requires the ovs_ports here to reference any 62 | # vlans above. There doesn't appear to be any reason for this, 63 | # but if you don't add them here and edit the network config inside 64 | # proxmox, it will delete the vlan interfaces above. 65 | auto vmbr0 66 | iface vmbr0 inet manual 67 | ovs_type OVSBridge 68 | ovs_ports bond0 vlan500 vlan555 69 | ovs_mtu 9000 70 | 71 | -------------------------------------------------------------------------------- /example.interfaces.std: -------------------------------------------------------------------------------- 1 | # network interface settings; autogenerated 2 | # Please do NOT modify this file directly, unless you know what 3 | # you're doing. 4 | # 5 | # If you want to manage parts of the network configuration manually, 6 | # please utilize the 'source' or 'source-directory' directives to do 7 | # so. # PVE will preserve these directives, but will NOT read its network 8 | # configuration from sourced files, so do not attempt to move any of 9 | # the PVE managed interfaces into external files! 10 | 11 | auto lo 12 | iface lo inet loopback 13 | 14 | auto eth0 15 | iface eth0 inet manual 16 | mtu 9000 17 | 18 | auto eth1 19 | iface eth1 inet manual 20 | mtu 9000 21 | 22 | # Do not use a different xmit_hash_policy, as it can lead 23 | # to out-of-order packets. These defaults will be fine for 24 | # almost everyone! 25 | iface bond0 inet manual 26 | bond-slaves eth0 eth1 27 | bond-mode 802.3ad 28 | bond-xmit-hash-policy layer2+3 29 | miimon 100 30 | mtu 9000 31 | 32 | # This is the primary bridge that everything feeds from. Yes, 33 | # you do want all of these settings. 34 | auto vmbr0 35 | iface vmbr0 inet manual 36 | bridge-ports bond0 37 | bridge-stp off 38 | bridge-fd 0 39 | bridge-vlan-aware yes 40 | bridge-vids 2-4094 41 | mtu 9000 42 | 43 | # This is a vmbridge, which allows VMs to connect to vlan30 as 44 | # well as the host. 45 | auto vmbr30 46 | iface vmbr30 inet static 47 | address 10.40.0.41/24 48 | gateway 10.40.0.1 49 | bridge-ports bond0.30 50 | bridge-stp off 51 | bridge-fd 0 52 | # If you want port 8006 to be mapped to port 443 on this 53 | # interface, uncomment this line. (The fix-port-8006 script 54 | # is in the Ansible proxmox-base role) 55 | # post-up /usr/local/bin/fix-port-8006.sh 56 | 57 | 58 | # You can add a secondary IP to that vmbridge with a second 'iface vmbr30' 59 | # stanza such as: 60 | # iface vmbr30 inet static 61 | # address 10.55.55.41/24 62 | 63 | 64 | # This is not a bridge, this is a standard vlan subinterface 65 | # that the host uses to connect to the SAN. It is not accessable 66 | # to VMs. If VMs needs access to vlan555, you need to configure it 67 | # as a vmbr555, like above. 68 | auto vlan555 69 | iface vlan555 inet manual 70 | address 10.254.0.41/24 71 | vlan-raw-device vmbr0 72 | mtu 9000 73 | 74 | # This is required to load the SDN configuration, and should be last. 75 | source /etc/network/interfaces.d/* 76 | 77 | -------------------------------------------------------------------------------- /fix-hp-ilo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 0 > /sys/bus/usb/devices/usb2/authorized 4 | echo 1 > /sys/bus/usb/devices/usb2/authorized 5 | 6 | 7 | -------------------------------------------------------------------------------- /group_vars/all/dns: -------------------------------------------------------------------------------- 1 | --- 2 | forcedns: 3 | - 1.1.1.1 4 | - 8.8.8.8 5 | -------------------------------------------------------------------------------- /group_vars/all/ssh_keys: -------------------------------------------------------------------------------- 1 | --- 2 | sshkeys: 3 | - 'cert-authority,principals="superuser" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJHwcd5nqXAN4NkNWG/F/29Bq3TpNhinQnn/CeA/5kG CA' 4 | - 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAfzTZHsOBZTkqSgNmQnW2O7K7sF4TeGWfq1+JiF5C589iZKdcBN+PArxJgmLodlwhfQFLnp6GG0fKSi/ARWOftSwr4wWXBhsEbaoU7Klq2IQKd4FsDoBm0UsxvotCpABd4PAqc3gfesElLDAAs14uv5pd0DtbijaLupXUokpv6CulFeH2oALwZoiS7F0awr3UWAK/nD58y7vChUlC/v06m4i0vw7j3vRGuqqHCOgzAPaNxh3CdHjbN+JZb6zUSML4AiS8/XBkqBXsXASiUZL8RpS0w1bNnWPA+/ww8flqpPn+PGjsJeLgRgAfXFORPZNtF9Jv4W2xVByBD5lKwEWB autogen-github-xrobau' 5 | -------------------------------------------------------------------------------- /includes/Makefile.ansible: -------------------------------------------------------------------------------- 1 | TOOLS += ansible-playbook 2 | PKG_ansible-playbook=ansible 3 | ANSBIN=/usr/bin/ansible-playbook 4 | 5 | STARGETS += $(ANSBIN) /etc/ansible.hostname /tmp/.hostschecked 6 | 7 | # This is needed so ansible can make sure /etc/hosts and other 8 | # things are correct 9 | .PHONY: hostname 10 | hostname /etc/ansible.hostname: 11 | @C=$(shell hostname); echo "Current hostname '$$C'"; read -p "Set hostname (blank to not change): " h; \ 12 | if [ "$$h" ]; then \ 13 | echo $$h > /etc/ansible.hostname; \ 14 | else \ 15 | if [ ! -s /etc/ansible.hostname ]; then \ 16 | hostname > /etc/ansible.hostname; \ 17 | fi; \ 18 | fi; rm -f hosts 19 | 20 | /tmp/.hostschecked: /etc/ansible.hostname 21 | @H=$$(cat $<); V=$$(awk '/'$$H'/ { print $$1 }' /etc/hosts); \ 22 | if [ ! "$$H" ]; then echo "The hostname '$$H' is not in /etc/hosts, this must be fixed"; exit 9; fi; \ 23 | if [ ! "$$(ip -o addr | grep "$$V")" ]; then echo "The IP $$V from /etc/hosts is not in on this system, fix /etc/network/interfaces (or /etc/hosts)"; exit 9; fi; 24 | @touch $@ 25 | 26 | hosts: /etc/ansible.hostname 27 | @echo -e '[all]\nlocalhost hostname='$$(cat $<) > $@ 28 | 29 | 30 | .PHONY: proxmox ansible 31 | proxmox ansible: hosts $(GROUPVARS)/all/ssh_keys ansible-collections 32 | @echo 'If this errors with ssh permission issues, run "make keys" to fix' 33 | $(ANSBIN) proxmox.yml 34 | 35 | $(ANSBIN): 36 | apt-get -y install ansible 37 | -------------------------------------------------------------------------------- /includes/Makefile.console: -------------------------------------------------------------------------------- 1 | GDIR=/etc/systemd/system/getty@tty1.service.d 2 | GETTY=$(GDIR)/override.conf 3 | 4 | STARGETS += $(GDIR) $(GETTY) 5 | MKDIRS += $(GDIR) 6 | 7 | $(GETTY): override.conf $(GDIR) 8 | cp override.conf $@ 9 | systemctl daemon-reload 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /includes/Makefile.fixvim: -------------------------------------------------------------------------------- 1 | VIMFIXED=/tmp/.vimfixed 2 | 3 | # Don't run this by default 4 | # STARGETS += $(VIMFIXED) 5 | 6 | .PHONY: vim 7 | vim: $(VIMFIXED) 8 | 9 | # Comment out (") any lines that enable mouse overrides 10 | $(VIMFIXED): /usr/bin/vim 11 | @sed -i 's/ set mouse=/"set mouse=/' /usr/share/vim/*/defaults* 12 | @touch $@ 13 | @echo Stopped vim from stealing the mouse. 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /includes/Makefile.kexec: -------------------------------------------------------------------------------- 1 | STOOLS += kexec 2 | TOOLS += as 3 | PKG_kexec = kexec-tools 4 | PKG_as = binutils 5 | 6 | RSVC=/etc/systemd/system/systemd-reboot.service.d/override.conf 7 | KSVC=/etc/systemd/system/kexec-load.service 8 | 9 | STARGETS += $(RSVC) $(KSVC) 10 | 11 | $(RSVC): reboot-override.conf 12 | mkdir -p $(@D) 13 | cp $< $@ 14 | systemctl daemon-reload 15 | 16 | $(KSVC): kexec-load.service 17 | cp $< $@ 18 | systemctl enable kexec-load 19 | systemctl start kexec-load 20 | systemctl daemon-reload 21 | 22 | -------------------------------------------------------------------------------- /includes/Makefile.noneedrestart: -------------------------------------------------------------------------------- 1 | STARGETS += $(TMPDIR)/.needrestart-removed 2 | 3 | $(TMPDIR)/.needrestart-removed: $(TMPDIR) 4 | @if [ -x /usr/sbin/needrestart ]; then apt-get remove --purge -y needrestart; fi 5 | @touch $@ 6 | 7 | 8 | -------------------------------------------------------------------------------- /includes/Makefile.packages: -------------------------------------------------------------------------------- 1 | .PHONY: ansible-collections 2 | ansible-collections: ~/.ansible/collections/ansible_collections/community/general ~/.ansible/roles/jhu-sheridan-libraries.postfix-smarthost/README.md ~/.ansible/collections/ansible_collections/ansible/posix/MANIFEST.json 3 | 4 | ~/.ansible/collections/ansible_collections/ansible/posix/MANIFEST.json: 5 | @ansible-galaxy collection install ansible.posix 6 | 7 | ~/.ansible/roles/jhu-sheridan-libraries.postfix-smarthost/README.md: 8 | @ansible-galaxy install jhu-sheridan-libraries.postfix-smarthost 9 | 10 | ~/.ansible/collections/ansible_collections/community/general: 11 | @ansible-galaxy collection install community.general 12 | 13 | .PHONY: base-packages 14 | base-packages: /usr/bin/wget /usr/bin/unzip /usr/bin/vim /usr/bin/ping 15 | 16 | -------------------------------------------------------------------------------- /includes/Makefile.ssh: -------------------------------------------------------------------------------- 1 | SHELL=/bin/bash 2 | 3 | # This is where proxmox keeps the replicated authkey file 4 | AKEYS=/etc/pve/priv/authorized_keys 5 | 6 | SSHFILES=$(addprefix $(TMPDIR)/,$(addsuffix .key,$(SSHKEYS))) 7 | 8 | ssh: $(GROUPVARS)/all/ssh_keys 9 | 10 | $(GROUPVARS)/all/ssh_keys: $(GROUPVARS) $(GROUPVARS)/all $(SSHFILES) 11 | @echo -e "---\nsshkeys:\n - 'cert-authority,principals=\"superuser\" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJHwcd5nqXAN4NkNWG/F/29Bq3TpNhinQnn/CeA/5kG CA'" > $@ 12 | @for k in $(SSHKEYS); do readarray -t bkeys < $(TMPDIR)/$$k.key; for l in "$${bkeys[@]}"; do echo " - '$$l autogen-github-$$k'"; done; done >>$@ 13 | 14 | $(TMPDIR)/%.key: $(TMPDIR) 15 | @echo I am trying to download the ssh key for $* 16 | @curl -s https://github.com/$*.keys -o $@ 17 | @if [ "$$(stat $@ --format='%s')" -lt 10 ]; then echo "Size of key for $* too small, deleting ('$$(cat $@)')"; rm -f $@; exit 1; fi 18 | 19 | 20 | # This makes sure that at least localhost can get in 21 | .PHONY: keys 22 | keys: $(AKEYS) 23 | 24 | $(AKEYS): ssh 25 | mkdir -p $(@D) 26 | cat $(SSHFILES) >> $@ 27 | cat $(HOME)/.ssh/id_rsa.pub >> $@ 28 | -------------------------------------------------------------------------------- /kexec-load.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Waiting for reboot to load kexec 3 | Documentation=man:kexec(8) 4 | DefaultDependencies=no 5 | Requires=sysinit.target 6 | After=sysinit.target 7 | 8 | [Service] 9 | Type=oneshot 10 | ExecStart=-/usr/bin/true 11 | RemainAfterExit=yes 12 | ExecStop=/usr/sbin/kexec -l /boot/vmlinuz --initrd=/boot/initrd.img --reuse-cmdline 13 | 14 | [Install] 15 | WantedBy=basic.target 16 | 17 | -------------------------------------------------------------------------------- /kexec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | roles: 4 | - kexec 5 | 6 | 7 | -------------------------------------------------------------------------------- /override.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart= 3 | ExecStart=-/sbin/agetty --autologin root --noclear %I 38400 linux 4 | 5 | -------------------------------------------------------------------------------- /proxmox.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | roles: 4 | - filehandles 5 | - apt-sources 6 | - sshkeys 7 | - proxmox-base 8 | - kexec 9 | - motd 10 | 11 | 12 | -------------------------------------------------------------------------------- /reboot-override.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | Type=oneshot 3 | ExecStart= 4 | ExecStart=-/bin/systemctl --force kexec 5 | ExecStart=/bin/systemctl --force reboot 6 | 7 | -------------------------------------------------------------------------------- /roles/7to8upgrade/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Fail if pve7to8 is missing 3 | fail: 4 | msg: /usr/bin/pve7to8 is not present 5 | when: pve7to8 is not defined 6 | 7 | - name: Update kexec to switch back to 5.x kernel if on 6.1 8 | include_role: 9 | name: kexec 10 | vars: 11 | forcekernelvers: "" 12 | when: ansible_facts.kernel is match ("6.1.*") 13 | 14 | - name: Run pve7to8 15 | shell: 16 | cmd: /usr/bin/pve7to8 --full | grep 'WARN:' 17 | failed_when: false 18 | changed_when: false 19 | register: p 20 | 21 | - name: Fail if there were warnings, ansible can not continue 22 | fail: 23 | msg: "{{ p.stdout | quote }}" 24 | when: p.stdout 25 | 26 | - name: Update apt sources to use bookworm 27 | include_role: 28 | name: apt-sources 29 | vars: 30 | forcedistro: bookworm 31 | when: ansible_facts.distribution_release != "bookworm" 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /roles/apt-sources/files/10-apt-use-ipv4: -------------------------------------------------------------------------------- 1 | # This file put in place by the proxmox-base ansible role 2 | Acquire::ForceIPv4 "true"; 3 | 4 | -------------------------------------------------------------------------------- /roles/apt-sources/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: apt-update 3 | apt: 4 | update_cache: true 5 | 6 | -------------------------------------------------------------------------------- /roles/apt-sources/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Force apt to only use ipv4 3 | copy: 4 | src: 10-apt-use-ipv4 5 | dest: /etc/apt/apt.conf.d/ 6 | 7 | - name: Select distro 8 | set_fact: 9 | distro: "{{ forcedistro | default(ansible_facts.distribution_release) }}" 10 | 11 | - name: Disable proxmox enterprise 12 | template: 13 | src: pve-enterprise.list 14 | dest: /etc/apt/sources.list.d/pve-enterprise.list 15 | notify: 16 | - apt-update 17 | 18 | - name: Disable proxmox ceph enterprise 19 | template: 20 | src: ceph.list 21 | dest: /etc/apt/sources.list.d/ceph.list 22 | notify: 23 | - apt-update 24 | 25 | - name: Update sources.list 26 | template: 27 | src: sources.list 28 | dest: /etc/apt/sources.list 29 | notify: 30 | - apt-update 31 | 32 | - meta: flush_handlers 33 | 34 | -------------------------------------------------------------------------------- /roles/apt-sources/templates/ceph.list: -------------------------------------------------------------------------------- 1 | # deb https://enterprise.proxmox.com/debian/ceph-quincy {{ distro }} enterprise 2 | -------------------------------------------------------------------------------- /roles/apt-sources/templates/pve-enterprise.list: -------------------------------------------------------------------------------- 1 | # deb https://enterprise.proxmox.com/debian/pve {{ distro }} pve-enterprise 2 | -------------------------------------------------------------------------------- /roles/apt-sources/templates/sources.list: -------------------------------------------------------------------------------- 1 | deb http://ftp.au.debian.org/debian {{ distro }} main contrib 2 | 3 | deb http://ftp.au.debian.org/debian {{ distro }}-updates main contrib 4 | 5 | # security updates 6 | deb http://security.debian.org {{ distro }}-security main contrib 7 | 8 | deb http://download.proxmox.com/debian/pve {{ distro }} pve-no-subscription 9 | 10 | -------------------------------------------------------------------------------- /roles/dpkg-python3/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Make sure python-is-python3 is installed 3 | raw: "dpkg -s python-is-python3" 4 | register: python3 5 | failed_when: false 6 | changed_when: false 7 | tags: 8 | - python3 9 | - packages 10 | 11 | - name: Purge needrestart if it's hanging around 12 | raw: "dpkg -P needrestart" 13 | when: python3.rc != 0 14 | failed_when: false 15 | changed_when: false 16 | tags: 17 | - python3 18 | - packages 19 | 20 | - name: Run update and install python3 21 | raw: "apt-get update && apt-get -y install python-is-python3" 22 | register: python 23 | when: python3.rc != 0 24 | failed_when: false 25 | tags: 26 | - python3 27 | - packages 28 | 29 | - name: python-is-python3 was installed 30 | debug: var=python 31 | when: python.skipped is not defined 32 | tags: 33 | - python3 34 | - packages 35 | -------------------------------------------------------------------------------- /roles/filehandles/files/20-nproc.conf: -------------------------------------------------------------------------------- 1 | # This has been updated by ansible to increase the number of 2 | # filehandles available on this machine. 3 | 4 | * soft nproc 65535 5 | * hard nproc 818354 6 | * soft nofile 65535 7 | * hard nofile 818354 8 | 9 | -------------------------------------------------------------------------------- /roles/filehandles/files/91-filehandles.conf: -------------------------------------------------------------------------------- 1 | fs.file-max=818354 2 | -------------------------------------------------------------------------------- /roles/filehandles/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: sysctl-reload 3 | command: sysctl --system 4 | ignore_errors: yes 5 | 6 | - name: systemctl-reload 7 | command: systemctl daemon-reload 8 | 9 | -------------------------------------------------------------------------------- /roles/filehandles/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Put sysctl fd limits in place 3 | copy: src=91-filehandles.conf dest=/etc/sysctl.d 4 | notify: sysctl-reload 5 | tags: 6 | - fh 7 | 8 | - meta: flush_handlers 9 | tags: 10 | - fh 11 | 12 | - name: Replace limits.conf 13 | copy: src=20-nproc.conf dest=/etc/security/limits.d 14 | tags: 15 | - fh 16 | 17 | - name: Add limits.so to pam 18 | lineinfile: 19 | line: session required pam_limits.so 20 | state: present 21 | path: /etc/pam.d/login 22 | tags: 23 | - fh 24 | 25 | - name: Update systemd filehandle limits 26 | lineinfile: 27 | path: /etc/systemd/{{ item }} 28 | regex: '^#?DefaultLimitNOFILE=' 29 | line: DefaultLimitNOFILE=818354 30 | tags: 31 | - fh 32 | - systemd 33 | notify: systemctl-reload 34 | with_items: 35 | - system.conf 36 | - user.conf 37 | 38 | - meta: flush_handlers 39 | -------------------------------------------------------------------------------- /roles/fixbash/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Fix default editor 3 | alternatives: 4 | name: editor 5 | path: /usr/bin/vim.basic 6 | tags: 7 | - editor 8 | 9 | - name: Turn off paste blocking in bash 10 | lineinfile: 11 | path: /etc/bash.bashrc 12 | line: bind 'set enable-bracketed-paste off' 13 | create: yes 14 | tags: 15 | - bracket 16 | 17 | - name: Turn off paste blocking everywhere else 18 | lineinfile: 19 | path: /etc/inputrc 20 | line: "set enable-bracketed-paste off" 21 | create: yes 22 | tags: 23 | - bracket 24 | 25 | - name: Hard-code editor 26 | lineinfile: 27 | path: /etc/bash.bashrc 28 | line: export EDITOR=vim 29 | create: yes 30 | 31 | - name: Hard-code visual 32 | lineinfile: 33 | path: /etc/bash.bashrc 34 | line: export VISUAL=vim 35 | create: yes 36 | 37 | 38 | -------------------------------------------------------------------------------- /roles/kexec/files/finalrd.override: -------------------------------------------------------------------------------- 1 | # Added by ubuntu-knfs role in ansible 2 | 3 | [Service] 4 | TimeoutStopSec=infinity 5 | -------------------------------------------------------------------------------- /roles/kexec/files/kexec.override: -------------------------------------------------------------------------------- 1 | # Let kexec run for as long as it wants 2 | # This file generated by the ubuntu-knfs ansible role 3 | 4 | [Service] 5 | TimeoutStartSec=infinity 6 | TimeoutStopSec=infinity 7 | -------------------------------------------------------------------------------- /roles/kexec/files/reboot.override.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | Type=oneshot 3 | ExecStart= 4 | ExecStart=-/bin/systemctl --force kexec 5 | ExecStart=/bin/systemctl --force reboot 6 | 7 | -------------------------------------------------------------------------------- /roles/kexec/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: systemctl-reload 3 | command: systemctl daemon-reload 4 | 5 | -------------------------------------------------------------------------------- /roles/kexec/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install kexec package 3 | apt: 4 | name: 5 | - kexec-tools 6 | - libpve-network-perl 7 | state: present 8 | 9 | - name: Make reboot override folder 10 | file: 11 | state: directory 12 | path: /etc/systemd/system/systemd-reboot.service.d 13 | mode: 0755 14 | tags: 15 | - kexec 16 | 17 | - name: Put reboot override in place 18 | copy: 19 | dest: /etc/systemd/system/systemd-reboot.service.d/override.conf 20 | src: reboot.override.conf 21 | mode: 0644 22 | tags: 23 | - kexec 24 | notify: systemctl-reload 25 | 26 | - name: Set bootpath and kernel version for proxmox 27 | set_fact: 28 | bootpath: /boot/pve 29 | kernelvers: "{{ forcekernelvers | default('') }}" 30 | tags: 31 | - kexec 32 | 33 | - name: Create kexec-load service 34 | template: 35 | dest: /etc/systemd/system/kexec-load.service 36 | src: kexec-load.service 37 | mode: 0644 38 | tags: 39 | - kexec 40 | notify: systemctl-reload 41 | 42 | - name: Make finalrd override folder 43 | file: 44 | state: directory 45 | path: /etc/systemd/system/finalrd.service.d 46 | mode: 0755 47 | tags: 48 | - kexec 49 | 50 | - name: Put finalrd override in place 51 | copy: 52 | dest: /etc/systemd/system/finalrd.service.d/override.conf 53 | src: finalrd.override 54 | mode: 0644 55 | tags: 56 | - kexec 57 | notify: systemctl-reload 58 | 59 | - name: Make kexec override folder 60 | file: 61 | state: directory 62 | path: /etc/systemd/system/systemd-kexec.service.d 63 | mode: 0755 64 | tags: 65 | - kexec 66 | 67 | - name: Put kexec override in place 68 | copy: 69 | dest: /etc/systemd/system/systemd-kexec.service.d/override.conf 70 | src: kexec.override 71 | mode: 0644 72 | tags: 73 | - kexec 74 | notify: systemctl-reload 75 | 76 | - meta: flush_handlers 77 | 78 | # Not sure why I need this *twice*, but it can't hurt. 79 | - name: Boot the kexec-load service 80 | service: 81 | name: kexec-load 82 | state: started 83 | 84 | - name: Enable the kexec-load service for next time 85 | service: 86 | name: kexec-load 87 | state: started 88 | enabled: true 89 | 90 | -------------------------------------------------------------------------------- /roles/kexec/templates/kexec-load.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Waiting for reboot to load kexec 3 | Documentation=man:kexec(8) 4 | DefaultDependencies=no 5 | Requires=sysinit.target 6 | After=sysinit.target 7 | 8 | [Service] 9 | Type=oneshot 10 | ExecStart=-/usr/bin/true 11 | RemainAfterExit=yes 12 | ExecStop=/usr/sbin/kexec -l {{ bootpath }}/vmlinuz{{ kernelvers }} --initrd={{ bootpath }}/initrd.img{{ kernelvers }} --reuse-cmdline 13 | 14 | [Install] 15 | WantedBy=basic.target 16 | 17 | -------------------------------------------------------------------------------- /roles/motd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Make sure ipmitool is installed 3 | package: 4 | name: 5 | - ipmitool 6 | tags: 7 | - ipmi 8 | - motd 9 | 10 | - name: Get IPMI Address 11 | shell: 12 | cmd: ipmitool lan print | awk '/^IP Address / { print $4 }' 13 | register: ipmi 14 | changed_when: false 15 | tags: 16 | - ipmi 17 | - motd 18 | 19 | - name: Put MOTD in place with ipmi address 20 | template: src=motd dest=/etc/motd 21 | tags: 22 | - motd 23 | 24 | 25 | -------------------------------------------------------------------------------- /roles/motd/templates/motd: -------------------------------------------------------------------------------- 1 | ** THIS IS A PROXMOX SERVER MANAGED BY ANSIBLE ** 2 | 3 | This machine has been deployed using the ansible-proxmox-host playbook. 4 | 5 | WARNING: When this machine is rebooted it will ALWAYS USE KEXEC. 6 | 7 | If you have changed the kernel params, they will not take effect 8 | as the default setting is --reuse-cmdline. Edit the kexec-load.service 9 | file in /etc/systemd/system with the correct params, and run 10 | systemctl daemon-reload. Or just do a full reboot. 11 | 12 | To force a full system reboot use 'systemctl --force reboot' 13 | 14 | {% if ipmi.stdout %} 15 | IPMI Address of this machine is {{ ipmi.stdout }} 16 | {% else %} 17 | {% if noipmi is not defined %} 18 | WARNING: No IPMI Address for this machine could be discovered! 19 | 20 | If this machine does NOT have IPMI, create an empty file /etc/noipmi 21 | to supress this warning and run ansible again. 22 | {% else %} 23 | This machine DOES NOT have IPMI hardware (/etc/noipmi exists) 24 | {% endif %} 25 | {% endif %} 26 | 27 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/10-keepalives.conf: -------------------------------------------------------------------------------- 1 | # Significantly shorten our keepalives so we know if something is missing 2 | 3 | # How long to wait on an idle TCP session before probing 4 | net.ipv4.tcp_keepalive_time = 60 5 | 6 | # After that, how long to wait before sending the next ping? 7 | net.ipv4.tcp_keepalive_intvl = 60 8 | 9 | # If there are this many unanswered probes, tell the application. 10 | net.ipv4.tcp_keepalive_probes = 5 11 | 12 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/60-faster-tcp.conf: -------------------------------------------------------------------------------- 1 | # This file was put in place by the proxmox-base ansible role 2 | # to allow TCP streams to recover rapidly from congestion. 3 | # 4 | # See https://en.wikipedia.org/wiki/Scalable_TCP for more info 5 | net.ipv4.tcp_congestion_control = scalable 6 | 7 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/chrony.conf: -------------------------------------------------------------------------------- 1 | # This file was put in place by the proxmox-base ansible role 2 | # 3 | pool 2.pool.ntp.org iburst 4 | pool 1.pool.ntp.org iburst 5 | 6 | # This directive specify the file into which chronyd will store the rate 7 | # information. 8 | driftfile /var/lib/chrony/chrony.drift 9 | 10 | # Save NTS keys and cookies (Which we don't use yet) 11 | ntsdumpdir /var/lib/chrony 12 | 13 | # Uncomment the following line to turn logging on. 14 | #log tracking measurements statistics 15 | 16 | # Let 10.0.0.0/8 use us as a client, but they shouldn't. 17 | allow 10.0.0.0/8 18 | 19 | # Log files location. 20 | logdir /var/log/chrony 21 | 22 | # Stop bad estimates upsetting machine clock. 23 | maxupdateskew 100.0 24 | 25 | # This directive enables kernel synchronisation (every 11 minutes) of the 26 | # real-time clock. Note that it can’t be used along with the 'rtcfile' directive. 27 | rtcsync 28 | 29 | # Step the system clock instead of slewing it if the adjustment is larger than 30 | # one second, but only in the first three clock updates. 31 | makestep 1 3 32 | 33 | # Get TAI-UTC offset and leap seconds from the system tz database. 34 | # This directive must be commented out when using time sources serving 35 | # leap-smeared time. 36 | leapsectz right/UTC 37 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/etc.default.ssh: -------------------------------------------------------------------------------- 1 | # This file put in place by the proxmox-base role of ansible 2 | # 3 | # Disable all DNS queries by sshd 4 | SSHD_OPTS=-u0 5 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/fix-port-8006.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Remap 8006 to 443 in iptables (so there's no need for anything 4 | # userspace that can break, like a proxy) 5 | 6 | # These environment variables are set when bringing the interface up, 7 | # and can be used by post-up scripts 8 | # 9 | # IFACE=vlan206 10 | # IF_ADDRESS=10.60.3.42/24 11 | # IF_GATEWAY=10.60.3.1 12 | # IF_OVS_BRIDGE=vmbr0 13 | # IF_OVS_MTU=1500 14 | # IF_OVS_OPTIONS=tag=206 15 | # IF_OVS_TYPE=OVSIntPort 16 | # IF_POST_UP=/usr/local/bin/fix-port-8006.sh 17 | # LOGICAL=vlan206 18 | 19 | # Debugging: 20 | set > /tmp/fix8006.env 21 | 22 | # Step 1 - Remove the netmask from IF_ADDRESS 23 | DEST=$(echo $IF_ADDRESS | cut -d/ -f1) 24 | 25 | # Step 2 - Remove any older ones hanging around 26 | CURRENT=$(iptables -t nat -L PREROUTING -n --line-numbers | awk '/ports 8006/ { print $1 }' | sort -n -r) 27 | for i in $CURRENT; do 28 | /usr/sbin/iptables -t nat -D PREROUTING $i 29 | done 30 | 31 | # Step 3 - ??? 32 | IPT="PREROUTING -p tcp --destination $DEST --dport 443 -j REDIRECT --to-ports 8006" 33 | 34 | # Step 4 - Profit! 35 | /usr/sbin/iptables -t nat -A $IPT 36 | 37 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/grubdefault: -------------------------------------------------------------------------------- 1 | # This file is put in place by the proxmox-base role in ansible. 2 | # If you change it, it will be overwritten. 3 | # 4 | # But IF YOU DO, don't forget to run 'update-grub' afterwards, to 5 | # update /boot/grub/grub.cfg. But please update it in ansible 6 | # instead. 7 | 8 | GRUB_DEFAULT=0 9 | GRUB_TIMEOUT_STYLE=menu 10 | GRUB_TIMEOUT=5 11 | GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` 12 | 13 | # The difference between _LINUX_DEFAULT and just _LINUX is that 14 | # the _DEFAULT entries are NOT used in recovery mode. We want 15 | # these everywhere, so they're used everywhere. 16 | GRUB_CMDLINE_LINUX_DEFAULT="" 17 | 18 | # ifnames/biosdevname: 19 | # Use ethx, not random enswhatever names 20 | # mitigations=off: 21 | # Disable all SPECTRE/etc mitigations (minor performance improvement) 22 | # init_on_alloc=0: 23 | # Do not clear pages when allocated (significant performance improvement) 24 | # pcie_aspm=off 25 | # Disable power management of PCIE cards, to avoid PME Spurious native interrupt errors 26 | # See https://forum.proxmox.com/threads/kernel-pcieport-0000-c0-03-1-pme-spurious-native-interrupt.101338/ 27 | GRUB_CMDLINE_LINUX="nofb nomodeset net.ifnames=0 biosdevname=0 mitigations=off init_on_alloc=0 pcie_aspm=off" 28 | 29 | # Always text console 30 | GRUB_TERMINAL=console 31 | GRUB_GFXMODE=text 32 | 33 | 34 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/rasdaemon.conf: -------------------------------------------------------------------------------- 1 | # The cpuid (optional) and msr kernel modules are needed to be loaded 2 | # by rasdaemon, otherwise it goes into stupid mode. 3 | msr 4 | cpuid 5 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/sshconfig: -------------------------------------------------------------------------------- 1 | # This file was created by ansible. It will not be updated 2 | # if modified. However, if it is deleted, it will be replaced 3 | # with a default of "Host *, ForwardAgent yes" 4 | 5 | Host * 6 | ForwardAgent yes 7 | 8 | 9 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/tmp-0777.conf: -------------------------------------------------------------------------------- 1 | # This overrides /usr/lib/tmpfiles.d/tmp.conf and is put in place by ansible 2 | # 3 | # systemd sets the default /tmp perms to be 1777 which is more secure, but 4 | # can cause pemissions conflicts. We've decided to revert that. 5 | 6 | D /tmp 0777 root root - 7 | -------------------------------------------------------------------------------- /roles/proxmox-base/files/vimrc: -------------------------------------------------------------------------------- 1 | if filereadable("/usr/share/vim/vim82/defaults.vim") 2 | source /usr/share/vim/vim82/defaults.vim 3 | endif 4 | 5 | set mouse= 6 | -------------------------------------------------------------------------------- /roles/proxmox-base/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: apt-update 3 | apt: 4 | update_cache: true 5 | 6 | - name: systemctl-reload 7 | command: systemctl daemon-reload 8 | 9 | - name: update-grub 10 | command: update-grub 11 | 12 | - name: restart-sshd 13 | service: name=sshd state=restarted 14 | 15 | - name: restart-chrony 16 | service: name=chrony state=restarted 17 | 18 | - name: systemd-tmpfiles 19 | command: systemd-tmpfiles --create 20 | 21 | - name: sysctl-reload 22 | command: sysctl --system 23 | ignore_errors: yes 24 | when: container is not defined 25 | 26 | - name: loadmodules 27 | command: modprobe cpuid msr 28 | -------------------------------------------------------------------------------- /roles/proxmox-base/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - dpkg-python3 4 | - apt-sources 5 | - fixbash 6 | -------------------------------------------------------------------------------- /roles/proxmox-base/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Set hostname 4 | hostname: 5 | name: "{{ hostname }}" 6 | when: hostname is defined 7 | tags: hostname 8 | 9 | #- name: Fix /etc/hosts 10 | # template: src=hosts dest=/etc/hosts 11 | # when: hostname is defined 12 | # tags: hostname 13 | 14 | - name: Remove unneeded packages 15 | apt: 16 | name: 17 | - multipath-tools 18 | - needrestart 19 | - snapd 20 | - cloud-init 21 | - ubuntu-advantage-tools 22 | state: absent 23 | purge: yes 24 | autoremove: yes 25 | 26 | - name: Install standard base packages 27 | apt: 28 | name: 29 | - vim 30 | - iputils-ping 31 | - open-vm-tools 32 | - jq 33 | - fdisk 34 | - gpg 35 | - dialog 36 | - qemu-guest-agent 37 | - net-tools 38 | - openvswitch-switch 39 | - libpve-network-perl 40 | - sysstat 41 | - chrony 42 | - cpuid 43 | - rasdaemon 44 | - numactl 45 | - numad 46 | - numatop 47 | state: present 48 | 49 | - name: Update grub defaults 50 | copy: 51 | src: grubdefault 52 | dest: /etc/default/grub 53 | notify: update-grub 54 | register: grub 55 | 56 | - meta: flush_handlers 57 | 58 | - name: Check that eth0 exists 59 | stat: 60 | path: /sys/class/net/eth0 61 | register: eth 62 | 63 | - fail: 64 | msg: "eth0 does not exist, you must reboot the machine and reconfig /etc/network/interfaces" 65 | when: not eth.stat.exists 66 | 67 | - name: Stop rsyslog from dropping privs if it's there 68 | lineinfile: 69 | path: /etc/rsyslog.conf 70 | regex: '^.PrivDropTo' 71 | state: absent 72 | tags: rsyslog 73 | 74 | - name: Put our /etc/sysctl.d files in place 75 | copy: 76 | src: "{{ item }}" 77 | dest: /etc/sysctl.d/ 78 | with_items: 79 | - 10-keepalives.conf 80 | - 60-faster-tcp.conf 81 | notify: sysctl-reload 82 | tags: 83 | - sysctl 84 | 85 | - meta: flush_handlers 86 | 87 | - name: Create default ssh config 88 | copy: 89 | src: sshconfig 90 | dest: /root/.ssh/config 91 | force: no 92 | tags: 93 | - ssh 94 | 95 | - name: Set system start timeout to 60s 96 | lineinfile: 97 | path: /etc/systemd/system.conf 98 | regex: '^#?DefaultTimeoutStartSec=' 99 | line: DefaultTimeoutStartSec=60s 100 | tags: 101 | - systemd 102 | 103 | - name: Set system stop timeout to 30s 104 | lineinfile: 105 | path: /etc/systemd/system.conf 106 | regex: '^#?DefaultTimeoutStopSec=' 107 | line: DefaultTimeoutStopSec=30s 108 | tags: 109 | - systemd 110 | 111 | - name: Never hang waiting for network connections 112 | systemd: 113 | name: systemd-networkd-wait-online.service 114 | state: stopped 115 | enabled: no 116 | masked: yes 117 | tags: 118 | - systemd 119 | 120 | - name: Set /tmp to be 0777 instead of 1777 121 | copy: 122 | src: tmp-0777.conf 123 | dest: /etc/tmpfiles.d/ 124 | tags: 125 | - systemd 126 | - tmpfiles 127 | notify: 128 | - systemd-tmpfiles 129 | 130 | - name: Check if resolv.conf is a symlink? 131 | stat: 132 | path: /etc/resolv.conf 133 | register: rconf 134 | tags: 135 | - dns 136 | 137 | - name: Delete resolv.conf symlink if it exists 138 | file: 139 | state: absent 140 | path: /etc/resolv.conf 141 | when: rconf.stat.islnk 142 | tags: 143 | - dns 144 | 145 | - name: Create valid /etc/resolv.conf 146 | template: 147 | src: resolv.conf 148 | dest: /etc/resolv.conf 149 | tags: 150 | - dns 151 | 152 | # SSH8 disables ssh-rsa keys. Re-enable it. 153 | - name: Allow ssh-rsa in ssh keys 154 | lineinfile: 155 | path: /etc/ssh/ssh_config 156 | state: present 157 | insertafter: ^Host 158 | regexp: 'PubkeyAcceptedKeyTypes ' 159 | line: " PubkeyAcceptedKeyTypes +ssh-rsa" 160 | 161 | - name: Enable agent forwarding 162 | lineinfile: 163 | path: /etc/ssh/ssh_config 164 | state: present 165 | insertafter: ^Host 166 | regexp: 'ForwardAgent ' 167 | line: " ForwardAgent yes" 168 | 169 | - name: VNC Proxy needs all the LC_ variables forwarded 170 | lineinfile: 171 | path: /etc/ssh/sshd_config 172 | state: present 173 | regexp: '^AcceptEnv' 174 | line: "AcceptEnv LANG LC_*" 175 | notify: 176 | - restart-sshd 177 | 178 | - name: Disable DNS Reverse lookups by sshd 179 | lineinfile: 180 | path: /etc/ssh/sshd_config 181 | state: present 182 | regexp: '^UseDNS' 183 | line: "UseDNS no" 184 | notify: 185 | - restart-sshd 186 | 187 | - name: ALSO Disable DNS Reverse lookups by sshd 188 | copy: 189 | src: etc.default.ssh 190 | dest: /etc/default/ssh 191 | notify: 192 | - restart-sshd 193 | 194 | - name: Put chrony config file in place 195 | copy: 196 | src: chrony.conf 197 | dest: /etc/chrony/chrony.conf 198 | notify: 199 | - restart-chrony 200 | tags: 201 | - chrony 202 | 203 | - name: Make sure chrony is enabled and running 204 | service: 205 | name: chrony 206 | state: started 207 | enabled: true 208 | tags: 209 | - chrony 210 | 211 | - name: Autoload msr and cpuid kernel modules 212 | copy: 213 | src: rasdaemon.conf 214 | dest: /etc/modules-load.d/ 215 | notify: 216 | - loadmodules 217 | tags: 218 | - ras 219 | 220 | - meta: flush_handlers 221 | 222 | - name: Make sure rasdaemon is ready to catch any hardware errors 223 | service: 224 | name: rasdaemon 225 | state: started 226 | enabled: true 227 | 228 | - name: Put 443-8006 remapper script in place 229 | copy: 230 | src: fix-port-8006.sh 231 | dest: /usr/local/bin/fix-port-8006.sh 232 | mode: 0755 233 | tags: 234 | - httpsport 235 | 236 | 237 | -------------------------------------------------------------------------------- /roles/proxmox-base/templates/hosts: -------------------------------------------------------------------------------- 1 | # Hosts file generated by 'proxmox-base' role 2 | 127.0.0.1 localhost localhost localhost.localdomain localhost4 localhost4.localdomain4 3 | 127.0.1.1 {{ hostname | default(name) }} 4 | 5 | # The following lines are desirable for IPv6 capable hosts 6 | ::1 ip6-localhost ip6-loopback 7 | fe00::0 ip6-localnet 8 | ff00::0 ip6-mcastprefix 9 | ff02::1 ip6-allnodes 10 | ff02::2 ip6-allrouters 11 | 12 | 13 | -------------------------------------------------------------------------------- /roles/proxmox-base/templates/resolv.conf: -------------------------------------------------------------------------------- 1 | {% for ip in forcedns %} 2 | nameserver {{ ip }} 3 | {% endfor %} 4 | 5 | search {{ searchdomain | default("xrob.au") }} 6 | options edns0 7 | 8 | -------------------------------------------------------------------------------- /roles/sshkeys/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart-sshd 3 | service: name=sshd state=restarted 4 | 5 | -------------------------------------------------------------------------------- /roles/sshkeys/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check that /etc/pve/priv/authorized_keys exists 3 | stat: 4 | path: /etc/pve/priv/authorized_keys 5 | register: pauthkey 6 | 7 | - name: Fail if it's not there 8 | fail: 9 | msg: "/etc/pve/priv/authorized_keys does not exist - Proxmox is not setup" 10 | when: not pauthkey.stat.exists 11 | 12 | - name: Add ssh keys from group vars 13 | authorized_key: 14 | user: root 15 | path: /etc/pve/priv/authorized_keys 16 | state: present 17 | exclusive: false 18 | manage_dir: false 19 | key: "{{ sshkeys | join('\n') | string }}" 20 | tags: ssh 21 | 22 | - name: SSH Security - Disable empty password login 23 | lineinfile: dest=/etc/ssh/sshd_config regexp="^#?PermitEmptyPasswords" line="PermitEmptyPasswords no" 24 | notify: restart-sshd 25 | 26 | - name: Disable password logins totally - keys only 27 | lineinfile: dest=/etc/ssh/sshd_config regexp="^(#\s*)?PasswordAuthentication " line="PasswordAuthentication no" 28 | notify: restart-sshd 29 | 30 | - name: Activate ssh keepalives if needed 31 | lineinfile: dest=/etc/ssh/sshd_config regexp="^(#\s*)?ClientAliveInterval " line="ClientAliveInterval = 60" 32 | notify: restart-sshd 33 | 34 | - meta: flush_handlers 35 | 36 | -------------------------------------------------------------------------------- /upgrade.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | roles: 4 | - 7to8upgrade 5 | 6 | 7 | --------------------------------------------------------------------------------