Initial commit (I feel unsafe)

This commit is contained in:
2026-01-16 00:11:58 -08:00
commit d69daa37bf
121 changed files with 4153 additions and 0 deletions

274
instance-setup Normal file
View File

@@ -0,0 +1,274 @@
#!/bin/bash
echo -e "\n[+] Let's begin!\n\n-------\n"
# define these first
[[ -z "$BASE_DOMAIN" ]] && echo "base domain missing" && exit 1
[[ -z "$CF_EMAIL_ALIAS" ]] && echo "domain email missing" && exit 1
[[ -z "$UBUNTU_PRO_TOKEN" ]] && echo "ubuntu pro token missing" && exit 1
[[ -z "$B2_COLON_BUCKET_NAME" ]] && echo "b2 bucket name missing" && exit 1
[[ -z "$NTFY_URL" ]] && echo "ntfy endpoint missing" && exit 1
domain=$BASE_DOMAIN
email_address=${CF_EMAIL_ALIAS}
echo "BASE_DOMAIN=${BASE_DOMAIN}" | sudo tee -a /etc/environment
echo "BACKUP_BUCKET=${B2_COLON_BUCKET_NAME}" | sudo tee -a /etc/environment # current: the startingOut one
echo "NOTIF_URL=${NTFY_URL}" | sudo tee -a /etc/environment # current: endpoint on ntfy.sh
# some useful aliases
cat instance-bash_aliases | tee -a ~/.bash_aliases
cat instance-bash_aliases | sudo tee -a /etc/skel/.bash_aliases
# some useful autocompletions
chmod 774 instance-bash_autocompletions
./instance-bash_autocompletions
cd ~ || exit
sudo apt-get update
sudo apt-get upgrade -y
sudo pro attach "$UBUNTU_PRO_TOKEN"
if [[ $(cloud-init query platform) == 'oracle' ]]; then
# https://www.reddit.com/r/oraclecloud/comments/r8lkf7/a_quick_tips_to_people_who_are_having_issue/
echo "[+] disabling ufw and netfilter rules (OCI default)"
sudo ufw disable
sudo iptables -I INPUT -j ACCEPT
sudo iptables-save | sudo dd of=/etc/iptables/rules.v4
fi
echo "[+] packages"
# JDK 17 or higher needed for MC
sudo apt-get install build-essential curl gnupg2 ca-certificates lsb-release ubuntu-keyring apt-transport-https expect -y
sudo apt-get install openjdk-21-jdk-headless systemd-container fail2ban -y
sudo systemctl enable --now fail2ban.service
echo "[+] docker"
sudo install -m 0775 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs 2>/dev/null) stable" |
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
echo "[+] nginx"
# http://nginx.org/en/linux_packages.html#Ubuntu
curl -L https://nginx.org/keys/nginx_signing.key | gpg --dearmor |
sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
expected_nginx_fingerprint='573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62'
if ! gpg --dry-run --quiet --no-keyring --import --import-options \
import-show /usr/share/keyrings/nginx-archive-keyring.gpg |
grep -c $expected_nginx_fingerprint; then
echo -e "\n[!] Nginx GPG key fingerprint does not match, aborting...\n"
sudo rm /usr/share/keyrings/nginx-archive-keyring.gpg
exit 1
fi
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs 2>/dev/null) nginx" |
sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" |
sudo tee /etc/apt/preferences.d/99nginx
echo "[+] syncthing"
sudo curl -L -o /etc/apt/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg
echo "deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg]\
https://apt.syncthing.net/ syncthing stable-v2" |
sudo tee /etc/apt/sources.list.d/syncthing.list
echo -e "Package: *\nPin: origin apt.syncthing.net\nPin-Priority: 990\n" |
sudo tee /etc/apt/preferences.d/syncthing.pref
echo "[+] putting it all together"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin nginx syncthing -y
if ! sudo docker run hello-world | grep -c 'installation appears to be working correctly'; then
echo -e "\n[!] Docker installation failed, aborting...\n"
exit 1
fi
echo "[+] rclone"
curl https://rclone.org/install.sh | sudo bash
echo "[+] certbot from snap ugh"
sudo snap install core
sudo snap refresh core
sudo apt-get remove certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
echo "[+] add users for applications"
# format - tool name underscore 'server'
users=(
"actual_server"
"authelia_server"
"foundry_server"
"ghost_server"
"gitea_server"
"homepage_server"
"mealie_server"
"memos_server"
"minecraft_server"
"pwpush_server"
"shlink_server"
"spotmgr_server"
"stirling_server"
"syncthing_server"
"vikunja_server"
"wg_server"
)
for username in "${users[@]}"; do
sudo useradd -m -U -s /bin/bash "${username}"
# setup script
sudo cp ~/"${username}"-setup /home/"${username}"/
sudo chmod 774 /home/"${username}"/"${username}"-setup
sudo chown "${username}":"${username}" /home/"${username}"/"${username}"-setup
sudo cp ~/"${username}"-env /home/"${username}"/
sudo chmod 600 /home/"${username}"/"${username}"-env
sudo chown "${username}":"${username}" /home/"${username}"/"${username}"-env
# user services won't linger by default
sudo loginctl enable-linger "${username}"
done
# admin privileges, needed for anyone running docker
admin_users=(
"actual_server"
"authelia_server"
"ghost_server"
"gitea_server"
"homepage_server"
"mealie_server"
"memos_server"
"pwpush_server"
"shlink_server"
"spotmgr_server"
"stirling_server"
"vikunja_server"
"wg_server"
)
for username in "${admin_users[@]}"; do
sudo usermod -aG sudo "${username}"
echo "${username} ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/"${username}"
# compose files
sudo cp ~/"${username}"-compose_template.yaml /home/"${username}"/
sudo chmod 664 /home/"${username}"/"${username}"-compose_template.yaml
sudo chown "${username}":"${username}" /home/"${username}"/"${username}"-compose_template.yaml
sudo cp ~/"${username}"-compose.yaml /home/"${username}"/
sudo chmod 600 /home/"${username}"/"${username}"-compose.yaml
sudo chown "${username}":"${username}" /home/"${username}"/"${username}"-compose.yaml
done
echo "[+] distribute and apply respective config files"
echo -e "\t[-] rclone"
for username in "${users[@]}"; do
sudo mkdir -p /home/"${username}"/.config/rclone/
sudo cp ~/.config/rclone/rclone.conf /home/"${username}"/.config/rclone/
sudo chmod -R 600 /home/"${username}"/.config/rclone/rclone.conf
sudo chown -R "${username}":"${username}" /home/"${username}"/
done
# consider switching to acme.sh instead of certbot to avoid snap
echo -e "\t[-] nginx and certbot"
cert_subdomains=(
"api.spotify-manager"
"auth"
"budget"
"dash"
"git"
"lnk"
"notes"
"paste"
"planning"
"pdf"
"recipes"
"syncthing"
"vpn"
"vtt"
)
# ghost handles SSL by itself, might be worth looking into it to either shift to certbot
for subdomain in "${cert_subdomains[@]}"; do
# revoke existing certs if any
sudo certbot revoke -n --delete-after-revoke --cert-name "${subdomain}"."${domain}"
sudo cp ~/"${subdomain}"."${domain}".conf /etc/nginx/conf.d/
sudo chmod 664 /etc/nginx/conf.d/"${subdomain}"."${domain}".conf
sudo chown root:root /etc/nginx/conf.d/"${subdomain}"."${domain}".conf
if ! sudo nginx -t; then
echo -e "\n\t[!] Bad Nginx config for ${subdomain}.${domain}, aborting...\n"
exit 1
fi
sudo nginx -s reload
# ----------------------------------------------------------------------
# STOP!
# Check DNS records before proceeding
# ----------------------------------------------------------------------
# https://letsencrypt.org/docs/duplicate-certificate-limit/#description
# certbot has 5 per week duplicate cert limit. use --test-cert flag for testing
if ! sudo certbot -n --nginx --agree-tos -m "${email_address}" -d "${subdomain}"."${domain}"; then
echo -e "\n\t[!] Certbot failed to get cert for ${subdomain}.${domain}, aborting...\n"
exit 1
fi
sudo nginx -s reload
done
echo -e "\t[-] user-specific files"
# bash variable expansion ftw - https://stackoverflow.com/a/63821858/7630441
user_files=(
"authelia_server-configuration.yaml"
"foundry_server-start.service"
"ghost_server-config.production.json"
"ghost_server-credentials.exp"
"minecraft_server-start.service"
"minecraft_server-start.socket"
"pwpush_server-settings.yaml"
)
for f in "${user_files[@]}"; do
username=${f%%-*} # strips the part from before the hyphen
sudo cp ~/"${f}" /home/"${username}"/
sudo chmod 664 /home/"${username}"/"${f}"
sudo chown "${username}":"${username}" /home/"${username}"/"${f}"
done
echo -e "[+] cronjobs: backups, updates"
for username in "${users[@]}"; do
sudo cp ~/"${username}"-backup /home/"${username}"/
sudo chmod 774 /home/"${username}"/"${username}"-backup
sudo chown "${username}":"${username}" /home/"${username}"/"${username}"-backup
sudo cp ~/"${username}"-update /home/"${username}"/
sudo chmod 774 /home/"${username}"/"${username}"-update
sudo chown "${username}":"${username}" /home/"${username}"/"${username}"-update
{
# first add some useful env vars that aren't in cron's exec env
echo "USER=$username"
echo "XDG_RUNTIME_DIR=/run/user/$(id -u "$username")"
echo "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u "$username")/bus"
# then the defined cronjob
cat ~/"${username}"-cronjob
} >~/"${username}".cronjobs
# install to crontab
sudo crontab -u "${username}" ~/"${username}".cronjobs
rm ~/"${username}".cronjobs
done
# shellcheck disable=SC2024
sudo crontab -l -u ubuntu >~/ubuntu.cronjobs
cat ~/ubuntu-cronjob >>~/ubuntu.cronjobs
sudo crontab -u ubuntu ~/ubuntu.cronjobs
rm ~/ubuntu.cronjobs
for username in "${users[@]}"; do
chmod ug+x "${username}"-teardown
done