From 53d62dca6cc7c3a5ec27eaa31af9ba930af4927d Mon Sep 17 00:00:00 2001 From: Price Hiller Date: Tue, 24 Aug 2021 22:21:44 -0500 Subject: [PATCH] Mordhau Manage and Nginx goodies --- CentOS/Mordhau/Mordhau-Manage.bash | 626 ++++++++++++++++++++++++++++ CentOS/Nginx/Install-SSL.bash | 112 +++++ CentOS/Nginx/Install-Wordpress.bash | 5 +- 3 files changed, 739 insertions(+), 4 deletions(-) create mode 100755 CentOS/Mordhau/Mordhau-Manage.bash create mode 100755 CentOS/Nginx/Install-SSL.bash diff --git a/CentOS/Mordhau/Mordhau-Manage.bash b/CentOS/Mordhau/Mordhau-Manage.bash new file mode 100755 index 0000000..b69b25f --- /dev/null +++ b/CentOS/Mordhau/Mordhau-Manage.bash @@ -0,0 +1,626 @@ +#!/bin/bash + +### CONSTANTS ### +START_PORT_RANGE=30000 +BASE_DIR=~/"Mordhau" +CONFIG_DIRECTORY="${BASE_DIR}/config" +MODS_CONFIG="${CONFIG_DIRECTORY}/mods.conf" +ADMINS_CONFIG="${CONFIG_DIRECTORY}/admins.conf" +RCON_PASS_LOCATION="${CONFIG_DIRECTORY}/rcon.pass" +SERVER_PASS_LOCATION="${CONFIG_DIRECTORY}/server.pass" +### CONSTANTS ### + +echo_rgb() { + # Echo a colored string to the terminal based on rgb values + # + # Positional Arguments: + # + # message + # - The message to be printed to stdout + # red + # - The red value from 0 to 255 + # green + # - The green value from 0 to 255 + # blue + # - The blue value from 0 to 255 + # + # Usage: + # echo_rgb "Yep" 10 8 30 + # + # POSIX Compliant: + # N/A + # + + local red + local green + local blue + local input + + input="${1}" + red="${2}" + green="${3}" + blue="${4}" + + printf "\e[0;38;2;%s;%s;%sm%s\e[m\n" "${red}" "${green}" "${blue}" "${input}" +} + +log() { + # Print a message and send it to stdout or stderr depending upon log level, also configurable with debug etc. + # + # Arguments: + # level + # - The log level, defined within a case check in this function + # message + # - The info message + # line_number + # - The line number of the calling function (${LINNO}) + # + # Usage: + # log "info" "Could not find that directory" + # + # POSIX Compliant: + # Yes + # + + # Set debug status depending if a global debug variable has been set to either 1 or 0 + local debug + if [ ${DEBUG} ]; then + debug=${DEBUG} + else + debug=0 + fi + + local FORMAT + FORMAT="[$(echo_rgb "$(date +%Y-%m-%dT%H:%M:%S)" 180 140 255)]" + + # Convert the level to uppercase + local level + level=$(echo "${1}" | tr '[:lower:]' '[:upper:]') + + local message + message="${2}" + + case "${level}" in + INFO) + # Output all info log levels to stdout + printf "${FORMAT}[$(echo_rgb "INFO" 0 140 255)] %s\n" "${message}" >&1 + return 0 + ;; + WARN | WARNING) + # Output all info log levels to stdout + printf "${FORMAT}[$(echo_rgb "WARNING" 255 255 0)] %s\n" "${message}" >&1 + return 0 + ;; + DEBUG) + [[ ${debug} == 0 ]] && return + printf "${FORMAT}[$(echo_rgb "DEBUG" 0 160 110)] %s\n" "${message}" >&1 + return 0 + ;; + ERROR) + # Output all error log levels to stderr + printf "${FORMAT}[$(echo_rgb "ERROR" 255 0 0)] %s\n" "${message}" >&2 + return 0 + ;; + # Further log levels can be added by extending this switch statement with more comparisons + + *) # Default case, no matches + # Returns non-zero code as an improper log option was passed, this helps with using `set -e` + printf "${FORMAT}[ERROR] %s\n" "Invalid log level passed, received level \"${level}\" with message \"${message}\"" >&2 + return 1 + ;; + esac +} + +confirmation() { + # Receive confirmation from user as y, Y, n, or N + # returns 0 when answer is yes and 1 when answer is no + # + # Arguments: + # message + # - The confirmation prompt sent to the user, for example: + # Would you like to overwrite foobar.txt (y/N)? + # + # Usage: + # confirmation "Some prompt" + # - Sends "Some prompt" to the user and gets their input + # + # POSIX Compliant: + # Yes + # + + local message + message="${1}" + + local choice + + while true; do + read -p "${message} " -n 1 -r choice + case "$choice" in + y | Y) + echo "" + return 0 + ;; + n | N) + echo "" + return 1 + ;; + *) echo -e "\nInput must be either y, Y, n, or N" ;; + esac + done +} + +important() { + echo_rgb "${1}" 135 195 255 +} + +kill_server() { + local prefix + local tmux_response + local server_id + + server_id="" + prefix="Mordhau" + + while :; do + case ${1} in + -h | -\? | --help) + printf "Usage: %s\n" \ + "kill --server | kill -s + --server | -s + Kills the server with the given id + + Example: + --server 3" + exit + ;; + --) # End of all options. + break + ;; + --server | -s) + shift + server_id="${1}" + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + ;; + -?*) + printf 'Unknown option: %s\n' "$1" >&2 + ;; + *) # Default case: No more options, so break out of the loop. + break ;; + esac + shift + done + + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + + tmux kill-session -t "${prefix}-Server-${server_id}" > /dev/null 2>&1 + tmux_response="${?}" + + if [ "${tmux_response}" == "0" ]; then + log "info" "Stopped $(important "${prefix}-Server-${server_id}")" + return "${tmux_response}" + else + log "error" "Could not find $(important "${prefix}-Server-${server_id}") or unable to shut down ${prefix}-Server-${server_id}" + return "${tmux_response}" + fi +} + +should_kill() { + local prefix + local server_id + + prefix="Mordhau" + server_id="${1}" + + tmux has-session -t "${prefix}-Server-${server_id}" >/dev/null 2>&1 + + if [ "${?}" == 0 ]; then + log "warning" "${prefix} server $(important "${prefix}-Server-${server_id}") is currently running" + + confirmation "Would you like to kill it (y/N)?" + + if [[ "${?}" -eq 0 ]]; then + log "info" "Ok, killing server $(important "${prefix}-Server-${server_id}")" + tmux kill-session -t "${prefix}-Server-${server_id}" && + log "info" "Successfully killed $(important "${prefix}-Server-${server_id}")" + return 0 + else + log "info" "Not ending current server $(important "${prefix}-Server-${server_id}"), exiting..." + return 1 + fi + fi + + return 0 +} + +generate_default_configs() { + + mkdir -p "${BASE_DIR}" && log "info" "Created base directory if it didn't exist" + mkdir -p "${CONFIG_DIRECTORY}" && log "info" "Created config directory if it didn't exist" + + if [ ! -f "${RCON_PASS_LOCATION}" ]; then + local rcon_pass + rcon_pass="$(openssl rand -base64 48)" + echo "${rcon_pass}" >"${RCON_PASS_LOCATION}" + log "info" "Generated a new rcon password as it did not exist" + fi + + if [ ! -f "${SERVER_PASS_LOCATION}" ]; then + echo "20rserver" >"${SERVER_PASS_LOCATION}" + log "info" "Generated the server password file as it did not exist" + fi + + if [ ! -f "${MODS_CONFIG}" ]; then + + cat <<__EOF__ >"${MODS_CONFIG}" +# This is the default mods configuration file +# To define mods use the following syntax: Mods=mod_id +# For example: +# Mods=1121745 +__EOF__ + log "info" "Created a new mods.conf with no mods" + fi + + if [ ! -f "${ADMINS_CONFIG}" ]; then + + cat <<__EOF__ >"${ADMINS_CONFIG}" +# This is the default admins configuration file +# To define admins use the following syntax: Admins=PLAYFAB_ID +# For example: +# Admins=5E92E0B55E90869C +__EOF__ + log "info" "Created a new mods.conf with no mods" + fi + + log "info" "Generated all configs if they did not exist" +} + +start() { + local server_id + local can_kill + + server_id="" + can_kill=0 + + while :; do + case ${1} in + -h | -\? | --help) + printf "Usage: %s\n" \ + "start --server | kill -s + --server | -s + Starts the given server id + + Example: + --server 3 + --can-kill | -c + Automatically kills the server if it is running without prompting + + Example: + --can-kill" + exit + ;; + --) # End of all options. + break + ;; + --server | -s) + shift + server_id="${1}" + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + ;; + --can-kill | -c) + can_kill=1 + ;; + -?*) + printf 'Unknown option: %s\n' "$1" >&2 + ;; + *) # Default case: No more options, so break out of the loop. + break ;; + esac + shift + done + + generate_default_configs + + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + + local server_directory + local server_config + server_directory="${BASE_DIR}/Server-${server_id}" + server_config="${server_directory}/Mordhau/Saved/Config/LinuxServer/Game.ini" + + [[ ! -d "${server_directory}" ]] && + log "error" "Unable to find the server directory for ${server_id}, verify the server exists at ${server_directory}" && + exit 1 + + [[ ! -f "${server_config}" ]] && + log "error" "Unable to find a valid Game.ini for ${server_id}, verify the installation is correct" && + exit 1 + + local rcon_pass + local server_pass + local mods + local admins + + rcon_pass="$(cat "${RCON_PASS_LOCATION}")" + server_pass="$(cat "${SERVER_PASS_LOCATION}")" + + if [[ "${can_kill}" -eq "1" ]]; then + kill_server -s "${server_id}" >/dev/null 2>&1 + else + should_kill "${server_id}" + [[ "${?}" == "1" ]] && exit 1 + fi + + while read -r line; do + if [[ "${line}" == "#"* ]]; then + : + else + echo "${line}" + fi + done <"${MODS_CONFIG}" >"${BASE_DIR}/mods.tmp" + + mods="$(cat "${BASE_DIR}/mods.tmp")" + rm -f "${BASE_DIR}/mods.tmp" + + while read -r line; do + if [[ "${line}" == "#"* ]]; then + : + else + echo "${line}" + fi + done <"${ADMINS_CONFIG}" >"${BASE_DIR}/admins.tmp" + + admins="$(cat "${BASE_DIR}/admins.tmp")" + rm -f "${BASE_DIR}/admins.tmp" + + local game_port + local query_port + local beacon_port + local rcon_port + + game_port=$(("${START_PORT_RANGE}" + $(("${server_id}" * 4)) + 0)) + query_port=$(("${START_PORT_RANGE}" + $(("${server_id}" * 4)) + 1)) + beacon_port=$(("${START_PORT_RANGE}" + $(("${server_id}" * 4)) + 2)) + rcon_port=$(("${START_PORT_RANGE}" + $(("${server_id}" * 4)) + 3)) + + while read -r line; do + if [[ "${line}" == "RconPort="* ]]; then + echo "RconPort=${rcon_port}" + elif [[ "${line}" == "RconPassword="* ]]; then + echo "RconPassword=${rcon_pass}" + elif [[ "${line}" == *"Mordhau.MordhauGameSession"* ]]; then + echo "${mods}" + echo "${admins}" + elif [[ "${line}" == "Mods="* ]]; then + : + fi + done <"${server_config}" >"serv.temp" && mv "serv.temp" "${server_config}" + + + log "info" "Ports: + $(important " Game Port: ${game_port}") + $(important " Query Port: ${query_port}") + $(important " Beacon Port: ${beacon_port}") + $(important " RCON Port: ${rcon_port}")" + log "info" "Startup Arguments: + $(important " -Port=${game_port}") + $(important " -QueryPort=${query_port}") + $(important " -BeaconPort=${beacon_port}") + $(important " -LOG") + $(important " -USEALLAVAILABLE")" + + tmux new-session -d -s "Mordhau-Server-${server_id}" \ + ${BASE_DIR}/Server-"${server_id}"/MordhauServer.sh \ + -Port="${game_port}" \ + -QueryPort="${query_port}" \ + -BeaconPort="${beacon_port}" \ + -LOG \ + -USEALLAVAILABLE \ + && log "info" "Successfully started Mordhau-Server-${server_id}" + +} + +update() { + local server_id + local redownload_mods + + server_id="" + redownload_mods=0 + + while :; do + case ${1} in + -h | -\? | --help) + printf "Usage: %s\n" \ + "update --server | kill -s + --server | -s + Starts the given server id + + Example: + --server 3 + --redownload-mods | -r + Redownloads all mods by clearing the .modio folder" + exit + ;; + --) # End of all options. + break + ;; + --server | -s) + shift + server_id="${1}" + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + ;; + -?*) + printf 'Unknown option: %s\n' "$1" >&2 + ;; + *) # Default case: No more options, so break out of the loop. + break ;; + esac + shift + done + + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + + kill_server -s "${server_id}" >/dev/null 2>&1 + + local server_directory + local server_config + server_directory="${BASE_DIR}/Server-${server_id}" + server_config="${server_directory}/Mordhau/Saved/Config/LinuxServer/Game.ini" + + [[ ! -d "${server_directory}" ]] && + log "error" "No server directory found for ${server_id}, checked at ${server_directory}" && + exit 1 + + if [ "${redownload_mods}" == "1" ]; then + rm -rf "${server_directory}/Mordhau/Content/.modio" + log "info" ".modio cleared, start Server-${server_id} to download mods" + fi + + log "info" "Verifying and updating server" + steamcmd +login anonymous +force_install_dir "${server_directory}" +app_update 629800 validate +quit + log "info" "Successfully verified and updated $(important "Server-${server_id}")" +} + +install() { + + local server_id + server_id="" + + while :; do + case ${1} in + -h | -\? | --help) + printf "Usage: %s\n" \ + "install --server | install -s + --server | -s + Installs the server to the given id if it doesn't exist + + Example: + --server 3" + exit + ;; + --) # End of all options. + break + ;; + --server | -s) + shift + server_id="${1}" + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + ;; + -?*) + printf 'Unknown option: %s\n' "$1" >&2 + ;; + *) # Default case: No more options, so break out of the loop. + break ;; + esac + shift + done + + [[ -z "${server_id}" ]] && log "error" "No server id passed" && exit 1 + + local prefix + + prefix="Mordhau" + + local server_directory + local server_config + server_directory="${BASE_DIR}/Server-${server_id}" + server_config="${server_directory}/Mordhau/Saved/Config/LinuxServer/Game.ini" + + [[ -d "${server_directory}" ]] && + log "error" "A server already exists at ${server_directory}, delete it and try again" && + exit 1 + + mkdir -p "${server_directory}" && log "info" "Created server directory ${server_directory}" + + steamcmd +login anonymous +force_install_dir "${server_directory}" +app_update 629800 validate +quit + log "info" "Successfully installed Server-${server_id}" + + log "info" "Starting server to install default configuration files, please wait..." + + tmux new-session -d -s "${prefix}-Server-${server_id}" \ + "${server_directory}/MordhauServer.sh" + + sleep 5 + + tmux send-keys -t "${prefix}-Server-${server_id}" "C-c" ENTER >/dev/null 2>&1 \ + && log "info" "Successfully ran the Mordhau session and stopped the session" +} + +usage() { + # Print out usage instructions for the local script + # + # Arguments: + # None + # + # Usage: + # usage + # + # POSIX Compliant: + # Yes + # + printf "Usage: %s\n" \ + "$(basename ${0}) -h + start + Exposes options to start Mordhau Servers, pass -h to it for details + kill + Exposes options to kill Mordhau Servers, pass -h to it for details + install + Exposes options to install Mordhau Servers, pass -h to it for details + update + Exposes options to update Mordhau Servers, pass -h to it for details" +} + +parse_args() { + # Parse input arguments + # + # Arguments: + # Consult the `usage` function + # + # Usage: + # parse_args "$@" + # - All arguments should be ingested by parse_args first for variable setting + # + # POSIX Compliant: + # Yes + # + + while :; do + case ${1} in + -h | -\? | --help) + usage # Display a usage synopsis. + exit + ;; + --) # End of all options. + break + ;; + start | s) + shift + start "$@" + break + ;; + kill | k) + shift + kill_server "$@" + break + ;; + install | i) + shift + install "$@" + break + ;; + update | u) + shift + update "$@" + break + ;; + -?*) + printf 'Unknown option: %s\n' "$1" >&2 + usage + ;; + *) # Default case: No more options, so break out of the loop. + break ;; + esac + shift + done +} + +parse_args "$@" diff --git a/CentOS/Nginx/Install-SSL.bash b/CentOS/Nginx/Install-SSL.bash new file mode 100755 index 0000000..376eae7 --- /dev/null +++ b/CentOS/Nginx/Install-SSL.bash @@ -0,0 +1,112 @@ +#!/bin/bash + +set -e + +echo_rgb() { + # Echo a colored string to the terminal based on rgb values + # + # Positional Arguments: + # + # message + # - The message to be printed to stdout + # red + # - The red value from 0 to 255 + # green + # - The green value from 0 to 255 + # blue + # - The blue value from 0 to 255 + # + # Usage: + # echo_rgb "Yep" 10 8 30 + # + # POSIX Compliant: + # N/A + # + + local red + local green + local blue + local input + + input="${1}" + red="${2}" + green="${3}" + blue="${4}" + + printf "\e[0;38;2;%s;%s;%sm%s\e[m\n" "${red}" "${green}" "${blue}" "${input}" +} + +log() { + # Print a message and send it to stdout or stderr depending upon log level, also configurable with debug etc. + # + # Arguments: + # level + # - The log level, defined within a case check in this function + # message + # - The info message + # line_number + # - The line number of the calling function (${LINNO}) + # + # Usage: + # log "info" "Could not find that directory" + # + # POSIX Compliant: + # Yes + # + + # Set debug status depending if a global debug variable has been set to either 1 or 0 + local debug + if [ ${DEBUG} ]; then + debug=${DEBUG} + else + debug=0 + fi + + local FORMAT + FORMAT="[$(echo_rgb "$(date +%Y-%m-%dT%H:%M:%S)" 180 140 255)]" + + # Convert the level to uppercase + local level + level=$(echo "${1}" | tr '[:lower:]' '[:upper:]') + + local message + message="${2}" + + case "${level}" in + INFO) + # Output all info log levels to stdout + printf "${FORMAT}[$(echo_rgb "INFO" 0 140 255)] %s\n" "${message}" >&1 + return 0 + ;; + WARN | WARNING) + # Output all info log levels to stdout + printf "${FORMAT}[$(echo_rgb "WARNING" 255 255 0)] %s\n" "${message}" >&1 + return 0 + ;; + DEBUG) + [[ ${debug} == 0 ]] && return + printf "${FORMAT}[$(echo_rgb "DEBUG" 0 160 110)] %s\n" "${message}" >&1 + return 0 + ;; + ERROR) + # Output all error log levels to stderr + printf "${FORMAT}[$(echo_rgb "ERROR" 255 0 0)] %s\n" "${message}" >&2 + return 0 + ;; + # Further log levels can be added by extending this switch statement with more comparisons + + *) # Default case, no matches + # Returns non-zero code as an improper log option was passed, this helps with using `set -e` + printf "${FORMAT}[ERROR] %s\n" "Invalid log level passed, received level \"${level}\" with message \"${message}\"" >&2 + return 1 + ;; + esac +} + +[[ "$(id -u)" -ne 0 ]] && log "error" "$(basename "${0}") must be ran as root, exiting..." && exit 1 + +dnf install epel-release -y +dnf install certbot python3-certbot-nginx -y + +log "info" "Installed required packages, to now install SSL for a domain type +\"certbot --nginx -d your_domain -d www.your_domain\"" \ No newline at end of file diff --git a/CentOS/Nginx/Install-Wordpress.bash b/CentOS/Nginx/Install-Wordpress.bash index 0b13805..6ff969f 100644 --- a/CentOS/Nginx/Install-Wordpress.bash +++ b/CentOS/Nginx/Install-Wordpress.bash @@ -161,6 +161,7 @@ cat << __EOF__ > "${nginx_server_config}" server { listen 80; server_name ${full_server_name}; + server_name ${server_name}; root /var/www/${server_name}; index index.php; @@ -222,10 +223,6 @@ systemctl restart nginx \ && systemctl restart php-fpm \ && log "info" "Successfully restarted nginx & php-fpm" -### SSL CONF SHOULD GO HERE - -### END SSL CONF - root_password="" echo "Enter root's password (necessary for mysql commands):" read_sensitive root_password