graphene-os-server-infrastr.../deploy-initial-vps
Daniel Micay abca76d110 switch to explicit sshd listen addresses
This makes more sense than blocking inbound traffic for specific IP
addresses where SSH doesn't make sense.

This orders sshd.service after network-online.target since otherwise
ListenAddress can fail to work with specific IP addresses assigned by
systemd-networkd.
2025-12-10 03:31:34 -05:00

88 lines
3.5 KiB
Bash
Executable file

#!/bin/bash
set -o errexit -o nounset -o pipefail
shopt -s expand_aliases
. hosts.sh
. ssh.sh
[[ $# -eq 1 ]] || exit 1
readonly host=$1
readonly ip=${hosts_ipv4_address[$host]}
readonly hostname=${hosts_hostname[$host]}
readonly agcount=${hosts_agcount[$host]:-4}
readonly swap=${hosts_swap[$host]:-2048}
readonly remote=root@$ip
readonly drive=$(ssh $remote '[[ -e /dev/sda ]] && echo sda || echo vda')
alias rsync='rsync -cpv --chmod=D755,F644 --preallocate'
# check for Arch ISO
ssh $remote '[[ $(grep IMAGE_ID /etc/os-release) = "IMAGE_ID=archlinux" ]]' || exit 5
ssh $remote '[[ $(grep IMAGE_VERSION /etc/os-release) = "IMAGE_VERSION=2025.11.01" ]]' || exit 5
ssh $remote "sfdisk /dev/$drive -w always <<< ';'"
ssh $remote "mkfs.xfs -d agcount=$agcount -f /dev/${drive}1"
rsync etc/pacman.d/mirrorlist $remote:/etc/pacman.d/mirrorlist
ssh $remote "mount /dev/${drive}1 /mnt"
ssh $remote "pacstrap -K /mnt $(tr '\n' ' ' < packages/$host)"
rsync etc/default/grub $remote:/mnt/etc/default/grub
ssh $remote "arch-chroot /mnt grub-install /dev/$drive"
ssh $remote "arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg"
ssh $remote "echo $hostname >/mnt/etc/hostname"
rsync etc/systemd/network/$host.link $remote:/mnt/etc/systemd/network/10-public.link
rsync etc/systemd/network/$host.network $remote:/mnt/etc/systemd/network/10-public.network
rsync etc/fstab.virtual $remote:/mnt/etc/fstab
rsync etc/{crypttab,locale.conf,pacman.conf,pacreport.conf,resolv.conf} $remote:/mnt/etc/
rsync etc/mkinitcpio.conf.simple $remote:/mnt/etc/mkinitcpio.conf
rsync etc/unbound/unbound.conf $remote:/mnt/etc/unbound/unbound.conf
if [[ $host = @(0.grapheneos.network|1.grapheneos.network|2.grapheneos.network|3.grapheneos.network) ]]; then
cp etc/chrony.conf tmp
echo -e '\nallow' >> tmp
rsync tmp $remote:/mnt/etc/chrony.conf
rm tmp
else
rsync etc/chrony.conf $remote:/mnt/etc/chrony.conf
fi
ssh $remote mkdir -vp /mnt/etc/sysconfig
rsync etc/sysconfig/chronyd $remote:/mnt/etc/sysconfig/chronyd
rsync ${hosts_authorized_keys[$host]:-authorized_keys} $remote:/mnt/root/.ssh/authorized_keys
cp etc/ssh/sshd_config tmp
sed -i "s/{{ipv4_address}}/${hosts_ipv4_address[$host]:-127.0.0.1}/g" tmp
sed -i "s/{{ipv6_address}}/${hosts_ipv6_address[$host]:-::1}/g" tmp
sed -i "s/{{ssh_users}}/${hosts_ssh_users[$host]:-root}/g" tmp
rsync tmp $remote:/mnt/etc/ssh/sshd_config
rm tmp
rsync -r --delete etc/systemd/system/sshd.service.d $remote:/mnt/etc/systemd/system/
cp etc/nftables/nftables-${hosts_firewall[$host]:-web}.conf tmp
sed -i "s/{{synproxy_threshold}}/$(( ${hosts_conntrack_size[$host]:-65536} / 64 ))/g" tmp
sed -i "s/{{ssh_ipv4}}/$ssh_ipv4/g" tmp
sed -i "s/{{ssh_ipv6}}/$ssh_ipv6/g" tmp
rsync tmp $remote:/mnt/etc/nftables.conf
rm tmp
ssh $remote "arch-chroot /mnt systemctl enable chronyd.service fstrim.timer logrotate.timer nftables.service systemd-networkd.service systemd-oomd.service sshd.service sysstat.service unbound.service"
ssh $remote "arch-chroot /mnt systemctl disable remote-fs.target systemd-network-generator.service systemd-userdbd.socket"
ssh $remote "arch-chroot /mnt groupadd -g 2000 io_uring"
ssh $remote "arch-chroot /mnt groupadd -g 2100 tls"
ssh $remote "umask 077 && dd if=/dev/random of=/mnt/swapfile bs=1M count=$swap status=progress"
ssh $remote "arch-chroot /mnt chsh -s /usr/bin/fish"
password=$(head -c32 <(tr -dc A-Za-z0-9 </dev/random))
echo password: $password
ssh $remote "echo root:$password | arch-chroot /mnt chpasswd"
ssh $remote umount /mnt
ssh $remote reboot