This commit is contained in:
itiligent 2023-04-22 14:51:19 +10:00
parent 29b2a63b6b
commit 6d27072539
14 changed files with 612 additions and 329 deletions

View file

@ -19,11 +19,6 @@
# 4a-install-self-signed-nginx.sh sets up the new Nginx/Guacamole front end with self signed SSL certificates. # 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. # 4b-install-ssl-letsencrypt-nginx.sh sets up Nginx with public SSL certificates from LetsEncrypt.
#######################################################################################################################
# Initial enviromment setup ###########################################################################################
#######################################################################################################################
clear clear
# Prepare text output colours # Prepare text output colours
@ -44,37 +39,34 @@ MAGENTA='\033[0;35m'
LMAGENTA='\033[0;95m' LMAGENTA='\033[0;95m'
NC='\033[0m' #No Colour 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 Virtual Desktop 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 #Setup download and temp directory paths
USER_HOME_DIR=$(eval echo ~${SUDO_USER}) USER_HOME_DIR=$(eval echo ~${SUDO_USER})
DOWNLOAD_DIR=$USER_HOME_DIR/guac-setup DOWNLOAD_DIR=$USER_HOME_DIR/guac-setup
DB_BACKUP_DIR=$USER_HOME_DIR/mysqlbackups/ DB_BACKUP_DIR=$USER_HOME_DIR/mysqlbackups/
TMP_DIR=$DOWNLOAD_DIR/tmp 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 download branch
GITHUB="https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/" GITHUB="https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/"
#Version of Guacamole to install #Version of Guacamole to install
GUAC_VERSION="1.5.0" GUAC_VERSION="1.5.1"
# Set preferred Apache CDN download link # Set preferred Apache CDN download link
GUAC_SOURCE_LINK="http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/${GUAC_VERSION}" GUAC_SOURCE_LINK="http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/${GUAC_VERSION}"
@ -91,49 +83,64 @@ LOG_LOCATION="${DOWNLOAD_DIR}/guacamole_${GUAC_VERSION}_setup.log"
# Guacamole default install URL # Guacamole default install URL
GUAC_URL=http://localhost:8080/guacamole/ GUAC_URL=http://localhost:8080/guacamole/
# Non interactive silent setup options - add true/false or specific values # Depending on the Linux distro, required libraries have varied names. Standardising with names makes adapting
SERVER_NAME="" # Preferred server hostname # to other distros easier.
INSTALL_MYSQL="" # Install locally true/false source /etc/os-release
SECURE_MYSQL="" # Apply mysql secure configurarion tool OS_FLAVOUR=$ID
MYSQL_HOST="" # leave blank for localhost default, only specify for remote servers OS_VERSION=$VERSION
MYSQL_PORT="" # If blank default is 3306 JPEGTURBO=""
GUAC_DB="" # If blank default is guacamole_db LIBPNG=""
GUAC_USER="" # if blank default is guacamole_user
GUAC_PWD="" # Should not be blank as this may break some aspects of install # Get the default route interface IP
MYSQL_ROOT_PWD="" # Should not be blank as this may break some aspects of install DEFAULT_IP=$(ip addr show $(ip route | awk '/default/ { print $5 }') | grep "inet" | head -n 1 | awk '/inet/ {print $2}' | cut -d'/' -f1)
INSTALL_TOTP="" # TOTP MFA extension
INSTALL_DUO="" # DUO MFA extension (cant be installed simultaneously with TOTP) # Get an intital search suffix for use as a starting default local dns domain prompt value, we change this later
INSTALL_LDAP="" # Active Directory extension DOMAIN_SEARCH_SUFFIX=$(grep search /etc/resolv.conf | grep -v "#" | sed 's/'search[[:space:]]'//')
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) # Silent setup options - adding true/false or specific values below prevents prompt at install ########################
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 SERVER_NAME="" # Preferred server hostname
LE_EMAIL="webmaster@itiligent.com" # Webmaster/admin email for Lets Encrypt LOCAL_DOMAIN="" # Local DNS space in use
EMAIL_DOMAIN="itiligent.com" # Email relay domain for backup notifications INSTALL_MYSQL="" # Install locally true/false
ALERT_EMAIL="alerts@itiligent.com" # Email address for backup notifications SECURE_MYSQL="" # Apply mysql secure configurarion tool
BACKUP_RETAIN_DAYS="30" # How long to keep backups for MYSQL_HOST="" # leave blank for localhost default, only specify for remote servers
CERT_COUNTRY="AU" # 2 coutry charater code only, must not be blank 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_STATE="Victoria" # Optional to change, must not be blank
CERT_LOCATION="Melbourne" # 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_ORG="Itiligent" # Optional to change, must not be blank
CERT_OU="I.T." # 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 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 DNS name to bind with Lets Encrypt certificates
LE_EMAIL="" # Webmaster/admin email for Lets Encrypt
BACKUP_EMAIL="" # Email address for backup notifications
BACKUP_RETENTION="30" # How many days to keep backups for
# We need to try and grab a default value for the local FQDN. Domain search suffix is used in this case becausue # Script branding header
# this is the simplest common default resolv.conf value available between recent Debian and Ubuntu flavours. YMMV. echo
DOMAIN_SEARCH_SUFFIX=$(grep search /etc/resolv.conf | grep -v "#" | sed 's/'search[[:space:]]'//') echo -e "${GREYB}Itiligent Virtual Desktop Appliance Setup."
DEFAULT_FQDN=$HOSTNAME.$DOMAIN_SEARCH_SUFFIX echo -e " ${LGREEN}Powered by Guacamole"
echo
# 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
# 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 # Download config scripts and setup items from github
@ -144,88 +151,143 @@ wget -q --show-progress ${GITHUB}2-install-guacamole.sh -O 2-install-guacamole.s
wget -q --show-progress ${GITHUB}3-install-nginx.sh -O 3-install-nginx.sh wget -q --show-progress ${GITHUB}3-install-nginx.sh -O 3-install-nginx.sh
wget -q --show-progress ${GITHUB}4a-install-ssl-self-signed-nginx.sh -O 4a-install-ssl-self-signed-nginx.sh wget -q --show-progress ${GITHUB}4a-install-ssl-self-signed-nginx.sh -O 4a-install-ssl-self-signed-nginx.sh
wget -q --show-progress ${GITHUB}4b-install-ssl-letsencrypt-nginx.sh -O 4b-install-ssl-letsencrypt-nginx.sh wget -q --show-progress ${GITHUB}4b-install-ssl-letsencrypt-nginx.sh -O 4b-install-ssl-letsencrypt-nginx.sh
# Grab Guacamole manually run add on scripts
# Grab Guacamole auth extension config scripts
wget -q --show-progress ${GITHUB}add-auth-duo.sh -O add-auth-duo.sh wget -q --show-progress ${GITHUB}add-auth-duo.sh -O add-auth-duo.sh
wget -q --show-progress ${GITHUB}add-auth-ldap.sh -O add-auth-ldap.sh wget -q --show-progress ${GITHUB}add-auth-ldap.sh -O add-auth-ldap.sh
wget -q --show-progress ${GITHUB}add-auth-totp.sh -O add-auth-totp.sh wget -q --show-progress ${GITHUB}add-auth-totp.sh -O add-auth-totp.sh
wget -q --show-progress ${GITHUB}add-smtp-relay-o365.sh -O add-smtp-relay-o365.sh
# Grab backup and security hardening scripts # Grab backup and security hardening scripts
wget -q --show-progress ${GITHUB}backup-guac.sh -O backup-guac.sh wget -q --show-progress ${GITHUB}backup-guac.sh -O backup-guac.sh
wget -q --show-progress ${GITHUB}add-ssl-guac-gaucd.sh -O add-ssl-guac-gaucd.sh wget -q --show-progress ${GITHUB}add-ssl-guac-gaucd.sh -O add-ssl-guac-gaucd.sh
wget -q --show-progress ${GITHUB}add-fail2ban.sh -O add-fail2ban.sh wget -q --show-progress ${GITHUB}add-fail2ban.sh -O add-fail2ban.sh
# Grab a (customisable) branding extension # Grab a (customisable) branding extension
wget -q --show-progress ${GITHUB}branding.jar -O branding.jar wget -q --show-progress ${GITHUB}branding.jar -O branding.jar
chmod +x *.sh chmod +x *.sh
sleep 2
clear
# Script branding header
echo
echo -e "${GREYB}Itiligent Virtual Desktop 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}Local DNS Domain\t= ${GREY}${LOCAL_DOMAIN}"
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}Backup notify email\t= ${GREY}${BACKUP_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
####################################################################################################################### #######################################################################################################################
# Begin install menu prompts ########################################################################################## # Begin install menu prompts ##########################################################################################
####################################################################################################################### #######################################################################################################################
# We need a default hostname avaiable to apply even if we do not want to change the hostname. This approach allows the # We need a default hostname available 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. # Hostnames and matching DNS entries are essential for implementing SSL succesfully.
echo echo
echo
if [[ -z ${SERVER_NAME} ]]; then if [[ -z ${SERVER_NAME} ]]; then
echo -e "${LYELLOW}Update Linux system HOSTNAME [Enter to keep: ${HOSTNAME}]${LGREEN}" echo -e "${LYELLOW}Update Linux system HOSTNAME [Enter to keep: ${HOSTNAME}]${LGREEN}"
read -p " Enter new HOSTNAME : " SERVER_NAME read -p " Enter new HOSTNAME : " SERVER_NAME
if [[ "${SERVER_NAME}" = "" ]]; then if [[ "${SERVER_NAME}" = "" ]]; then
SERVER_NAME=$HOSTNAME SERVER_NAME=$HOSTNAME
fi
echo echo
sudo hostnamectl set-hostname $SERVER_NAME &>> ${LOG_LOCATION} sudo hostnamectl set-hostname $SERVER_NAME &>> ${LOG_LOCATION}
sudo sed -i '/127.0.1.1/d' /etc/hosts &>> ${LOG_LOCATION} sudo sed -i '/127.0.1.1/d' /etc/hosts &>> ${LOG_LOCATION}
echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION} echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION}
sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION} sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION}
else else
echo echo
sudo hostnamectl set-hostname $SERVER_NAME &>> ${LOG_LOCATION} sudo hostnamectl set-hostname $SERVER_NAME &>> ${LOG_LOCATION}
sudo sed -i '/127.0.1.1/d' /etc/hosts &>> ${LOG_LOCATION} sudo sed -i '/127.0.1.1/d' /etc/hosts &>> ${LOG_LOCATION}
echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION} echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION}
sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION} sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION}
fi fi
fi
echo
if [[ -z ${LOCAL_DOMAIN} ]]; then
echo -e "${LYELLOW}Update Linux LOCAL DNS DOMAIN [Enter to keep: .${DOMAIN_SEARCH_SUFFIX}]${LGREEN}"
read -p " Enter LOCAL DOMAIN NAME: " LOCAL_DOMAIN
if [[ "${LOCAL_DOMAIN}" = "" ]]; then
LOCAL_DOMAIN=$DOMAIN_SEARCH_SUFFIX
fi
echo
sudo sed -i "/${DEFAULT_IP}/d" /etc/hosts
sudo sed -i '/domain/d' /etc/resolv.conf
sudo sed -i '/search/d' /etc/resolv.conf
# Update the /etc/hosts file with the new domain values
echo ''${DEFAULT_IP}' '${SERVER_NAME}.${LOCAL_DOMAIN} ${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION}
#Update resolv.conf with new domain and search suffix values
echo 'domain '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>> ${LOG_LOCATION}
echo 'search '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>> ${LOG_LOCATION}
sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION}
else
echo
sudo sed -i "/${DEFAULT_IP}/d" /etc/hosts
sudo sed -i '/domain/d' /etc/resolv.conf
sudo sed -i '/search/d' /etc/resolv.conf
# Update the /etc/hosts file with the new domain values
echo ''${DEFAULT_IP}' '${SERVER_NAME}.${LOCAL_DOMAIN} ${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION}
#Update resolv.conf with new domain and search suffix values
echo 'domain '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>> ${LOG_LOCATION}
echo 'search '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>> ${LOG_LOCATION}
sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION}
fi
# After updateing the hostname and domain names, we can now use a refreshed value for the local FQDN.
DEFAULT_FQDN=$SERVER_NAME.$LOCAL_DOMAIN
clear 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 Virtual Desktop Appliance Setup."
echo -e " ${LGREEN}Powered by Guacamole"
echo
echo
echo -e "${LGREEN}MySQL setup options:${GREY}"
# Prompt the user to install MySQL, default of yes
if [[ -z ${INSTALL_MYSQL} ]]; then if [[ -z ${INSTALL_MYSQL} ]]; then
echo echo -e -n "SQL: Install MySQL? (for a remote MySQL Server select 'n') (y/n) [default y]: ${GREY}"
echo -e -n "${LGREEN}SQL: Install MySQL? (for a remote MySQL Server select 'n') (y/n) [default y]: ${GREY}"
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
INSTALL_MYSQL=false INSTALL_MYSQL=false
@ -234,7 +296,7 @@ if [[ -z ${INSTALL_MYSQL} ]]; then
fi fi
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 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}" echo -e -n "${GREY}SQL: Apply MySQL secure installation settings to LOCAL db? (y/n) [default y]: ${GREY}"
read PROMPT read PROMPT
@ -245,7 +307,7 @@ if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = true ]; then
fi fi
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 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}" echo -e -n "${GREY}SQL: Apply MySQL secure installation settings to REMOTE db? (y/n) [default n]: ${GREY}"
read PROMPT read PROMPT
@ -256,8 +318,8 @@ if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = false ]; then
fi fi
fi fi
# We need to get some additional MYSQL values
if [ "${INSTALL_MYSQL}" = false ]; then if [ "${INSTALL_MYSQL}" = false ]; then
# We need to get some additional MYSQL values
[ -z "${MYSQL_HOST}" ] \ [ -z "${MYSQL_HOST}" ] \
&& read -p "SQL: Enter MySQL server hostname or IP: " MYSQL_HOST && read -p "SQL: Enter MySQL server hostname or IP: " MYSQL_HOST
[ -z "${MYSQL_PORT}" ] \ [ -z "${MYSQL_PORT}" ] \
@ -288,18 +350,6 @@ if [ -z "${GUAC_USER}" ]; then
GUAC_USER="guacamole_user" GUAC_USER="guacamole_user"
fi 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 # Get Guacamole User password, confirm correct password entry and prevent blank passwords
if [ -z "${GUAC_PWD}" ]; then if [ -z "${GUAC_PWD}" ]; then
while true; do while true; do
@ -312,9 +362,39 @@ if [ -z "${GUAC_PWD}" ]; then
done done
fi 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 for preferred backup notification email address
if [[ -z ${BACKUP_EMAIL} ]]; then
while true; do
read -p "SQL: Enter email address for SQL backup messages [Enter to skip]: " BACKUP_EMAIL
[ "${BACKUP_EMAIL}" = "" ] || [ "${BACKUP_EMAIL}" != "" ] && break
# Rather than allow a blank value, uncomment to alternately force user to enter an explicit value instead
# [ "${BACKUP_EMAIL}" != "" ] && break
# echo -e "${RED}You must enter an email address. Please try again.${GREY}" 1>&2
done
fi
# If no backup notification email address is given, enter a default value
if [ -z ${BACKUP_EMAIL} ]; then
BACKUP_EMAIL="backup-email@yourdomain.com"
fi
echo
echo -e "${LGREEN}Guacamole authentication extension options:${GREY}"
# Prompt the user if they would like to install TOTP MFA, default of no # Prompt the user if they would like to install TOTP MFA, default of no
if [[ -z "${INSTALL_TOTP}" ]] && [[ "${INSTALL_DUO}" != true ]]; then 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]: " echo -e -n "AUTH: Install TOTP? (choose 'n' if you want Duo) (y/n)? [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_TOTP=true INSTALL_TOTP=true
@ -326,7 +406,7 @@ fi
# Prompt the user if they would like to install Duo MFA, default of no # Prompt the user if they would like to install Duo MFA, default of no
if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then
echo -e -n "${GREY}GUAC MFA: Install Duo? (y/n) [default n]: " echo -e -n "${GREY}AUTH: Install Duo? (y/n) [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_DUO=true INSTALL_DUO=true
@ -336,7 +416,7 @@ if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then
fi fi
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 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 echo -e "${RED}GUAC MFA: TOTP and Duo cannot be installed at the same time.${GREY}" 1>&2
exit 1 exit 1
@ -344,7 +424,7 @@ fi
# Prompt the user if they would like to install Duo MFA, default of no # Prompt the user if they would like to install Duo MFA, default of no
if [[ -z "${INSTALL_LDAP}" ]]; then if [[ -z "${INSTALL_LDAP}" ]]; then
echo -e -n "${GREY}GUAC AUTH: Install LDAP? (y/n) [default n]: " echo -e -n "${GREY}AUTH: Install LDAP? (y/n) [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_LDAP=true INSTALL_LDAP=true
@ -353,9 +433,11 @@ if [[ -z "${INSTALL_LDAP}" ]]; then
fi fi
fi fi
echo
echo -e "${LGREEN}Nginx reverse proxy options:${GREY}"
# Prompt for Guacamole front end reverse proxy option # Prompt for Guacamole front end reverse proxy option
if [[ -z ${INSTALL_NGINX} ]]; then if [[ -z ${INSTALL_NGINX} ]]; then
echo -e -n "${LGREEN}ADD REVERSE PROXY?: Protect Gucamole behind Nginx reverse proxy (y/n)? [default y]: ${GREY}" echo -e -n "REV PROXY: Protect Gucamole behind Nginx reverse proxy (y/n)? [default y]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
INSTALL_NGINX=false INSTALL_NGINX=false
@ -367,9 +449,9 @@ fi
# We must assign a DNS name for the new proxy site # We must assign a DNS name for the new proxy site
if [[ -z ${PROXY_SITE} ]] && [[ "${INSTALL_NGINX}" = true ]]; then if [[ -z ${PROXY_SITE} ]] && [[ "${INSTALL_NGINX}" = true ]]; then
while true; do while true; do
read -p "REVERSE PROXY NAME?: Enter proxy local DNS name? [Enter to use ${DEFAULT_FQDN}]: " PROXY_SITE read -p "REV PROXY: Enter proxy local DNS name? [Enter to use ${DEFAULT_FQDN}]: " PROXY_SITE
[ "${PROXY_SITE}" = "" ] || [ "${PROXY_SITE}" != "" ] && break [ "${PROXY_SITE}" = "" ] || [ "${PROXY_SITE}" != "" ] && break
# rather than allow any default, alternately force user to enter an explicit name instead # Rather than allow the default value below, uncomment to alternately force user to enter an explicit name instead
# [ "${PROXY_SITE}" != "" ] && break # [ "${PROXY_SITE}" != "" ] && break
# echo -e "${RED}You must enter a proxy site DNS name. Please try again.${GREY}" 1>&2 # echo -e "${RED}You must enter a proxy site DNS name. Please try again.${GREY}" 1>&2
done done
@ -381,19 +463,19 @@ PROXY_SITE="${DEFAULT_FQDN}"
fi fi
# Prompt for self signed SSL reverse proxy option # 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 # 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]: " echo -e -n "REV PROXY: Add self signed SSL support to Nginx? (y/n)? (choose 'n' for Let's Encrypt)[default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
SELF_SIGNED=true SELF_SIGN=true
else else
SELF_SIGNED=false SELF_SIGN=false
fi fi
fi fi
# Prompt to assign the self sign SSL certficate a custom expiry date, uncomment to force a manual entry # Optional prompt to assign the self sign SSL certficate a custom expiry date, uncomment to force a manual entry
#if [ "${SELF_SIGNED}" = true ]; then #if [ "${SELF_SIGN}" = true ]; then
# read - p "PROXY: Enter number of days till SSL certificate expires [default 3650]: " CERT_DAYS # read - p "PROXY: Enter number of days till SSL certificate expires [default 3650]: " CERT_DAYS
#fi #fi
@ -403,29 +485,29 @@ if [ -z "${CERT_DAYS}" ]; then
fi fi
# Prompt for Let's Encrypt SSL reverse proxy configuration option # 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}" echo -e -n "REV PROXY: Add Let's Encrypt SSL support to Nginx reverse proxy (y/n) [default n]: ${GREY}"
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_LETS_ENCRYPT=true LETS_ENCRYPT=true
else else
INSTALL_LETS_ENCRYPT=false LETS_ENCRYPT=false
fi fi
fi fi
# Prompt for Let's Encrypt public dns name # 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 while true; do
read -p "Enter the FQDN for your public proxy site : " LE_DNS_NAME read -p "REV PROXY: Enter the FQDN for your public proxy site : " LE_DNS_NAME
[ "${LE_DNS_NAME}" != "" ] && break [ "${LE_DNS_NAME}" != "" ] && break
echo -e "${RED}You must enter a public DNS name. Please try again.${GREY}" 1>&2 echo -e "${RED}You must enter a public DNS name. Please try again.${GREY}" 1>&2
done done
fi fi
# Prompt for Let's Encrypt admin email # 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 while true; do
read -p "Enter the email address for Let's Encrypt notifications : " LE_EMAIL read -p "REV PROXY: Enter the email address for Let's Encrypt notifications : " LE_EMAIL
[ "${LE_EMAIL}" != "" ] && break [ "${LE_EMAIL}" != "" ] && break
echo -e "${RED}You must enter an email address. Please try again.${GREY}" 1>&2 echo -e "${RED}You must enter an email address. Please try again.${GREY}" 1>&2
done done
@ -437,6 +519,8 @@ fi
####################################################################################################################### #######################################################################################################################
# Ubuntu and Debian each require different dependency packages. Below works ok from Ubuntu 18.04 / Debian 10 and above. # 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..." echo -e "${GREY}Checking linux distro specific dependencies..."
if [[ $OS_FLAVOUR == "ubuntu" ]] || [[ $OS_FLAVOUR == "ubuntu"* ]]; then # potentially expand out distro choices here if [[ $OS_FLAVOUR == "ubuntu" ]] || [[ $OS_FLAVOUR == "ubuntu"* ]]; then # potentially expand out distro choices here
JPEGTURBO="libjpeg-turbo8-dev" JPEGTURBO="libjpeg-turbo8-dev"
@ -454,15 +538,16 @@ else
fi fi
# Because the below scripts may be run manually after install, we need to sync them # 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_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|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 sed -i "s|GUAC_USER=|GUAC_USER='${GUAC_USER}'|g" $DOWNLOAD_DIR/backup-guac.sh
sed -i "s|GUAC_PWD=|GUAC_PWD='${GUAC_PWD}'|g" $DOWNLOAD_DIR/backup-guac.sh 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|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|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_EMAIL=|BACKUP_EMAIL='${BACKUP_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-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-ldap.sh
sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-totp.sh sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-totp.sh
@ -470,7 +555,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-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-auth-totp.sh
sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-fail2ban.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) 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-duo.sh
sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh
@ -479,7 +569,7 @@ sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/ad
# Pass the relevant variable selections to child install scripts below # Pass the relevant variable selections to child install scripts below
# (This is a more robust method than export, which is unreliable in this instance) # (This is a more robust method than export, which is unreliable in this instance)
COLOUR_VAR="GREY=$GREY DGREY=$DGREY GREYB=$GREYB RED=$RED LRED=$LRED GREEN=$GREEN LGREEN=$LGREEN YELLOW=$YELLOW LYELLOW=$LYELLOW BLUE=$BLUE LBLUE=$LBLUECYAN=$CYAN LCYAN=$LCYAN MAGENTA=$MAGENTA LMAGENTA=$LMAGENTA NC=$NC" COLOUR_VAR="GREY=$GREY DGREY=$DGREY GREYB=$GREYB RED=$RED LRED=$LRED GREEN=$GREEN LGREEN=$LGREEN YELLOW=$YELLOW LYELLOW=$LYELLOW BLUE=$BLUE LBLUE=$LBLUECYAN=$CYAN LCYAN=$LCYAN MAGENTA=$MAGENTA LMAGENTA=$LMAGENTA NC=$NC"
GUAC_VAR="JPEGTURBO=$JPEGTURBO LIBPNG=$LIBPNG GUAC_VERSION=$GUAC_VERSION MYSQLJCON=$MYSQLJCON GUAC_SOURCE_LINK=$GUAC_SOURCE_LINK TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION INSTALL_MYSQL=$INSTALL_MYSQL SECURE_MYSQL=$SECURE_MYSQL MYSQL_HOST=$MYSQL_HOST MYSQL_PORT=$MYSQL_PORT GUAC_DB=$GUAC_DB GUAC_USER=$GUAC_USER GUAC_PWD=$GUAC_PWD MYSQL_ROOT_PWD=$MYSQL_ROOT_PWD INSTALL_TOTP=$INSTALL_TOTP INSTALL_DUO=$INSTALL_DUO INSTALL_LDAP=$INSTALL_LDAP EMAIL_DOMAIN=$EMAIL_DOMAIN" GUAC_VAR="JPEGTURBO=$JPEGTURBO LIBPNG=$LIBPNG GUAC_VERSION=$GUAC_VERSION MYSQLJCON=$MYSQLJCON GUAC_SOURCE_LINK=$GUAC_SOURCE_LINK TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION INSTALL_MYSQL=$INSTALL_MYSQL SECURE_MYSQL=$SECURE_MYSQL MYSQL_HOST=$MYSQL_HOST MYSQL_PORT=$MYSQL_PORT GUAC_DB=$GUAC_DB GUAC_USER=$GUAC_USER GUAC_PWD=$GUAC_PWD MYSQL_ROOT_PWD=$MYSQL_ROOT_PWD INSTALL_TOTP=$INSTALL_TOTP INSTALL_DUO=$INSTALL_DUO INSTALL_LDAP=$INSTALL_LDAP BACKUP_EMAIL=$BACKUP_EMAIL"
NGINX_VAR="TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION GUAC_URL=$GUAC_URL PROXY_SITE=$PROXY_SITE" NGINX_VAR="TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION GUAC_URL=$GUAC_URL PROXY_SITE=$PROXY_SITE"
SELF_SIGN_VAR="DOWNLOAD_DIR=$DOWNLOAD_DIR TMP_DIR=$TMP_DIR TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION GUAC_URL=$GUAC_URL PROXY_SITE=$PROXY_SITE CERT_COUNTRY=$CERT_COUNTRY CERT_STATE=$CERT_STATE CERT_LOCATION=$CERT_LOCATION CERT_ORG=$CERT_ORG CERT_OU=$CERT_OU" SELF_SIGN_VAR="DOWNLOAD_DIR=$DOWNLOAD_DIR TMP_DIR=$TMP_DIR TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION GUAC_URL=$GUAC_URL PROXY_SITE=$PROXY_SITE CERT_COUNTRY=$CERT_COUNTRY CERT_STATE=$CERT_STATE CERT_LOCATION=$CERT_LOCATION CERT_ORG=$CERT_ORG CERT_OU=$CERT_OU"
LE_VAR="DOWNLOAD_DIR=$DOWNLOAD_DIR TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION PROXY_SITE=$PROXY_SITE GUAC_URL=$GUAC_URL LE_DNS_NAME=$LE_DNS_NAME LE_EMAIL=$LE_EMAIL" LE_VAR="DOWNLOAD_DIR=$DOWNLOAD_DIR TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION PROXY_SITE=$PROXY_SITE GUAC_URL=$GUAC_URL LE_DNS_NAME=$LE_DNS_NAME LE_EMAIL=$LE_EMAIL"
@ -490,23 +580,23 @@ if [ $? -ne 0 ]; then
echo -e "${RED}2-install-guacamole.sh FAILED. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}2-install-guacamole.sh FAILED. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
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}" 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 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 if [ $INSTALL_DUO == "true" ]; then
echo -e "${YELLOW}Reminder: Duo requires extra account specific config before you can log in to Guacamole." 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" echo -e "See https://guacamole.apache.org/doc/${GUAC_VERSION}/gug/duo-auth.html"
fi fi
# Add a Guacamole database backup (mon-fri 12:00am) into cron # Add a Guacamole database backup (mon-fri 12:00am) into cron
crontab -l > cron_1 > /dev/null 2>&1 crontab -l > cron_1
# Remove existing entry to allow multiple runs # Remove existing entry to allow multiple runs
sed -i '/# backup guacamole/d' cron_1 sed -i '/# backup guacamole/d' cron_1
# Create the job # Create the job
echo "0 0 * * 1-5 ${DOWNLOAD_DIR}/backup-guac.sh # backup guacamole" >> cron_1 echo "0 0 * * 1-5 ${DOWNLOAD_DIR}/backup-guac.sh # backup guacamole" >> cron_1
# Overwrite the cron settings and cleanup # Overwrite the cron settings and cleanup
crontab cron_1 > /dev/null 2>&1 crontab cron_1
rm cron_1 rm cron_1
@ -516,30 +606,31 @@ rm cron_1
### Install Nginx reverse proxy front end to Guacamole if option is selected ### Install Nginx reverse proxy front end to Guacamole if option is selected
if [ "${INSTALL_NGINX}" = true ]; then 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}" 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 fi
### Apply self signed SSL certificates to Nginx reverse proxy if option is selected ### Apply self signed SSL certificates to Nginx reverse proxy if option is selected
if [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGNED}" = true ]]; then 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} | tee -a ${LOG_LOCATION} 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}" 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 fi
### Apply Let's Encrypt SSL certificates to Nginx reverse proxy if option is selected ### Apply Let's Encrypt SSL certificates to Nginx reverse proxy if option is selected
if [[ "${INSTALL_NGINX}" = true ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then if [[ "${INSTALL_NGINX}" = true ]] && [[ "${LETS_ENCRYPT}" = true ]]; then
sudo -E $LE_VAR $COLOUR_VAR ./4b-install-ssl-letsencrypt-nginx.sh | tee -a ${LOG_LOCATION} 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}" 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 fi
# Final tidy up # Final tidy up
echo
echo -e "${LGREEN}Finally, 1-setup.sh was moved to ${USER_HOME_DIR}/guacamole."
mv $USER_HOME_DIR/1-setup.sh $DOWNLOAD_DIR mv $USER_HOME_DIR/1-setup.sh $DOWNLOAD_DIR
sudo rm -R $TMP_DIR sudo rm -R $TMP_DIR
# Done # Done
echo echo
printf "${LGREEN}Guacamole ${GUAC_VERSION} install complete! \n${NC}" printf "${LGREEN}Guacamole ${GUAC_VERSION} install complete! \n${NC}"

View file

@ -8,8 +8,36 @@
# pls see https://github.com/MysticRyuujin/guac-install for more # 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 clear
#Script branding header
echo
echo -e "${GREYB}Itiligent Virtual Desktop Appliance Setup."
echo -e " ${LGREEN}Powered by Guacamole"
echo
echo
echo -e "Beginning Guacamole setup...${GREY}"
echo
# Pre-seed MySQL install values # Pre-seed MySQL install values
if [ "${INSTALL_MYSQL}" = true ]; then if [ "${INSTALL_MYSQL}" = true ]; then
debconf-set-selections <<< "mysql-server mysql-server/root_password password ${MYSQL_ROOT_PWD}" debconf-set-selections <<< "mysql-server mysql-server/root_password password ${MYSQL_ROOT_PWD}"
@ -26,11 +54,10 @@ if [ "${INSTALL_MYSQL}" = true ]; then
fi fi
# Don't do annoying prompts during apt installs # Don't do annoying prompts during apt installs
echo
echo -e "${GREY}Updating base Linux OS..." echo -e "${GREY}Updating base Linux OS..."
export DEBIAN_FRONTEND=noninteractive &>> ${LOG_LOCATION} export DEBIAN_FRONTEND=noninteractive
sudo apt-get update &>> ${LOG_LOCATION} sudo apt-get update -qq &>> ${LOG_LOCATION}
sudo apt-get upgrade -y &>> ${LOG_LOCATION} sudo apt-get upgrade -qq -y &>> ${LOG_LOCATION}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
@ -41,10 +68,9 @@ fi
# Install Guacamole build dependencies. # Install Guacamole build dependencies.
echo echo
echo -e "${GREY}Installing dependencies required for building Guacamole, this might take a few minutes..." 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 \ 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 \ libvorbis-dev libwebp-dev ghostscript ${MYSQL} ${TOMCAT_VERSION} &>> ${LOG_LOCATION}
${MYSQL} ${TOMCAT_VERSION} &>> ${LOG_LOCATION}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
@ -52,20 +78,17 @@ if [ $? -ne 0 ]; then
echo -e "${LGREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
fi fi
# Setup email relay # Install Postfix with default settings for smtp email relay
echo echo
echo -e "${GREY}Setting up SMTP for backup alerts (requires SMTP relay be permitted from this server's IP address)..." echo -e "${GREY}Installing SMTP email for backup email notifications, for SMTP realy with Office365, see separate configuration script..."
echo "postfix postfix/mailname string ${EMAIL_DOMAIN} | debconf-set-selections" &>> ${LOG_LOCATION} DEBIAN_FRONTEND="noninteractive" apt-get install postfix mailutils -qq -y &>> ${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}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
echo -e "${LGREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
fi fi
service postfix restart
# Download Guacamole Server # Download Guacamole Server
echo echo
@ -150,8 +173,7 @@ if [ $? -ne 0 ]; then
fi fi
echo -e "${LGREEN}Downloaded mysql-connector-java-${MYSQLJCON}.tar.gz${GREY}" echo -e "${LGREEN}Downloaded mysql-connector-java-${MYSQLJCON}.tar.gz${GREY}"
echo echo -e "Source download complete.${GREY}"
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 # Option to pause script here as we might want to make final tweaks to source code just before compiling
#echo -e "${LYELLOW}" #echo -e "${LYELLOW}"
@ -181,7 +203,7 @@ echo -e "${GREY}Compiling Guacamole-Server from source with with GCC $( gcc --ve
export CFLAGS="-Wno-error" export CFLAGS="-Wno-error"
# Configure Guacamole Server source # 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 if [ $? -ne 0 ]; then
echo "Failed to configure guacamole-server" echo "Failed to configure guacamole-server"
echo "Trying again with --enable-allow-freerdp-snapshots" echo "Trying again with --enable-allow-freerdp-snapshots"
@ -227,7 +249,13 @@ ln -sf /etc/guacamole/guacamole.war /var/lib/${TOMCAT_VERSION}/webapps/
# Move MySQL connector/j files # Move MySQL connector/j files
echo -e "${GREY}Moving mysql-connector-java-${MYSQLJCON}.jar (/etc/guacamole/lib/mysql-connector-java.jar)..." 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 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 # Move TOTP files
if [ "${INSTALL_TOTP}" = true ]; then if [ "${INSTALL_TOTP}" = true ]; then
@ -467,7 +495,6 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
else else
echo -e "${LGREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo
fi fi
# Done # Done

View file

@ -7,11 +7,35 @@
# August 2023 # August 2023
####################################################################################################################### #######################################################################################################################
# Install Nginx # Prepare text output colours
sudo apt-get install nginx -y &>> ${LOG_LOCATION} 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 reverse proxy for Guacamole's Apache Tomcat front end...${DGREY}"
# Configure /etc/nginx/sites-available/(local dns site name) # Configure /etc/nginx/sites-available/(local dns site name)
cat >/etc/nginx/sites-available/$PROXY_SITE <<EOL cat <<EOF | tee /etc/nginx/sites-available/$PROXY_SITE
server { server {
listen 80 default_server; listen 80 default_server;
root /var/www/html; root /var/www/html;
@ -27,10 +51,7 @@ server {
access_log off; access_log off;
} }
} }
EOL EOF
echo
echo -e "${GREY}Configuring Nginx proxy to connect to Guacamole's Apache front end..."
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
@ -46,8 +67,8 @@ ln -s /etc/nginx/sites-available/$PROXY_SITE /etc/nginx/sites-enabled/
unlink /etc/nginx/sites-enabled/default 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! # 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 valve for pass through of client IPs to Guacamole logs...${GREY}"
sudo sed -i '/pattern="%h %l %u %t &quot;%r&quot; %s %b"/a \ <!-- Allow host IP to pass through to guacamole.-->\n <Valve className="org.apache.catalina.valves.RemoteIpValve"\n internalProxies="127\.0\.0\.1|0:0:0:0:0:0:0:1"\n remoteIpHeader="x-forwarded-for"\n remoteIpProxiesHeader="x-forwarded-by"\n protocolHeader="x-forwarded-proto" />' /etc/$TOMCAT_VERSION/server.xml sudo sed -i '/pattern="%h %l %u %t &quot;%r&quot; %s %b"/a \ <!-- Allow host IP to pass through to guacamole.-->\n <Valve className="org.apache.catalina.valves.RemoteIpValve"\n internalProxies="127\.0\.0\.1|0:0:0:0:0:0:0:1"\n remoteIpHeader="x-forwarded-for"\n remoteIpProxiesHeader="x-forwarded-by"\n protocolHeader="x-forwarded-proto" />' /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 if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
@ -85,13 +106,12 @@ fi
# Update general ufw rules so force traffic via reverse proxy. Only Nginx and SSH will be available over the network. # 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..." echo -e "${GREY}Updating firewall rules to allow only SSH and tcp 80/443..."
sudo ufw default allow outgoing &>> ${LOG_LOCATION} sudo ufw default allow outgoing > /dev/null 2>&1
sudo ufw default deny incoming &>> ${LOG_LOCATION} sudo ufw default deny incoming > /dev/null 2>&1
sudo ufw delete allow 8080/tcp &>> ${LOG_LOCATION} sudo ufw allow OpenSSH > /dev/null 2>&1
sudo ufw allow OpenSSH &>> ${LOG_LOCATION} sudo ufw allow 80/tcp > /dev/null 2>&1
sudo ufw allow 80/tcp &>> ${LOG_LOCATION} sudo ufw allow 443/tcp > /dev/null 2>&1
sudo ufw allow 443/tcp &>> ${LOG_LOCATION} echo "y" | sudo ufw enable > /dev/null 2>&1
echo "y" | sudo ufw enable &>> ${LOG_LOCATION}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
@ -102,15 +122,14 @@ fi
# Reload everything # Reload everything
echo -e "${GREY}Restaring Guacamole & Ngnix..." echo -e "${GREY}Restaring Guacamole & Ngnix..."
sudo systemctl restart $TOMCAT_VERSION &>> ${LOG_LOCATION} sudo systemctl restart $TOMCAT_VERSION
sudo systemctl restart guacd &>> ${LOG_LOCATION} sudo systemctl restart guacd
sudo systemctl restart nginx &>> ${LOG_LOCATION} sudo systemctl restart nginx
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
echo -e "${LGREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo
fi fi
# Done # Done

