Compare commits

...

42 commits

Author SHA1 Message Date
itiligent
d3c0eeab20
Update README.md 2025-12-11 09:22:03 +11:00
itiligent
5bc439bf11
Update README.md 2025-12-11 09:19:34 +11:00
itiligent
b8ecc10f3d Update README.md 2025-09-24 20:49:34 +10:00
itiligent
9499408573 force freerdp2 with Debian 13 2025-08-21 01:06:55 +10:00
itiligent
5423eecfe0
update DB timezone check for Debian 13 2025-08-20 23:40:57 +10:00
itiligent
f0bc38028e
move to FreeRDP3 2025-07-17 16:36:01 +10:00
itiligent
04151be101 Update README.md 2025-07-05 13:45:59 +10:00
itiligent
909970fe9e allow upgrader null sqlroot password
allow upgrader a null sql root password
2025-07-05 13:45:59 +10:00
itiligent
50b2935457 Add redirect warning for DUO
reversed default, redirected guacamole URL no longer the default
2025-06-24 21:43:10 +10:00
itiligent
3a357c0451
Update README.md 2025-06-24 19:33:29 +10:00
itiligent
77826bd010 Bump up Guacamole install version to 1.6.0 2025-06-24 19:30:58 +10:00
itiligent
9915697260
Update README.md 2025-06-07 10:37:55 +10:00
itiligent
8c8aed28f8
Update README.md 2025-06-07 10:37:29 +10:00
itiligent
bc3b1530fb
Update README.md 2025-06-07 10:37:19 +10:00
itiligent
8059220396
Update README.md 2025-06-07 10:29:55 +10:00
itiligent
1222d0d30d Update README.md 2025-01-25 11:00:18 +11:00
itiligent
083109946f refined branding instructions 2025-01-12 15:58:49 +11:00
Itiligent
152e9d9d73 fix for recent tomcat log changes #69 2024-12-07 17:28:12 +11:00
itiligent
d42109fa1f
Update add-fail2ban.sh 2024-12-07 10:02:52 +11:00
itiligent
16ca246428
fix typo in ssh restart cmd 2024-11-13 06:04:49 +11:00
itiligent
6371c33552 Update README.md 2024-11-09 11:26:44 +11:00
itiligent
4d14707fe0 Add SSO build instructions 2024-11-01 15:36:49 +11:00
itiligent
94b5e421f6 bump up mysql connector version 2024-11-01 10:43:33 +11:00
Itiligent
457d0c122d custom guacd service account option 2024-10-31 18:47:49 +11:00
itiligent
b66f7418ce updated sudo add instructions 2024-10-31 15:29:47 +11:00
itiligent
b0084fb406 instructions for radius and other sso extensions 2024-10-30 09:01:54 +11:00
Itiligent
79019fdbc4 make default self sign TLS lifetime 3650 2024-10-13 13:59:43 +11:00
Itiligent
86a29b9853 change cert days prompt behaviour 2024-09-05 09:11:21 +10:00
Itiligent
802987c52d Update useful-config-info.txt 2024-08-26 17:35:18 +10:00
itiligent
01ce8e094b
typo 2024-08-20 02:37:55 +10:00
itiligent
ac69d3ee7c
U20.4 and Deb 10 no longer supported 2024-08-20 02:30:04 +10:00
itiligent
7f9897296c
Update README.md 2024-08-20 02:28:33 +10:00
itiligent
b0a509325e visual changes for dns prompt 2024-08-16 06:04:58 +10:00
itiligent
ba24092e0c update download link
Update README.md
2024-08-16 06:04:58 +10:00
itiligent
86570a38b9 typos 2024-08-13 15:34:19 +10:00
Itiligent
14495c3dc5 workaround for for Bookworm syslog changes 2024-08-12 15:56:13 +10:00
Itiligent
5787e1b01d improve dns suffix prompt 2024-08-08 20:21:37 +10:00
Itiligent
4a392bea2e Merge branch 'main' of https://github.com/itiligent/Guacamole-Installer 2024-07-23 14:47:00 +10:00
Itiligent
52aefab427 testing support for Kali and Linux Mint 2024-07-23 14:46:55 +10:00
Itiligent
d40f7671f7 add support for Kali and Linux Mint 2024-07-23 14:46:28 +10:00
Itiligent
36d6ab4fcd Update README.md 2024-07-23 14:46:28 +10:00
Itiligent
3b42eac51d keep custom rdp share names after upgrade 2024-07-20 14:03:33 +10:00
11 changed files with 429 additions and 209 deletions

View file

