Initial commit (I feel unsafe)
This commit is contained in:
274
instance-setup
Normal file
274
instance-setup
Normal 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
|
||||
Reference in New Issue
Block a user