View file

@ -11,12 +11,34 @@
# to provide certifacate outputs correctly. Runing just as sudo will save certs to sudo's home path # 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] # 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 # Hack to assist with displaying "$" symbols and " ' quotes in a (cut/pasteable) bash screen output format for Nginx configs
SHOWASTEXT1='$mypwd' SHOWASTEXT1='$mypwd'
SHOWASTEXT2='"Cert:\LocalMachine\Root"' SHOWASTEXT2='"Cert:\LocalMachine\Root"'
# Discover all IPv4 interfaces addresses to bind to new SSL certficates # 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..." 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 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) 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 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
echo -e "${GREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo echo
fi fi
echo echo -e "${GREY}New self signed SSL certificate attributes are shown below...${DGREY}"
echo -e "${GREY}New self signed SSL certificate attributes are shown below...${GREY}"
echo -e "${DGREY}"
# Display the new SSL cert parameters. Prompt for change if required # Display the new SSL cert parameters. Prompt for change if required
cat <<EOF | tee -a $TMP_DIR/cert_attributes.txt cat <<EOF | tee -a $TMP_DIR/cert_attributes.txt
[req] [req]
@ -86,13 +105,6 @@ DIR_SSL_KEY="/etc/nginx/ssl/private"
SSLNAME=$1 SSLNAME=$1
SSLDAYS=$2 SSLDAYS=$2
if [[ $SSLDAYS == "" ]]; then
$SSLDAYS = 3650
fi
echo "Creating a new Certificate ..."
openssl req -x509 -nodes -newkey rsa:2048 -keyout $SSLNAME.key -out $SSLNAME.crt -days $SSLDAYS -config $TMP_DIR/cert_attributes.txt
# Make directories to place SSL Certificate if they don't exist # Make directories to place SSL Certificate if they don't exist
if [[ ! -d $DIR_SSL_KEY ]]; then if [[ ! -d $DIR_SSL_KEY ]]; then
sudo mkdir -p $DIR_SSL_KEY sudo mkdir -p $DIR_SSL_KEY
@ -102,19 +114,34 @@ if [[ ! -d $DIR_SSL_CERT ]]; then
sudo mkdir -p $DIR_SSL_CERT sudo mkdir -p $DIR_SSL_CERT
fi fi
if [[ $SSLDAYS == "" ]]; then
$SSLDAYS = 3650
fi
echo
echo "{$GREY}Creating a new Nginx SSL Certificate ..."
openssl req -x509 -nodes -newkey rsa:2048 -keyout $SSLNAME.key -out $SSLNAME.crt -days $SSLDAYS -config $TMP_DIR/cert_attributes.txt
if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1
else
echo -e "${LGREEN}OK${GREY}"
echo
fi
# Place SSL Certificate within defined path # Place SSL Certificate within defined path
sudo cp $SSLNAME.key $DIR_SSL_KEY/$SSLNAME.key sudo cp $SSLNAME.key $DIR_SSL_KEY/$SSLNAME.key
sudo cp $SSLNAME.crt $DIR_SSL_CERT/$SSLNAME.crt 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 # 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 openssl pkcs12 -export -out $SSLNAME.pfx -inkey $SSLNAME.key -in $SSLNAME.crt -password pass:1234
sudo chmod 0774 $SSLNAME.pfx 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 if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
echo -e "${GREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo echo
fi fi
@ -125,12 +152,14 @@ if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
echo -e "${GREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo echo
fi fi
# Update Nginx config to accept the new certificates # Update Nginx config to accept the new certificates
cat > /etc/nginx/sites-available/$PROXY_SITE <<EOL | > /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 <<EOL | > /dev/null
cat <<EOF | tee /etc/nginx/sites-available/$PROXY_SITE
server { server {
#listen 80 default_server; #listen 80 default_server;
root /var/www/html; root /var/www/html;
@ -167,31 +196,30 @@ server {
access_log off; access_log off;
} }
} }
EOL EOF
echo -e "${GREY}Configuring Nginx proxy to use self signed SSL certificates and setting up automatic HTTP to HTTPS redirect...${GREY}"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 exit 1
else else
echo -e "${GREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo echo
fi fi
printf "${GREY}+------------------------------------------------------------------------------------------------------------- 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. + 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" \n"
echo -e "${SHOWASTEXT1} = ConvertTo-SecureString -String "1234" -Force -AsPlainText" echo -e "${SHOWASTEXT1} = ConvertTo-SecureString -String "1234" -Force -AsPlainText"
echo -e "Import-pfxCertificate -FilePath $SSLNAME.pfx -Password "${SHOWASTEXT1}" -CertStoreLocation "${SHOWASTEXT2}"" echo -e "Import-pfxCertificate -FilePath $SSLNAME.pfx -Password "${SHOWASTEXT1}" -CertStoreLocation "${SHOWASTEXT2}""
echo -e "(Clear your browser cache and restart your browser to test.)" echo -e "(Clear your browser cache and restart your browser to test.)"
printf "${GREY}+------------------------------------------------------------------------------------------------------------- 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. + 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): + 3. Import the CRT file into your Linux client certificate store with the below command (as sudo):
\n" \n"
@ -199,7 +227,7 @@ echo -e "certutil -d sql:$HOME/.pki/nssdb -A -t "CT,C,c" -n $SSLNAME -i $SSLNAME
echo -e "(If certutil is not installed, run apt-get install libnss3-tools)" echo -e "(If certutil is not installed, run apt-get install libnss3-tools)"
printf "+-------------------------------------------------------------------------------------------------------------\n" printf "+-------------------------------------------------------------------------------------------------------------\n"
echo echo
echo -e "${LYELLOW}The above SSL browser config instructions are also saved in ${LGREEN}$LOG_LOCATION${GREY}" echo -e "${LYELLOW}The above SSL browser config instructions are saved in ${LGREEN}$LOG_LOCATION${GREY}"
echo echo
# Reload everything # Reload everything
@ -212,7 +240,6 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
else else
echo -e "${LGREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo
fi fi
# Done # Done