@ -43,7 +43,7 @@ if [[ $EUID -eq 0 ]]; then
exit 1 exit 1
fi fi
# Check if sudo is installed. (Debian does not always include sudo by default.) # Check if sudo is installed. (Debian does not always include sudo by default)
if ! command -v sudo &> /dev/null; then if ! command -v sudo &> /dev/null; then
echo "${LRED}Sudo is not installed. Please install sudo." echo "${LRED}Sudo is not installed. Please install sudo."
echo -e ${NC} echo -e ${NC}
@ -53,11 +53,11 @@ fi
# Make sure the user running setup is a member of the sudo group # Make sure the user running setup is a member of the sudo group
if ! id -nG "$USER" | grep -qw "sudo"; then if ! id -nG "$USER" | grep -qw "sudo"; then
echo echo
echo -e "${LRED}The current user (${USER}) must be a member of the 'sudo' group. Run: sudo usermod -aG sudo ${USER}${NC}" 1>&2 echo -e "${LRED}The current user (${USER}) must be a member of the 'sudo' group. Run as root: usermod -aG sudo your-username & re-login ${USER}${NC}" 1>&2
exit 1 exit 1
fi fi
# Check to see if any previous version of build/install files exist, if so stop and check to be safe. # Check to see if any previous version of build files exist, if so stop and check to be safe.
if [[ "$(find . -maxdepth 1 \( -name 'guacamole-*' -o -name 'mysql-connector-j-*' \))" != "" ]]; then if [[ "$(find . -maxdepth 1 \( -name 'guacamole-*' -o -name 'mysql-connector-j-*' \))" != "" ]]; then
echo echo
echo -e "${LRED}Possible previous install files detected in current build path. Please review and remove old guacamole install files before proceeding.${GREY}, exiting..." 1>&2 echo -e "${LRED}Possible previous install files detected in current build path. Please review and remove old guacamole install files before proceeding.${GREY}, exiting..." 1>&2
@ -67,9 +67,6 @@ fi
# Query the OS version # Query the OS version
source /etc/os-release source /etc/os-release
ID=$ID
VERSION_ID=$VERSION_ID
VERSION_CODENAME=$VERSION_CODENAME
####################################################################################################################### #######################################################################################################################
# Core setup variables and mandatory inputs - EDIT VARIABLE VALUES TO SUIT ############################################ # Core setup variables and mandatory inputs - EDIT VARIABLE VALUES TO SUIT ############################################
@ -86,11 +83,11 @@ mkdir -p $DB_BACKUP_DIR
GITHUB="https://raw.githubusercontent.com/itiligent/Guacamole-Install/main" GITHUB="https://raw.githubusercontent.com/itiligent/Guacamole-Install/main"
# Version of Guacamole to install # Version of Guacamole to install
GUAC_VERSION="1.5.5" GUAC_VERSION="1.6.0"
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}"
# MySQL Connector/J version to install # MySQL Connector/J version to install
MYSQLJCON="8.4.0" MYSQLJCON="9.3.0"
MYSQLJCON_SOURCE_LINK="https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-${MYSQLJCON}.tar.gz" MYSQLJCON_SOURCE_LINK="https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-${MYSQLJCON}.tar.gz"
# Provide a specific MySQL version e.g. 11.1.2 or leave blank "" to use distro default MySQL packages. # Provide a specific MySQL version e.g. 11.1.2 or leave blank "" to use distro default MySQL packages.
@ -110,17 +107,18 @@ INSTALL_LOG="${DOWNLOAD_DIR}/guacamole_install.log"
####################################################################################################################### #######################################################################################################################
# Silent setup options - true/false or specific values below will skip prompt at install. EDIT TO SUIT ################ # Silent setup options - true/false or specific values below will skip prompt at install. EDIT TO SUIT ################
####################################################################################################################### #######################################################################################################################
SERVER_NAME="" # Server hostname. (Blank = use the current hostname.) SERVER_NAME="" # Server hostname (blank = use the current hostname)
LOCAL_DOMAIN="" # Local DNS namespace/domain suffix. (Blank = keep the current suffix.) LOCAL_DOMAIN="" # Local DNS namespace/domain suffix (blank = keep the current suffix)
INSTALL_MYSQL="" # Install MySQL locally (true/false) INSTALL_MYSQL="" # Install MySQL locally (true/false)
SECURE_MYSQL="" # Apply mysql secure configuration tool (true/false) SECURE_MYSQL="" # Apply mysql secure configuration tool (true/false)
MYSQL_HOST="" # Blank "" = localhost MySQL install, adding a specific IP address will assume a remote MySQL instance. MYSQL_HOST="" # Blank "" = localhost MySQL install, adding a specific IP address will assume a remote MySQL instance
MYSQL_PORT="" # If blank "" default is 3306 MYSQL_PORT="" # If blank "" default is 3306
GUAC_DB="" # If blank "" default is guacamole_db GUAC_DB="" # If blank "" default is guacamole_db
GUAC_USER="" # If blank "" default is guacamole_user GUAC_USER="" # If blank "" default is guacamole_user
MYSQL_ROOT_PWD="" # Manadatory entry here or at script prompt. MYSQL_ROOT_PWD="" # Manadatory entry here or at script prompt
GUAC_PWD="" # Manadatory entry here or at script prompt. GUAC_PWD="" # Manadatory entry here or at script prompt
DB_TZ=$(cat /etc/timezone) # Blank "" defaults to UTC, for local timezone: $(cat /etc/timezone) GUACD_ACCOUNT="guacd" # Service account guacd will run under (and will be very heavily locked down)
DB_TZ=$(timedatectl show -p Timezone --value) # Blank "" defaults to UTC, for local timezone: $(cat /etc/timezone)
INSTALL_TOTP="" # Add TOTP MFA extension (true/false), can't be installed simultaneously with DUO) INSTALL_TOTP="" # Add TOTP MFA extension (true/false), can't be installed simultaneously with DUO)
INSTALL_DUO="" # Add DUO MFA extension (true/false, can't be installed simultaneously with TOTP) INSTALL_DUO="" # Add DUO MFA extension (true/false, can't be installed simultaneously with TOTP)
INSTALL_LDAP="" # Add Active Directory extension (true/false) INSTALL_LDAP="" # Add Active Directory extension (true/false)
@ -129,15 +127,15 @@ INSTALL_HISTREC="" # Add Guacamole history recording storage featur
HISTREC_PATH="" # If blank "" sets the Apache's default path of /var/lib/guacamole/recordings HISTREC_PATH="" # If blank "" sets the Apache's default path of /var/lib/guacamole/recordings
GUAC_URL_REDIR="" # Auto redirect of host root URL http://xxx:8080 to http://xxx:8080/guacamole (true/false) GUAC_URL_REDIR="" # Auto redirect of host root URL http://xxx:8080 to http://xxx:8080/guacamole (true/false)
INSTALL_NGINX="" # Install & configure Nginx reverse proxy http:80 frontend (true/false) INSTALL_NGINX="" # Install & configure Nginx reverse proxy http:80 frontend (true/false)
PROXY_SITE="" # Local DNS name for reverse proxy site and/or self signed TLS certificates (Blank "" defaults to $DEFAULT_FQDN) PROXY_SITE="" # Local DNS name for reverse proxy site and/or self signed TLS certificates (blank "" defaults to $DEFAULT_FQDN)
SELF_SIGN="" # Add self signed TLS/https support to Nginx (true/false, Let's Encrypt not available with this option) SELF_SIGN="" # Add self signed TLS/https support to Nginx (true/false, Let's Encrypt not available with this option)
RSA_KEYLENGTH="2048" # Self signed RSA TLS key length. At least 2048, must not be blank. RSA_KEYLENGTH="2048" # Self signed RSA TLS key length. At least 2048, must not be blank
CERT_COUNTRY="AU" # Self signed cert setup, 2 character country code only, must not be blank. CERT_COUNTRY="AU" # Self signed cert setup, 2 character country code only, must not be blank
CERT_STATE="Victoria" # Self signed cert setup, must not be blank CERT_STATE="Victoria" # Self signed cert setup, must not be blank
CERT_LOCATION="Melbourne" # Self signed cert setup, must not be blank CERT_LOCATION="Melbourne" # Self signed cert setup, must not be blank
CERT_ORG="Itiligent" # Self signed cert setup, must not be blank CERT_ORG="Itiligent" # Self signed cert setup, must not be blank
CERT_OU="I.T." # Self signed cert setup, must not be blank CERT_OU="I.T." # Self signed cert setup, must not be blank
CERT_DAYS="" # Self signed cert setup, days until self signed TLS cert expiry, blank = default 3650 CERT_DAYS="3650" # Self signed cert setup, days until self signed TLS cert expiry, blank = default 3650
LETS_ENCRYPT="" # Add Lets Encrypt public TLS cert for Nginx (true/false, self signed TLS not available with this option) LETS_ENCRYPT="" # Add Lets Encrypt public TLS cert for Nginx (true/false, self signed TLS not available with this option)
LE_DNS_NAME="" # Public DNS name for use with Lets Encrypt certificates, must match public DNS LE_DNS_NAME="" # Public DNS name for use with Lets Encrypt certificates, must match public DNS
LE_EMAIL="" # Webmaster email for Lets Encrypt notifications LE_EMAIL="" # Webmaster email for Lets Encrypt notifications
@ -146,6 +144,8 @@ BACKUP_RETENTION="30" # Days to keep SQL backups locally
RDP_SHARE_HOST="" # Custom RDP host name shown in Windows Explorer (eg. "RDP_SHARE_LABEL on RDP_SHARE_HOST"). Blank "" = $SERVER_NAME RDP_SHARE_HOST="" # Custom RDP host name shown in Windows Explorer (eg. "RDP_SHARE_LABEL on RDP_SHARE_HOST"). Blank "" = $SERVER_NAME
RDP_SHARE_LABEL="RDP Share" # Custom RDP shared drive name in Windows Explorer (eg. "RDP_SHARE_LABEL on RDP_SHARE_HOST" eg. "your RDP share name on server01" RDP_SHARE_LABEL="RDP Share" # Custom RDP shared drive name in Windows Explorer (eg. "RDP_SHARE_LABEL on RDP_SHARE_HOST" eg. "your RDP share name on server01"
RDP_PRINTER_LABEL="RDP Printer" # Custom RDP printer name shown in Windows RDP_PRINTER_LABEL="RDP Printer" # Custom RDP printer name shown in Windows
CRON_DENY_FILE="/etc/cron.deny" # Distro's cron deny file
FREERDP="freerdp2-dev" # Set default FreeRDP package
####################################################################################################################### #######################################################################################################################
# Download GitHub setup scripts. BEFORE RUNNING SETUP, COMMENT OUT DOWNLOAD LINES OF ANY SCRIPTS YOU HAVE EDITED ! #### # Download GitHub setup scripts. BEFORE RUNNING SETUP, COMMENT OUT DOWNLOAD LINES OF ANY SCRIPTS YOU HAVE EDITED ! ####
@ -153,12 +153,12 @@ RDP_PRINTER_LABEL="RDP Printer" # Custom RDP printer name shown in Windows
# Script branding header # Script branding header
echo echo
echo -e "${GREYB}Guacamole ${GUAC_VERSION} Auto Installer." echo -e "${GREYB}Guacamole ${GUAC_VERSION} Appliance Auto Installer"
echo -e " ${LGREEN}Powered by Itiligent" echo -e " ${LGREEN}Powered by Itiligent"
echo echo
echo echo
# Download the set of config scripts from GitHub # Download the suite of install scripts from GitHub
cd $DOWNLOAD_DIR cd $DOWNLOAD_DIR
echo -e "${GREY}Downloading the Guacamole build suite...${DGREY}" echo -e "${GREY}Downloading the Guacamole build suite...${DGREY}"
wget -q --show-progress ${GITHUB}/2-install-guacamole.sh -O 2-install-guacamole.sh wget -q --show-progress ${GITHUB}/2-install-guacamole.sh -O 2-install-guacamole.sh
@ -166,7 +166,7 @@ wget -q --show-progress ${GITHUB}/3-install-nginx.sh -O 3-install-nginx.sh
wget -q --show-progress ${GITHUB}/4a-install-tls-self-signed-nginx.sh -O 4a-install-tls-self-signed-nginx.sh wget -q --show-progress ${GITHUB}/4a-install-tls-self-signed-nginx.sh -O 4a-install-tls-self-signed-nginx.sh
wget -q --show-progress ${GITHUB}/4b-install-tls-letsencrypt-nginx.sh -O 4b-install-tls-letsencrypt-nginx.sh wget -q --show-progress ${GITHUB}/4b-install-tls-letsencrypt-nginx.sh -O 4b-install-tls-letsencrypt-nginx.sh
# Download the Guacamole optional feature scripts # Download the suite of optional feature adding scripts
wget -q --show-progress ${GITHUB}/guac-optional-features/add-auth-duo.sh -O add-auth-duo.sh wget -q --show-progress ${GITHUB}/guac-optional-features/add-auth-duo.sh -O add-auth-duo.sh
wget -q --show-progress ${GITHUB}/guac-optional-features/add-auth-ldap.sh -O add-auth-ldap.sh wget -q --show-progress ${GITHUB}/guac-optional-features/add-auth-ldap.sh -O add-auth-ldap.sh
wget -q --show-progress ${GITHUB}/guac-optional-features/add-auth-totp.sh -O add-auth-totp.sh wget -q --show-progress ${GITHUB}/guac-optional-features/add-auth-totp.sh -O add-auth-totp.sh
@ -175,10 +175,10 @@ wget -q --show-progress ${GITHUB}/guac-optional-features/add-xtra-histrecstor.sh
wget -q --show-progress ${GITHUB}/guac-optional-features/add-smtp-relay-o365.sh -O add-smtp-relay-o365.sh wget -q --show-progress ${GITHUB}/guac-optional-features/add-smtp-relay-o365.sh -O add-smtp-relay-o365.sh
wget -q --show-progress ${GITHUB}/guac-optional-features/add-tls-guac-daemon.sh -O add-tls-guac-daemon.sh wget -q --show-progress ${GITHUB}/guac-optional-features/add-tls-guac-daemon.sh -O add-tls-guac-daemon.sh
wget -q --show-progress ${GITHUB}/guac-optional-features/add-fail2ban.sh -O add-fail2ban.sh wget -q --show-progress ${GITHUB}/guac-optional-features/add-fail2ban.sh -O add-fail2ban.sh
wget -q --show-progress ${GITHUB}/guac-management/backup-guac.sh -O backup-guac.sh wget -q --show-progress ${GITHUB}/guac-management/backup-guacamole.sh -O backup-guacamole.sh
wget -q --show-progress ${GITHUB}/upgrade-guac.sh -O upgrade-guac.sh wget -q --show-progress ${GITHUB}/upgrade-guacamole.sh -O upgrade-guacamole.sh
# Download the (customisable) dark theme & branding template # Download the dark theme & branding template
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
@ -198,19 +198,19 @@ if [[ -z "${MYSQL_VERSION}" ]]; then
# Use Linux distro default version. # Use Linux distro default version.
MYSQLSRV="default-mysql-server default-mysql-client mysql-common" # Server MYSQLSRV="default-mysql-server default-mysql-client mysql-common" # Server
MYSQLCLIENT="default-mysql-client" # Client MYSQLCLIENT="default-mysql-client" # Client
DB_CMD="mysql" # The mysql -v command is depricated on some versions, here is an option to substitute any another. DB_CMD="mysql" # The mysql -v command is depricated on some versions.
else else
# Use official mariadb.org repo # Use official mariadb.org repo
MYSQLSRV="mariadb-server mariadb-client mariadb-common" # Server MYSQLSRV="mariadb-server mariadb-client mariadb-common" # Server
MYSQLCLIENT="mariadb-client" # Client MYSQLCLIENT="mariadb-client" # Client
DB_CMD="mariadb" # The mysql -v command is depricated on some versions, option to substitute any another. DB_CMD="mariadb" # The mysql -v command is depricated on some versions.
fi fi
# Standardise on a lexicon for the differing dependency package names between distros # Standardise on a lexicon for the differing dependency package names between distros
# Current package names for various distros are referenced at https://guacamole.apache.org/doc/gug/installing-guacamole.html # Current package names for various distros are referenced at https://guacamole.apache.org/doc/gug/installing-guacamole.html
JPEGTURBO="" JPEGTURBO=""
LIBPNG="" LIBPNG=""
if [[ ${ID,,} = "ubuntu" ]] || [[ ${ID,,} = *"ubuntu"* ]]; then if [[ ${ID,,} = "ubuntu" ]] || [[ ${ID,,} = *"ubuntu"* ]] || [[ ${ID,,} = *"linuxmint"* ]]; then
JPEGTURBO="libjpeg-turbo8-dev" JPEGTURBO="libjpeg-turbo8-dev"
LIBPNG="libpng-dev" LIBPNG="libpng-dev"
# Just in case this repo is not present in the distro # Just in case this repo is not present in the distro
@ -220,6 +220,10 @@ elif [[ ${ID,,} = "debian" ]] || [[ ${ID,,} = "raspbian" ]]; then
LIBPNG="libpng-dev" LIBPNG="libpng-dev"
fi fi
#######################################################################################################################
# Ongoing fixes and workarounds as distros diverge/change #############################################################
#######################################################################################################################
# Check for the more recent versions of Tomcat currently supported by the distro # Check for the more recent versions of Tomcat currently supported by the distro
if [[ $(apt-cache show tomcat10 2>/dev/null | egrep "Version: 10" | wc -l) -gt 0 ]]; then if [[ $(apt-cache show tomcat10 2>/dev/null | egrep "Version: 10" | wc -l) -gt 0 ]]; then
TOMCAT_VERSION="tomcat10" TOMCAT_VERSION="tomcat10"
@ -230,24 +234,25 @@ else
TOMCAT_VERSION="tomcat9" TOMCAT_VERSION="tomcat9"
fi fi
####################################################################################################################### # Decide the appropriate FreeRDP package (Debian 13.0 has issues with FreeRDP3)
# Ongoing fixes and workarounds as distros diverge/change ############################################################# if [[ "${VERSION_CODENAME,,}" == "bookworm" || "${VERSION_CODENAME,,}" == "noble" ]]; then
####################################################################################################################### FREERDP="freerdp3-dev"
fi
# Workaround for Debian incompatibilities with latet Tomcat versions. (Adds the oldstable repo and downgrades the Tomcat version to be installed) # Workaround for Debian incompatibilities with later Tomcat versions. (Adds the oldstable repo and downgrades the Tomcat version)
if [[ ${ID,,} = "debian" && ${VERSION_CODENAME,,} = *"bookworm"* ]] || [[ ${ID,,} = "debian" && ${VERSION_CODENAME,,} = *"trixie"* ]]; then #(checks for upper and lower case) if [[ ${ID,,} = "debian" && ${VERSION_CODENAME,,} = *"bookworm"* ]] || [[ ${ID,,} = "debian" && ${VERSION_CODENAME,,} = *"trixie"* ]]; then #(checks for upper and lower case)
echo "deb http://deb.debian.org/debian/ bullseye main" | sudo tee /etc/apt/sources.list.d/bullseye.list &> /dev/null echo "deb http://deb.debian.org/debian/ bullseye main" | sudo tee /etc/apt/sources.list.d/bullseye.list &> /dev/null
sudo apt-get update -qq &> /dev/null sudo apt-get update -qq &> /dev/null
TOMCAT_VERSION="tomcat9" TOMCAT_VERSION="tomcat9"
fi fi
# Workaround for Ubuntu 23.x Tomcat 10 incompatibilities. Force older version 9 also found in the Lunar repo. # Workaround for Ubuntu 23.x Tomcat 10 incompatibilities. Downgrades Tomcat to version 9 which is available from the Lunar repo.
if [[ ${ID,,} = "ubuntu" ]] && [[ ${VERSION_CODENAME,,} = *"lunar"* ]]; then #(checks for upper and lower case) if [[ ${ID,,} = "ubuntu" ]] && [[ ${VERSION_CODENAME,,} = *"lunar"* ]]; then
TOMCAT_VERSION="tomcat9" TOMCAT_VERSION="tomcat9"
fi fi
# Workaround for Ubuntu 24.x Tomcat 10 incompatibilities. (Adds old Jammy repo and downgrades the Tomcat version to be installed) # Workaround for Ubuntu 24.x Tomcat 10 incompatibilities. (Adds old Jammy repo and downgrades the Tomcat version)
if [[ ${ID,,} = "ubuntu" && ${VERSION_CODENAME,,} = *"noble"* ]]; then #(checks for upper and lower case) if [[ ${ID,,} = "ubuntu" && ${VERSION_CODENAME,,} = *"noble"* ]]; then
echo "deb http://archive.ubuntu.com/ubuntu/ jammy universe" | sudo tee /etc/apt/sources.list.d/jammy.list &> /dev/null echo "deb http://archive.ubuntu.com/ubuntu/ jammy universe" | sudo tee /etc/apt/sources.list.d/jammy.list &> /dev/null
sudo apt-get update -qq &> /dev/null sudo apt-get update -qq &> /dev/null
TOMCAT_VERSION="tomcat9" TOMCAT_VERSION="tomcat9"
@ -273,7 +278,7 @@ fi
# DO NOT EDIT PAST THIS POINT! ######################################################################################## # DO NOT EDIT PAST THIS POINT! ########################################################################################
####################################################################################################################### #######################################################################################################################
# An intitial dns suffix is needed as a starting value for the script prompts. # An intitial dns suffix is needed as a starting value for the script prompts
get_domain_suffix() { get_domain_suffix() {
echo "$1" | awk '{print $2}' echo "$1" | awk '{print $2}'
} }
@ -312,68 +317,68 @@ fi
# Ensure SERVER_NAME is consistent with local host entries # Ensure SERVER_NAME is consistent with local host entries
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 Linux hostname : " SERVER_NAME
# If hit enter making no SERVER_NAME change, assume the existing hostname as current # If hit enter making no SERVER_NAME change, assume the existing hostname as current
if [[ "${SERVER_NAME}" = "" ]]; then if [[ "${SERVER_NAME}" = "" ]]; then
SERVER_NAME=$HOSTNAME SERVER_NAME=$HOSTNAME
fi fi
echo echo
# A SERVER_NAME was derived via the prompt # A SERVER_NAME was derived via the prompt
# Apply the SERVER_NAME value & remove and update any old 127.0.1.1 localhost references # Apply the SERVER_NAME value & remove & update any old 127.0.1.1 localhost references
$(sudo hostnamectl set-hostname $SERVER_NAME &> /dev/null &) &> /dev/null $(sudo hostnamectl set-hostname $SERVER_NAME &>/dev/null &) &>/dev/null
sleep 1 sleep 1
sudo sed -i '/127.0.1.1/d' /etc/hosts &>>${INSTALL_LOG} sudo sed -i '/127.0.1.1/d' /etc/hosts &>>${INSTALL_LOG}
echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG} echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG}
$(sudo systemctl restart systemd-hostnamed &> /dev/null &) &> /dev/null $(sudo systemctl restart systemd-hostnamed &>/dev/null &) &>/dev/null
else else
echo echo
# A SERVER_NAME value was derived from a pre-set silent install option. # A SERVER_NAME value was derived from a pre-set silent install option.
# Apply the SERVER_NAME value & remove and update any old 127.0.1.1 localhost references # Apply the SERVER_NAME value & remove & update any old 127.0.1.1 localhost references
$(sudo hostnamectl set-hostname $SERVER_NAME &> /dev/null &) &> /dev/null $(sudo hostnamectl set-hostname $SERVER_NAME &>/dev/null &) &>/dev/null
sleep 1 sleep 1
sudo sed -i '/127.0.1.1/d' /etc/hosts &>>${INSTALL_LOG} sudo sed -i '/127.0.1.1/d' /etc/hosts &>>${INSTALL_LOG}
echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG} echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG}
$(sudo systemctl restart systemd-hostnamed &> /dev/null &) &> /dev/null $(sudo systemctl restart systemd-hostnamed &>/dev/null &) &>/dev/null
fi fi
# Ensure LOCAL_DOMAIN suffix and localhost entries are consistent # Ensure LOCAL_DOMAIN suffix & localhost entries are consistent
if [[ -z ${LOCAL_DOMAIN} ]]; then if [[ -z ${LOCAL_DOMAIN} ]]; then
echo -e "${LYELLOW}Update Linux LOCAL DNS DOMAIN [Enter to keep: ${DOMAIN_SUFFIX}]${LGREEN}" echo -e "${LYELLOW} Update Linux LOCAL DNS SUFFIX [Enter to keep: ${SERVER_NAME}.${DOMAIN_SUFFIX}]${LGREEN}"
read -p " Enter FULL LOCAL DOMAIN NAME: " LOCAL_DOMAIN read -p " Complete this local domain suffix: $SERVER_NAME." LOCAL_DOMAIN
# If hit enter making no LOCAL_DOMAIN name change, assume the existing domain suffix as current # If hit enter making no LOCAL_DOMAIN name change, assume the existing domain suffix as current
if [[ "${LOCAL_DOMAIN}" = "" ]]; then if [[ "${LOCAL_DOMAIN}" = "" ]]; then
LOCAL_DOMAIN=$DOMAIN_SUFFIX LOCAL_DOMAIN=$DOMAIN_SUFFIX
fi fi
echo echo
# A LOCAL_DOMAIN value was derived via the prompt # A LOCAL_DOMAIN value was derived via the prompt
# Remove any old localhost & resolv file values and update these with the new LOCAL_DOMAIN value # Remove any old localhost & resolv file values & update these with the new LOCAL_DOMAIN value
$(sudo systemctl restart systemd-hostnamed &> /dev/null &) &> /dev/null $(sudo systemctl restart systemd-hostnamed &>/dev/null &) &>/dev/null
sleep 1 sleep 1
sudo sed -i "/${DEFAULT_IP}/d" /etc/hosts sudo sed -i "/${DEFAULT_IP}/d" /etc/hosts
sudo sed -i '/domain/d' /etc/resolv.conf sudo sed -i '/domain/d' /etc/resolv.conf
sudo sed -i '/search/d' /etc/resolv.conf sudo sed -i '/search/d' /etc/resolv.conf
# Refresh the /etc/hosts file with the server name and new local domain value # Refresh the /etc/hosts file with the server name & new local domain value
echo ''${DEFAULT_IP}' '${SERVER_NAME}.${LOCAL_DOMAIN} ${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG} echo ''${DEFAULT_IP}' '${SERVER_NAME}.${LOCAL_DOMAIN} ${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG}
# Refresh /etc/resolv.conf with new domain and search suffix values # Refresh /etc/resolv.conf with new domain & search suffix values
echo 'domain '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG} echo 'domain '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG}
echo 'search '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG} echo 'search '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG}
$(sudo systemctl restart systemd-hostnamed &> /dev/null &) &> /dev/null $(sudo systemctl restart systemd-hostnamed &>/dev/null &) &>/dev/null
else else
echo echo
# A LOCAL_DOMIN value was derived from a pre-set silent install option. # A LOCAL_DOMIN value was derived from a pre-set silent install option.
# Remove any old localhost & resolv file values and update these with the new LOCAL_DOMAIN value # Remove any old localhost & resolv file values & update these with the new LOCAL_DOMAIN value
$(sudo systemctl restart systemd-hostnamed &> /dev/null &) &> /dev/null $(sudo systemctl restart systemd-hostnamed &>/dev/null &) &>/dev/null
sleep 1 sleep 1
sudo sed -i "/${DEFAULT_IP}/d" /etc/hosts sudo sed -i "/${DEFAULT_IP}/d" /etc/hosts
sudo sed -i '/domain/d' /etc/resolv.conf sudo sed -i '/domain/d' /etc/resolv.conf
sudo sed -i '/search/d' /etc/resolv.conf sudo sed -i '/search/d' /etc/resolv.conf
# Refresh the /etc/hosts file with the server name and new local domain value # Refresh the /etc/hosts file with the server name & new local domain value
echo ''${DEFAULT_IP}' '${SERVER_NAME}.${LOCAL_DOMAIN} ${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG} echo ''${DEFAULT_IP}' '${SERVER_NAME}.${LOCAL_DOMAIN} ${SERVER_NAME}'' | sudo tee -a /etc/hosts &>>${INSTALL_LOG}
# Refresh /etc/resolv.conf with new domain and search suffix values # Refresh /etc/resolv.conf with new domain & search suffix values
echo 'domain '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG} echo 'domain '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG}
echo 'search '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG} echo 'search '${LOCAL_DOMAIN}'' | sudo tee -a /etc/resolv.conf &>>${INSTALL_LOG}
$(sudo systemctl restart systemd-hostnamed &> /dev/null &) &> /dev/null $(sudo systemctl restart systemd-hostnamed &>/dev/null &) &>/dev/null
fi fi
# Now that $SERVER_NAME and $LOCAL_DOMAIN values are updated and refreshed, both values are merged to build # Now that $SERVER_NAME and $LOCAL_DOMAIN values are updated and refreshed, both values are merged to build
@ -388,7 +393,7 @@ fi
# Prompt to install MySQL # Prompt to install MySQL
echo -e "${LGREEN}MySQL setup options:${GREY}" echo -e "${LGREEN}MySQL setup options:${GREY}"
if [[ -z ${INSTALL_MYSQL} ]]; then if [[ -z ${INSTALL_MYSQL} ]]; then
echo -e -n "SQL: Install MySQL locally? (For a REMOTE MySQL server select 'n') [Y/n] [default y]: ${GREY}" echo -e -n "SQL: Install MySQL locally? (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
@ -399,7 +404,7 @@ fi
# Prompt to apply the Mysql secure installation locally # Prompt 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
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
SECURE_MYSQL=false SECURE_MYSQL=false
@ -479,7 +484,7 @@ echo
# Prompt to install TOTP MFA # Prompt to install TOTP MFA
echo -e "${LGREEN}Guacamole authentication extension options:${GREY}" echo -e "${LGREEN}Guacamole authentication extension options:${GREY}"
if [[ -z "${INSTALL_TOTP}" ]] && [[ "${INSTALL_DUO}" != true ]]; then if [[ -z "${INSTALL_TOTP}" ]] && [[ "${INSTALL_DUO}" != true ]]; then
echo -e -n "AUTH: 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
@ -491,7 +496,7 @@ fi
# Prompt to install Duo MFA # Prompt to install Duo MFA
if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then
echo -e -n "${GREY}AUTH: 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
@ -509,7 +514,7 @@ fi
# Prompt to install Duo MFA # Prompt to install Duo MFA
if [[ -z "${INSTALL_LDAP}" ]]; then if [[ -z "${INSTALL_LDAP}" ]]; then
echo -e -n "${GREY}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
@ -522,7 +527,7 @@ echo
# Prompt to install the Quick Connect feature (some higher security use cases may not want this) # Prompt to install the Quick Connect feature (some higher security use cases may not want this)
echo -e "${LGREEN}Guacamole console optional extras:${GREY}" echo -e "${LGREEN}Guacamole console optional extras:${GREY}"
if [[ -z "${INSTALL_QCONNECT}" ]]; then if [[ -z "${INSTALL_QCONNECT}" ]]; then
echo -e -n "${GREY}EXTRAS: Install Quick Connect feature? [y/N] [default n]: " echo -e -n "${GREY}EXTRAS: Install Quick Connect feature? [y/n] [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_QCONNECT=true INSTALL_QCONNECT=true
@ -533,7 +538,7 @@ fi
# Prompt to install the History Recorded Storage feature # Prompt to install the History Recorded Storage feature
if [[ -z "${INSTALL_HISTREC}" ]]; then if [[ -z "${INSTALL_HISTREC}" ]]; then
echo -e -n "${GREY}EXTRAS: Install History Recorded Storage feature [y/N] [default n]: " echo -e -n "${GREY}EXTRAS: Install History Recorded Storage feature [y/n] [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_HISTREC=true INSTALL_HISTREC=true
@ -559,7 +564,7 @@ echo
# Prompt for Guacamole front end reverse proxy option # Prompt for Guacamole front end reverse proxy option
echo -e "${LGREEN}Reverse Proxy & front end options:${GREY}" echo -e "${LGREEN}Reverse Proxy & front end options:${GREY}"
if [[ -z ${INSTALL_NGINX} ]]; then if [[ -z ${INSTALL_NGINX} ]]; then
echo -e -n "FRONT END: Protect Guacamole behind Nginx reverse proxy [y/N]? [default n]: " echo -e -n "FRONT END: Protect Guacamole behind Nginx reverse proxy [y/n]? [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
INSTALL_NGINX=true INSTALL_NGINX=true
@ -571,12 +576,12 @@ fi
# Prompt to redirect http://root:8080 to http://root:8080/guacamole if not installing reverse proxy # Prompt to redirect http://root:8080 to http://root:8080/guacamole if not installing reverse proxy
if [[ -z ${GUAC_URL_REDIR} ]] && [[ "${INSTALL_NGINX}" = false ]]; then if [[ -z ${GUAC_URL_REDIR} ]] && [[ "${INSTALL_NGINX}" = false ]]; then
echo -e -n "FRONT END: Redirect Guacamole http://domain.root:8080 to /guacamole [Y/n]? [default y]: " echo -e -n "FRONT END: Redirect http://domain.root:8080 to /guacamole (Warning: redirect may break DUO) [y/n]? [default n]: "
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
GUAC_URL_REDIR=false
else
GUAC_URL_REDIR=true GUAC_URL_REDIR=true
else
GUAC_URL_REDIR=false
fi fi
fi fi
@ -599,7 +604,7 @@ fi
# Prompt for self signed TLS reverse proxy option # Prompt for self signed TLS reverse proxy option
if [[ -z ${SELF_SIGN} ]] && [[ "${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 TLS support for Nginx, default of no # Prompt the user to see if they would like to install self signed TLS support for Nginx, default of no
echo -e -n "FRONT END: Add self signed TLS support to Nginx? [y/N]? (choose 'n' for Let's Encrypt)[default n]: " echo -e -n "FRONT END: Add self signed TLS 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_SIGN=true SELF_SIGN=true
@ -610,9 +615,9 @@ if [[ -z ${SELF_SIGN} ]] && [[ "${INSTALL_NGINX}" = true ]]; then
fi fi
# Prompt to enter a self sign TLS certificate expiry # Prompt to enter a self sign TLS certificate expiry
if [[ "${SELF_SIGN}" = true ]]; then if [[ -z "${CERT_DAYS}" ]] && [[ "${SELF_SIGN}" = true ]]; then
while true; do while true; do
read -p "FRONT END: Enter number of days till TLS certificates will expire [Enter for 3650]: " CERT_DAYS read -p "FRONT END: Enter number of days till TLS certificates will expire [Enter for ${CERT_DAYS}]: " CERT_DAYS
[[ "${CERT_DAYS}" = "" ]] || [[ "${CERT_DAYS}" != "" ]] && break [[ "${CERT_DAYS}" = "" ]] || [[ "${CERT_DAYS}" != "" ]] && break
done done
fi fi
@ -623,7 +628,7 @@ fi
# Prompt for Let's Encrypt TLS reverse proxy configuration option # Prompt for Let's Encrypt TLS reverse proxy configuration option
if [[ -z ${LETS_ENCRYPT} ]] && [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGN}" = false ]]; then if [[ -z ${LETS_ENCRYPT} ]] && [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGN}" = false ]]; then
echo -e -n "FRONT END: Add Let's Encrypt TLS support to Nginx reverse proxy [y/N] [default n]: ${GREY}" echo -e -n "FRONT END: Add Let's Encrypt TLS support to Nginx reverse proxy [y/n] [default n]: ${GREY}"
read PROMPT read PROMPT
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
LETS_ENCRYPT=true LETS_ENCRYPT=true
@ -668,14 +673,14 @@ echo
echo -e "${GREY}Synchronising the install script suite with the selected installation options..." echo -e "${GREY}Synchronising the install script suite with the selected installation options..."
# Sync the various manual config scripts with the relevant variables selected at install # Sync the various manual config scripts with the relevant variables selected at install
# This way scripts can be run at a later time without modification to match the original install # This way scripts can be run at a later time without modification to match the original install
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-guacamole.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-guacamole.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-guacamole.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-guacamole.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-guacamole.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-guacamole.sh
sed -i "s|BACKUP_EMAIL=|BACKUP_EMAIL='${BACKUP_EMAIL}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|BACKUP_EMAIL=|BACKUP_EMAIL='${BACKUP_EMAIL}'|g" $DOWNLOAD_DIR/backup-guacamole.sh
sed -i "s|BACKUP_RETENTION=|BACKUP_RETENTION='${BACKUP_RETENTION}'|g" $DOWNLOAD_DIR/backup-guac.sh sed -i "s|BACKUP_RETENTION=|BACKUP_RETENTION='${BACKUP_RETENTION}'|g" $DOWNLOAD_DIR/backup-guacamole.sh
sed -i "s|CERT_COUNTRY=|CERT_COUNTRY='${CERT_COUNTRY}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh sed -i "s|CERT_COUNTRY=|CERT_COUNTRY='${CERT_COUNTRY}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh
sed -i "s|CERT_STATE=|CERT_STATE='${CERT_STATE}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh sed -i "s|CERT_STATE=|CERT_STATE='${CERT_STATE}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh
@ -684,13 +689,18 @@ sed -i "s|CERT_ORG=|CERT_ORG='${CERT_ORG}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.
sed -i "s|CERT_OU=|CERT_OU='${CERT_OU}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh sed -i "s|CERT_OU=|CERT_OU='${CERT_OU}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh
sed -i "s|CERT_DAYS=|CERT_DAYS='${CERT_DAYS}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh sed -i "s|CERT_DAYS=|CERT_DAYS='${CERT_DAYS}'|g" $DOWNLOAD_DIR/add-tls-guac-daemon.sh
sed -i "s|INSTALL_MYSQL=|INSTALL_MYSQL='${INSTALL_MYSQL}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|INSTALL_MYSQL=|INSTALL_MYSQL='${INSTALL_MYSQL}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|MYSQL_HOST=|MYSQL_HOST='${MYSQL_HOST}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|MYSQL_HOST=|MYSQL_HOST='${MYSQL_HOST}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|MYSQL_PORT=|MYSQL_PORT='${MYSQL_PORT}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|MYSQL_PORT=|MYSQL_PORT='${MYSQL_PORT}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|GUAC_DB=|GUAC_DB='${GUAC_DB}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|GUAC_DB=|GUAC_DB='${GUAC_DB}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|MYSQL_ROOT_PWD=|MYSQL_ROOT_PWD='${MYSQL_ROOT_PWD}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|MYSQL_ROOT_PWD=|MYSQL_ROOT_PWD='${MYSQL_ROOT_PWD}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|GUAC_USER=|GUAC_USER='${GUAC_USER}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|GUAC_USER=|GUAC_USER='${GUAC_USER}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|GUAC_PWD=|GUAC_PWD='${GUAC_PWD}'|g" $DOWNLOAD_DIR/upgrade-guac.sh sed -i "s|GUAC_PWD=|GUAC_PWD='${GUAC_PWD}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|GUACD_ACCOUNT=|GUACD_ACCOUNT='${GUACD_ACCOUNT}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|RDP_SHARE_HOST=|RDP_SHARE_HOST='${RDP_SHARE_HOST}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|RDP_SHARE_LABEL=|RDP_SHARE_LABEL='${RDP_SHARE_LABEL}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|RDP_PRINTER_LABEL=|RDP_PRINTER_LABEL='${RDP_PRINTER_LABEL}'|g" $DOWNLOAD_DIR/upgrade-guacamole.sh
sed -i "s|PROXY_SITE=|PROXY_SITE='${PROXY_SITE}'|g" $DOWNLOAD_DIR/3-install-nginx.sh sed -i "s|PROXY_SITE=|PROXY_SITE='${PROXY_SITE}'|g" $DOWNLOAD_DIR/3-install-nginx.sh
sed -i "s|INSTALL_LOG=|INSTALL_LOG='${INSTALL_LOG}'|g" $DOWNLOAD_DIR/3-install-nginx.sh sed -i "s|INSTALL_LOG=|INSTALL_LOG='${INSTALL_LOG}'|g" $DOWNLOAD_DIR/3-install-nginx.sh
@ -731,6 +741,7 @@ export GUAC_VERSION=$GUAC_VERSION
export GUAC_SOURCE_LINK=$GUAC_SOURCE_LINK export GUAC_SOURCE_LINK=$GUAC_SOURCE_LINK
export ID=$ID export ID=$ID
export VERSION_ID=$VERSION_ID export VERSION_ID=$VERSION_ID
export FREERDP=$FREERDP
export VERSION_CODENAME=$VERSION_CODENAME export VERSION_CODENAME=$VERSION_CODENAME
export MYSQLJCON=$MYSQLJCON export MYSQLJCON=$MYSQLJCON
export MYSQLJCON_SOURCE_LINK=$MYSQLJCON_SOURCE_LINK export MYSQLJCON_SOURCE_LINK=$MYSQLJCON_SOURCE_LINK
@ -752,6 +763,7 @@ export GUAC_DB=$GUAC_DB
export GUAC_USER=$GUAC_USER export GUAC_USER=$GUAC_USER
export MYSQL_ROOT_PWD="${MYSQL_ROOT_PWD}" export MYSQL_ROOT_PWD="${MYSQL_ROOT_PWD}"
export GUAC_PWD="${GUAC_PWD}" export GUAC_PWD="${GUAC_PWD}"
export GUACD_ACCOUNT=$GUACD_ACCOUNT
export DB_TZ="${DB_TZ}" export DB_TZ="${DB_TZ}"
export INSTALL_TOTP=$INSTALL_TOTP export INSTALL_TOTP=$INSTALL_TOTP
export INSTALL_DUO=$INSTALL_DUO export INSTALL_DUO=$INSTALL_DUO
@ -778,8 +790,9 @@ export RDP_SHARE_LABEL="${RDP_SHARE_LABEL}"
export RDP_PRINTER_LABEL="${RDP_PRINTER_LABEL}" export RDP_PRINTER_LABEL="${RDP_PRINTER_LABEL}"
export LOCAL_DOMAIN=$LOCAL_DOMAIN export LOCAL_DOMAIN=$LOCAL_DOMAIN
export DOMAIN_SUFFIX=$DOMAIN_SUFFIX export DOMAIN_SUFFIX=$DOMAIN_SUFFIX
export CRON_DENY_FILE=$CRON_DENY_FILE
# Run the Guacamole install script keeping all exported variables from the current shell # Run the Guacamole install script (with all exported variables from this current shell)
sudo -E ./2-install-guacamole.sh sudo -E ./2-install-guacamole.sh
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo -e "${LRED}2-install-guacamole.sh FAILED. See ${INSTALL_LOG}${GREY}" 1>&2 echo -e "${LRED}2-install-guacamole.sh FAILED. See ${INSTALL_LOG}${GREY}" 1>&2
@ -791,12 +804,12 @@ else
fi fi
# Add a Guacamole database backup (Mon-Fri 12:00am) into the current user's cron # Add a Guacamole database backup (Mon-Fri 12:00am) into the current user's cron
mv $DOWNLOAD_DIR/backup-guac.sh $DB_BACKUP_DIR mv $DOWNLOAD_DIR/backup-guacamole.sh $DB_BACKUP_DIR
crontab -l >cron_1 crontab -l >cron_1
# Remove any pre-existing entry just in case # Remove any pre-existing entry just in case
sed -i '/# backup guacamole/d' cron_1 sed -i '/# backup guacamole/d' cron_1
# Create the backup job # Create the backup job
echo "0 0 * * 1-5 ${DB_BACKUP_DIR}/backup-guac.sh # backup guacamole" >>cron_1 echo "0 0 * * 1-5 ${DB_BACKUP_DIR}/backup-guacamole.sh # backup guacamole" >>cron_1
# Overwrite the old cron settings and cleanup # Overwrite the old cron settings and cleanup
crontab cron_1 crontab cron_1
rm cron_1 rm cron_1
@ -805,19 +818,19 @@ rm cron_1
# Start optional setup actions ###################################################################################### # Start optional setup actions ######################################################################################
####################################################################################################################### #######################################################################################################################
# Install Nginx reverse proxy front end to Guacamole if option is selected keeping all exported variables from the current shell # Install Nginx reverse proxy front end to Guacamole if option is selected (with all exported variables from this current shell)
if [[ "${INSTALL_NGINX}" = true ]]; then if [[ "${INSTALL_NGINX}" = true ]]; then
sudo -E ./3-install-nginx.sh sudo -E ./3-install-nginx.sh
echo -e "${LGREEN}Nginx install complete\nhttp://${PROXY_SITE} - admin login: guacadmin pass: guacadmin\n${LYELLOW}***Be sure to change the password***${GREY}" echo -e "${LGREEN}Nginx install complete\nhttp://${PROXY_SITE} - admin login: guacadmin pass: guacadmin\n${LYELLOW}***Be sure to change the password***${GREY}"
fi fi
# Apply self signed TLS certificates to Nginx reverse proxy if option is selected keeping all exported variables from the current shell # Apply self signed TLS certificates to Nginx reverse proxy if option is selected (with all exported variables from this current shell)
if [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGN}" = true ]] && [[ "${LETS_ENCRYPT}" != true ]]; then if [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGN}" = true ]] && [[ "${LETS_ENCRYPT}" != true ]]; then
sudo -E ./4a-install-tls-self-signed-nginx.sh ${PROXY_SITE} ${CERT_DAYS} ${DEFAULT_IP} | tee -a ${INSTALL_LOG} # Logged to capture client cert import instructions sudo -E ./4a-install-tls-self-signed-nginx.sh ${PROXY_SITE} ${CERT_DAYS} ${DEFAULT_IP} | tee -a ${INSTALL_LOG} # Logged to capture client cert import instructions
echo -e "${LGREEN}Self signed certificate configured for Nginx \n${LYELLOW}https:${LGREEN}//${PROXY_SITE} - login user/pass: guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***${GREY}" echo -e "${LGREEN}Self signed certificate configured for Nginx \n${LYELLOW}https:${LGREEN}//${PROXY_SITE} - login user/pass: guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***${GREY}"
fi fi
# Apply Let's Encrypt TLS certificates to Nginx reverse proxy if option is selected keeping all exported variables from the current shell # Apply Let's Encrypt TLS certificates to Nginx reverse proxy if option is selected (with all exported variables from this current shell)
if [[ "${INSTALL_NGINX}" = true ]] && [[ "${LETS_ENCRYPT}" = true ]] && [[ "${SELF_SIGN}" != true ]]; then if [[ "${INSTALL_NGINX}" = true ]] && [[ "${LETS_ENCRYPT}" = true ]] && [[ "${SELF_SIGN}" != true ]]; then
sudo -E ./4b-install-tls-letsencrypt-nginx.sh sudo -E ./4b-install-tls-letsencrypt-nginx.sh
echo -e "${LGREEN}Let's Encrypt TLS configured for Nginx \n${LYELLOW}https:${LGREEN}//${LE_DNS_NAME} - login user/pass: guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***${GREY}" echo -e "${LGREEN}Let's Encrypt TLS configured for Nginx \n${LYELLOW}https:${LGREEN}//${LE_DNS_NAME} - login user/pass: guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***${GREY}"
@ -839,7 +852,7 @@ fi
# Tidy up # Tidy up
echo echo
echo -e "${GREY}Removing build-essential packages..." echo -e "${GREY}Removing build-essential package & cleaning up..."
mv $USER_HOME_DIR/1-setup.sh $DOWNLOAD_DIR mv $USER_HOME_DIR/1-setup.sh $DOWNLOAD_DIR
sudo apt remove -y build-essential &>>${INSTALL_LOG} # Lets not leave build resources installed on a secure system sudo apt remove -y build-essential &>>${INSTALL_LOG} # Lets not leave build resources installed on a secure system
sudo apt-get -y autoremove &>>${INSTALL_LOG} sudo apt-get -y autoremove &>>${INSTALL_LOG}

