#!/bin/bash # Script to setup account on VPS, verified versions: Ubuntu 24.04, Debian 13. # # Example usage: curl -L joyus.org/vps/init | bash -s github_account set -o errexit set -o nounset GITHUB_ID="${1?:'Usage: $0 '}" SSHD_PORT="60022" PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin function main { install_pkgs setup_firewall create_user modify_user setup_ssh setup_sshd setup_sudo setup_kernal_params setup_resolved disable_exim disable_rpcbind } function info { echo -e "\e[32m$*\e[0m" } function error { echo -e "\e[31m$*\e[0m" } function install_pkgs { sudo apt update -y sudo apt install -y \ caddy \ cron \ curl \ dnsutils \ docker.io \ git \ iputils-ping \ locate \ make \ net-tools \ rsync \ systemd-resolved \ tmux \ tree \ ufw \ vim-nox \ zsh } function create_user { ! id $GITHUB_ID >& /dev/null || return 0 info "Creating user $GITHUB_ID" sudo useradd --home-dir /home/$GITHUB_ID --create-home \ --shell /bin/zsh $GITHUB_ID id $GITHUB_ID } function modify_user { local home=$(eval echo ~${GITHUB_ID}) sudo usermod -a -G docker $GITHUB_ID [[ -f $home/.zshrc ]] || { # Set up a minimal zsh prompt echo "PROMPT='%(?.%F{green}✔.%F{red}✘)%f %m:%~ %# '" \ | sudo tee $home/.zshrc > /dev/null sudo chown $GITHUB_ID $home/.zshrc } } function setup_ssh { local home=$(eval echo ~${GITHUB_ID}) local key_file=$home/.ssh/authorized_keys local key_line local tmpf sudo mkdir -p $home/.ssh sudo touch $key_file sudo chown $GITHUB_ID $home $home/.ssh $key_file sudo chmod go-w $home sudo chmod -R 700 $home/.ssh # Fix missing EOL [[ -z $(sudo tail -c 1 $key_file) ]] || echo | sudo tee -a $key_file tmpf=$(mktemp) trap "rm -f $tmpf" RETURN curl -SsL https://github.com/${GITHUB_ID}.keys > $tmpf while read -r key_line; do setup_public_key $key_file "$key_line" done < $tmpf sudo chmod 600 $home/.ssh/authorized_keys } function setup_public_key { local key_file=${1:?} local pkey=${2:?} ! sudo grep -qF "$pkey" $key_file || return 0 info "Adding ssh public key: $pkey" echo "$pkey" | sudo tee -a $key_file } function setup_sshd { local status status=$(curl ipfw.net/$SSHD_PORT) case "$status" in open) info "Port 60222 is already reachable"; return 0 ;; refused) info "Going to change sshd port to $SSHD_PORT" ;; *) error "Port 6022 status unknown, check firewall!"; return 1 ;; esac info "Updating ssh listening port from 22 to $SSHD_PORT / disable root login" sudo sed -i'' -r \ -e "s/^#?\s*Port 22$/Port $SSHD_PORT/" \ -e 's/^#?\s*PermitRootLogin .*/PermitRootLogin no/' \ /etc/ssh/sshd_config # Disable the magic ssh.socket, so sshd_config explicitly controls the port # See: https://discourse.ubuntu.com/t/sshd-now-uses-socket-based-activation-ubuntu-22-10-and-later/30189 if systemctl list-unit-files ssh.socket >/dev/null 2>&1; then sudo systemctl disable --now ssh.socket fi sudo systemctl enable ssh.service sudo systemctl restart ssh } function setup_sudo { ! sudo -l -U $GITHUB_ID | grep -Eq "NOPASSWD:[[:blank:]]*ALL" || return 0 info "Add sudoer entry file for $GITHUB_ID" echo "$GITHUB_ID ALL=(ALL:ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/$GITHUB_ID sudo chmod 440 /etc/sudoers.d/$GITHUB_ID sudo -l -U $GITHUB_ID } function setup_kernal_params { # https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes echo "net.core.rmem_max=7500000" | sudo tee /etc/sysctl.d/99-udp-buffer-sizes echo "net.core.wmem_max=7500000" | sudo tee -a /etc/sysctl.d/99-udp-buffer-sizes sudo sysctl --system } function setup_firewall { info "Configuring UFW firewall rules..." sudo ufw --force reset sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw default allow routed sudo ufw allow 22,80,443,60000:65535/tcp sudo ufw allow 60000:65535/udp sudo ufw --force enable sudo ufw reload } function setup_resolved { # NOTE! :53 is required for xray and naive to work local conf="/etc/systemd/resolved.conf" if grep -Eq '^DNS=.+' $conf && grep -Eq '^LLMNR=no$' $conf; then return 0 fi sudo sed -i'' -r \ -e 's/^#DNS=.*/DNS=1.1.1.1 8.8.8.8/' \ -e 's/^#?\s*LLMNR=.*/LLMNR=no/' \ $conf sudo systemctl restart systemd-resolved } function disable_exim { [[ -f /usr/sbin/exim4 ]] || return 0 sudo systemctl stop exim4 sudo systemctl disable exim4 } function disable_rpcbind { [[ -f /sbin/rpcbind ]] || return 0 sudo systemctl stop rpcbind.service sudo systemctl stop rpcbind.socket sudo systemctl disable rpcbind.service sudo systemctl disable rpcbind.socket } main "$@"