View file

@ -7,61 +7,32 @@
# April 2023 # April 2023
####################################################################################################################### #######################################################################################################################
# Prepare text output colours
GREY='\033[0;37m' GREY='\033[0;37m'
DGREY='\033[0;90m'
GREYB='\033[1;37m'
RED='\033[0;31m' RED='\033[0;31m'
LRED='\033[0;91m'
GREEN='\033[0;32m'
LGREEN='\033[0;92m' 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 NC='\033[0m' #No Colour
# Announce which script you're running echo
echo -e "${GREY}" echo
echo -e "Let's Encrypt SSL configuration for Nginx.." echo -e "${LGREEN}Installing Let's Encrypt SSL configuration for Nginx...${GREY}"
echo
############################################################################
# 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}"
############################################################################
# Install nginx # Install nginx
apt-get update apt-get update -qq &>> ${LOG_LOCATION}
apt-get install nginx certbot python3-certbot-nginx -y &>> ${LOG_LOCATION} apt-get install nginx certbot python3-certbot-nginx -qq -y &>> ${LOG_LOCATION}
# Backup the current Nginx config # Backup the current Nginx config
cp /etc/nginx/sites-enabled/${PROXY_SITE} $DOWNLOAD_DIR/${PROXY_SITE}-nginx.bak cp /etc/nginx/sites-enabled/${PROXY_SITE} $DOWNLOAD_DIR/${PROXY_SITE}-nginx.bak
@ -76,6 +47,7 @@ else
fi fi
# Configure Nginx to accept the new certificates # 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 <<EOL cat > /etc/nginx/sites-available/$PROXY_SITE <<EOL
server { server {
listen 80 default_server; listen 80 default_server;
@ -94,8 +66,6 @@ server {
} }
} }
EOL EOL
echo -e "${GREY}Configuring Nginx proxy for Let's Encrypt SSL and setting up automatic HTTP redirect...${GREY}"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 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) # 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 certbot --nginx -n -d $LE_DNS_NAME --email $LE_EMAIL --agree-tos --redirect --hsts
echo -e 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 if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
exit 1 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. # 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}" echo -e "${GREY}Scheduling automatic certificate renewals for certificates with < 30 days till expiry.)${GREY}"
#Dump out the current crontab #Dump out the current crontab
crontab -l > cron_1 &>> ${LOG_LOCATION} crontab -l > cron_1
# Remove any previosly added certbot renewal entries # Remove any previosly added certbot renewal entries
sed -i '/# certbot renew/d' cron_1 sed -i '/# certbot renew/d' cron_1
# Randomly choose a daily update schedule and append this to the cron schedule # 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) 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 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 # Overwrite old cron settings and cleanup
crontab cron_1 &>> ${LOG_LOCATION} crontab cron_1
rm cron_1 rm cron_1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2 echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
@ -151,7 +121,6 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
else else
echo -e "${LGREEN}OK${GREY}" echo -e "${LGREEN}OK${GREY}"
echo
fi fi
# Done # Done