View file

@ -98,9 +98,9 @@ spinner() {
printf " " printf " "
tput rc tput rc
} }
apt-get -qq -y install ${MYSQLPKG} ${TOMCAT_VERSION} ${JPEGTURBO} ${LIBPNG} ufw pwgen expect \ apt-get -qq -y install ${MYSQLPKG} ${TOMCAT_VERSION} ${JPEGTURBO} ${LIBPNG} ${FREERDP} ufw pwgen expect \
build-essential libcairo2-dev libtool-bin uuid-dev libavcodec-dev libavformat-dev libavutil-dev \ 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 \ libswscale-dev libpango1.0-dev libssh2-1-dev libtelnet-dev libvncserver-dev libwebsockets-dev \
libpulse-dev libssl-dev libvorbis-dev libwebp-dev ghostscript &>>${INSTALL_LOG} & libpulse-dev libssl-dev libvorbis-dev libwebp-dev ghostscript &>>${INSTALL_LOG} &
command_pid=$! command_pid=$!
spinner $command_pid spinner $command_pid
@ -268,19 +268,31 @@ rm -rf /etc/guacamole/extensions/
mkdir -p /etc/guacamole/lib/ mkdir -p /etc/guacamole/lib/
mkdir -p /etc/guacamole/extensions/ mkdir -p /etc/guacamole/extensions/
# Setup freerdp profile permissions for storing certificates # Create a custom guacd service account and heavily lock it down
mkdir -p /usr/sbin/.config/freerdp adduser "${GUACD_ACCOUNT}" --disabled-password --disabled-login --gecos "" > /dev/null 2>&1
chown daemon:daemon /usr/sbin/.config/freerdp gpasswd -d "${GUACD_ACCOUNT}" users > /dev/null 2>&1
echo -e "\nMatch User ${GUACD_ACCOUNT}\n X11Forwarding no\n AllowTcpForwarding no\n PermitTTY no\n ForceCommand cvs server" | sudo tee -a /etc/ssh/sshd_config > /dev/null 2>&1
systemctl restart ssh
touch "${CRON_DENY_FILE}"
chmod 644 "${CRON_DENY_FILE}"
chown root:root "${CRON_DENY_FILE}"
if ! grep -q "^${GUACD_ACCOUNT}$" "${CRON_DENY_FILE}"; then
echo "$GUACD_ACCOUNT" | sudo tee -a "$CRON_DENY_FILE" > /dev/null 2>&1
fi
# Setup correct permissions for history recorded storage feature # Setup freerdp profile permissions for storing certificates
mkdir -p /home/"${GUACD_ACCOUNT}"/.config/freerdp
chown ${GUACD_ACCOUNT}:${GUACD_ACCOUNT} /home/"${GUACD_ACCOUNT}"/.config/freerdp
# Setup guacamole permissions
mkdir -p /var/guacamole mkdir -p /var/guacamole
chown daemon:daemon /var/guacamole chown "${GUACD_ACCOUNT}":"${GUACD_ACCOUNT}" /var/guacamole
# Make and install guacd (Guacamole-Server) # Make and install guacd (Guacamole-Server)
cd guacamole-server-${GUAC_VERSION}/
echo echo
echo -e "${GREY}Compiling Guacamole-Server from source with with GCC $(gcc --version | head -n1 | grep -oP '\)\K.*' | awk '{print $1}'), this might take a few minutes...${GREY}" echo -e "${GREY}Compiling Guacamole-Server from source with with GCC $(gcc --version | head -n1 | grep -oP '\)\K.*' | awk '{print $1}'), this might take a few minutes...${GREY}"
cd guacamole-server-${GUAC_VERSION}/
# Skip any deprecated software warnings various distros may throw during build # Skip any deprecated software warnings various distros may throw during build
export CFLAGS="-Wno-error" export CFLAGS="-Wno-error"
@ -487,7 +499,7 @@ if [[ "${INSTALL_HISTREC}" = true ]]; then
chmod 664 /etc/guacamole/extensions/guacamole-history-recording-storage-${GUAC_VERSION}.jar chmod 664 /etc/guacamole/extensions/guacamole-history-recording-storage-${GUAC_VERSION}.jar
#Setup the default recording path #Setup the default recording path
mkdir -p ${HISTREC_PATH} mkdir -p ${HISTREC_PATH}
chown daemon:tomcat ${HISTREC_PATH} chown ${GUACD_ACCOUNT}:tomcat ${HISTREC_PATH}
chmod 2750 ${HISTREC_PATH} chmod 2750 ${HISTREC_PATH}
echo "recording-search-path: ${HISTREC_PATH}" >>/etc/guacamole/guacamole.properties echo "recording-search-path: ${HISTREC_PATH}" >>/etc/guacamole/guacamole.properties
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
@ -690,6 +702,9 @@ fi
# Ensure guacd is started # Ensure guacd is started
echo -e "${GREY}Starting guacd service & enable at boot..." echo -e "${GREY}Starting guacd service & enable at boot..."
# Update the systemd unit file the default daemon to the chosen service account
sudo sed -i "s/\bdaemon\b/${GUACD_ACCOUNT}/g" /etc/systemd/system/guacd.service
systemctl daemon-reload
systemctl enable guacd systemctl enable guacd
systemctl stop guacd 2>/dev/null systemctl stop guacd 2>/dev/null
systemctl start guacd systemctl start guacd

