diff --git a/1-setup.sh b/1-setup.sh index 3b06e30..f5e519e 100644 --- a/1-setup.sh +++ b/1-setup.sh @@ -11,7 +11,7 @@ # If something isn't working? # tail -f /var/log/syslog /var/log/tomcat*/*.out /var/log/mysql/*.log -# This whole install routine could be collated into one huge script, but it is far easer to manage and maintan by +# This whole install routine could be collated into one huge script, but it is far easer to manage and maintan by # breaking up the different stages of the install into at least 4 separate scripts as follows... # 1-setup.sh is a central script that manages all inputs, options and sequences other included 'install' scripts. # 2-install-guacamole is the main guts of the whole build. This script downloads and builds Guacamole from source. @@ -19,11 +19,6 @@ # 4a-install-self-signed-nginx.sh sets up the new Nginx/Guacamole front end with self signed SSL certificates. # 4b-install-ssl-letsencrypt-nginx.sh sets up Nginx with public SSL certificates from LetsEncrypt. - -####################################################################################################################### -# Initial enviromment setup ########################################################################################### -####################################################################################################################### - clear # Prepare text output colours @@ -44,37 +39,34 @@ MAGENTA='\033[0;35m' LMAGENTA='\033[0;95m' NC='\033[0m' #No Colour +# Check to see if previous build/install files exist, stop and check to be safe. +if [ "$( find . -maxdepth 1 \( -name 'guacamole-*' -o -name 'mysql-connector-java-*' \) )" != "" ]; then +# Script branding header +echo + echo -e "${GREYB}Itiligent Jump Server Appliance Setup." + echo -e " ${LGREEN}Powered by Guacamole" + echo + echo + echo -e "${RED}Possible previous temp files detected in current build path. Please review and remove old 'guacamole-*' & 'mysql-connector-java-*' files before proceeding.${GREY}" 1>&2 + echo +exit 1 +fi + +####################################################################################################################### +# Core setup ########################################################################################################## +####################################################################################################################### + #Setup download and temp directory paths USER_HOME_DIR=$(eval echo ~${SUDO_USER}) DOWNLOAD_DIR=$USER_HOME_DIR/guac-setup DB_BACKUP_DIR=$USER_HOME_DIR/mysqlbackups/ TMP_DIR=$DOWNLOAD_DIR/tmp -source /etc/os-release -OS_FLAVOUR=$ID -OS_VERSION=$VERSION -JPEGTURBO="" -LIBPNG="" - -# Announce the script we're running -echo -echo -e "${GREYB}Itiligent Jump Server Appliance Setup." -echo -e " ${LGREEN}Powered by Guacamole" -echo - -# Setup directory locations -mkdir -p $DOWNLOAD_DIR -mkdir -p $DB_BACKUP_DIR -mkdir -p $TMP_DIR - -# Now prompt for sudo and set dir permissions so both sudo and non sudo functions can access tmp setup files -sudo chmod -R 770 $TMP_DIR -sudo chown -R $SUDO_USER:root $TMP_DIR # Github download branch GITHUB="https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/" #Version of Guacamole to install -GUAC_VERSION="1.5.0" +GUAC_VERSION="1.5.1" # Set preferred Apache CDN download link GUAC_SOURCE_LINK="http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/${GUAC_VERSION}" @@ -91,49 +83,63 @@ LOG_LOCATION="${DOWNLOAD_DIR}/guacamole_${GUAC_VERSION}_setup.log" # Guacamole default install URL GUAC_URL=http://localhost:8080/guacamole/ -# Non interactive silent setup options - add true/false or specific values -SERVER_NAME="" # Preferred server hostname -INSTALL_MYSQL="" # Install locally true/false -SECURE_MYSQL="" # Apply mysql secure configurarion tool -MYSQL_HOST="" # leave blank for localhost default, only specify for remote servers -MYSQL_PORT="" # If blank default is 3306 -GUAC_DB="" # If blank default is guacamole_db -GUAC_USER="" # if blank default is guacamole_user -GUAC_PWD="" # Should not be blank as this may break some aspects of install -MYSQL_ROOT_PWD="" # Should not be blank as this may break some aspects of install -INSTALL_TOTP="" # TOTP MFA extension -INSTALL_DUO="" # DUO MFA extension (cant be installed simultaneously with TOTP) -INSTALL_LDAP="" # Active Directory extension -INSTALL_NGINX="" # Install and configure Guacamole behind Nginx reverse proxy (http port 80 only) -PROXY_SITE="" # Local DNS name for reverse proxy and self signed ssl certificates -SELF_SIGNED="" # Add self signed SSL support to Nginx (Let's Encrypt not available) -INSTALL_LETS_ENCRYPT="" # Add Lets Encrypt public SSL support for Nginx (self signed SSL certs not available) -LE_DNS_NAME="" # Public DNS name to bind with Lets Encrypt certificates -LE_EMAIL="webmaster@itiligent.com" # Webmaster/admin email for Lets Encrypt -EMAIL_DOMAIN="itiligent.com" # Email relay domain for backup notifications -ALERT_EMAIL="alerts@itiligent.com" # Email address for backup notifications -BACKUP_RETAIN_DAYS="30" # How long to keep backups for -CERT_COUNTRY="AU" # 2 coutry charater code only, must not be blank -CERT_STATE="Victoria" # Optional to change, must not be blank -CERT_LOCATION="Melbourne" # Optional to change, must not be blank -CERT_ORG="Itiligent" # Optional to change, must not be blank -CERT_OU="I.T." # Optional to change, must not be blank -CERT_DAYS="3650" # Number of days until self signed certificate expiry +# Depending on the Linux distro, required libraries have varied names. Standardising with names makes adapting +# to other distros easier. +source /etc/os-release +OS_FLAVOUR=$ID +OS_VERSION=$VERSION +JPEGTURBO="" +LIBPNG="" -# We need to try and grab a default value for the local FQDN. Domain search suffix is used in this case becausue +# We need to try and grab a default value for the local FQDN. Domain search suffix is used in this case because # this is the simplest common default resolv.conf value available between recent Debian and Ubuntu flavours. YMMV. DOMAIN_SEARCH_SUFFIX=$(grep search /etc/resolv.conf | grep -v "#" | sed 's/'search[[:space:]]'//') DEFAULT_FQDN=$HOSTNAME.$DOMAIN_SEARCH_SUFFIX -# Finally we check to prevent reinstalling over the current from possibly older/previous versions of build files. -if [ "$( find . -maxdepth 2 \( -name 'guacamole-*' -o -name 'mysql-connector-java-*' \) )" != "" ]; then - echo -e "${RED}Possible previous temp files detected in current build path. Please review and remove old 'guacamole-*' & 'mysql-connector-java-*' files before proceeding.${GREY}" 1>&2 -exit 1 -fi +####################################################################################################################### +# Silent setup options - adding true/false or specific values below prevents prompt at install ######################## +####################################################################################################################### +SERVER_NAME="" # Preferred server hostname +INSTALL_MYSQL="" # Install locally true/false +SECURE_MYSQL="" # Apply mysql secure configurarion tool +MYSQL_HOST="" # leave blank for localhost default, only specify for remote servers +MYSQL_PORT="" # If blank default is 3306 +GUAC_DB="" # If blank default is guacamole_db +GUAC_USER="" # if blank default is guacamole_user +GUAC_PWD="" # Should not be blank as this may break some aspects of install +MYSQL_ROOT_PWD="" # Should not be blank as this may break some aspects of install +INSTALL_TOTP="" # TOTP MFA extension +INSTALL_DUO="" # DUO MFA extension (cant be installed simultaneously with TOTP) +INSTALL_LDAP="" # Active Directory extension +INSTALL_NGINX="" # Install and configure Guacamole behind Nginx reverse proxy (http port 80 only) +PROXY_SITE="" # Local DNS name for reverse proxy and self signed ssl certificates +SELF_SIGN="" # Add self signed SSL support to Nginx (Let's Encrypt not available) +CERT_COUNTRY="AU" # 2 coutry charater code only, must not be blank +CERT_STATE="Victoria" # Optional to change, must not be blank +CERT_LOCATION="Melbourne" # Optional to change, must not be blank +CERT_ORG="Itiligent" # Optional to change, must not be blank +CERT_OU="I.T." # Optional to change, must not be blank +CERT_DAYS="3650" # Number of days until self signed certificate expiry +LETS_ENCRYPT="" # Add Lets Encrypt public SSL support for Nginx (self signed SSL certs not available) +LE_DNS_NAME="public.yourdomain.com" # Public DNS name to bind with Lets Encrypt certificates +LE_EMAIL="webmaster@yourdomain.com" # Webmaster/admin email for Lets Encrypt +EMAIL_DOMAIN="yourdomain.com" # Email relay domain for backup notifications +ALERT_EMAIL="alerts@domain.com" # Email address for backup notifications +BACKUP_RETENTION="30" # How many days to keep backups for +# Script branding header +echo +echo -e "${GREYB}Itiligent Jump Server Appliance Setup." +echo -e " ${LGREEN}Powered by Guacamole" +echo + +# Setup directory locations +mkdir -p $DOWNLOAD_DIR +mkdir -p $DB_BACKUP_DIR +mkdir -p $TMP_DIR ####################################################################################################################### -# Download github setup scripts ####################################################################################### +# Download github setup scripts. To prevent overwrite, comment out lines of any scripts you have edited. ############## ####################################################################################################################### # Download config scripts and setup items from github @@ -159,6 +165,55 @@ wget -q --show-progress ${GITHUB}add-fail2ban.sh -O add-fail2ban.sh # Grab a (customisable) branding extension wget -q --show-progress ${GITHUB}branding.jar -O branding.jar chmod +x *.sh +sleep 2 +clear + +# Script branding header +echo +echo -e "${GREYB}Itiligent Jump Server Appliance Setup." +echo -e " ${LGREEN}Powered by Guacamole" +echo +echo + +# For convenience & sanity check, diplay status of preset script options at start of install +echo -e "${GREY}Enabled non-interactive presets are listed below, blank entries will prompt." +echo -e "${DGREY}Server host name\t= ${GREY}${SERVER_NAME}" +echo -e "${DGREY}Install MYSQL locally\t= ${GREY}${INSTALL_MYSQL}" +echo -e "${DGREY}MySQL secure install\t= ${GREY}${SECURE_MYSQL}" +echo -e "${DGREY}MySQL remote IP\t\t= ${GREY}${MYSQL_HOST}" +echo -e "${DGREY}MySQL port\t\t= ${GREY}${MYSQL_PORT}" +echo -e "${DGREY}Guacamole db name\t= ${GREY}${GUAC_DB}" +echo -e "${DGREY}Guacamole db user name\t= ${GREY}${GUAC_USER}" +echo -e "${DGREY}Guacamole user pwd\t= ${GREY}${GUAC_PWD}" +echo -e "${DGREY}MySQL root pwd\t\t= ${GREY}${MYSQL_ROOT_PWD}" +echo -e "${DGREY}Add TOTP\t\t= ${GREY}${INSTALL_TOTP}" +echo -e "${DGREY}Add DUO\t\t\t= ${GREY}${INSTALL_DUO}" +echo -e "${DGREY}Add LDAP\t\t= ${GREY}${INSTALL_LDAP}${GREY}" +echo -e "${DGREY}Install Nginx rev proxy\t= ${GREY}${INSTALL_NGINX}${GREY}" +echo -e "${DGREY}Proxy local DNS name\t= ${GREY}${PROXY_SITE}" +echo -e "${DGREY}Add self signed SSL\t= ${GREY}${SELF_SIGN}${GREY}" +echo -e "${DGREY}Self sign cert days\t= ${GREY}${CERT_DAYS}${GREY}" +echo -e "${DGREY}Self sign country\t= ${GREY}${CERT_COUNTRY}${GREY}" +echo -e "${DGREY}Self sign state\t\t= ${GREY}${CERT_STATE}${GREY}" +echo -e "${DGREY}Self sign location\t= ${GREY}${CERT_LOCATION}${GREY}" +echo -e "${DGREY}Self sign ORG\t\t= ${GREY}${CERT_ORG}${GREY}" +echo -e "${DGREY}Self sign OU\t\t= ${GREY}${CERT_OU}${GREY}" +echo -e "${DGREY}Add Let's Encrypt SSL\t= ${GREY}${LETS_ENCRYPT}${GREY}" +echo -e "${DGREY}Let's Encrypt FQDN\t= ${GREY}${LE_DNS_NAME}${GREY}" +echo -e "${DGREY}Let's Encrypt email\t= ${GREY}${LE_EMAIL}${GREY}" +echo -e "${DGREY}SMTP relay domain\t= ${GREY}${EMAIL_DOMAIN}${GREY}" +echo -e "${DGREY}Alerts email address\t= ${GREY}${ALERT_EMAIL}${GREY}" +echo -e "${DGREY}Days to keep backups\t= ${GREY}${BACKUP_RETENTION}${GREY}" + +# Pause to optionally customise downloaded scripts before any install actions +echo +echo -e "${LYELLOW}Ctrl+Z now to exit if you wish to set any above options for an unattended install." +echo -e "${LYELLOW}After editing the setup script, you must always run it locally (not as sudo) i.e ./1-setup.sh (not from the web link)." + +# Now prompt for sudo to get ready for a hostname change or so both sudo and non sudo functions can access tmp setup files +echo -e "${LGREEN}" +sudo chmod -R 770 $TMP_DIR +sudo chown -R $SUDO_USER:root $TMP_DIR ####################################################################################################################### @@ -166,10 +221,9 @@ chmod +x *.sh ####################################################################################################################### # We need a default hostname avaiable to apply even if we do not want to change the hostname. This approach allows the -# user to simply hit enter at the prompt without this creating a blank entry into the /etc/hosts file. +# user to simply hit enter at the prompt without this creating a blank entry into the /etc/hosts file. # Hostnames and matching DNS entries are essential for implementing SSL succesfully. echo -echo if [[ -z ${SERVER_NAME} ]]; then echo -e "${LYELLOW}Update Linux system HOSTNAME [Enter to keep: ${HOSTNAME}]${LGREEN}" read -p " Enter new HOSTNAME : " SERVER_NAME @@ -190,41 +244,16 @@ if [[ -z ${SERVER_NAME} ]]; then fi clear -echo -# For convenience & sanity check, diplay status of preset script options at start of install -echo -e "${GREY}Enabled non-interactive presets are listed below, blank entries will prompt." -echo -e "(Ctrl+C to exit & edit 1-setup.sh before continuning.)" -echo -e "${DGREY}Server host name\t= ${GREY}${SERVER_NAME}" -echo -e "${DGREY}Install MYSQL locally\t= ${GREY}${INSTALL_MYSQL}" -echo -e "${DGREY}MySQL secure install\t= ${GREY}${SECURE_MYSQL}" -echo -e "${DGREY}MySQL hostname/IP\t= ${GREY}${MYSQL_HOST}" -echo -e "${DGREY}MySQL port\t\t= ${GREY}${MYSQL_PORT}" -echo -e "${DGREY}Guacamole db name\t= ${GREY}${GUAC_DB}" -echo -e "${DGREY}Guacamole db user name\t= ${GREY}${GUAC_USER}" -echo -e "${DGREY}Guacamole user pwd\t= ${GREY}${GUAC_PWD}" -echo -e "${DGREY}MySQL root pwd\t\t= ${GREY}${MYSQL_ROOT_PWD}" -echo -e "${DGREY}Install TOTP\t\t= ${GREY}${INSTALL_TOTP}" -echo -e "${DGREY}Install DUO\t\t= ${GREY}${INSTALL_DUO}" -echo -e "${DGREY}Install LDAP\t\t= ${GREY}${INSTALL_LDAP}${GREY}" -echo -e "${DGREY}Install Nginx rev proxy\t= ${GREY}${INSTALL_NGINX}${GREY}" -echo -e "${DGREY}Proxy local DNS name\t= ${GREY}${PROXY_SITE}" -echo -e "${DGREY}Add self signed SSL\t= ${GREY}${SELF_SIGNED}${GREY}" -echo -e "${DGREY}Add Let's Encrypt SSL\t= ${GREY}${INSTALL_LETS_ENCRYPT}${GREY}" -echo -e "${DGREY}Let's Encrypt pub FQDN\t= ${GREY}${LE_DNS_NAME}${GREY}" -echo -e "${DGREY}Let's Encrypt email\t= ${GREY}${LE_EMAIL}${GREY}" -echo -e "${DGREY}SMTP relay domain\t= ${GREY}${EMAIL_DOMAIN}${GREY}" -echo -e "${DGREY}Alerts email address\t= ${GREY}${ALERT_EMAIL}${GREY}" -echo -e "${DGREY}Days to keep backups\t= ${GREY}${BACKUP_RETAIN_DAYS}${GREY}" -echo -e "${DGREY}Self signed cert days\t= ${DGREY}${CERT_DAYS}${GREY}" -echo -e "${DGREY}Self signed country\t= ${DGREY}${CERT_COUNTRY}${GREY}" -echo -e "${DGREY}Self signed state\t= ${DGREY}${CERT_STATE}${GREY}" -echo -e "${DGREY}Self signed location\t= ${DGREY}${CERT_LOCATION}${GREY}" -echo -e "${DGREY}Self signed ORG\t\t= ${DGREY}${CERT_ORG}${GREY}" -echo -e "${DGREY}Self signed OU\t\t= ${DGREY}${CERT_OU}${GREY}" -# Prompt the user to see if they would like to install MySQL, default of yes +# Script branding header +echo +echo -e "${GREYB}Itiligent Jump Server Appliance Setup." +echo -e " ${LGREEN}Powered by Guacamole" +echo +echo + +# Prompt the user to install MySQL, default of yes if [[ -z ${INSTALL_MYSQL} ]]; then - echo echo -e -n "${LGREEN}SQL: Install MySQL? (for a remote MySQL Server select 'n') (y/n) [default y]: ${GREY}" read PROMPT if [[ ${PROMPT} =~ ^[Nn]$ ]]; then @@ -234,7 +263,7 @@ if [[ -z ${INSTALL_MYSQL} ]]; then fi fi -# Prompt the user to see if they would like to apply the Mysql secure installation +# Prompt the user to apply the Mysql secure installation locally if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = true ]; then echo -e -n "${GREY}SQL: Apply MySQL secure installation settings to LOCAL db? (y/n) [default y]: ${GREY}" read PROMPT @@ -245,7 +274,7 @@ if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = true ]; then fi fi -# Prompt the user to see if they would like to apply the Mysql secure installation +# Prompt the user to apply the Mysql secure installation to remote db if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = false ]; then echo -e -n "${GREY}SQL: Apply MySQL secure installation settings to REMOTE db? (y/n) [default n]: ${GREY}" read PROMPT @@ -256,8 +285,8 @@ if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = false ]; then fi fi +# We need to get some additional MYSQL values if [ "${INSTALL_MYSQL}" = false ]; then - # We need to get some additional MYSQL values [ -z "${MYSQL_HOST}" ] \ && read -p "SQL: Enter MySQL server hostname or IP: " MYSQL_HOST [ -z "${MYSQL_PORT}" ] \ @@ -288,18 +317,6 @@ if [ -z "${GUAC_USER}" ]; then GUAC_USER="guacamole_user" fi -# Get MySQL root password, confirm correct password entry and prevent blank passwords -if [ -z "${MYSQL_ROOT_PWD}" ]; then - while true; do - read -s -p "SQL: Enter ${MYSQL_HOST}'s MySQL root password: " MYSQL_ROOT_PWD - echo - read -s -p "SQL: Confirm ${MYSQL_HOST}'s MySQL root password: " PROMPT2 - echo - [ "${MYSQL_ROOT_PWD}" = "${PROMPT2}" ] && [ "${MYSQL_ROOT_PWD}" != "" ] && [ "${PROMPT2}" != "" ] && break - echo -e "${RED}Passwords don't match or can't be null. Please try again.${GREY}" 1>&2 - done -fi - # Get Guacamole User password, confirm correct password entry and prevent blank passwords if [ -z "${GUAC_PWD}" ]; then while true; do @@ -312,6 +329,18 @@ if [ -z "${GUAC_PWD}" ]; then done fi +# Get MySQL root password, confirm correct password entry and prevent blank passwords +if [ -z "${MYSQL_ROOT_PWD}" ]; then + while true; do + read -s -p "SQL: Enter ${MYSQL_HOST}'s MySQL root password: " MYSQL_ROOT_PWD + echo + read -s -p "SQL: Confirm ${MYSQL_HOST}'s MySQL root password: " PROMPT2 + echo + [ "${MYSQL_ROOT_PWD}" = "${PROMPT2}" ] && [ "${MYSQL_ROOT_PWD}" != "" ] && [ "${PROMPT2}" != "" ] && break + echo -e "${RED}Passwords don't match or can't be null. Please try again.${GREY}" 1>&2 + done +fi + # Prompt the user if they would like to install TOTP MFA, default of no if [[ -z "${INSTALL_TOTP}" ]] && [[ "${INSTALL_DUO}" != true ]]; then echo -e -n "${GREY}GUAC MFA: Install TOTP? (choose 'n' if you want Duo) (y/n)? [default n]: " @@ -336,7 +365,7 @@ if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then fi fi -# We can't install TOTP and Duo at the same time, option not supported by Guacamole... +# We can't install TOTP and Duo at the same time (option not supported by Guacamole) if [[ "${INSTALL_TOTP}" = true ]] && [[ "${INSTALL_DUO}" = true ]]; then echo -e "${RED}GUAC MFA: TOTP and Duo cannot be installed at the same time.${GREY}" 1>&2 exit 1 @@ -381,19 +410,19 @@ PROXY_SITE="${DEFAULT_FQDN}" fi # Prompt for self signed SSL reverse proxy option -if [[ -z ${SELF_SIGNED} ]] && [[ "${INSTALL_NGINX}" = true ]]; then +if [[ -z ${SELF_SIGN} ]] && [[ "${INSTALL_NGINX}" = true ]]; then # Prompt the user to see if they would like to install self signed SSL support for Nginx, default of no echo -e -n "${GREY}PROXY SSL?: Add self signed SSL support to Nginx? (y/n)? (choose 'n' for Let's Encrypt)[default n]: " read PROMPT if [[ ${PROMPT} =~ ^[Yy]$ ]]; then - SELF_SIGNED=true + SELF_SIGN=true else - SELF_SIGNED=false + SELF_SIGN=false fi fi -# Prompt to assign the self sign SSL certficate a custom expiry date, uncomment to force a manual entry -#if [ "${SELF_SIGNED}" = true ]; then +# Optional prompt to assign the self sign SSL certficate a custom expiry date, uncomment to force a manual entry +#if [ "${SELF_SIGN}" = true ]; then # read - p "PROXY: Enter number of days till SSL certificate expires [default 3650]: " CERT_DAYS #fi @@ -403,18 +432,18 @@ if [ -z "${CERT_DAYS}" ]; then fi # Prompt for Let's Encrypt SSL reverse proxy configuration option -if [[ -z ${INSTALL_LETS_ENCRYPT} ]] && [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGNED}" = "false" ]]; then +if [[ -z ${LETS_ENCRYPT} ]] && [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGN}" = "false" ]]; then echo -e -n "${GREY}SSL PROXY: Add Let's Encrypt SSL support to Nginx reverse proxy (y/n) [default n]: ${GREY}" read PROMPT if [[ ${PROMPT} =~ ^[Yy]$ ]]; then - INSTALL_LETS_ENCRYPT=true + LETS_ENCRYPT=true else - INSTALL_LETS_ENCRYPT=false + LETS_ENCRYPT=false fi fi # Prompt for Let's Encrypt public dns name -if [[ -z ${LE_DNS_NAME} ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then +if [[ -z ${LE_DNS_NAME} ]] && [[ "${LETS_ENCRYPT}" = true ]]; then while true; do read -p "Enter the FQDN for your public proxy site : " LE_DNS_NAME [ "${LE_DNS_NAME}" != "" ] && break @@ -423,7 +452,7 @@ if [[ -z ${LE_DNS_NAME} ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then fi # Prompt for Let's Encrypt admin email -if [[ -z ${LE_EMAIL} ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then +if [[ -z ${LE_EMAIL} ]] && [[ "${LETS_ENCRYPT}" = true ]]; then while true; do read -p "Enter the email address for Let's Encrypt notifications : " LE_EMAIL [ "${LE_EMAIL}" != "" ] && break @@ -437,6 +466,8 @@ fi ####################################################################################################################### # Ubuntu and Debian each require different dependency packages. Below works ok from Ubuntu 18.04 / Debian 10 and above. +# To adapt this script to other distros, research the correct library package names and reference these with the varible +# names assigned here. See https://guacamole.apache.org/doc/gug/installing-guacamole.html for dependecy info. echo -e "${GREY}Checking linux distro specific dependencies..." if [[ $OS_FLAVOUR == "ubuntu" ]] || [[ $OS_FLAVOUR == "ubuntu"* ]]; then # potentially expand out distro choices here JPEGTURBO="libjpeg-turbo8-dev" @@ -454,7 +485,8 @@ else fi # Because the below scripts may be run manually after install, we need to sync them -# with global variables or setup prompt options. +# with our global variables or any setup prompt choices we make. This way we can run them +# later and they will all work as a set without any manual changes. sed -i "s|MYSQL_HOST=|MYSQL_HOST='${MYSQL_HOST}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|MYSQL_PORT=|MYSQL_PORT='${MYSQL_PORT}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|GUAC_USER=|GUAC_USER='${GUAC_USER}'|g" $DOWNLOAD_DIR/backup-guac.sh @@ -462,7 +494,7 @@ sed -i "s|GUAC_PWD=|GUAC_PWD='${GUAC_PWD}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|GUAC_DB=|GUAC_DB='${GUAC_DB}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|DB_BACKUP_DIR=|DB_BACKUP_DIR='${DB_BACKUP_DIR}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|ALERT_EMAIL=|ALERT_EMAIL='${ALERT_EMAIL}'|g" $DOWNLOAD_DIR/backup-guac.sh -sed -i "s|BACKUP_RETAIN_DAYS=|BACKUP_RETAIN_DAYS='${BACKUP_RETAIN_DAYS}'|g" $DOWNLOAD_DIR/backup-guac.sh +sed -i "s|BACKUP_RETENTION=|BACKUP_RETENTION='${BACKUP_RETENTION}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-duo.sh sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-totp.sh @@ -470,7 +502,12 @@ sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/ad sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-auth-totp.sh sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-fail2ban.sh -# As web links may contain "&" characters, GUAC_SOURCE_LINK is fixed to parse "&" with sed correctly +sed -i "s|CERT_COUNTRY=|CERT_COUNTRY='${CERT_COUNTRY}'|g" $DOWNLOAD_DIR/add-ssl-guac-gaucd.sh +sed -i "s|CERT_STATE=|CERT_STATE='${CERT_STATE}'|g" $DOWNLOAD_DIR/add-ssl-guac-gaucd.sh +sed -i "s|CERT_LOCATION=|CERT_LOCATION='${CERT_LOCATION=}'|g" $DOWNLOAD_DIR/add-ssl-guac-gaucd.sh +sed -i "s|CERT_ORG=|CERT_ORG='${CERT_ORG}'|g" $DOWNLOAD_DIR/add-ssl-guac-gaucd.sh +sed -i "s|CERT_OU=|CERT_OU='${CERT_OU}'|g" $DOWNLOAD_DIR/add-ssl-guac-gaucd.sh +# As dynamic web links may contain "&" characters, GUAC_SOURCE_LINK is fixed to parse "&" with sed correctly FIXED_LINK=$(sed 's/\&/\\&/g' <<< $GUAC_SOURCE_LINK) sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-duo.sh sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh @@ -493,7 +530,7 @@ if [ $? -ne 0 ]; then echo -e "${LGREEN}Guacamole installation complete\n- Visit: http://${PROXY_SITE}:8080/guacamole\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}" fi -# Duo Settings reminder that if due is slected you cant login to Guacamole at all until this extension is fully configured +# Duo Settings reminder - If Duo is selected you can't login to Guacamole at all until this extension is fully configured if [ $INSTALL_DUO == "true" ]; then echo -e "${YELLOW}Reminder: Duo requires extra account specific config before you can log in to Guacamole." echo -e "See https://guacamole.apache.org/doc/${GUAC_VERSION}/gug/duo-auth.html" @@ -516,30 +553,31 @@ rm cron_1 ### Install Nginx reverse proxy front end to Guacamole if option is selected if [ "${INSTALL_NGINX}" = true ]; then - sudo $NGINX_VAR $COLOUR_VAR ./3-install-nginx.sh | tee -a ${LOG_LOCATION} + sudo $NGINX_VAR $COLOUR_VAR ./3-install-nginx.sh echo -e "${LGREEN}Nginx installation complete\n- Site changed to : http://${PROXY_SITE}\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}" fi ### Apply self signed SSL certificates to Nginx reverse proxy if option is selected -if [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGNED}" = true ]]; then - sudo -E $SELF_SIGN_VAR $COLOUR_VAR ./4a-install-ssl-self-signed-nginx.sh ${PROXY_SITE} ${CERT_DAYS} | tee -a ${LOG_LOCATION} +if [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGN}" = true ]]; then + sudo -E $SELF_SIGN_VAR $COLOUR_VAR ./4a-install-ssl-self-signed-nginx.sh ${PROXY_SITE} ${CERT_DAYS} echo -e "${LGREEN}Self signed certificates successfully created and configured for Nginx \n- Site changed to : ${LYELLOW}https:${LGREEN}//${PROXY_SITE}\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}" fi ### Apply Let's Encrypt SSL certificates to Nginx reverse proxy if option is selected -if [[ "${INSTALL_NGINX}" = true ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then - sudo -E $LE_VAR $COLOUR_VAR ./4b-install-ssl-letsencrypt-nginx.sh | tee -a ${LOG_LOCATION} +if [[ "${INSTALL_NGINX}" = true ]] && [[ "${LETS_ENCRYPT}" = true ]]; then + sudo -E $LE_VAR $COLOUR_VAR ./4b-install-ssl-letsencrypt-nginx.sh echo -e "${LGREEN}Let's Encrypt SSL successfully configured for Nginx \n- Site changed to : ${LYELLOW}https:${LGREEN}//${LE_DNS_NAME}\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}" fi # Final tidy up +echo +echo -e "${LGREEN}1-setup.sh was moved to ${USER_HOME_DIR}/guac-setup." mv $USER_HOME_DIR/1-setup.sh $DOWNLOAD_DIR sudo rm -R $TMP_DIR - # Done echo printf "${LGREEN}Guacamole ${GUAC_VERSION} install complete! \n${NC}" diff --git a/2-install-guacamole.sh b/2-install-guacamole.sh index 8cca399..7cc5685 100644 --- a/2-install-guacamole.sh +++ b/2-install-guacamole.sh @@ -8,8 +8,36 @@ # pls see https://github.com/MysticRyuujin/guac-install for more ####################################################################################################################### +# Prepare text output colours +GREY='\033[0;37m' +DGREY='\033[0;90m' +GREYB='\033[1;37m' +RED='\033[0;31m' +LRED='\033[0;91m' +GREEN='\033[0;32m' +LGREEN='\033[0;92m' +YELLOW='\033[0;33m' +LYELLOW='\033[0;93m' +BLUE='\033[0;34m' +LBLUE='\033[0;94m' +CYAN='\033[0;36m' +LCYAN='\033[0;96m' +MAGENTA='\033[0;35m' +LMAGENTA='\033[0;95m' +NC='\033[0m' #No Colour + clear +#Script branding header +echo +echo -e "${GREYB}Itiligent Jump Server Appliance Setup." +echo -e " ${LGREEN}Powered by Guacamole" + +echo +echo +echo -e "Beginning Guacamole setup...${GREY}" +echo + # Pre-seed MySQL install values if [ "${INSTALL_MYSQL}" = true ]; then debconf-set-selections <<< "mysql-server mysql-server/root_password password ${MYSQL_ROOT_PWD}" @@ -26,11 +54,10 @@ if [ "${INSTALL_MYSQL}" = true ]; then fi # Don't do annoying prompts during apt installs -echo echo -e "${GREY}Updating base Linux OS..." -export DEBIAN_FRONTEND=noninteractive &>> ${LOG_LOCATION} -sudo apt-get update &>> ${LOG_LOCATION} -sudo apt-get upgrade -y &>> ${LOG_LOCATION} +export DEBIAN_FRONTEND=noninteractive +sudo apt-get update -qq &>> ${LOG_LOCATION} +sudo apt-get upgrade -qq -y &>> ${LOG_LOCATION} if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 @@ -41,10 +68,9 @@ fi # Install Guacamole build dependencies. echo echo -e "${GREY}Installing dependencies required for building Guacamole, this might take a few minutes..." -apt-get -y install ${JPEGTURBO} ${LIBPNG} ufw htop pwgen wget crudini build-essential libcairo2-dev libtool-bin uuid-dev libavcodec-dev libavformat-dev libavutil-dev \ +apt-get -qq -y install ${JPEGTURBO} ${LIBPNG} ufw htop pwgen wget crudini build-essential libcairo2-dev libtool-bin uuid-dev libavcodec-dev libavformat-dev libavutil-dev \ libswscale-dev freerdp2-dev libpango1.0-dev libssh2-1-dev libtelnet-dev libvncserver-dev libwebsockets-dev libpulse-dev libssl-dev \ -libvorbis-dev libwebp-dev ghostscript \ -${MYSQL} ${TOMCAT_VERSION} &>> ${LOG_LOCATION} +libvorbis-dev libwebp-dev ghostscript ${MYSQL} ${TOMCAT_VERSION} &>> ${LOG_LOCATION} if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 @@ -56,10 +82,10 @@ fi echo echo -e "${GREY}Setting up SMTP for backup alerts (requires SMTP relay be permitted from this server's IP address)..." echo "postfix postfix/mailname string ${EMAIL_DOMAIN} | debconf-set-selections" &>> ${LOG_LOCATION} -DEBIAN_FRONTEND="noninteractive" apt-get install postfix -y &>> ${LOG_LOCATION} -apt-get install mailutils -y &>> ${LOG_LOCATION} -sed -i 's/inet_interfaces = all/inet_interfaces = loopback-only/g' /etc/postfix/main.cf &>> ${LOG_LOCATION} -service postfix restart &>> ${LOG_LOCATION} +DEBIAN_FRONTEND="noninteractive" apt-get install postfix -qq -y &>> ${LOG_LOCATION} +apt-get install mailutils -qq -y &>> ${LOG_LOCATION} +sed -i 's/inet_interfaces = all/inet_interfaces = loopback-only/g' /etc/postfix/main.cf +service postfix restart if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 @@ -150,7 +176,6 @@ if [ $? -ne 0 ]; then fi echo -e "${LGREEN}Downloaded mysql-connector-java-${MYSQLJCON}.tar.gz${GREY}" -echo echo -e "${LGREEN}Source download complete.${GREY}" # Option to pause script here as we might want to make final tweaks to source code just before compiling @@ -181,7 +206,7 @@ echo -e "${GREY}Compiling Guacamole-Server from source with with GCC $( gcc --ve export CFLAGS="-Wno-error" # Configure Guacamole Server source -./configure --with-systemd-dir=/etc/systemd/system &>> ${LOG_LOCATION} +./configure --with-systemd-dir=/etc/systemd/system &>> ${LOG_LOCATION} if [ $? -ne 0 ]; then echo "Failed to configure guacamole-server" echo "Trying again with --enable-allow-freerdp-snapshots" @@ -227,7 +252,13 @@ ln -sf /etc/guacamole/guacamole.war /var/lib/${TOMCAT_VERSION}/webapps/ # Move MySQL connector/j files echo -e "${GREY}Moving mysql-connector-java-${MYSQLJCON}.jar (/etc/guacamole/lib/mysql-connector-java.jar)..." mv -f mysql-connector-java-${MYSQLJCON}/mysql-connector-java-${MYSQLJCON}.jar /etc/guacamole/lib/mysql-connector-java.jar -echo +if [ $? -ne 0 ]; then + echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 + exit 1 + else + echo -e "${LGREEN}OK${GREY}" + echo +fi # Move TOTP files if [ "${INSTALL_TOTP}" = true ]; then @@ -467,7 +498,6 @@ if [ $? -ne 0 ]; then exit 1 else echo -e "${LGREEN}OK${GREY}" - echo fi # Done diff --git a/3-install-nginx.sh b/3-install-nginx.sh index 9954d79..d0c0b4a 100644 --- a/3-install-nginx.sh +++ b/3-install-nginx.sh @@ -7,11 +7,35 @@ # August 2023 ####################################################################################################################### -# Install Nginx -sudo apt-get install nginx -y &>> ${LOG_LOCATION} +# Prepare text output colours +GREY='\033[0;37m' +DGREY='\033[0;90m' +GREYB='\033[1;37m' +RED='\033[0;31m' +LRED='\033[0;91m' +GREEN='\033[0;32m' +LGREEN='\033[0;92m' +YELLOW='\033[0;33m' +LYELLOW='\033[0;93m' +BLUE='\033[0;34m' +LBLUE='\033[0;94m' +CYAN='\033[0;36m' +LCYAN='\033[0;96m' +MAGENTA='\033[0;35m' +LMAGENTA='\033[0;95m' +NC='\033[0m' #No Colour +echo +echo +echo -e "${LGREEN}Installing Nginx...${DGREY}" +echo + +# Install Nginx +sudo apt-get install nginx -qq -y &>> ${LOG_LOCATION} + +echo -e "${GREY}Configuring Nginx as a proxy for Guacamole's Apache Tomcat front end...${DGREY}" # Configure /etc/nginx/sites-available/(local dns site name) -cat >/etc/nginx/sites-available/$PROXY_SITE <&2 exit 1 @@ -46,8 +67,9 @@ ln -s /etc/nginx/sites-available/$PROXY_SITE /etc/nginx/sites-enabled/ unlink /etc/nginx/sites-enabled/default # Do mandatory Nginx tweaks for logging actual client IPs through a proxy IP of 127.0.0.1 - DO NOT CHANGE COMMAND FORMATING! +echo -e "${GREY}Configuring Apache Tomcat's valve to support for pass through of client IPs to Guacamole logs...${GREY}" sudo sed -i '/pattern="%h %l %u %t "%r" %s %b"/a \ \n ' /etc/$TOMCAT_VERSION/server.xml -echo -e "${GREY}Configuring Apache Tomcat's internal proxy valve to support proxy client IP4 & IPv6 address passthough for correct logging and ACL support...${GREY}" + if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 @@ -85,13 +107,12 @@ fi # Update general ufw rules so force traffic via reverse proxy. Only Nginx and SSH will be available over the network. echo -e "${GREY}Updating firewall rules to allow only SSH and tcp 80/443..." -sudo ufw default allow outgoing &>> ${LOG_LOCATION} -sudo ufw default deny incoming &>> ${LOG_LOCATION} -sudo ufw delete allow 8080/tcp &>> ${LOG_LOCATION} -sudo ufw allow OpenSSH &>> ${LOG_LOCATION} -sudo ufw allow 80/tcp &>> ${LOG_LOCATION} -sudo ufw allow 443/tcp &>> ${LOG_LOCATION} -echo "y" | sudo ufw enable &>> ${LOG_LOCATION} +sudo ufw default allow outgoing > /dev/null 2>&1 +sudo ufw default deny incoming > /dev/null 2>&1 +sudo ufw allow OpenSSH > /dev/null 2>&1 +sudo ufw allow 80/tcp > /dev/null 2>&1 +sudo ufw allow 443/tcp > /dev/null 2>&1 +echo "y" | sudo ufw enable > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 @@ -102,15 +123,14 @@ fi # Reload everything echo -e "${GREY}Restaring Guacamole & Ngnix..." -sudo systemctl restart $TOMCAT_VERSION &>> ${LOG_LOCATION} -sudo systemctl restart guacd &>> ${LOG_LOCATION} -sudo systemctl restart nginx &>> ${LOG_LOCATION} +sudo systemctl restart $TOMCAT_VERSION +sudo systemctl restart guacd +sudo systemctl restart nginx if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 else echo -e "${LGREEN}OK${GREY}" - echo fi # Done diff --git a/4a-install-ssl-self-signed-nginx.sh b/4a-install-ssl-self-signed-nginx.sh index 4a55c3f..da93709 100644 --- a/4a-install-ssl-self-signed-nginx.sh +++ b/4a-install-ssl-self-signed-nginx.sh @@ -11,12 +11,34 @@ # to provide certifacate outputs correctly. Runing just as sudo will save certs to sudo's home path # sudo -E ./4a-install-ssl-self-signed-nginx.sh [your-dns-name.local] [3650] +# Prepare text output colours +GREY='\033[0;37m' +DGREY='\033[0;90m' +GREYB='\033[1;37m' +RED='\033[0;31m' +LRED='\033[0;91m' +GREEN='\033[0;32m' +LGREEN='\033[0;92m' +YELLOW='\033[0;33m' +LYELLOW='\033[0;93m' +BLUE='\033[0;34m' +LBLUE='\033[0;94m' +CYAN='\033[0;36m' +LCYAN='\033[0;96m' +MAGENTA='\033[0;35m' +LMAGENTA='\033[0;95m' +NC='\033[0m' #No Colour + +echo +echo +echo -e "${LGREEN}Setting up self signed SSL certificates for Nginx...${GREY}" +echo + # Hack to assist with displaying "$" symbols and " ' quotes in a (cut/pasteable) bash screen output format for Nginx configs SHOWASTEXT1='$mypwd' SHOWASTEXT2='"Cert:\LocalMachine\Root"' # Discover all IPv4 interfaces addresses to bind to new SSL certficates -echo echo -e "${GREY}Discovering the default route interface and DNS names to bind with the new SSL certificate..." # Dump interface info and copy this output to a temp file DUMP_IPS=$(ip -o addr show up primary scope global | while read -r num dev fam addr rest; do echo ${addr%/*}; done) @@ -38,14 +60,11 @@ if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 else - echo -e "${GREEN}OK${GREY}" + echo -e "${LGREEN}OK${GREY}" echo fi -echo -echo -e "${GREY}New self signed SSL certificate attributes are shown below...${GREY}" -echo -e "${DGREY}" - +echo -e "${GREY}New self signed SSL certificate attributes are shown below...${DGREY}" # Display the new SSL cert parameters. Prompt for change if required cat <&2 + exit 1 + else + echo -e "${LGREEN}OK${GREY}" + echo +fi + # Place SSL Certificate within defined path sudo cp $SSLNAME.key $DIR_SSL_KEY/$SSLNAME.key sudo cp $SSLNAME.crt $DIR_SSL_CERT/$SSLNAME.crt # Create a PFX formatted key for easier import to Windows hosts and change permissions to enable copying elsewhere + echo -e "${GREY}Creating client certificates for Windows & Linux...${GREY}" sudo openssl pkcs12 -export -out $SSLNAME.pfx -inkey $SSLNAME.key -in $SSLNAME.crt -password pass:1234 sudo chmod 0774 $SSLNAME.pfx - echo -e "${GREY}Creating a selection of self signed certificates for Nginx and Windows/Linux browser clients...${GREY}" if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 else - echo -e "${GREEN}OK${GREY}" + echo -e "${LGREEN}OK${GREY}" echo fi @@ -125,12 +152,14 @@ if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 else - echo -e "${GREEN}OK${GREY}" + echo -e "${LGREEN}OK${GREY}" echo fi # Update Nginx config to accept the new certificates -cat > /etc/nginx/sites-available/$PROXY_SITE < /dev/null +echo -e "${GREY}Configuring Nginx proxy to use self signed SSL certificates and setting up automatic HTTP to HTTPS redirect...${DGREY}" +#cat > /etc/nginx/sites-available/$PROXY_SITE < /dev/null +cat <&2 exit 1 else - echo -e "${GREEN}OK${GREY}" + echo -e "${LGREEN}OK${GREY}" echo fi + printf "${GREY}+------------------------------------------------------------------------------------------------------------- -${GREEN}+ WINDOWS CLIENT SELF SIGNED SSL BROWSER CONFIG - SAVE THIS BEFORE CONTINUING!${GREY} +${LGREEN}+ WINDOWS CLIENT SELF SIGNED SSL BROWSER CONFIG - SAVE THIS BEFORE CONTINUING!${GREY} + -+ 1. In ${DOWNLOAD_DIR} is a Windows friendly version of the new certificate ${LYELLOW}$SSLNAME.pfx${GREY} ++ 1. In ${DOWNLOAD_DIR} is a new Windows friendly version of the new certificate ${LYELLOW}$SSLNAME.pfx${GREY} + 2. Copy this .pfx file to a location accessible by Windows. -+ 3. Import the PFX file into your Windows client with the below Powershell commands (as administrator): ++ 3. Import the PFX file into your Windows client with the below Powershell commands (as Administrator): \n" echo -e "${SHOWASTEXT1} = ConvertTo-SecureString -String "1234" -Force -AsPlainText" echo -e "Import-pfxCertificate -FilePath $SSLNAME.pfx -Password "${SHOWASTEXT1}" -CertStoreLocation "${SHOWASTEXT2}"" echo -e "(Clear your browser cache and restart your browser to test.)" printf "${GREY}+------------------------------------------------------------------------------------------------------------- -${GREEN}+ LINUX CLIENT SELF SIGNED SSL BROWSER CONFIG - SAVE THIS BEFORE CONTINUING!${GREY} +${LGREEN}+ LINUX CLIENT SELF SIGNED SSL BROWSER CONFIG - SAVE THIS BEFORE CONTINUING!${GREY} + -+ 1. In In ${DOWNLOAD_DIR} is also the Linux native OpenSSL certificate ${LYELLOW}$SSLNAME.crt${GREY} ++ 1. In ${DOWNLOAD_DIR} is a new Linux native OpenSSL certificate ${LYELLOW}$SSLNAME.crt${GREY} + 2. Copy this file to a location accessible by Linux. + 3. Import the CRT file into your Linux client certificate store with the below command (as sudo): \n" @@ -212,7 +240,6 @@ if [ $? -ne 0 ]; then exit 1 else echo -e "${LGREEN}OK${GREY}" - echo fi # Done diff --git a/4b-install-ssl-letsencrypt-nginx.sh b/4b-install-ssl-letsencrypt-nginx.sh index 318b74a..a8b5bd3 100644 --- a/4b-install-ssl-letsencrypt-nginx.sh +++ b/4b-install-ssl-letsencrypt-nginx.sh @@ -7,61 +7,32 @@ # April 2023 ####################################################################################################################### +# Prepare text output colours GREY='\033[0;37m' +DGREY='\033[0;90m' +GREYB='\033[1;37m' RED='\033[0;31m' +LRED='\033[0;91m' +GREEN='\033[0;32m' LGREEN='\033[0;92m' +YELLOW='\033[0;33m' +LYELLOW='\033[0;93m' +BLUE='\033[0;34m' +LBLUE='\033[0;94m' +CYAN='\033[0;36m' +LCYAN='\033[0;96m' +MAGENTA='\033[0;35m' +LMAGENTA='\033[0;95m' NC='\033[0m' #No Colour -# Announce which script you're running -echo -e "${GREY}" -echo -e "Let's Encrypt SSL configuration for Nginx.." - -############################################################################ -# If running this script standalone un-comment entire below section as we need -# the correct $PROXY_SITE, LE_DNS_NAME and LE_EMAIL values to reconfigure Nginx - -#TOMCAT_VERSION="tomcat9" -#LOG_LOCATION=$(eval echo ~${SUDO_USER})/lets-encrypt-inst.log -#DOWNLOAD_DIR=$(eval echo ~${SUDO_USER}) -#GUAC_URL=http://localhost:8080/guacamole/ -#for file in "/etc/nginx/sites-enabled"/* -#do -#PROXY_SITE="${file##*/}" -#done -#echo -#echo -e "${GREY}Discovering exising proxy sites to configure with SSL...${GREY}" -#if [ $? -ne 0 ]; then -# echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 -# exit 1 -# else -# echo -e "${LGREEN}OK${GREY}" -#fi - -# Get domain name for new Let's encrypt certificate -#while true -#do -#echo -e "${LGREEN}" -#read -p "Enter the public FQDN for your proxy site: " LE_DNS_NAME -#echo -# [ "${LE_DNS_NAME}" != "" ] && break -#done - -# Get admin email for Let's encrypt certificate notifications -#while true -#do -#echo -e "${LGREEN}" -#read -p "Enter the email address for Let's Encrypt notifications : " LE_EMAIL -#echo -# [ "${LE_EMAIL}" != "" ] && break -#done - -#echo -e "${GREY}" - -############################################################################ +echo +echo +echo -e "${LGREEN}Installing Let's Encrypt SSL configuration for Nginx...${GREY}" +echo # Install nginx -apt-get update -apt-get install nginx certbot python3-certbot-nginx -y &>> ${LOG_LOCATION} +apt-get update -qq &>> ${LOG_LOCATION} +apt-get install nginx certbot python3-certbot-nginx -qq -y &>> ${LOG_LOCATION} # Backup the current Nginx config cp /etc/nginx/sites-enabled/${PROXY_SITE} $DOWNLOAD_DIR/${PROXY_SITE}-nginx.bak @@ -76,6 +47,7 @@ else fi # Configure Nginx to accept the new certificates +echo -e "${GREY}Configuring Nginx proxy for Let's Encrypt SSL and setting up automatic HTTP redirect...${GREY}" cat > /etc/nginx/sites-available/$PROXY_SITE <&2 exit 1 @@ -110,7 +80,7 @@ systemctl restart nginx # Run certbot to create and associate certificates with currenly public IP (must have tcp 80 and 443 open to work) certbot --nginx -n -d $LE_DNS_NAME --email $LE_EMAIL --agree-tos --redirect --hsts echo -e -echo -e "${GREY}Let's Encrypt successfully installed. Check for errors above (DNS & firewall are usual culprits).${GREY}" +echo -e "${GREY}Let's Encrypt successfully installed, but check for any errors above (DNS & firewall are the usual culprits).${GREY}" if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 exit 1 @@ -123,7 +93,7 @@ fi # If are any due to expire within a 30 day window, Certbot will attempt to renew automatically renew. echo -e "${GREY}Scheduling automatic certificate renewals for certificates with < 30 days till expiry.)${GREY}" #Dump out the current crontab -crontab -l > cron_1 &>> ${LOG_LOCATION} +crontab -l > cron_1 # Remove any previosly added certbot renewal entries sed -i '/# certbot renew/d' cron_1 # Randomly choose a daily update schedule and append this to the cron schedule @@ -131,7 +101,7 @@ HOUR=$(shuf -i 0-23 -n 1) MINUTE=$(shuf -i 0-59 -n 1) echo "${MINUTE} ${HOUR} * * * /usr/bin/certbot renew --quiet --pre-hook 'service nginx stop' --post-hook 'service nginx start'" >> cron_1 # Overwrite old cron settings and cleanup -crontab cron_1 &>> ${LOG_LOCATION} +crontab cron_1 rm cron_1 if [ $? -ne 0 ]; then echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 @@ -151,7 +121,6 @@ if [ $? -ne 0 ]; then exit 1 else echo -e "${LGREEN}OK${GREY}" - echo fi # Done diff --git a/README.md b/README.md index 7ef6b89..ddfe2f8 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,61 @@ -# Guacamole 1.5.0 RDP jump server appliance with MFA, Active Directory integration & Nginx SSL reverse proxy +# Guacamole 1.5.1 RDP jump server appliance with MFA, Active Directory integration & Nginx SSL reverse proxy ## Automatic build, install & config script: wget https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/1-setup.sh && chmod +x 1-setup.sh && ./1-setup.sh - ## Prerequisites: - Ubuntu / Debian / Raspian + Recent flavours of Ubuntu / Debian / Raspian Min 8GB RAM, 40GB HDD Public or private DNS entries matching the default physical interface IP address. (needed for SSL) Incoming access on tcp 22, 80 & 443 - -### All install variables can be set from the first setup script. i.e. Guacamole, Tomcat & MySQL connector versions etc. Follow on screen prompts to install Guacamole, Nginx & SSL. - -### Scripted setup options are: +### Setup menu opations are: ### 1. Install default Guacamole with either a local MySQL database or with a remote MySQL instance + sub-options: + a. Add MySQL mysql_secure_installation settings (to a local or remote MySQL instance) + b. Add Guacamole MFA and Auth extensions - DUO, TOTP, LDAP. (Simultaneous TOTP & DUO not possible) - a. Add Guacamole MFA and Auth extensions (DUO, TOTP, LDAP) - b. Add MySQL mysql_secure_installation settings ### 2. Optionally add a reverse proxy front end to Guacamole of either: - a) None: Skip Nginx and keep the default Guacamole front end e.g. http://hostname:8080/guacamole - b) Install Nginx with NO SSL (http 80) e.g. http://hostname.local - c) Install Nginx with SELF SIGNED SSL certificates e.g. https://hostname.local - - includes client certificates for Windows & Linux browsers with final SSL client setup instructions. - d) Install Nginx with LET'S ENCRYPT certificates e.g. https://public.site.com - -### 3. After installation, optional hardening scripts are included for : + b) Install Nginx with NO SSL: e.g. http://hostname.local + c) Install Nginx with SELF SIGNED SSL certificates: e.g. https://hostname.local + - Newly created Windows & Linux browser certs $site.crt, $site.key & $site.pfx are saved to $DOWNLOAD_DIR/guac-setup + - Exact custom commands for the import of client certificates is generated on screen and is logged for later use. + d) Install Nginx with LET'S ENCRYPT certificates: e.g. https://public.site.com + +### 3. After installation, optional hardening scripts can be manually run for : a. Adding a fail2ban lockdown policy for Guacamole - b. Encryption of internal traffic between the Gaucamole client and Guacd deamon with SSL - To do list: Create hardening scripts for Nginx & MFA for shell access) - -### Items downloaded with the setup command above are setup are placed in the $DOWNLOAD_DIR/guacamole-setup dir as follows + b. Encryption of internal traffic between the Gaucamole client and Guacd daemon with SSL + To do list: (Hardening scripts for Nginx & MFA for shell access) + +## Install notes: + +To create an unattended setup, you must first run the link as above, then EXIT the 1-setup.sh script when prompted. +At this point only a download of all scripts has occurred and from there you may edit the "Silent setup options" +section at the start of 1-setup.sh as needed. + +In 1-setup-sh, any variables with an actual setting i.e. Variable="value" will not prompt during interactive setup, +so with the right combination of saved inputs it is fully possible to deploy Guacamole with Nginx and SSL with zero touch! + +Note: If you have edited 1-setup.sh, you must now run the setup script you saved LOCALLY with ./1-setup.sh (DO NOT RUN AS SUDO). +Beware: If you start setup again from the above wget link this will re-download and overwrite any previous customisations. +There should be no need to customise any other scripts before installation. All optional (manually run) scripts are +dynamically updated with their specific and relevant variables during setup. Essentially, this means that all scripts are built +to work as a set that are specific to your exact and particular install. Editing anything but 1-setup.sh (untill a at least a full install +is completed) is not therefore not recommended. + +To keep any adaptations you do make to any of the scripts, simply comment out the relevant wget lines in the "Download github setup" +section at the top of script 1-setup.sh. This willl prevent any subsequent setup re-runs from overwriting your own edited versions. + +This approach of pre-saving of options in the setup script itself has been taken because as there are just far too many potential +inputs and combinations of command line arguments that would need to be handeld and managed. With so much input required for what +is quite a complex install, any other method would require digesting and typing and insanely long string of setup arguments before the script itself. + + # Items downloaded with the setup command above are placed in the $DOWNLOAD_DIR/guac-setup directory... 1. 1-setup.sh - the parent install script itself 2. 2-install-guacamole.sh - Guacamole install script (inspired by https://github.com/MysticRyuujin/guac-install) 3. 3-install-nginx.sh - Installs Nginx and auto configures as a front end for Guacamole (optional) @@ -50,4 +70,5 @@ 12. branding.jar - An extension to customise the Guacomole login screen (optional) see: https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension -Special acknowledgement to MysticRyuujin @ https://github.com/MysticRyuujin/guac-install and Zer0CoolX @ https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension whos repos were a helpful source of ideas in assembling this project. +Special acknowledgement to MysticRyuujin @ https://github.com/MysticRyuujin/guac-install and +Zer0CoolX @ https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension whos repos were a helpful source of ideas in assembling this project. diff --git a/add-auth-duo.sh b/add-auth-duo.sh index d6db814..ee82f3d 100644 --- a/add-auth-duo.sh +++ b/add-auth-duo.sh @@ -35,6 +35,7 @@ fi GUAC_VERSION= TOMCAT_VERSION= GUAC_SOURCE_LINK= + echo wget -q --show-progress -O guacamole-auth-duo-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-duo-${GUAC_VERSION}.tar.gz tar -xzf guacamole-auth-duo-${GUAC_VERSION}.tar.gz diff --git a/add-auth-ldap.sh b/add-auth-ldap.sh index d6ec619..a8612eb 100644 --- a/add-auth-ldap.sh +++ b/add-auth-ldap.sh @@ -37,6 +37,7 @@ fi GUAC_VERSION= TOMCAT_VERSION= GUAC_SOURCE_LINK= + echo echo -e "${LYELLOW}Have you updated this script to reflect your Active Directory settings?${NC}" diff --git a/add-auth-totp.sh b/add-auth-totp.sh index f92a735..0a6202f 100644 --- a/add-auth-totp.sh +++ b/add-auth-totp.sh @@ -35,6 +35,7 @@ fi GUAC_VERSION= TOMCAT_VERSION= GUAC_SOURCE_LINK= + echo wget -q --show-progress -O guacamole-auth-totp-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-totp-${GUAC_VERSION}.tar.gz tar -xzf guacamole-auth-totp-${GUAC_VERSION}.tar.gz diff --git a/add-fail2ban.sh b/add-fail2ban.sh index 20cb31a..d9d4cd1 100644 --- a/add-fail2ban.sh +++ b/add-fail2ban.sh @@ -104,8 +104,8 @@ fi if [ "${FAIL2BAN_BASE}" = true ]; then #Update and install fail2ban (and john for management of config file updates) -sudo apt-get update > /dev/null 2>&1 -sudo apt-get install fail2ban john -y > /dev/null 2>&1 +sudo apt-get update -qq > /dev/null 2>&1 +sudo apt-get install fail2ban john -qq -y > /dev/null 2>&1 # Create the basic jail.local template cat > /tmp/fail2ban.conf <