View file

@ -1,41 +1,62 @@
# Guacamole 1.5.0 RDP jump server appliance with MFA, Active Directory integration & Nginx SSL reverse proxy # Guacamole 1.5.1 Virtual Desktop/Jump Server appliance with MFA, Active Directory integration & Nginx SSL reverse proxy
## Automatic build, install & config script: ## 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 wget https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/1-setup.sh && chmod +x 1-setup.sh && ./1-setup.sh
## Prerequisites: ## Prerequisites:
Ubuntu / Debian / Raspian Recent flavours of Ubuntu / Debian / Raspian
Min 8GB RAM, 40GB HDD Min 8GB RAM, 40GB HDD
Public or private DNS entries matching the default physical interface IP address. (needed for SSL) Public or private DNS entries matching the default physical interface IP address. (needed for SSL)
Incoming access on tcp 22, 80 & 443 Incoming access on tcp 22, 80 & 443
### Setup menu options are:
### 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:
### 1. Install default Guacamole with either a local MySQL database or with a remote MySQL instance ### 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: ### 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 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 b) Install Nginx with NO SSL: e.g. http://hostname.local
c) Install Nginx with SELF SIGNED SSL certificates e.g. https://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. - Newly created Windows & Linux browser certs $site.crt, $site.key & $site.pfx are saved to $DOWNLOAD_DIR/guac-setup
d) Install Nginx with LET'S ENCRYPT certificates e.g. https://public.site.com - Exact custom commands for the import of client certificates is generated on screen and is logged for later reference.
d) Install Nginx with LET'S ENCRYPT certificates: e.g. https://public.site.com
### 3. After installation, optional hardening scripts are included for : ### 3. After installation, optional hardening scripts can be manually run for :
a. Adding a fail2ban lockdown policy for Guacamole a. Adding a fail2ban lockdown policy for Guacamole
b. Encryption of internal traffic between the Gaucamole client and Guacd deamon with SSL b. Encryption of internal traffic between the Gaucamole client and Guacd daemon with SSL
To do list: Create hardening scripts for Nginx & MFA for shell access) To do list: (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 ## Install notes:
To create an unattended setup, run the link above first, 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 ="variable" inputs it is fully possible to deploy Guacamole, Nginx and SSL with zero touch!
Note: If you have edited 1-setup.sh, you must setup script you saved LOCALLY with ./1-setup.sh (Important: DO NOT RUN AS SUDO, it will prompt for sudo as needed).
Be aware that if you start setup again from the above link this will re-download and overwrite any of your 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 specific to your particular install. Editing anything but 1-setup.sh (before a full install
is first completed once) is 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 as a more flexible route because there are far too
many potential inputs and combinations of command line arguments that would need to be passed to the setup script at the command line for
a full build, and this would require an impractically long string of setup arguments to type run correctly.
# 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 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) 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) 3. 3-install-nginx.sh - Installs Nginx and auto configures as a front end for Guacamole (optional)
@ -46,8 +67,10 @@
8. add-auth-totp.sh - Adds the TOTP MFA extension if not selected at install (optional) 8. add-auth-totp.sh - Adds the TOTP MFA extension if not selected at install (optional)
9. add-ssl-guac-gaucd.sh - A hardening script to wrap an extra ssl layer between the guacd server and the Guacamole client (optional) 9. add-ssl-guac-gaucd.sh - A hardening script to wrap an extra ssl layer between the guacd server and the Guacamole client (optional)
10. add-fail2ban.sh - Adds and configures fail2ban to secure Guacamole against brute force attacks 10. add-fail2ban.sh - Adds and configures fail2ban to secure Guacamole against brute force attacks
11. backup-guacamole.sh - A simple Guacamole backup script 11. add-smtp-relay-o365.sh - Sets up TLS SMTP authenticated relay with O365 (BYO app password)
12. branding.jar - An extension to customise the Guacomole login screen (optional) 12. backup-guacamole.sh - A simple Guacamole backup script
13. branding.jar - An extension to customise the Guacomole login screen (optional)
see: https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension 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.

View file

@ -35,6 +35,7 @@ fi
GUAC_VERSION= GUAC_VERSION=
TOMCAT_VERSION= TOMCAT_VERSION=
GUAC_SOURCE_LINK= GUAC_SOURCE_LINK=
echo echo
wget -q --show-progress -O guacamole-auth-duo-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-duo-${GUAC_VERSION}.tar.gz 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 tar -xzf guacamole-auth-duo-${GUAC_VERSION}.tar.gz

View file

@ -37,6 +37,7 @@ fi
GUAC_VERSION= GUAC_VERSION=
TOMCAT_VERSION= TOMCAT_VERSION=
GUAC_SOURCE_LINK= GUAC_SOURCE_LINK=
echo echo
echo -e "${LYELLOW}Have you updated this script to reflect your Active Directory settings?${NC}" echo -e "${LYELLOW}Have you updated this script to reflect your Active Directory settings?${NC}"

View file

@ -35,6 +35,7 @@ fi
GUAC_VERSION= GUAC_VERSION=
TOMCAT_VERSION= TOMCAT_VERSION=
GUAC_SOURCE_LINK= GUAC_SOURCE_LINK=
echo echo
wget -q --show-progress -O guacamole-auth-totp-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-totp-${GUAC_VERSION}.tar.gz 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 tar -xzf guacamole-auth-totp-${GUAC_VERSION}.tar.gz

View file

@ -104,8 +104,8 @@ fi
if [ "${FAIL2BAN_BASE}" = true ]; then if [ "${FAIL2BAN_BASE}" = true ]; then
#Update and install fail2ban (and john for management of config file updates) #Update and install fail2ban (and john for management of config file updates)
sudo apt-get update > /dev/null 2>&1 sudo apt-get update -qq > /dev/null 2>&1
sudo apt-get install fail2ban john -y > /dev/null 2>&1 sudo apt-get install fail2ban john -qq -y > /dev/null 2>&1
# Create the basic jail.local template # Create the basic jail.local template
cat > /tmp/fail2ban.conf <<EOF cat > /tmp/fail2ban.conf <<EOF
@ -208,7 +208,7 @@ sudo systemctl restart fail2ban
# Done # Done
echo echo
echo -e "${LGREEN}Fail2ban installed.${GREY}" echo -e "${LGREEN}Fail2ban installed...${GREY}"
echo echo
else else
@ -256,7 +256,7 @@ rm -f /tmp/netaddr.txt
rm -f /tmp/fail2ban.update rm -f /tmp/fail2ban.update
# Done # Done
echo -e "${LGREEN}Guacamole security policy applied${GREY}\n-${SED_NETADDR}are whitelisted from all IP bans.\n- To alter the whitelist edit /etc/fail2ban/jail.local & sudo systemctl restart fail2ban" echo -e "${LGREEN}Guacamole security policy applied${GREY}\n-${SED_NETADDR}are whitelisted from all IP bans.\n- To alter this whitelist, edit /etc/fail2ban/jail.local & sudo systemctl restart fail2ban"
echo echo

125
add-smtp-relay-o365.sh Normal file
View file

@ -0,0 +1,125 @@
#!/bin/bash
#######################################################################################################################
# SMTP relay with Office 365 Setup
# For Ubuntu / Debian / Raspian
# David Harrop
# April 2023
#######################################################################################################################
# Prerequisites:
# An office 365 account with a mailbox (NON ADMIN!!)
# An app password created for the above office 365 user at https://mysignins.microsoft.com/security-info
# SMTP Auth enabled for that user under "manage mail apps in the Office365 admin centre
# Prepare text output colours
GREY='\033[0;37m'
DGREY='\033[0;90m'
GREYB='\033[1;37m'
RED='\033[0;31m'
LGREEN='\033[0;92m'
LYELLOW='\033[0;93m'
NC='\033[0m' #No Colour
clear
SENDER=$SUDO_USER
SERVER=$(uname -n)
DOMAIN_SEARCH_SUFFIX=$(grep search /etc/resolv.conf | grep -v "#" | sed 's/'search[[:space:]]'//')
if ! [ $( id -u ) = 0 ]; then
echo
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
exit 1
fi
echo
echo -e "${LYELLOW}SMTP relay for Office365 setup...${LGREEN}"
# Install Posfix
echo
echo -e "${GREY}Installing Postfix with non-interactive defaults..."
sudo apt update -qq > /dev/null 2>&1
DEBIAN_FRONTEND="noninteractive" apt-get install postfix mailutils -qq -y > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "${RED}Postfix install failed. ${GREY}" 1>&2
exit 1
else
echo -e "${LGREEN}OK${GREY}"
fi
# Get the Office365 smtp authentication credentials
echo
echo -e "${LYELLOW}An Office365 account email account is needed for SMTP relay authentication...${LGREEN}"
echo
read -p "Enter O365 SMTP auth enabled email : " SMTP_EMAIL
read -s -p "Enter the SMTP auth account 'app password': " APP_PWD
echo
echo
# Remove some default Postifx config items that conflict with new entries
sudo sed -i '/relayhost/d' /etc/postfix/main.cf
sudo sed -i '/smtp_tls_security_level=may/d' /etc/postfix/main.cf
# For simple relay outbound only, limit Postfix to just loopback and IPv4
sed -i 's/inet_interfaces = all/inet_interfaces = loopback-only/g' /etc/postfix/main.cf
sed -i "s/inet_protocols = all/inet_protocols = ipv4/g" /etc/postfix/main.cf
echo -e "${GREY}Configuring Postfix for O365 SMTP relay and TLS auth..."
# Add the new Office365 SMTP auth with TLS settings
cat <<EOF | sudo tee -a /etc/postfix/main.cf > /dev/null 2>&1
relayhost = [smtp.office365.com]:587
smtp_use_tls = yes
smtp_always_send_ehlo = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
EOF
if [ $? -ne 0 ]; then
echo -e "${RED}Postfix restart failed. ${GREY}" 1>&2
exit 1
else
echo -e "${LGREEN}OK${GREY}"
echo
fi
# Setup the password file and postmap
sudo touch /etc/postfix/sasl_passwd
cat <<EOF | sudo tee -a /etc/postfix/sasl_passwd > /dev/null 2>&1
[smtp.office365.com]:587 ${SMTP_EMAIL}:${APP_PWD}
EOF
sudo chown root:root /etc/postfix/sasl_passwd
sudo chmod 0600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
# Setup the generic map file
sudo touch /etc/postfix/generic
cat <<EOF | sudo tee -a /etc/postfix/generic > /dev/null 2>&1
root@${SERVER} ${SMTP_EMAIL}
${SENDER}@${SERVER} ${SMTP_EMAIL}
@${DOMAIN_SEARCH_SUFFIX} ${SMTP_EMAIL}
EOF
sudo chown root:root /etc/postfix/generic
sudo chmod 0600 /etc/postfix/generic
sudo postmap /etc/postfix/generic
# Restart and test
echo -e "${GREY}Restarting Postfix..."
sudo service postfix restart
if [ $? -ne 0 ]; then
echo -e "${RED}Postfix restart failed. ${GREY}" 1>&2
exit 1
else
echo -e "${LGREEN}OK${GREY}"
fi
echo
read -p "Enter an email address to test that email relay is working : " TEST_EMAIL
echo "This is a test email" | mail -s "SMTP Auth Relay Is Working is working" ${TEST_EMAIL} -a "FROM:${SMTP_EMAIL}"
echo -e "${LGREEN}Test message sent.."
echo -e ${NC}

View file

@ -24,6 +24,12 @@ MAGENTA='\033[0;35m'
LMAGENTA='\033[0;95m' LMAGENTA='\033[0;95m'
NC='\033[0m' #No Colour NC='\033[0m' #No Colour
CERT_COUNTRY=
CERT_STATE=
CERT_LOCATION=
CERT_ORG=
CERT_OU=
clear clear
if ! [ $( id -u ) = 0 ]; then if ! [ $( id -u ) = 0 ]; then
@ -43,11 +49,11 @@ prompt = no
string_mask = utf8only string_mask = utf8only
[req_distinguished_name] [req_distinguished_name]
C = AU C = $CERT_COUNTRY
ST = Victoria ST = $CERT_STATE
L = Melbourne L = $CERT_LOCATION
O = Itiligent O = $CERT_ORG
OU = I.T. OU = $CERT_OU
CN = localhost CN = localhost
[v3_req] [v3_req]

View file

@ -34,11 +34,11 @@ GUAC_USER=
GUAC_PWD= GUAC_PWD=
GUAC_DB= GUAC_DB=
DB_BACKUP_DIR= DB_BACKUP_DIR=
ALERT_EMAIL= BACKUP_EMAIL=
BACKUP_RETAIN_DAYS= BACKUP_RETENTION=
# Protect disk space and remove backups older than {BACKUP_RETAIN_DAYS} days # Protect disk space and remove backups older than {BACKUP_RETENTION} days
find ${DB_BACKUP_DIR} -mtime +${BACKUP_RETAIN_DAYS} -delete find ${DB_BACKUP_DIR} -mtime +${BACKUP_RETENTION} -delete
# Backup code # Backup code
mkdir -p ${DB_BACKUP_DIR} mkdir -p ${DB_BACKUP_DIR}
@ -68,8 +68,8 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
else else
echo -e "${LGREEN}${GUAC_DB} backup was successfully copied to ${DB_BACKUP_DIR}" echo -e "${LGREEN}${GUAC_DB} backup was successfully copied to ${DB_BACKUP_DIR}"
#mailx -s "Guacamomle Database Backup Success" ${ALERT_EMAIL} #mailx -s "Guacamomle Database Backup Success" ${BACKUP_EMAIL}
echo "${GUAC_DB} backup was successfully copied to $DB_BACKUP_DIR}" | mailx -s "Guacamole backup " ${ALERT_EMAIL} echo "${GUAC_DB} backup was successfully copied to $DB_BACKUP_DIR" | mailx -s "Guacamole backup " ${BACKUP_EMAIL}
fi fi
echo -e ${NC} echo -e ${NC}

View file

@ -4,11 +4,7 @@ https://ourcodeworld.com/articles/read/949/how-to-perform-a-dos-attack-slow-http
slowhttptest -c 10000 -H -g -o ./output_file -i 3 -r 500 -t GET -u http://jumpbox.domain.com -x 24 -p 2 slowhttptest -c 10000 -H -g -o ./output_file -i 3 -r 500 -t GET -u http://jumpbox.domain.com -x 24 -p 2
## Audit Guacamole Connections and User access.##
## UAudit Guacamole Connections and User access.##
Query current connection profile allocations
mysql -u root -p guacamole_db mysql -u root -p guacamole_db
select select
@ -26,14 +22,11 @@ where
Quit to exit Quit to exit
## Reset TOTP configuration for a user account # Reset TOTP configuration for a user account
## This is likely not needed in Gucamole 1.40 as the gui provides an option to reset. Kept for reference. #This is likely not needed in Gucamole 1.40 as the gui provides an option to reset. Kept for reference.
mysql -u root -p mysql -u root -p
use guacamol_db; use guacamol_db;
SELECT user_id FROM guacamole_user INNER JOIN guacamole_entity ON guacamole_entity.entity_id = guacamole_user.entity_id WHERE guacamole_entity.name = 'guacadmin'; SELECT user_id FROM guacamole_user INNER JOIN guacamole_entity ON guacamole_entity.entity_id = guacamole_user.entity_id WHERE guacamole_entity.name = 'guacadmin';
UPDATE guacamole_user_attribute SET attribute_value='false' WHERE attribute_name = 'guac-totp-key-confirmed' and user_id = '1'; UPDATE guacamole_user_attribute SET attribute_value='false' WHERE attribute_name = 'guac-totp-key-confirmed' and user_id = '1';
quit; quit;