View file

@ -98,7 +98,7 @@ ln -s /etc/nginx/sites-available/$PROXY_SITE /etc/nginx/sites-enabled/
# Make sure the default Nginx site is unlinked # Make sure the default Nginx site is unlinked
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 FORMATTING!
echo -e "${GREY}Configuring Apache Tomcat valve for pass through of client IPs to Guacamole logs...${GREY}" echo -e "${GREY}Configuring Apache Tomcat valve for pass through of client IPs to Guacamole logs...${GREY}"
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 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
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then

View file

@ -95,7 +95,7 @@ sudo $USER_HOME_DIR/guac-setup/add-ldap-auth-guacamole.sh
- If not using the **mysql-auto-create-accounts** directive, manually re-create the exact user account names in Guacamole as those in the directory that you wish to give specific local adminstrative permissions and/or provision Guacamole's MFA access. **DO NOT configure a Guacamole password for any users that will be exclusively authenticating via Active directory**. Guacamole database local user accounts without a password are first given an MFA challenge by the local Guacamole application (Only where the local passwordless Guacamole account is configured for MFA) and then will be brokered to Active Directory for their Kerberos authentication challenge. Guacamole database local user accounts that are given passwords in Guacamole will always refer to the local database account for authentication, never Active Directory. This design allows for a matrix of local, domain, MFA & non-MFA access use cases to be deployed. - If not using the **mysql-auto-create-accounts** directive, manually re-create the exact user account names in Guacamole as those in the directory that you wish to give specific local adminstrative permissions and/or provision Guacamole's MFA access. **DO NOT configure a Guacamole password for any users that will be exclusively authenticating via Active directory**. Guacamole database local user accounts without a password are first given an MFA challenge by the local Guacamole application (Only where the local passwordless Guacamole account is configured for MFA) and then will be brokered to Active Directory for their Kerberos authentication challenge. Guacamole database local user accounts that are given passwords in Guacamole will always refer to the local database account for authentication, never Active Directory. This design allows for a matrix of local, domain, MFA & non-MFA access use cases to be deployed.
### :key: **Logging using Gucamole local vs. domain guacbind-ad account** ### :key: **Logging in using Gucamole local vs. domain guacbind-ad account**
- As described above, logging on with the Guacamole admin user password will authenticate with the local Guacamole admin account, conversely if the Guacamole admin domain account password is given, the domain account is authenticated via Active Directory and then passed through as authorized to administer Guacamole. It may sometimes be necessary to log on with the local Guacamole admin account to manage some application functions, but be aware that when doing so you will not be able to view and search the user list from Active Directory. Only when logged on with the domain version of the Guacamole admin account can domain user permissions to various Guacamole sessions and objects be delegated and managed. - As described above, logging on with the Guacamole admin user password will authenticate with the local Guacamole admin account, conversely if the Guacamole admin domain account password is given, the domain account is authenticated via Active Directory and then passed through as authorized to administer Guacamole. It may sometimes be necessary to log on with the local Guacamole admin account to manage some application functions, but be aware that when doing so you will not be able to view and search the user list from Active Directory. Only when logged on with the domain version of the Guacamole admin account can domain user permissions to various Guacamole sessions and objects be delegated and managed.

139
README.md
View file

@ -1,4 +1,14 @@
# 🥑 Easy Guacamole Installer & Jump-Host Builder <div align="center">
![GitHub release version](https://img.shields.io/github/v/release/itiligent/Easy-Guacamole-Installer?style=flat-square&color=orange&labelColor=black)
![GitHub stars](https://img.shields.io/github/stars/itiligent/Easy-Guacamole-Installer?style=flat-square&color=yellow&labelColor=black)
![GitHub forks](https://img.shields.io/github/forks/itiligent/Easy-Guacamole-Installer?style=flat-square&color=blue&labelColor=black)
# 🥑 Easy Guacamole Installer
</div>
<p align="center"> <p align="center">
<a href="https://www.paypal.com/donate/?business=PSZ878JBJDMB8&amount=10&no_recurring=0&item_name=Thankyou+for+your+support+in+maintaining+this+project&currency_code=AUD"> <a href="https://www.paypal.com/donate/?business=PSZ878JBJDMB8&amount=10&no_recurring=0&item_name=Thankyou+for+your+support+in+maintaining+this+project&currency_code=AUD">
@ -6,101 +16,116 @@
</a> </a>
</p> </p>
This suite of build and management scripts makes setting up a secure Guacamole jump server a breeze. It supports TLS reverse proxy (self-signed or Let's Encrypt), Active Directory integration, multi-factor authentication, Quick Connect & History Recording Storage UI enhancements, a custom UI theme creation template (with dark mode as default), auto database backup, O365 email alerts, internal security hardening options, and a fail2ban policy for defense against brute force attacks. The suite also includes code for enterprise deployment similar to [Amazon's Guacamole Bastion Cluster](http://netcubed-ami.s3-website-us-east-1.amazonaws.com/guaws/v2.3.1/cluster/). ## Introduction
#### v1.6.0 is working. Issues and notes are tracked in https://github.com/itiligent/Easy-Guacamole-Installer/issues/78
This install script automatically sets up a Guacamole jump-host with optional for TLS reverse proxy (self-signed or Let's Encrypt), Active Directory integration, multi-factor authentication, Quick Connect & History Recording Storage UI enhancements. Other options also include a custom UI dark themed template, auto database backups, email alerts and internal hardening options including fail2ban for defence against brute force attacks. There is also facility for enterprise deployment similar to [Amazon's Guacamole Bastion Cluster](http://netcubed-ami.s3-website-us-east-1.amazonaws.com/guaws/v2.3.1/cluster/).
## Automatic Installation ## Automatic Installation
🚀 To start building your Guacamole appliance, paste the below link into a terminal & follow the prompts (**A secure build requires you do NOT run this script as sudo or root, but the script will prompt for sudo**): 🚀 Move to you your home directory, paste the below link, then follow the prompts (**do NOT run as root, the script will prompt for sudo**):
```shell ```shell
wget https://raw.githubusercontent.com/itiligent/Guacamole-Install/main/1-setup.sh && chmod +x 1-setup.sh && ./1-setup.sh wget https://raw.githubusercontent.com/itiligent/Guacamole-Install/main/1-setup.sh && chmod +x 1-setup.sh && ./1-setup.sh
``` ```
---
## Prerequisites ## Prerequisites
🔒 **Before diving in, make sure you have:** 📋 **You will need:**
- **Supported OS: Debian 12 or 13** | **Ubuntu LTS 22.x or 24.x** | **Raspbian**
- **A compatible OS (with sudo & wget packages installed):** - **1 CPU core + 2GB RAM for every 25 users (plus minimum RAM & disk space for your selected OS).**
- **Debian: 12.x, 11.x, 10.x**
- **Ubuntu LTS variants: 24.04, 23.04, 22.04, 20.04**
- **Raspbian Buster or Bullseye**
- **Official vendor cloud images equivalent to the above versions.**
- (if your cloud image uses an IP of 127.0.1.1, [see here to use TLS with Nginx](https://github.com/itiligent/Guacamole-Install/issues/21))
- **1 CPU core + 2GB RAM for every 25 users (plus minimum RAM & disk space for your selected OS).**
- **Open TCP ports: 22, 80, and 443 (no other services using 80, 8080 & 443)** - **Open TCP ports: 22, 80, and 443 (no other services using 80, 8080 & 443)**
- **If selecting either of the TLS reverse proxy options, you must create an internal DNS record for the internal proxy site, and an additional public DNS record if selecting the Let's Encrypt option.** - **For both TLS reverse proxy options you will need a PRIVATE DNS record for the internal proxy site, and an additional PUBLIC DNS record for the Let's Encrypt option.**
- **Sudo package installed** - **Sudo & wget packages installed**
- **The username running the 1-setup.sh script must have sudo permissions** - **The user running `1-setup.sh` must have sudo permissions.**
---
## Setup Script Menu ## Setup Script Menu
🔧 **The main 1-setup.sh script guides you through the installation options in the following steps:** 🔧 **The main `1-setup.sh` script guides the installation with the following steps:**
1. Sets up the system hostname and local DNS name (Local DNS must be consistent for TLS proxy). 1. Setup the system hostname & local DNS name (Local DNS must be consistent for TLS proxy).
2. Select either a local MySQL install or use a pre-existing local or remote MySQL instance. 2. Select either a local MySQL install or use a pre-existing local or remote MySQL instance.
3. Pick your authentication extension: DUO, TOTP, LDAP/Active Directory, or none. 3. Pick an authentication extension: DUO, TOTP, LDAP/Active Directory, or none.
4. Select optional console features: Quick Connect & History Recorded Storage UI integrations. 4. Select optional console features: Quick Connect & History Recorded Storage UI integrations.
5. Decide on the Guacamole front end: Nginx reverse proxy (HTTP or HTTPS) or use only the native Guacamole interface on port 8080. 5. Select the Guacamole front end: Nginx reverse proxy (HTTP or HTTPS) or use the native Guacamole interface on port 8080.
- If you opt to install Nginx with self-signed TLS: - If you opt to install Nginx with self-signed TLS:
- New server and client browser certificates are saved to `$HOME/guac-setup/tls-certs/[date-time]`. - New server & client browser certificates are saved to `$HOME/guac-setup/tls-certs/[date-time]/`.
- Optionally follow on-screen instructions for client certificate import to avoid https browser warnings. - Optionally follow on-screen instructions for client certificate import to avoid https browser warnings.
## Custom Installation Instructions ---
⚙️ **If you want to customize the available script options:** ## Customising The Build
- Exit `1-setup.sh` at the first prompt (Typically this will have been download to `$HOME/guac-setup`). ⚙️ **To customise the many available script options:**
- All configurable script options are noted at the start of `1-setup.sh` under **Silent setup options**. Re-run the edited setup script (locally, not from the web link) after making your changes.
- Certain combinations of the **Silent setup options** allow for a fully unattended install (making mass deployment or build of a customized docker containers much simpler).
**Other useful custom install notes:** - Exit `1-setup.sh` at the first prompt.
- **Caution:** Re-running the auto-installer re-downloads the suite of scripts and this will overwrite your script edits. Run setup locally after editing the setup script. If any other scripts are edited, their corresponding download links in the setup script must also be commented out in the main setup script. - All configurable script options are shown under **Silent setup options** at the start of `1-setup.sh`.
- Many scripts are **automatically adjusted with your chosen installation settings at 1st install** to create a matched set that allows for application upgrades or extra feature additions in future without fiddly configuration tasks. - Certain combinations of the **Silent setup options** will allow for a fully unattended install supporting mass deployment or highly customised docker builds.
- Nginx reverse proxy is configured to default to at least TLS 1.2. To revert, see commented sections of the `/etc/nginx/nginx.conf` file after install. - Re-run your edited script locally after making changes (do not re-run the automatic install web link - see below).
**Other custom install notes:**
- **Caution:** Re-running the auto-installer link re-downloads the suite of scripts which will overwrite any custom script edits. You must run 1-setup.sh LOCALLY after editing. If any child scripts are edited, their corresponding download links in 1-setup.sh script must also be commented out.
- Upgrade scripts are **automatically customised with your specifc installation settings** for consistent future updates.
- Nginx reverse proxy is configured to default to at least TLS 1.2. For ancient systems, see commented sections of the `/etc/nginx/nginx.conf` file after install.
- A daily MySQL backup job is automatically configured under the script owner's crontab. - A daily MySQL backup job is automatically configured under the script owner's crontab.
- **Security note:** The Quick Connect option brings some extra security implications, be aware of potential risks in your environment. - The Quick Connect option brings some extra security implications, be aware of potential risks in your environment.
**Post-install hardening script options available:** **Post-install manual hardening options:**
- `add-fail2ban.sh`: Adds a lockdown policy for Guacamole to guard against brute force password attacks. - `add-fail2ban.sh`: Adds a lockdown policy for Guacamole to guard against brute force password attacks.
- `add-tls-guac-daemon.sh`: Wraps internal traffic between the guac server & guac application in TLS. - `add-tls-guac-daemon.sh`: Wraps internal traffic between the guac server & guac application in TLS.
- `add-auth-ldap.sh`: Template script for simplified Active Directory SSO integration. - `add-auth-ldap.sh`: Template script for simplified Active Directory integration.
- `add-smtp-relay-o365.sh`: Template script for email alert integration with MSO65 (BYO app password). - `add-smtp-relay-o365.sh`: Template script for email alert integration with MSO65 (BYO app password).
## Customise & Brand Your Guacamole Theme ---
🎨 **Want to give Guacamole your own personal touch? Follow the theme and branding instructions** [here](https://github.com/itiligent/Guacamole-Install/tree/main/guac-custom-theme-builder). To revert to the default theme, after install simply delete the branding.jar file from `/etc/guacamole/extensions`, clear your browser cache, and run: ## Branding The Guacamole UI Theme
```shell 🎨 **Follow the theme and branding instructions** [here](https://github.com/itiligent/Guacamole-Install/tree/main/guac-custom-theme-builder). To revert to the default theme, simply delete the branding.jar file from `/etc/guacamole/extensions`, clear your browser cache and restart.
TOMCAT=$(ls /etc/ | grep tomcat) && sudo systemctl restart ${TOMCAT} && sudo systemctl restart guacd && sudo systemctl restart nginx
```
## Managing Self-Signed TLS Certs with Nginx (the Easy Way!) ---
## Managing Self-Signed TLS Certs With Nginx
**To renew self-signed certificates or change the reverse proxy local DNS name/IP address:** **To renew self-signed certificates or change the reverse proxy local DNS name/IP address:**
- Re-run `4a-install-tls-self-signed-nginx.sh` to create a new certificate for Nginx (accompanying browser client certificates will also be updated). Refer to the script's comments for further command line options and always clear your browser cache after changing certificates. - Re-run `4a-install-tls-self-signed-nginx.sh` to create a new Nginx certificate (new browser client certificates will also be created for re-import). Always clear your browser cache after changing certificates.
## Active Directory SSO Integration ---
🔑 **Need help with Active Directory integration & SSO authentication?** Check [here](https://github.com/itiligent/Guacamole-Install/blob/main/ACTIVE-DIRECTORY-HOW-TO.md). ## Active Directory Integration
🔑 See [here](https://github.com/itiligent/Guacamole-Install/blob/main/ACTIVE-DIRECTORY-HOW-TO.md).
---
## SS0 Extensions (Radius, Base, CAS, OpenID, SAML, Dist)
🔑 See [here](https://github.com/itiligent/Guacamole-Installer/blob/main/SSO-EXTENSIONS-HOW-TO.md)
---
## Upgrading Guacamole ## Upgrading Guacamole
🌐 **To upgrade Guacamole, edit `upgrade-guac.sh` to reflect the latest versions of Guacamole & MySQL connector/J before running.** This script will also automatically update TOTP, DUO, LDAP, Quick Connect, and History Recorded Storage extensions if present. 🌐 To upgrade Guacamole, edit `upgrade-guacamole.sh` to reflect the latest versions of Guacamole & MySQL connector/J before running. This script will automatically update TOTP, DUO, LDAP, Quick Connect, and History Recorded Storage extensions if present.
---
## High Availability Deployment ## High Availability Deployment
👔 **Did you know that Guacamole can run in a load-balanced high availability farm with layered physical/virtual separation between front end, application, and database layers?** - 👔 **For a separate DATABASE layer:** Use the `install-mysql-backend-only.sh` [here](https://github.com/itiligent/Guacamole-Install/tree/main/guac-enterprise-build) to install a standalone instance of the Guacamole MySQL database.
- 👔 **For a separate APPLICATION layer:** Run `1-setup.sh` and point new installations to your separate database instance. Just say **no** to the "Install MySQL locally" option and any other local reverse proxy install options.
- 👔 **For a separate FRONT END layer:** Use the included Nginx installer scripts to build out a separate Nginx front end layer, and then apply your preferred TLS load balancing technique. Alternatively, AWS/Azure/GCP load balancers or [HA Proxy](https://www.haproxy.org/) may provide superior session persistence & affinity compared to [Open Source Nginx](https://www.nginx.com/products/nginx/compare-models/).
- **For a separate DATABASE layer:** Use the `install-mysql-backend-only.sh` [here](https://github.com/itiligent/Guacamole-Install/tree/main/guac-enterprise-build) to install a standalone instance of the Guacamole MySQL database. ---
- **For a separate APPLICATION layer:** Run the main installer to point new installations to your separate/remote backend database. Say **no** to the "Install MySQL locally" option and any other local reverse proxy install options.
- **For a separate WEB layer:** Use the included Nginx installer scripts to build the basis of a separate TLS front end layer, and apply your preferred Nginx load balancing technique. Note that there are too many load balancing strategies to list here, but as an example [HA Proxy](https://www.haproxy.org/) generally provides superior session persistence/affinity under load-balanced conditions [compared to Open Source Nginx](https://www.nginx.com/products/nginx/compare-models/).
### Installer Script Download Manifest ### Script Download Manifest
📦 **The autorun link downloads these repo files into `$HOME/guac-setup`:** 📦 **The autorun link downloads these files into `$HOME/guac-setup`:**
- `1-setup.sh`: The parent main installation script. - `1-setup.sh`: The parent setup script.
- `2-install-guacamole.sh`: Guacamole source build & installer script. - `2-install-guacamole.sh`: Guacamole source build & installer script.
- `3-install-nginx.sh`: Nginx installation script. - `3-install-nginx.sh`: Nginx installation script.
- `4a-install-tls-self-signed-nginx.sh`: Install/refresh self-signed TLS certificates script. - `4a-install-tls-self-signed-nginx.sh`: Install/refresh self-signed TLS certificates script.
@ -111,11 +136,21 @@ TOMCAT=$(ls /etc/ | grep tomcat) && sudo systemctl restart ${TOMCAT} && sudo sys
- `add-xtra-quickconnect.sh`: Quick Connect console extension installer script. - `add-xtra-quickconnect.sh`: Quick Connect console extension installer script.
- `add-xtra-histrecstore.sh`: History Recorded Storage extension installer script. - `add-xtra-histrecstore.sh`: History Recorded Storage extension installer script.
- `add-smtp-relay-o365.sh`: Script for O365 SMTP auth relay setup (BYO app password). - `add-smtp-relay-o365.sh`: Script for O365 SMTP auth relay setup (BYO app password).
- `add-tls-guac-daemon.sh`: Wraps internal traffic between guacd server & Guacamole web app in TLS. - `add-tls-guac-daemon.sh`: Wrap internal traffic between guacd server & Guacamole web app in TLS.
- `add-fail2ban.sh`: Fail2ban (& Guacamole protection policy) installer script. - `add-fail2ban.sh`: Fail2ban (& Guacamole protection policy) installer script.
- `backup-guacamole.sh`: MySQL backup setup script. - `backup-guacamole.sh`: MySQL backup setup script.
- `upgrade-guac.sh`: Guacamole application, extension, and MySQL connector upgrade script. - `upgrade-guacamole.sh`: Guacamole application, extension, and MySQL connector upgrade script.
- `branding.jar`: Base template for customizing Guacamole's UI theme. - `branding.jar`: Base template for customizing Guacamole's UI theme.
😄🥑 😄🥑
```

74
SSO-EXTENSIONS-HOW-TO.md Normal file
View file

@ -0,0 +1,74 @@
### How to build all Guacamole client extensions:
Licensing prevents some extensions being supplied in binary form, therefore these must be built from source. To achieve this, follow the exact order below on a fresh Linux system **WITHOUT JVM INSTALLED**.
#### 1. Obtain the specific JDK dependency
Download jdk-8u411-linux-x64.tar.gz from [Oracle](https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html) (needs an Oracle sign in, select the Linux x64 compressed archive and copy it to your Linux home dir) A backup of this file is achived [here]( https://1drv.ms/u/s!Asccp3ag4RnQj-dAGYyfqwf-Rf5mTg?e=uRy1DM).
### 2. Install the JDK
```
sudo mkdir -p /usr/lib/jvm
sudo tar zxvf jdk-8u411-linux-x64.tar.gz -C /usr/lib/jvm
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_411/bin/java" 1
sudo update-alternatives --set java /usr/lib/jvm/jdk1.8.0_411/bin/java
```
### 3. Clone Guacamole client source
```sudo apt update && sudo apt -y install git
git clone https://github.com/apache/guacamole-client.git
cd guacamole-client
git checkout 1.5.5 # or whatever version
```
### 4. Install Maven and build all the client binaries (with Radius support)
```
sudo apt -y install maven
mvn clean package -Plgpl-extensions
```
Build output should show:
```
[INFO] Reactor Summary for guacamole-client 1.5.5:
[INFO] guacamole-client ................................... SUCCESS [ 18.363 s]
[INFO] guacamole-common ................................... SUCCESS [ 10.902 s]
[INFO] guacamole-ext ...................................... SUCCESS [ 6.032 s]
[INFO] guacamole-common-js ................................ SUCCESS [ 14.552 s]
[INFO] guacamole .......................................... SUCCESS [01:04 min]
[INFO] extensions ......................................... SUCCESS [ 0.132 s]
[INFO] guacamole-auth-duo ................................. SUCCESS [ 5.207 s]
[INFO] guacamole-auth-header .............................. SUCCESS [ 0.793 s]
[INFO] guacamole-auth-jdbc ................................ SUCCESS [ 0.143 s]
[INFO] guacamole-auth-jdbc-base ........................... SUCCESS [ 3.314 s]
[INFO] guacamole-auth-jdbc-mysql .......................... SUCCESS [ 1.208 s]
[INFO] guacamole-auth-jdbc-postgresql ..................... SUCCESS [ 1.008 s]
[INFO] guacamole-auth-jdbc-sqlserver ...................... SUCCESS [ 1.004 s]
[INFO] guacamole-auth-jdbc-dist ........................... SUCCESS [ 1.072 s]
[INFO] guacamole-auth-json ................................ SUCCESS [ 2.648 s]
[INFO] guacamole-auth-ldap ................................ SUCCESS [ 8.882 s]
[INFO] guacamole-auth-quickconnect ........................ SUCCESS [ 1.704 s]
[INFO] guacamole-auth-sso ................................. SUCCESS [ 0.132 s]
[INFO] guacamole-auth-sso-base ............................ SUCCESS [ 0.667 s]
[INFO] guacamole-auth-sso-cas ............................. SUCCESS [ 5.205 s]
[INFO] guacamole-auth-sso-openid .......................... SUCCESS [ 1.237 s]
[INFO] guacamole-auth-sso-saml ............................ SUCCESS [ 3.801 s]
[INFO] guacamole-auth-sso-dist ............................ SUCCESS [ 1.312 s]
[INFO] guacamole-auth-totp ................................ SUCCESS [ 2.780 s]
[INFO] guacamole-history-recording-storage ................ SUCCESS [ 0.646 s]
[INFO] guacamole-vault .................................... SUCCESS [ 0.117 s]
[INFO] guacamole-vault-base ............................... SUCCESS [ 1.005 s]
[INFO] guacamole-vault-ksm ................................ SUCCESS [ 5.242 s]
[INFO] guacamole-vault-dist ............................... SUCCESS [ 1.050 s]
[INFO] guacamole-auth-radius .............................. SUCCESS [ 11.777 s]
[INFO] guacamole-example .................................. SUCCESS [ 2.080 s]
[INFO] guacamole-playback-example ......................... SUCCESS [ 0.883 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:59 min
[INFO] Finished at: 2024-10-29T11:38:19+11:00
[INFO] ------------------------------------------------------------------------
```
### 5 Move your new extension to the Guacamole server
1. As sudo, copy the new `extension.jar` file (found in `guacamole-client/extensions/guacamole-auth-radius/target/`) to `/etc/guacamole/extensions` on your Guacamole server.
2. Adjust permissions on the new `extension.jar` file with `sudo chmod 664 /etc/guacamole/extensions/extension.jar`
3. Restart and continue configuring the new extension as per the Guacmole official documentation [here](https://guacamole.apache.org/doc/gug/).

View file

@ -15,8 +15,17 @@ sudo systemctl restart guacd && sudo systemctl restart ${TOMCAT}
## Theme customisation hints: ## ## Theme customisation hints: ##
- Do not change any of the theme's directory structure or file names. File contents can be carefully edited according to the following constraints: - Do not change any of the theme's directory structure or file names. File contents can be carefully edited according to the following constraints:
- `MANIFEST.MF`: All values in here can be updated. Be aware that the "Name:" value MUST use same value in front of the the .jar creation command shown above in the 1st line e.g. `Name: branding` expects branding.jar - `META-INF/MANIFEST.MF`: All values in here can be updated, **BUT** be aware that `Name: branding` is linked to the commands above e.g. `Name: branding` expects `branding.jar` as the .jar filename
- `guac-manifest.json`: The "name:" value in here can be changed to anything. The "namespace:" value given in this file MUST match the namespace image path line found in `custom-theme.css`, eg.`background-image: url('app/ext/custom-namespace/images/logo.png');` - `guac-manifest.json`: The "name:" value in here can be changed to anything **BUT** the `"namespace" : "custom-namespace"` value MUST match the namespace image path line found in `custom-theme.css`, eg:
```
.login-ui .login-dialog .logo {
background-image: url('app/ext/custom-namespace/images/logo.png');
width: 7em;
height: 7em;
-webkit-background-size: 7em auto;
}
```
- It is preferable to give css a range of logo sizes as shown in the template. The "smallIcon" value in `guac-manifest.json` is used for browser tab favicons. As such this file can be kept to < 80x80 pixels. The example used is 64x64 pixels. - It is preferable to give css a range of logo sizes as shown in the template. The "smallIcon" value in `guac-manifest.json` is used for browser tab favicons. As such this file can be kept to < 80x80 pixels. The example used is 64x64 pixels.
- Within `custom-theme.css`, you may need to experiment with the the height and width values under `.login-ui .login-dialog .logo` to scale your particular logo neatly within the dialog box. Another option is to make the login dialog box larger. Under `.login-ui .login-dialog`, experiment with adding a `max-width: 4in;` or similar. There's a ton of css options available and this template is just starting point, Google is your friend! - Within `custom-theme.css`, you may need to experiment with the the height and width values under `.login-ui .login-dialog .logo` to scale your particular logo neatly within the dialog box. Another option is to make the login dialog box larger. Under `.login-ui .login-dialog`, experiment with adding a `max-width: 4in;` or similar. There's a ton of css options available and this template is just starting point, Google is your friend!
- An easy way to debug and preview potential style changes is to tweak various values by setting your browser to developer mode. - An easy way to debug and preview potential style changes is to tweak various values by setting your browser to developer mode.

View file

@ -94,4 +94,32 @@ slowhttptest -c 10000 -H -g -o ./output_file -i 3 -r 500 -t GET -u http://jumpbo
##################################################### #####################################################
Allow local browser microphone redirect without TLS Allow local browser microphone redirect without TLS
##################################################### #####################################################
chrome://flags/#unsafely-treat-insecure-origin-as-secure chrome://flags/#unsafely-treat-insecure-origin-as-secure
#####################################################
Build Custom Console
####################################################
# clone and edit source
sudo apt update && sudo apt install git
git clone https://github.com/apache/guacamole-client.git
Wdit the en.json file to the values you need
# Install Older Java 8 prerequisites
https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html (needs oracle sign in)
sudo mkdir -p /usr/lib/jvm
sudo tar zxvf jdk-8u411-linux-x64.tar.gz -C /usr/lib/jvm
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_411/bin/java" 1
sudo update-alternatives --set java /usr/lib/jvm/jdk1.8.0_411/bin/java
# Install maven to build the new war file
sudo apt install maven
cd ~/guacamole-client
mvn package
new .war file is found in guacamole-client/guacamole/target
# Install the bew .war file into Guacamole
sudo mv -f guacamole-1.5.5.war /etc/guacamole/guacamole.war # copy and rename the new war file
sudo chmod 664 /etc/guacamole/guacamole.war
sudo ln -sf /etc/guacamole/guacamole.war /var/lib/tomcat9/webapps/
sudo systemctl restart tomcat9 && sudo systemctl restart guacd

View file

@ -3,7 +3,7 @@
# Add fail2ban restrictions to Guacamole # Add fail2ban restrictions to Guacamole
# For Ubuntu / Debian / Raspbian # For Ubuntu / Debian / Raspbian
# David Harrop # David Harrop
# April 2023 # December 2024
####################################################################################################################### #######################################################################################################################
# Prepare text output colours # Prepare text output colours
@ -21,6 +21,7 @@ clear
if ! [[ $(id -u) = 0 ]]; then if ! [[ $(id -u) = 0 ]]; then
echo echo
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2 echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
echo
exit 1 exit 1
fi fi
@ -30,12 +31,16 @@ FAIL2BAN_GUAC=""
FAIL2BAN_NGINX="" FAIL2BAN_NGINX=""
FAIL2BAN_SSH="" FAIL2BAN_SSH=""
TOMCAT_VERSION=$(ls /etc/ | grep tomcat) TOMCAT_VERSION=$(ls /etc/ | grep tomcat)
TOMCAT_SERVICE_FILE="/usr/lib/systemd/system/$TOMCAT_VERSION.service"
# Tomcat service file logging lines that must exist
OUTPUT_LINE="StandardOutput=append:/var/log/$TOMCAT_VERSION/catalina.out"
ERROR_LINE="StandardError=append:/var/log/$TOMCAT_VERSION/catalina.out"
#Clean up from any previous runs #Clean up from any previous runs
rm -f /tmp/fail2ban.conf rm -f /tmp/fail2ban.temp1
rm -f /tmp/fail2ban.temp2
rm -f /tmp/ip_list.txt rm -f /tmp/ip_list.txt
rm -f /tmp/netaddr.txt rm -f /tmp/netaddr.txt
rm -f /tmp/fail2ban.update
####################################################################################################################### #######################################################################################################################
# Start setup prompts ################################################################################################# # Start setup prompts #################################################################################################
@ -92,18 +97,23 @@ fi
# Install base fail2ban base application, and whitelist the local subnet as the starting baseline (no policy defined yet) # Install base fail2ban base application, and whitelist the local subnet as the starting baseline (no policy defined yet)
if [[ "${FAIL2BAN_BASE}" = true ]]; then if [[ "${FAIL2BAN_BASE}" = true ]]; then
echo
#Update and install fail2ban (and john for management of config file updates, and not overwrite any existing settings) #Update and install fail2ban (and john for management of config file updates, and not overwrite any existing settings)
apt-get update -qq apt-get update -qq
apt-get install fail2ban john -qq -y apt-get install fail2ban john -qq -y
# Create the basic jail.local template and local subnet whitelist # Create the basic jail.local template local subnet whitelist
cat >/tmp/fail2ban.conf <<EOF echo
cat >/tmp/fail2ban.temp1 <<EOF
[DEFAULT] [DEFAULT]
destemail = yourname@example.com destemail = yourname@example.com
sender = yourname@example.com sender = yourname@example.com
action = %(action_mwl)s action = %(action_mwl)s
ignoreip = ignoreip =
[sshd]
backend = systemd
enabled = true
EOF EOF
# We need to discover all interfaces to ascertain what network ranges to add to fail2ban "ignoreip" policy override defaults # We need to discover all interfaces to ascertain what network ranges to add to fail2ban "ignoreip" policy override defaults
@ -177,26 +187,23 @@ if [[ "${FAIL2BAN_BASE}" = true ]]; then
# Finally assemble the entire syntax of the ignoreip whitelist for insertion into the base fail2ban config # Finally assemble the entire syntax of the ignoreip whitelist for insertion into the base fail2ban config
SED_IGNORE=$(echo "ignoreip = ") SED_IGNORE=$(echo "ignoreip = ")
SED_NETADDR=$(cat /tmp/netaddr.txt) SED_NETADDR=$(cat /tmp/netaddr.txt)
sed -i "s|ignoreip \=|${SED_IGNORE}${SED_NETADDR}|g" /tmp/fail2ban.conf sed -i "s|ignoreip \=|${SED_IGNORE}${SED_NETADDR}|g" /tmp/fail2ban.temp1
# Move the new base fail2ban config to the jail.local file # Move the new base fail2ban config to the jail.local file
touch /etc/fail2ban/jail.local touch /etc/fail2ban/jail.local
# Apply the base config, keeping any pre-existing settings # Apply the base config, keeping any pre-existing settings
sudo bash -c 'cat /tmp/fail2ban.conf /etc/fail2ban/jail.local | unique /tmp/fail2ban.update ; cat /tmp/fail2ban.update > /etc/fail2ban/jail.local' sudo bash -c 'cat /tmp/fail2ban.temp1 > /etc/fail2ban/jail.local'
# Clean up
rm -f /tmp/fail2ban.conf
rm -f /tmp/ip_list.txt
rm -f /tmp/netaddr.txt
rm -f /tmp/fail2ban.update
# bounce the service to reload the new config # bounce the service to reload the new config
systemctl restart fail2ban systemctl restart fail2ban
# Display the new config
echo "New base /etc/fail2ban/jail.local config:"
cat /etc/fail2ban/jail.local
# Done
echo echo
echo -e "${LGREEN}Fail2ban installed...${GREY}" echo -e "${LGREEN}Fail2ban base installed...${GREY}"
echo echo
else else
@ -208,21 +215,22 @@ fi
# Fail2ban optional policy setup items ################################################################################ # Fail2ban optional policy setup items ################################################################################
####################################################################################################################### #######################################################################################################################
if [[ "${FAIL2BAN_GUAC}" = true ]]; then
if [[ "${FAIL2BAN_GUAC}" = true ]]; then
# Create the Guacamole jail.local policy template # Create the Guacamole jail.local policy template
cat >/tmp/fail2ban.conf <<EOF cat >/tmp/fail2ban.temp2 <<EOF
[guacamole] [guacamole]
enabled = true enabled = true
port = http,https port = http,https
logpath = /var/log/$TOMCAT_VERSION/catalina.out logpath = /var/log/$TOMCAT_VERSION/catalina.out
bantime = 15m bantime = 10m
findtime = 60m findtime = 60m
maxretry = 5 maxretry = 5
EOF EOF
# Apply the new Guacamole jail config keeping any pre-existing settings # Apply the new Guacamole jail config
sudo bash -c 'cat /tmp/fail2ban.conf /etc/fail2ban/jail.local | unique /tmp/fail2ban.update ; cat /tmp/fail2ban.update > /etc/fail2ban/jail.local' sudo bash -c 'cat /tmp/fail2ban.temp2 >> /etc/fail2ban/jail.local'
# Backup the default Fail2ban Guacamole filter # Backup the default Fail2ban Guacamole filter
cp /etc/fail2ban/filter.d/guacamole.conf /etc/fail2ban/filter.d/guacamole.conf.bak cp /etc/fail2ban/filter.d/guacamole.conf /etc/fail2ban/filter.d/guacamole.conf.bak
@ -234,20 +242,41 @@ EOF
REGEX='failregex = ^.*WARN o\.a\.g\.r\.auth\.AuthenticationService - Authentication attempt from <HOST> for user "[^"]*" failed\.$' REGEX='failregex = ^.*WARN o\.a\.g\.r\.auth\.AuthenticationService - Authentication attempt from <HOST> for user "[^"]*" failed\.$'
#Insert the new regex #Insert the new regex
sed -i -e "/Authentication attempt from/a ${REGEX}" /etc/fail2ban/filter.d/guacamole.conf sed -i -e "/Authentication attempt from/a ${REGEX}" /etc/fail2ban/filter.d/guacamole.conf
# Done
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 \n \n This script may take a while to complete on first run..."
# Bounce the service to reload the new config
systemctl restart fail2ban
echo
fi fi
# Clean up # Clean up
rm -f /tmp/fail2ban.conf rm -f /tmp/fail2ban.temp1
rm -f /tmp/ip_list.txt rm -f /tmp/fail2ban.temp2
rm -f /tmp/netaddr.txt rm -f /tmp/ip_list.txt
rm -f /tmp/fail2ban.update rm -f /tmp/netaddr.txt
apt-get -y remove john > /dev/null 2>&1
apt-get -y autoremove > /dev/null 2>&1
# Display the updated config
echo "Updated jail.local with Guacamole filter policy:"
cat /etc/fail2ban/jail.local
# make sure Tomcat catalina logs are configured
if [[ ! -f "$TOMCAT_SERVICE_FILE" ]]; then
echo "Error: $TOMCAT_SERVICE_FILE not found, exiting..."
exit 1
else
if grep -q "^$OUTPUT_LINE" "$TOMCAT_SERVICE_FILE" && grep -q "^$ERROR_LINE" "$TOMCAT_SERVICE_FILE"; then
echo "Required lines already exist in $TOMCAT_SERVICE_FILE. No changes made."
else
# Add lines if they don't already exist
sed -i "/^\[Service\]/a $OUTPUT_LINE\n$ERROR_LINE" "$TOMCAT_SERVICE_FILE"
systemctl daemon-reload
systemctl restart fail2ban
systemctl restart guacd
systemctl restart ${TOMCAT_VERSION}
echo "Lines were added successfully to $TOMCAT_SERVICE_FILE."
fi
fi
# Done
echo
echo -e "${LGREEN}Guacamole security policy applied, but NOT YET ENABLED FOR LOCAL NETWORK(S) ${GREY}\n- Local network(s) ${SED_NETADDR}are currently whitelisted from all IP bans.\n- To alter this whitelist, edit /etc/fail2ban/jail.local then sudo systemctl restart fail2ban"
############## Start Fail2ban NGINX security policy option ############### ############## Start Fail2ban NGINX security policy option ###############
#if [[ "${FAIL2BAN_NGINX}" = true ]]; then #if [[ "${FAIL2BAN_NGINX}" = true ]]; then

View file

@ -50,10 +50,10 @@ mkdir -p $DOWNLOAD_DIR
chown -R $SUDO_USER:root $DOWNLOAD_DIR chown -R $SUDO_USER:root $DOWNLOAD_DIR
# Version of Guacamole to upgrade to. See https://guacamole.apache.org/releases/ for latest version info. # Version of Guacamole to upgrade to. See https://guacamole.apache.org/releases/ for latest version info.
NEW_GUAC_VERSION="1.5.5" NEW_GUAC_VERSION="1.6.0"
# MySQL Connector/J version. See https://dev.mysql.com/downloads/connector/j/ for latest version number. # MySQL Connector/J version. See https://dev.mysql.com/downloads/connector/j/ for latest version number.
NEW_MYSQLJCON="8.4.0" NEW_MYSQLJCON="9.3.0"
# Get the currently installed Tomcat version. # Get the currently installed Tomcat version.
TOMCAT_VERSION=$(ls /etc/ | grep tomcat) TOMCAT_VERSION=$(ls /etc/ | grep tomcat)
@ -75,6 +75,10 @@ GUAC_USER=
GUAC_PWD= GUAC_PWD=
GUAC_DB= GUAC_DB=
MYSQL_ROOT_PWD= MYSQL_ROOT_PWD=
RDP_SHARE_HOST=
RDP_SHARE_LABEL=
RDP_PRINTER_LABEL=
GUACD_ACCOUNT=
# Standardise on a distro version identification lexicon # Standardise on a distro version identification lexicon
source /etc/os-release source /etc/os-release
@ -82,7 +86,6 @@ ID=$ID
VERSION_ID=$VERSION_ID VERSION_ID=$VERSION_ID
VERSION_CODENAME=$VERSION_CODENAME VERSION_CODENAME=$VERSION_CODENAME
# Workaround for issue #31 # Workaround for issue #31
if [[ "${ID,,}" = "debian" && "${VERSION_CODENAME,,}" = *"bullseye"* ]] || [[ "${ID,,}" = "ubuntu" && "${VERSION_CODENAME,,}" = *"focal"* ]]; then if [[ "${ID,,}" = "debian" && "${VERSION_CODENAME,,}" = *"bullseye"* ]] || [[ "${ID,,}" = "ubuntu" && "${VERSION_CODENAME,,}" = *"focal"* ]]; then
IFS='.' read -ra guac_version_parts <<< "${GUAC_VERSION}" IFS='.' read -ra guac_version_parts <<< "${GUAC_VERSION}"
@ -98,7 +101,7 @@ fi
# Script branding header # Script branding header
echo echo
echo -e "${GREYB}Guacamole Appliance Auto Upgrade Script." echo -e "${GREYB}Guacamole Appliance Auto Upgrade Script"
echo -e " ${LGREEN}Powered by Itiligent" echo -e " ${LGREEN}Powered by Itiligent"
echo echo
@ -168,6 +171,11 @@ else
fi fi
echo -e "${LGREEN}Downloaded guacamole-server-${NEW_GUAC_VERSION}.tar.gz${GREY}" echo -e "${LGREEN}Downloaded guacamole-server-${NEW_GUAC_VERSION}.tar.gz${GREY}"
# Add customised RDP share names and printer labels, remove Guacamole default labelling
sed -i -e 's/IDX_CLIENT_NAME, "Guacamole RDP"/IDX_CLIENT_NAME, "'"${RDP_SHARE_HOST}"'"/' ${DOWNLOAD_DIR}/guacamole-server-${NEW_GUAC_VERSION}/src/protocols/rdp/settings.c
sed -i -e 's/IDX_DRIVE_NAME, "Guacamole Filesystem"/IDX_DRIVE_NAME, "'"${RDP_SHARE_LABEL}"'"/' ${DOWNLOAD_DIR}/guacamole-server-${NEW_GUAC_VERSION}/src/protocols/rdp/settings.c
sed -i -e 's/IDX_PRINTER_NAME, "Guacamole Printer"/IDX_PRINTER_NAME, "'"${RDP_PRINTER_LABEL}"'"/' ${DOWNLOAD_DIR}/guacamole-server-${NEW_GUAC_VERSION}/src/protocols/rdp/settings.c
# Make and install guacd (Guacamole-Server) # Make and install guacd (Guacamole-Server)
cd guacamole-server-${NEW_GUAC_VERSION}/ cd guacamole-server-${NEW_GUAC_VERSION}/
echo echo
@ -223,7 +231,12 @@ if [[ "${INSTALL_MYSQL}" = true ]]; then
FILEVERSION=$(echo ${FILE} | grep -oP 'upgrade-pre-\K[0-9\.]+(?=\.)') FILEVERSION=$(echo ${FILE} | grep -oP 'upgrade-pre-\K[0-9\.]+(?=\.)')
if [[ $(echo -e "${FILEVERSION}\n${OLD_GUAC_VERSION}" | sort -V | head -n1) == ${OLD_GUAC_VERSION} && ${FILEVERSION} != ${OLD_GUAC_VERSION} ]]; then if [[ $(echo -e "${FILEVERSION}\n${OLD_GUAC_VERSION}" | sort -V | head -n1) == ${OLD_GUAC_VERSION} && ${FILEVERSION} != ${OLD_GUAC_VERSION} ]]; then
echo "Patching ${GUAC_DB} with ${FILE}" echo "Patching ${GUAC_DB} with ${FILE}"
mysql -u root -D ${GUAC_DB} -h ${MYSQL_HOST} -P ${MYSQL_PORT} <guacamole-auth-jdbc-${NEW_GUAC_VERSION}/mysql/schema/upgrade/${FILE} &>>${INSTALL_LOG}
if [[ ! -z "$MYSQL_ROOT_PWD" ]]; then
mysql -u root -p${MYSQL_ROOT_PWD} -D ${GUAC_DB} -h ${MYSQL_HOST} -P ${MYSQL_PORT} <guacamole-auth-jdbc-${NEW_GUAC_VERSION}/mysql/schema/upgrade/${FILE} &>>${INSTALL_LOG}
else
mysql -u root -D ${GUAC_DB} -h ${MYSQL_HOST} -P ${MYSQL_PORT} <guacamole-auth-jdbc-${NEW_GUAC_VERSION}/mysql/schema/upgrade/${FILE} &>>${INSTALL_LOG}
fi
fi fi
done done
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
@ -335,16 +348,20 @@ for file in /etc/guacamole/extensions/guacamole-history-recording-storage*.jar;
fi fi
done done
# Setup freerdp profile permissions for storing certificates
mkdir -p /usr/sbin/.config/freerdp
chown daemon:daemon /usr/sbin/.config/freerdp
# Setup correct permissions for history recorded storage feature
mkdir -p /var/guacamole
chown daemon:daemon /var/guacamole
# Bring guacd and Tomcat back up # Bring guacd and Tomcat back up
echo -e "${GREY}Starting guacd and Tomcat services..." echo -e "${GREY}Starting guacd and Tomcat services..."
# Reset freerdp profile permissions for storing certificates
mkdir -p /home/"${GUACD_ACCOUNT}"/.config/freerdp
chown ${GUACD_ACCOUNT}:${GUACD_ACCOUNT} /home/"${GUACD_ACCOUNT}"/.config/freerdp
# Reset guacamole permissions
mkdir -p /var/guacamole
chown "${GUACD_ACCOUNT}":"${GUACD_ACCOUNT}" /var/guacamole
# Reset the guacd systemd unit file's default service account
sudo sed -i "s/\bdaemon\b/${GUACD_ACCOUNT}/g" /etc/systemd/system/guacd.service
systemctl daemon-reload
systemctl enable guacd systemctl enable guacd
systemctl start guacd systemctl start guacd
systemctl start ${TOMCAT_VERSION} systemctl start ${TOMCAT_VERSION}