mirror of
https://github.com/itiligent/Easy-Guacamole-Installer.git
synced 2025-12-13 18:02:32 +00:00
v1.5.0.0
v1.5.0.0
This commit is contained in:
commit
29b2a63b6b
14 changed files with 2250 additions and 0 deletions
546
1-setup.sh
Normal file
546
1-setup.sh
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
#!/bin/bash
|
||||
######################################################################################################################
|
||||
# Guacamole appliance setup script
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# To install latest snapshot:
|
||||
# wget https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/1-setup.sh && chmod +x 1-setup.sh && ./1-setup.sh
|
||||
|
||||
# If something isn't working? # tail -f /var/log/syslog /var/log/tomcat*/*.out /var/log/mysql/*.log
|
||||
|
||||
# This whole install routine could be collated into one huge script, but it is far easer to manage and maintan by
|
||||
# breaking up the different stages of the install into at least 4 separate scripts as follows...
|
||||
# 1-setup.sh is a central script that manages all inputs, options and sequences other included 'install' scripts.
|
||||
# 2-install-guacamole is the main guts of the whole build. This script downloads and builds Guacamole from source.
|
||||
# 3-install-nginx.sh automatically installs and configues Nginx to work as an http port 80 front end to Gaucamole
|
||||
# 4a-install-self-signed-nginx.sh sets up the new Nginx/Guacamole front end with self signed SSL certificates.
|
||||
# 4b-install-ssl-letsencrypt-nginx.sh sets up Nginx with public SSL certificates from LetsEncrypt.
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Initial enviromment setup ###########################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
clear
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
#Setup download and temp directory paths
|
||||
USER_HOME_DIR=$(eval echo ~${SUDO_USER})
|
||||
DOWNLOAD_DIR=$USER_HOME_DIR/guac-setup
|
||||
DB_BACKUP_DIR=$USER_HOME_DIR/mysqlbackups/
|
||||
TMP_DIR=$DOWNLOAD_DIR/tmp
|
||||
source /etc/os-release
|
||||
OS_FLAVOUR=$ID
|
||||
OS_VERSION=$VERSION
|
||||
JPEGTURBO=""
|
||||
LIBPNG=""
|
||||
|
||||
# Announce the script we're running
|
||||
echo
|
||||
echo -e "${GREYB}Itiligent Jump Server Appliance Setup."
|
||||
echo -e " ${LGREEN}Powered by Guacamole"
|
||||
echo
|
||||
|
||||
# Setup directory locations
|
||||
mkdir -p $DOWNLOAD_DIR
|
||||
mkdir -p $DB_BACKUP_DIR
|
||||
mkdir -p $TMP_DIR
|
||||
|
||||
# Now prompt for sudo and set dir permissions so both sudo and non sudo functions can access tmp setup files
|
||||
sudo chmod -R 770 $TMP_DIR
|
||||
sudo chown -R $SUDO_USER:root $TMP_DIR
|
||||
|
||||
# Github download branch
|
||||
GITHUB="https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/"
|
||||
|
||||
#Version of Guacamole to install
|
||||
GUAC_VERSION="1.5.0"
|
||||
|
||||
# Set preferred Apache CDN download link
|
||||
GUAC_SOURCE_LINK="http://apache.org/dyn/closer.cgi?action=download&filename=guacamole/${GUAC_VERSION}"
|
||||
|
||||
# MySQL Connector/J version
|
||||
MYSQLJCON="8.0.30"
|
||||
|
||||
# Apache Tomcat version. You will need to check the correct version for your particular distro.
|
||||
TOMCAT_VERSION="tomcat9"
|
||||
|
||||
# Install log Location
|
||||
LOG_LOCATION="${DOWNLOAD_DIR}/guacamole_${GUAC_VERSION}_setup.log"
|
||||
|
||||
# Guacamole default install URL
|
||||
GUAC_URL=http://localhost:8080/guacamole/
|
||||
|
||||
# Non interactive silent setup options - add true/false or specific values
|
||||
SERVER_NAME="" # Preferred server hostname
|
||||
INSTALL_MYSQL="" # Install locally true/false
|
||||
SECURE_MYSQL="" # Apply mysql secure configurarion tool
|
||||
MYSQL_HOST="" # leave blank for localhost default, only specify for remote servers
|
||||
MYSQL_PORT="" # If blank default is 3306
|
||||
GUAC_DB="" # If blank default is guacamole_db
|
||||
GUAC_USER="" # if blank default is guacamole_user
|
||||
GUAC_PWD="" # Should not be blank as this may break some aspects of install
|
||||
MYSQL_ROOT_PWD="" # Should not be blank as this may break some aspects of install
|
||||
INSTALL_TOTP="" # TOTP MFA extension
|
||||
INSTALL_DUO="" # DUO MFA extension (cant be installed simultaneously with TOTP)
|
||||
INSTALL_LDAP="" # Active Directory extension
|
||||
INSTALL_NGINX="" # Install and configure Guacamole behind Nginx reverse proxy (http port 80 only)
|
||||
PROXY_SITE="" # Local DNS name for reverse proxy and self signed ssl certificates
|
||||
SELF_SIGNED="" # Add self signed SSL support to Nginx (Let's Encrypt not available)
|
||||
INSTALL_LETS_ENCRYPT="" # Add Lets Encrypt public SSL support for Nginx (self signed SSL certs not available)
|
||||
LE_DNS_NAME="" # Public DNS name to bind with Lets Encrypt certificates
|
||||
LE_EMAIL="webmaster@itiligent.com" # Webmaster/admin email for Lets Encrypt
|
||||
EMAIL_DOMAIN="itiligent.com" # Email relay domain for backup notifications
|
||||
ALERT_EMAIL="alerts@itiligent.com" # Email address for backup notifications
|
||||
BACKUP_RETAIN_DAYS="30" # How long to keep backups for
|
||||
CERT_COUNTRY="AU" # 2 coutry charater code only, must not be blank
|
||||
CERT_STATE="Victoria" # Optional to change, must not be blank
|
||||
CERT_LOCATION="Melbourne" # Optional to change, must not be blank
|
||||
CERT_ORG="Itiligent" # Optional to change, must not be blank
|
||||
CERT_OU="I.T." # Optional to change, must not be blank
|
||||
CERT_DAYS="3650" # Number of days until self signed certificate expiry
|
||||
|
||||
# We need to try and grab a default value for the local FQDN. Domain search suffix is used in this case becausue
|
||||
# this is the simplest common default resolv.conf value available between recent Debian and Ubuntu flavours. YMMV.
|
||||
DOMAIN_SEARCH_SUFFIX=$(grep search /etc/resolv.conf | grep -v "#" | sed 's/'search[[:space:]]'//')
|
||||
DEFAULT_FQDN=$HOSTNAME.$DOMAIN_SEARCH_SUFFIX
|
||||
|
||||
# Finally we check to prevent reinstalling over the current from possibly older/previous versions of build files.
|
||||
if [ "$( find . -maxdepth 2 \( -name 'guacamole-*' -o -name 'mysql-connector-java-*' \) )" != "" ]; then
|
||||
echo -e "${RED}Possible previous temp files detected in current build path. Please review and remove old 'guacamole-*' & 'mysql-connector-java-*' files before proceeding.${GREY}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Download github setup scripts #######################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
# Download config scripts and setup items from github
|
||||
cd $DOWNLOAD_DIR
|
||||
echo
|
||||
echo -e "${GREY}Downloading setup files...${DGREY}"
|
||||
wget -q --show-progress ${GITHUB}2-install-guacamole.sh -O 2-install-guacamole.sh
|
||||
wget -q --show-progress ${GITHUB}3-install-nginx.sh -O 3-install-nginx.sh
|
||||
wget -q --show-progress ${GITHUB}4a-install-ssl-self-signed-nginx.sh -O 4a-install-ssl-self-signed-nginx.sh
|
||||
wget -q --show-progress ${GITHUB}4b-install-ssl-letsencrypt-nginx.sh -O 4b-install-ssl-letsencrypt-nginx.sh
|
||||
|
||||
# Grab Guacamole auth extension config scripts
|
||||
wget -q --show-progress ${GITHUB}add-auth-duo.sh -O add-auth-duo.sh
|
||||
wget -q --show-progress ${GITHUB}add-auth-ldap.sh -O add-auth-ldap.sh
|
||||
wget -q --show-progress ${GITHUB}add-auth-totp.sh -O add-auth-totp.sh
|
||||
|
||||
|
||||
# Grab backup and security hardening scripts
|
||||
wget -q --show-progress ${GITHUB}backup-guac.sh -O backup-guac.sh
|
||||
wget -q --show-progress ${GITHUB}add-ssl-guac-gaucd.sh -O add-ssl-guac-gaucd.sh
|
||||
wget -q --show-progress ${GITHUB}add-fail2ban.sh -O add-fail2ban.sh
|
||||
|
||||
# Grab a (customisable) branding extension
|
||||
wget -q --show-progress ${GITHUB}branding.jar -O branding.jar
|
||||
chmod +x *.sh
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Begin install menu prompts ##########################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
# We need a default hostname avaiable to apply even if we do not want to change the hostname. This approach allows the
|
||||
# user to simply hit enter at the prompt without this creating a blank entry into the /etc/hosts file.
|
||||
# Hostnames and matching DNS entries are essential for implementing SSL succesfully.
|
||||
echo
|
||||
echo
|
||||
if [[ -z ${SERVER_NAME} ]]; then
|
||||
echo -e "${LYELLOW}Update Linux system HOSTNAME [Enter to keep: ${HOSTNAME}]${LGREEN}"
|
||||
read -p " Enter new HOSTNAME : " SERVER_NAME
|
||||
if [[ "${SERVER_NAME}" = "" ]]; then
|
||||
SERVER_NAME=$HOSTNAME
|
||||
echo
|
||||
sudo hostnamectl set-hostname $SERVER_NAME &>> ${LOG_LOCATION}
|
||||
sudo sed -i '/127.0.1.1/d' /etc/hosts &>> ${LOG_LOCATION}
|
||||
echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION}
|
||||
sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION}
|
||||
else
|
||||
echo
|
||||
sudo hostnamectl set-hostname $SERVER_NAME &>> ${LOG_LOCATION}
|
||||
sudo sed -i '/127.0.1.1/d' /etc/hosts &>> ${LOG_LOCATION}
|
||||
echo '127.0.1.1 '${SERVER_NAME}'' | sudo tee -a /etc/hosts &>> ${LOG_LOCATION}
|
||||
sudo systemctl restart systemd-hostnamed &>> ${LOG_LOCATION}
|
||||
fi
|
||||
fi
|
||||
|
||||
clear
|
||||
echo
|
||||
# For convenience & sanity check, diplay status of preset script options at start of install
|
||||
echo -e "${GREY}Enabled non-interactive presets are listed below, blank entries will prompt."
|
||||
echo -e "(Ctrl+C to exit & edit 1-setup.sh before continuning.)"
|
||||
echo -e "${DGREY}Server host name\t= ${GREY}${SERVER_NAME}"
|
||||
echo -e "${DGREY}Install MYSQL locally\t= ${GREY}${INSTALL_MYSQL}"
|
||||
echo -e "${DGREY}MySQL secure install\t= ${GREY}${SECURE_MYSQL}"
|
||||
echo -e "${DGREY}MySQL hostname/IP\t= ${GREY}${MYSQL_HOST}"
|
||||
echo -e "${DGREY}MySQL port\t\t= ${GREY}${MYSQL_PORT}"
|
||||
echo -e "${DGREY}Guacamole db name\t= ${GREY}${GUAC_DB}"
|
||||
echo -e "${DGREY}Guacamole db user name\t= ${GREY}${GUAC_USER}"
|
||||
echo -e "${DGREY}Guacamole user pwd\t= ${GREY}${GUAC_PWD}"
|
||||
echo -e "${DGREY}MySQL root pwd\t\t= ${GREY}${MYSQL_ROOT_PWD}"
|
||||
echo -e "${DGREY}Install TOTP\t\t= ${GREY}${INSTALL_TOTP}"
|
||||
echo -e "${DGREY}Install DUO\t\t= ${GREY}${INSTALL_DUO}"
|
||||
echo -e "${DGREY}Install LDAP\t\t= ${GREY}${INSTALL_LDAP}${GREY}"
|
||||
echo -e "${DGREY}Install Nginx rev proxy\t= ${GREY}${INSTALL_NGINX}${GREY}"
|
||||
echo -e "${DGREY}Proxy local DNS name\t= ${GREY}${PROXY_SITE}"
|
||||
echo -e "${DGREY}Add self signed SSL\t= ${GREY}${SELF_SIGNED}${GREY}"
|
||||
echo -e "${DGREY}Add Let's Encrypt SSL\t= ${GREY}${INSTALL_LETS_ENCRYPT}${GREY}"
|
||||
echo -e "${DGREY}Let's Encrypt pub FQDN\t= ${GREY}${LE_DNS_NAME}${GREY}"
|
||||
echo -e "${DGREY}Let's Encrypt email\t= ${GREY}${LE_EMAIL}${GREY}"
|
||||
echo -e "${DGREY}SMTP relay domain\t= ${GREY}${EMAIL_DOMAIN}${GREY}"
|
||||
echo -e "${DGREY}Alerts email address\t= ${GREY}${ALERT_EMAIL}${GREY}"
|
||||
echo -e "${DGREY}Days to keep backups\t= ${GREY}${BACKUP_RETAIN_DAYS}${GREY}"
|
||||
echo -e "${DGREY}Self signed cert days\t= ${DGREY}${CERT_DAYS}${GREY}"
|
||||
echo -e "${DGREY}Self signed country\t= ${DGREY}${CERT_COUNTRY}${GREY}"
|
||||
echo -e "${DGREY}Self signed state\t= ${DGREY}${CERT_STATE}${GREY}"
|
||||
echo -e "${DGREY}Self signed location\t= ${DGREY}${CERT_LOCATION}${GREY}"
|
||||
echo -e "${DGREY}Self signed ORG\t\t= ${DGREY}${CERT_ORG}${GREY}"
|
||||
echo -e "${DGREY}Self signed OU\t\t= ${DGREY}${CERT_OU}${GREY}"
|
||||
|
||||
# Prompt the user to see if they would like to install MySQL, default of yes
|
||||
if [[ -z ${INSTALL_MYSQL} ]]; then
|
||||
echo
|
||||
echo -e -n "${LGREEN}SQL: Install MySQL? (for a remote MySQL Server select 'n') (y/n) [default y]: ${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
|
||||
INSTALL_MYSQL=false
|
||||
else
|
||||
INSTALL_MYSQL=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt the user to see if they would like to apply the Mysql secure installation
|
||||
if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = true ]; then
|
||||
echo -e -n "${GREY}SQL: Apply MySQL secure installation settings to LOCAL db? (y/n) [default y]: ${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
|
||||
SECURE_MYSQL=false
|
||||
else
|
||||
SECURE_MYSQL=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt the user to see if they would like to apply the Mysql secure installation
|
||||
if [ -z ${SECURE_MYSQL} ] && [ "${INSTALL_MYSQL}" = false ]; then
|
||||
echo -e -n "${GREY}SQL: Apply MySQL secure installation settings to REMOTE db? (y/n) [default n]: ${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
SECURE_MYSQL=true
|
||||
else
|
||||
SECURE_MYSQL=false
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${INSTALL_MYSQL}" = false ]; then
|
||||
# We need to get some additional MYSQL values
|
||||
[ -z "${MYSQL_HOST}" ] \
|
||||
&& read -p "SQL: Enter MySQL server hostname or IP: " MYSQL_HOST
|
||||
[ -z "${MYSQL_PORT}" ] \
|
||||
&& read -p "SQL: Enter MySQL server port [3306]: " MYSQL_PORT
|
||||
[ -z "${GUAC_DB}" ] \
|
||||
&& read -p "SQL: Enter Guacamole database name [guacamole_db]: " GUAC_DB
|
||||
[ -z "${GUAC_USER}" ] \
|
||||
&& read -p "SQL: Enter Guacamole user name [guacamole_user]: " GUAC_USER
|
||||
fi
|
||||
|
||||
# Checking if a mysql host given, if not set a default
|
||||
if [ -z "${MYSQL_HOST}" ]; then
|
||||
MYSQL_HOST="localhost"
|
||||
fi
|
||||
|
||||
# Checking if a mysql port given, if not set a default
|
||||
if [ -z "${MYSQL_PORT}" ]; then
|
||||
MYSQL_PORT="3306"
|
||||
fi
|
||||
|
||||
# Checking if a database name given, if not set a default
|
||||
if [ -z "${GUAC_DB}" ]; then
|
||||
GUAC_DB="guacamole_db"
|
||||
fi
|
||||
|
||||
# Checking if a mysql user given, if not set a default
|
||||
if [ -z "${GUAC_USER}" ]; then
|
||||
GUAC_USER="guacamole_user"
|
||||
fi
|
||||
|
||||
# Get MySQL root password, confirm correct password entry and prevent blank passwords
|
||||
if [ -z "${MYSQL_ROOT_PWD}" ]; then
|
||||
while true; do
|
||||
read -s -p "SQL: Enter ${MYSQL_HOST}'s MySQL root password: " MYSQL_ROOT_PWD
|
||||
echo
|
||||
read -s -p "SQL: Confirm ${MYSQL_HOST}'s MySQL root password: " PROMPT2
|
||||
echo
|
||||
[ "${MYSQL_ROOT_PWD}" = "${PROMPT2}" ] && [ "${MYSQL_ROOT_PWD}" != "" ] && [ "${PROMPT2}" != "" ] && break
|
||||
echo -e "${RED}Passwords don't match or can't be null. Please try again.${GREY}" 1>&2
|
||||
done
|
||||
fi
|
||||
|
||||
# Get Guacamole User password, confirm correct password entry and prevent blank passwords
|
||||
if [ -z "${GUAC_PWD}" ]; then
|
||||
while true; do
|
||||
read -s -p "SQL: Enter ${MYSQL_HOST}'s MySQL ${GUAC_USER} password: " GUAC_PWD
|
||||
echo
|
||||
read -s -p "SQL: Confirm ${MYSQL_HOST}'s MySQL ${GUAC_USER} password: " PROMPT2
|
||||
echo
|
||||
[ "${GUAC_PWD}" = "${PROMPT2}" ] && [ "${GUAC_PWD}" != "" ] && [ "${PROMPT2}" != "" ] && break
|
||||
echo -e "${RED}Passwords don't match or can't be null. Please try again.${GREY}" 1>&2
|
||||
done
|
||||
fi
|
||||
|
||||
# Prompt the user if they would like to install TOTP MFA, default of no
|
||||
if [[ -z "${INSTALL_TOTP}" ]] && [[ "${INSTALL_DUO}" != true ]]; then
|
||||
echo -e -n "${GREY}GUAC MFA: Install TOTP? (choose 'n' if you want Duo) (y/n)? [default n]: "
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
INSTALL_TOTP=true
|
||||
INSTALL_DUO=false
|
||||
else
|
||||
INSTALL_TOTP=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt the user if they would like to install Duo MFA, default of no
|
||||
if [[ -z "${INSTALL_DUO}" ]] && [[ "${INSTALL_TOTP}" != true ]]; then
|
||||
echo -e -n "${GREY}GUAC MFA: Install Duo? (y/n) [default n]: "
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
INSTALL_DUO=true
|
||||
INSTALL_TOTP=false
|
||||
else
|
||||
INSTALL_DUO=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# We can't install TOTP and Duo at the same time, option not supported by Guacamole...
|
||||
if [[ "${INSTALL_TOTP}" = true ]] && [[ "${INSTALL_DUO}" = true ]]; then
|
||||
echo -e "${RED}GUAC MFA: TOTP and Duo cannot be installed at the same time.${GREY}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prompt the user if they would like to install Duo MFA, default of no
|
||||
if [[ -z "${INSTALL_LDAP}" ]]; then
|
||||
echo -e -n "${GREY}GUAC AUTH: Install LDAP? (y/n) [default n]: "
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
INSTALL_LDAP=true
|
||||
else
|
||||
INSTALL_LDAP=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt for Guacamole front end reverse proxy option
|
||||
if [[ -z ${INSTALL_NGINX} ]]; then
|
||||
echo -e -n "${LGREEN}ADD REVERSE PROXY?: Protect Gucamole behind Nginx reverse proxy (y/n)? [default y]: ${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
|
||||
INSTALL_NGINX=false
|
||||
else
|
||||
INSTALL_NGINX=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# We must assign a DNS name for the new proxy site
|
||||
if [[ -z ${PROXY_SITE} ]] && [[ "${INSTALL_NGINX}" = true ]]; then
|
||||
while true; do
|
||||
read -p "REVERSE PROXY NAME?: Enter proxy local DNS name? [Enter to use ${DEFAULT_FQDN}]: " PROXY_SITE
|
||||
[ "${PROXY_SITE}" = "" ] || [ "${PROXY_SITE}" != "" ] && break
|
||||
# rather than allow any default, alternately force user to enter an explicit name instead
|
||||
# [ "${PROXY_SITE}" != "" ] && break
|
||||
# echo -e "${RED}You must enter a proxy site DNS name. Please try again.${GREY}" 1>&2
|
||||
done
|
||||
fi
|
||||
|
||||
# If no proxy site dns name is given, lets assume a default FQDN
|
||||
if [ -z "${PROXY_SITE}" ]; then
|
||||
PROXY_SITE="${DEFAULT_FQDN}"
|
||||
fi
|
||||
|
||||
# Prompt for self signed SSL reverse proxy option
|
||||
if [[ -z ${SELF_SIGNED} ]] && [[ "${INSTALL_NGINX}" = true ]]; then
|
||||
# Prompt the user to see if they would like to install self signed SSL support for Nginx, default of no
|
||||
echo -e -n "${GREY}PROXY SSL?: Add self signed SSL support to Nginx? (y/n)? (choose 'n' for Let's Encrypt)[default n]: "
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
SELF_SIGNED=true
|
||||
else
|
||||
SELF_SIGNED=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt to assign the self sign SSL certficate a custom expiry date, uncomment to force a manual entry
|
||||
#if [ "${SELF_SIGNED}" = true ]; then
|
||||
# read - p "PROXY: Enter number of days till SSL certificate expires [default 3650]: " CERT_DAYS
|
||||
#fi
|
||||
|
||||
# If no self sign SSL certificate expiry given, lets assume a generous 10 year default certificate expiry
|
||||
if [ -z "${CERT_DAYS}" ]; then
|
||||
CERT_DAYS="3650"
|
||||
fi
|
||||
|
||||
# Prompt for Let's Encrypt SSL reverse proxy configuration option
|
||||
if [[ -z ${INSTALL_LETS_ENCRYPT} ]] && [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGNED}" = "false" ]]; then
|
||||
echo -e -n "${GREY}SSL PROXY: Add Let's Encrypt SSL support to Nginx reverse proxy (y/n) [default n]: ${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
INSTALL_LETS_ENCRYPT=true
|
||||
else
|
||||
INSTALL_LETS_ENCRYPT=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt for Let's Encrypt public dns name
|
||||
if [[ -z ${LE_DNS_NAME} ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then
|
||||
while true; do
|
||||
read -p "Enter the FQDN for your public proxy site : " LE_DNS_NAME
|
||||
[ "${LE_DNS_NAME}" != "" ] && break
|
||||
echo -e "${RED}You must enter a public DNS name. Please try again.${GREY}" 1>&2
|
||||
done
|
||||
fi
|
||||
|
||||
# Prompt for Let's Encrypt admin email
|
||||
if [[ -z ${LE_EMAIL} ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then
|
||||
while true; do
|
||||
read -p "Enter the email address for Let's Encrypt notifications : " LE_EMAIL
|
||||
[ "${LE_EMAIL}" != "" ] && break
|
||||
echo -e "${RED}You must enter an email address. Please try again.${GREY}" 1>&2
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Start global setup actions #########################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
# Ubuntu and Debian each require different dependency packages. Below works ok from Ubuntu 18.04 / Debian 10 and above.
|
||||
echo -e "${GREY}Checking linux distro specific dependencies..."
|
||||
if [[ $OS_FLAVOUR == "ubuntu" ]] || [[ $OS_FLAVOUR == "ubuntu"* ]]; then # potentially expand out distro choices here
|
||||
JPEGTURBO="libjpeg-turbo8-dev"
|
||||
LIBPNG="libpng-dev"
|
||||
sudo add-apt-repository -y universe &>> ${LOG_LOCATION}
|
||||
elif [[ $OS_FLAVOUR == "debian" ]] || [[ $OS_FLAVOUR == "raspbian" ]] ; then # expand distro choices here if req
|
||||
JPEGTURBO="libjpeg62-turbo-dev"
|
||||
LIBPNG="libpng-dev"
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
fi
|
||||
|
||||
# Because the below scripts may be run manually after install, we need to sync them
|
||||
# with global variables or setup prompt options.
|
||||
sed -i "s|MYSQL_HOST=|MYSQL_HOST='${MYSQL_HOST}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|MYSQL_PORT=|MYSQL_PORT='${MYSQL_PORT}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|GUAC_USER=|GUAC_USER='${GUAC_USER}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|GUAC_PWD=|GUAC_PWD='${GUAC_PWD}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|GUAC_DB=|GUAC_DB='${GUAC_DB}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|DB_BACKUP_DIR=|DB_BACKUP_DIR='${DB_BACKUP_DIR}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|ALERT_EMAIL=|ALERT_EMAIL='${ALERT_EMAIL}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|BACKUP_RETAIN_DAYS=|BACKUP_RETAIN_DAYS='${BACKUP_RETAIN_DAYS}'|g" $DOWNLOAD_DIR/backup-guac.sh
|
||||
sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-duo.sh
|
||||
sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh
|
||||
sed -i "s|GUAC_VERSION=|GUAC_VERSION='${GUAC_VERSION}'|g" $DOWNLOAD_DIR/add-auth-totp.sh
|
||||
sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-auth-duo.sh
|
||||
sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh
|
||||
sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-auth-totp.sh
|
||||
sed -i "s|TOMCAT_VERSION=|TOMCAT_VERSION='${TOMCAT_VERSION}'|g" $DOWNLOAD_DIR/add-fail2ban.sh
|
||||
# As web links may contain "&" characters, GUAC_SOURCE_LINK is fixed to parse "&" with sed correctly
|
||||
FIXED_LINK=$(sed 's/\&/\\&/g' <<< $GUAC_SOURCE_LINK)
|
||||
sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-duo.sh
|
||||
sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-ldap.sh
|
||||
sed -i "s|GUAC_SOURCE_LINK=|GUAC_SOURCE_LINK='${FIXED_LINK}'|g" $DOWNLOAD_DIR/add-auth-totp.sh
|
||||
|
||||
# Pass the relevant variable selections to child install scripts below
|
||||
# (This is a more robust method than export, which is unreliable in this instance)
|
||||
COLOUR_VAR="GREY=$GREY DGREY=$DGREY GREYB=$GREYB RED=$RED LRED=$LRED GREEN=$GREEN LGREEN=$LGREEN YELLOW=$YELLOW LYELLOW=$LYELLOW BLUE=$BLUE LBLUE=$LBLUECYAN=$CYAN LCYAN=$LCYAN MAGENTA=$MAGENTA LMAGENTA=$LMAGENTA NC=$NC"
|
||||
GUAC_VAR="JPEGTURBO=$JPEGTURBO LIBPNG=$LIBPNG GUAC_VERSION=$GUAC_VERSION MYSQLJCON=$MYSQLJCON GUAC_SOURCE_LINK=$GUAC_SOURCE_LINK TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION INSTALL_MYSQL=$INSTALL_MYSQL SECURE_MYSQL=$SECURE_MYSQL MYSQL_HOST=$MYSQL_HOST MYSQL_PORT=$MYSQL_PORT GUAC_DB=$GUAC_DB GUAC_USER=$GUAC_USER GUAC_PWD=$GUAC_PWD MYSQL_ROOT_PWD=$MYSQL_ROOT_PWD INSTALL_TOTP=$INSTALL_TOTP INSTALL_DUO=$INSTALL_DUO INSTALL_LDAP=$INSTALL_LDAP EMAIL_DOMAIN=$EMAIL_DOMAIN"
|
||||
NGINX_VAR="TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION GUAC_URL=$GUAC_URL PROXY_SITE=$PROXY_SITE"
|
||||
SELF_SIGN_VAR="DOWNLOAD_DIR=$DOWNLOAD_DIR TMP_DIR=$TMP_DIR TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION GUAC_URL=$GUAC_URL PROXY_SITE=$PROXY_SITE CERT_COUNTRY=$CERT_COUNTRY CERT_STATE=$CERT_STATE CERT_LOCATION=$CERT_LOCATION CERT_ORG=$CERT_ORG CERT_OU=$CERT_OU"
|
||||
LE_VAR="DOWNLOAD_DIR=$DOWNLOAD_DIR TOMCAT_VERSION=$TOMCAT_VERSION LOG_LOCATION=$LOG_LOCATION PROXY_SITE=$PROXY_SITE GUAC_URL=$GUAC_URL LE_DNS_NAME=$LE_DNS_NAME LE_EMAIL=$LE_EMAIL"
|
||||
|
||||
# Run the Guacamole install script
|
||||
sudo $GUAC_VAR $COLOUR_VAR ./2-install-guacamole.sh
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}2-install-guacamole.sh FAILED. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}Guacamole installation complete\n- Visit: http://${PROXY_SITE}:8080/guacamole\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}"
|
||||
fi
|
||||
|
||||
# Duo Settings reminder that if due is slected you cant login to Guacamole at all until this extension is fully configured
|
||||
if [ $INSTALL_DUO == "true" ]; then
|
||||
echo -e "${YELLOW}Reminder: Duo requires extra account specific config before you can log in to Guacamole."
|
||||
echo -e "See https://guacamole.apache.org/doc/${GUAC_VERSION}/gug/duo-auth.html"
|
||||
fi
|
||||
|
||||
# Add a Guacamole database backup (mon-fri 12:00am) into cron
|
||||
crontab -l > cron_1 > /dev/null 2>&1
|
||||
# Remove existing entry to allow multiple runs
|
||||
sed -i '/# backup guacamole/d' cron_1
|
||||
# Create the job
|
||||
echo "0 0 * * 1-5 ${DOWNLOAD_DIR}/backup-guac.sh # backup guacamole" >> cron_1
|
||||
# Overwrite the cron settings and cleanup
|
||||
crontab cron_1 > /dev/null 2>&1
|
||||
rm cron_1
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Start optional setup actions ######################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
### Install Nginx reverse proxy front end to Guacamole if option is selected
|
||||
if [ "${INSTALL_NGINX}" = true ]; then
|
||||
sudo $NGINX_VAR $COLOUR_VAR ./3-install-nginx.sh | tee -a ${LOG_LOCATION}
|
||||
echo -e "${LGREEN}Nginx installation complete\n- Site changed to : http://${PROXY_SITE}\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}"
|
||||
fi
|
||||
|
||||
|
||||
### Apply self signed SSL certificates to Nginx reverse proxy if option is selected
|
||||
if [[ "${INSTALL_NGINX}" = true ]] && [[ "${SELF_SIGNED}" = true ]]; then
|
||||
sudo -E $SELF_SIGN_VAR $COLOUR_VAR ./4a-install-ssl-self-signed-nginx.sh ${PROXY_SITE} ${CERT_DAYS} | tee -a ${LOG_LOCATION}
|
||||
echo -e "${LGREEN}Self signed certificates successfully created and configured for Nginx \n- Site changed to : ${LYELLOW}https:${LGREEN}//${PROXY_SITE}\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}"
|
||||
fi
|
||||
|
||||
|
||||
### Apply Let's Encrypt SSL certificates to Nginx reverse proxy if option is selected
|
||||
if [[ "${INSTALL_NGINX}" = true ]] && [[ "${INSTALL_LETS_ENCRYPT}" = true ]]; then
|
||||
sudo -E $LE_VAR $COLOUR_VAR ./4b-install-ssl-letsencrypt-nginx.sh | tee -a ${LOG_LOCATION}
|
||||
echo -e "${LGREEN}Let's Encrypt SSL successfully configured for Nginx \n- Site changed to : ${LYELLOW}https:${LGREEN}//${LE_DNS_NAME}\n- Default login (user/pass): guacadmin/guacadmin\n${LYELLOW}***Be sure to change the password***.${GREY}"
|
||||
fi
|
||||
|
||||
|
||||
# Final tidy up
|
||||
mv $USER_HOME_DIR/1-setup.sh $DOWNLOAD_DIR
|
||||
sudo rm -R $TMP_DIR
|
||||
|
||||
|
||||
# Done
|
||||
echo
|
||||
printf "${LGREEN}Guacamole ${GUAC_VERSION} install complete! \n${NC}"
|
||||
echo -e ${NC}
|
||||
474
2-install-guacamole.sh
Normal file
474
2-install-guacamole.sh
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Guacamole main build script
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
# Special thanks to MysticRyuujin for much of the guac install outline here
|
||||
# pls see https://github.com/MysticRyuujin/guac-install for more
|
||||
#######################################################################################################################
|
||||
|
||||
clear
|
||||
|
||||
# Pre-seed MySQL install values
|
||||
if [ "${INSTALL_MYSQL}" = true ]; then
|
||||
debconf-set-selections <<< "mysql-server mysql-server/root_password password ${MYSQL_ROOT_PWD}"
|
||||
debconf-set-selections <<< "mysql-server mysql-server/root_password_again password ${MYSQL_ROOT_PWD}"
|
||||
fi
|
||||
|
||||
# Checking if (any kind of) mysql-client or compatible command installed. This is useful for existing mariadb server
|
||||
if [ "${INSTALL_MYSQL}" = true ]; then
|
||||
MYSQL="default-mysql-server default-mysql-client mysql-common"
|
||||
elif [ -x "$( command -v mysql )" ]; then
|
||||
MYSQL=""
|
||||
else
|
||||
MYSQL="default-mysql-client"
|
||||
fi
|
||||
|
||||
# Don't do annoying prompts during apt installs
|
||||
echo
|
||||
echo -e "${GREY}Updating base Linux OS..."
|
||||
export DEBIAN_FRONTEND=noninteractive &>> ${LOG_LOCATION}
|
||||
sudo apt-get update &>> ${LOG_LOCATION}
|
||||
sudo apt-get upgrade -y &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
fi
|
||||
|
||||
# Install Guacamole build dependencies.
|
||||
echo
|
||||
echo -e "${GREY}Installing dependencies required for building Guacamole, this might take a few minutes..."
|
||||
apt-get -y install ${JPEGTURBO} ${LIBPNG} ufw htop pwgen wget crudini build-essential libcairo2-dev libtool-bin uuid-dev libavcodec-dev libavformat-dev libavutil-dev \
|
||||
libswscale-dev freerdp2-dev libpango1.0-dev libssh2-1-dev libtelnet-dev libvncserver-dev libwebsockets-dev libpulse-dev libssl-dev \
|
||||
libvorbis-dev libwebp-dev ghostscript \
|
||||
${MYSQL} ${TOMCAT_VERSION} &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
fi
|
||||
|
||||
# Setup email relay
|
||||
echo
|
||||
echo -e "${GREY}Setting up SMTP for backup alerts (requires SMTP relay be permitted from this server's IP address)..."
|
||||
echo "postfix postfix/mailname string ${EMAIL_DOMAIN} | debconf-set-selections" &>> ${LOG_LOCATION}
|
||||
DEBIAN_FRONTEND="noninteractive" apt-get install postfix -y &>> ${LOG_LOCATION}
|
||||
apt-get install mailutils -y &>> ${LOG_LOCATION}
|
||||
sed -i 's/inet_interfaces = all/inet_interfaces = loopback-only/g' /etc/postfix/main.cf &>> ${LOG_LOCATION}
|
||||
service postfix restart &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
fi
|
||||
|
||||
# Download Guacamole Server
|
||||
echo
|
||||
echo -e "${GREY}Downloading Guacamole source files..."
|
||||
wget -q --show-progress -O guacamole-server-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/source/guacamole-server-${GUAC_VERSION}.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download guacamole-server-${GUAC_VERSION}.tar.gz" 1>&2
|
||||
echo -e "${GUAC_SOURCE_LINK}/source/guacamole-server-${GUAC_VERSION}.tar.gz${GREY}"
|
||||
exit 1
|
||||
else
|
||||
tar -xzf guacamole-server-${GUAC_VERSION}.tar.gz
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded guacamole-server-${GUAC_VERSION}.tar.gz${GREY}"
|
||||
|
||||
# Download Guacamole Client
|
||||
wget -q --show-progress -O guacamole-${GUAC_VERSION}.war ${GUAC_SOURCE_LINK}/binary/guacamole-${GUAC_VERSION}.war
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download guacamole-${GUAC_VERSION}.war" 1>&2
|
||||
echo -e "${GUAC_SOURCE_LINK}/binary/guacamole-${GUAC_VERSION}.war${GREY}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded guacamole-${GUAC_VERSION}.war${GREY}"
|
||||
|
||||
# Download Guacamole authentication extensions
|
||||
wget -q --show-progress -O guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz" 1>&2
|
||||
echo -e "${GUAC_SOURCE_LINK}/binary/guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz"
|
||||
exit 1
|
||||
else
|
||||
tar -xzf guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz${GREY}"
|
||||
|
||||
# Download TOTP extension
|
||||
if [ "${INSTALL_TOTP}" = true ]; then
|
||||
wget -q --show-progress -O guacamole-auth-totp-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-totp-${GUAC_VERSION}.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download guacamole-auth-totp-${GUAC_VERSION}.tar.gz" 1>&2
|
||||
echo -e "${GUAC_SOURCE_LINK}/binary/guacamole-auth-totp-${GUAC_VERSION}.tar.gz"
|
||||
exit 1
|
||||
else
|
||||
tar -xzf guacamole-auth-totp-${GUAC_VERSION}.tar.gz
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded guacamole-auth-totp-${GUAC_VERSION}.tar.gz${GREY}"
|
||||
fi
|
||||
|
||||
# Download DUO extension
|
||||
if [ "${INSTALL_DUO}" = true ]; then
|
||||
wget -q --show-progress -O guacamole-auth-duo-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-duo-${GUAC_VERSION}.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download guacamole-auth-duo-${GUAC_VERSION}.tar.gz" 1>&2
|
||||
echo -e "${GUAC_SOURCE_LINK}/binary/guacamole-auth-duo-${GUAC_VERSION}.tar.gz"
|
||||
exit 1
|
||||
else
|
||||
tar -xzf guacamole-auth-duo-${GUAC_VERSION}.tar.gz
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded guacamole-auth-duo-${GUAC_VERSION}.tar.gz${GREY}"
|
||||
fi
|
||||
|
||||
# Download LDAP extension
|
||||
if [ "${INSTALL_LDAP}" = true ]; then
|
||||
wget -q --show-progress -O guacamole-auth-ldap-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-ldap-${GUAC_VERSION}.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download guacamole-auth-ldap-${GUAC_VERSION}.tar.gz" 1>&2
|
||||
echo -e "${GUAC_SOURCE_LINK}/binary/guacamole-auth-ldap-${GUAC_VERSION}.tar.gz"
|
||||
exit 1
|
||||
else
|
||||
tar -xzf guacamole-auth-ldap-${GUAC_VERSION}.tar.gz
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded guacamole-auth-ldap-${GUAC_VERSION}.tar.gz${GREY}"
|
||||
fi
|
||||
|
||||
# Download MySQL connector/j
|
||||
wget -q --show-progress -O mysql-connector-java-${MYSQLJCON}.tar.gz https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-${MYSQLJCON}.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to download mysql-connector-java-${MYSQLJCON}.tar.gz" 1>&2
|
||||
echo -e "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-${MYSQLJCON}}.tar.gz${GREY}"
|
||||
exit 1
|
||||
else
|
||||
tar -xzf mysql-connector-java-${MYSQLJCON}.tar.gz
|
||||
fi
|
||||
echo -e "${LGREEN}Downloaded mysql-connector-java-${MYSQLJCON}.tar.gz${GREY}"
|
||||
|
||||
echo
|
||||
echo -e "${LGREEN}Source download complete.${GREY}"
|
||||
|
||||
# Option to pause script here as we might want to make final tweaks to source code just before compiling
|
||||
#echo -e "${LYELLOW}"
|
||||
#read -t 15 -p $'Script paused for (optional) tweaking of source before building. Enter to Continue... (Script will auto resume after 15 sec.)\n'
|
||||
#echo -e "${GREY}"
|
||||
|
||||
# Make Guacamole directories
|
||||
rm -rf /etc/guacamole/lib/
|
||||
rm -rf /etc/guacamole/extensions/
|
||||
mkdir -p /etc/guacamole/lib/
|
||||
mkdir -p /etc/guacamole/extensions/
|
||||
|
||||
# Fix for #196 see https://github.com/MysticRyuujin/guac-install/issues/196
|
||||
mkdir -p /usr/sbin/.config/freerdp
|
||||
chown daemon:daemon /usr/sbin/.config/freerdp
|
||||
|
||||
# Fix for #197 see https://github.com/MysticRyuujin/guac-install/issues/197
|
||||
mkdir -p /var/guacamole
|
||||
chown daemon:daemon /var/guacamole
|
||||
|
||||
# Make and install guacd (Guacamole-Server)
|
||||
cd guacamole-server-${GUAC_VERSION}/
|
||||
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}"
|
||||
|
||||
# Fix for warnings see #222 https://github.com/MysticRyuujin/guac-install/issues/222
|
||||
export CFLAGS="-Wno-error"
|
||||
|
||||
# Configure Guacamole Server source
|
||||
./configure --with-systemd-dir=/etc/systemd/system &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to configure guacamole-server"
|
||||
echo "Trying again with --enable-allow-freerdp-snapshots"
|
||||
./configure --with-systemd-dir=/etc/systemd/system --enable-allow-freerdp-snapshots
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to configure guacamole-server - again"
|
||||
exit
|
||||
fi
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo -e "${GREY}Running Make and building the Guacamole-Server application..."
|
||||
make &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo -e "${GREY}Installing Guacamole-Server..."
|
||||
make install &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
ldconfig
|
||||
|
||||
# Move files to correct install locations (guacamole-client & Guacamole authentication extensions)
|
||||
cd ..
|
||||
mv -f guacamole-${GUAC_VERSION}.war /etc/guacamole/guacamole.war
|
||||
mv -f guacamole-auth-jdbc-${GUAC_VERSION}/mysql/guacamole-auth-jdbc-mysql-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
|
||||
# Create a symbolic link for Tomcat
|
||||
ln -sf /etc/guacamole/guacamole.war /var/lib/${TOMCAT_VERSION}/webapps/
|
||||
|
||||
# Move MySQL connector/j files
|
||||
echo -e "${GREY}Moving mysql-connector-java-${MYSQLJCON}.jar (/etc/guacamole/lib/mysql-connector-java.jar)..."
|
||||
mv -f mysql-connector-java-${MYSQLJCON}/mysql-connector-java-${MYSQLJCON}.jar /etc/guacamole/lib/mysql-connector-java.jar
|
||||
echo
|
||||
|
||||
# Move TOTP files
|
||||
if [ "${INSTALL_TOTP}" = true ]; then
|
||||
echo -e "${GREY}Moving guacamole-auth-totp-${GUAC_VERSION}.jar (/etc/guacamole/extensions/)..."
|
||||
mv -f guacamole-auth-totp-${GUAC_VERSION}/guacamole-auth-totp-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
echo
|
||||
fi
|
||||
|
||||
# Move Duo files
|
||||
if [ "${INSTALL_DUO}" = true ]; then
|
||||
echo -e "${GREY}Moving guacamole-auth-duo-${GUAC_VERSION}.jar (/etc/guacamole/extensions/)..."
|
||||
mv -f guacamole-auth-duo-${GUAC_VERSION}/guacamole-auth-duo-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
echo
|
||||
fi
|
||||
|
||||
# Move LDAP files
|
||||
if [ "${INSTALL_LDAP}" = true ]; then
|
||||
echo -e "${GREY}Moving guacamole-auth-ldap-${GUAC_VERSION}.jar (/etc/guacamole/extensions/)..."
|
||||
mv -f guacamole-auth-ldap-${GUAC_VERSION}/guacamole-auth-ldap-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
echo
|
||||
fi
|
||||
|
||||
# Configure guacamole.properties file
|
||||
rm -f /etc/guacamole/guacamole.properties
|
||||
touch /etc/guacamole/guacamole.properties
|
||||
echo "mysql-hostname: ${MYSQL_HOST}" >> /etc/guacamole/guacamole.properties
|
||||
echo "mysql-port: ${MYSQL_PORT}" >> /etc/guacamole/guacamole.properties
|
||||
echo "mysql-database: ${GUAC_DB}" >> /etc/guacamole/guacamole.properties
|
||||
echo "mysql-username: ${GUAC_USER}" >> /etc/guacamole/guacamole.properties
|
||||
echo "mysql-password: ${GUAC_PWD}" >> /etc/guacamole/guacamole.properties
|
||||
|
||||
# Output Duo configuration settings into guacamole.properties
|
||||
if [ "${INSTALL_DUO}" = true ]; then
|
||||
echo "duo-api-hostname: " >> /etc/guacamole/guacamole.properties
|
||||
echo "duo-integration-key: " >> /etc/guacamole/guacamole.properties
|
||||
echo "duo-secret-key: " >> /etc/guacamole/guacamole.properties
|
||||
echo "duo-application-key: " >> /etc/guacamole/guacamole.properties
|
||||
echo -e "${YELLOW}Duo is installed, it will need to be configured via guacamole.properties${GREY}"
|
||||
fi
|
||||
|
||||
echo -e "${GREY}Applying branded Guacamole login page and favicons."
|
||||
# For details on how to brand Guacamole, see https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension
|
||||
sudo mv branding.jar /etc/guacamole/extensions
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Restart Tomcat
|
||||
echo -e "${GREY}Restarting Tomcat service & enable at boot..."
|
||||
service ${TOMCAT_VERSION} restart
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
fi
|
||||
# Set Tomcat to start at boot
|
||||
systemctl enable ${TOMCAT_VERSION}
|
||||
echo
|
||||
|
||||
# Set MySQL password
|
||||
export MYSQL_PWD=${MYSQL_ROOT_PWD}
|
||||
|
||||
# Restart MySQL service
|
||||
if [ "${INSTALL_MYSQL}" = true ]; then
|
||||
echo -e "${GREY}Restarting MySQL service & enable at boot..."
|
||||
service mysql restart
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Set MySQl to start at boot
|
||||
systemctl enable mysql
|
||||
|
||||
# Default locations of MySQL config files
|
||||
for x in /etc/mysql/mariadb.conf.d/50-server.cnf \
|
||||
/etc/mysql/mysql.conf.d/mysqld.cnf \
|
||||
/etc/mysql/my.cnf \
|
||||
; do
|
||||
# Check the path exists
|
||||
if [ -e "${x}" ]; then
|
||||
# Does it have the necessary section?
|
||||
if grep -q '^\[mysqld\]$' "${x}"; then
|
||||
mysqlconfig="${x}"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "${mysqlconfig}" ]; then
|
||||
echo -e "${GREY}Couldn't detect MySQL config file - you may need to manually enter timezone settings"
|
||||
else
|
||||
# Is there already a value?
|
||||
if grep -q "^default_time_zone[[:space:]]?=" "${mysqlconfig}"; then
|
||||
echo -e "MySQL database timezone already defined in ${mysqlconfig}"
|
||||
else
|
||||
timezone="$( cat /etc/timezone )"
|
||||
if [ -z "${timezone}" ]; then
|
||||
echo -e "Couldn't find system timezone, using UTC$"
|
||||
timezone="UTC"
|
||||
fi
|
||||
echo -e "Setting MySQL database timezone as ${timezone}${GREY}"
|
||||
# Fix for https://issues.apache.org/jira/browse/GUACAMOLE-760
|
||||
mysql_tzinfo_to_sql /usr/share/zoneinfo 2>/dev/null | mysql -u root -D mysql -h ${MYSQL_HOST} -P ${MYSQL_PORT}
|
||||
crudini --set ${mysqlconfig} mysqld default_time_zone "${timezone}"
|
||||
# Restart to apply
|
||||
service mysql restart
|
||||
fi
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Create ${GUAC_DB} and grant ${GUAC_USER} permissions to it
|
||||
# SQL code
|
||||
GUAC_USERHost="localhost"
|
||||
if [[ "${MYSQL_HOST}" != "localhost" ]]; then
|
||||
GUAC_USERHost="%"
|
||||
echo -e "${YELLOW}MySQL Guacamole user is set to accept login from any host, please change this for security reasons if possible.${GREY}"
|
||||
fi
|
||||
|
||||
# Check for ${GUAC_DB} already being there
|
||||
echo -e "${GREY}Checking MySQL for existing database (${GUAC_DB})"
|
||||
SQLCODE="
|
||||
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='${GUAC_DB}';"
|
||||
|
||||
# Execute SQL code
|
||||
MYSQL_RESULT=$( echo ${SQLCODE} | mysql -u root -D information_schema -h ${MYSQL_HOST} -P ${MYSQL_PORT} )
|
||||
if [[ $MYSQL_RESULT != "" ]]; then
|
||||
echo -e "${RED}It appears there is already a MySQL database (${GUAC_DB}) on ${MYSQL_HOST}${GREY}" 1>&2
|
||||
echo -e "${RED}Try: mysql -e 'DROP DATABASE ${GUAC_DB}'${GREY}" 1>&2
|
||||
#exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Check for ${GUAC_USER} already being there
|
||||
echo -e "${GREY}Checking MySQL for existing user (${GUAC_USER})"
|
||||
SQLCODE="
|
||||
SELECT COUNT(*) FROM mysql.user WHERE user = '${GUAC_USER}';"
|
||||
|
||||
# Execute SQL code
|
||||
MYSQL_RESULT=$( echo ${SQLCODE} | mysql -u root -D mysql -h ${MYSQL_HOST} -P ${MYSQL_PORT} | grep '0' )
|
||||
if [[ $MYSQL_RESULT == "" ]]; then
|
||||
echo -e "${RED}It appears there is already a MySQL user (${GUAC_USER}) on ${MYSQL_HOST}${GREY}" 1>&2
|
||||
echo -e "${RED}Try: mysql -e \"DROP USER '${GUAC_USER}'@'${GUAC_USERHost}'; FLUSH PRIVILEGES;\"${GREY}" 1>&2
|
||||
#exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Create database & user, then set permissions
|
||||
SQLCODE="
|
||||
DROP DATABASE IF EXISTS ${GUAC_DB};
|
||||
CREATE DATABASE IF NOT EXISTS ${GUAC_DB};
|
||||
CREATE USER IF NOT EXISTS '${GUAC_USER}'@'${GUAC_USERHost}' IDENTIFIED BY \"${GUAC_PWD}\";
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON ${GUAC_DB}.* TO '${GUAC_USER}'@'${GUAC_USERHost}';
|
||||
FLUSH PRIVILEGES;"
|
||||
|
||||
# Execute SQL code
|
||||
echo ${SQLCODE} | mysql -u root -D mysql -h ${MYSQL_HOST} -P ${MYSQL_PORT}
|
||||
|
||||
# Add Guacamole schema to newly created database
|
||||
echo -e "${GREY}Adding database tables..."
|
||||
cat guacamole-auth-jdbc-${GUAC_VERSION}/mysql/schema/*.sql | mysql -u root -D ${GUAC_DB} -h ${MYSQL_HOST} -P ${MYSQL_PORT}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Create guacd.conf. This is later changed to 127.0.0.1 during Nginx reverse proxy install.
|
||||
echo -e "${GREY}Binding guacd to 0.0.0.0 port 4822..."
|
||||
cat > /etc/guacamole/guacd.conf <<- "EOF"
|
||||
[server]
|
||||
bind_host = 0.0.0.0
|
||||
bind_port = 4822
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Ensure guacd is started
|
||||
echo -e "${GREY}Starting guacd service & enable at boot..."
|
||||
systemctl enable guacd
|
||||
service guacd stop 2>/dev/null
|
||||
service guacd start
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
echo -e "${GREY}Cleanup install files...${GREY}"
|
||||
rm -rf guacamole-*
|
||||
rm -rf mysql-connector-java-*
|
||||
unset MYSQL_PWD
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Apply Secure MySQL installation settings
|
||||
if [ "${SECURE_MYSQL}" = true ]; then
|
||||
echo -e "${GREY}Applying mysql_secure_installation settings...${GREY}"
|
||||
printf "${MYSQL_ROOT_PWD}\n n\n n\n y\n y\n y\n y\n y\n" | mysql_secure_installation -u root --password="${MYSQL_ROOT_PWD}" &>> ${LOG_LOCATION}
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Done
|
||||
echo -e ${NC}
|
||||
117
3-install-nginx.sh
Normal file
117
3-install-nginx.sh
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add Nginx reverse proxy fromt end to default Guacamole install
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# 3 of 4
|
||||
# David Harrop
|
||||
# August 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Install Nginx
|
||||
sudo apt-get install nginx -y &>> ${LOG_LOCATION}
|
||||
|
||||
# Configure /etc/nginx/sites-available/(local dns site name)
|
||||
cat >/etc/nginx/sites-available/$PROXY_SITE <<EOL
|
||||
server {
|
||||
listen 80 default_server;
|
||||
root /var/www/html;
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
server_name $GUAC_URL;
|
||||
location / {
|
||||
proxy_pass $GUAC_URL;
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
echo
|
||||
echo -e "${GREY}Configuring Nginx proxy to connect to Guacamole's Apache front end..."
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Symlink from sites-available to sites-enabled
|
||||
ln -s /etc/nginx/sites-available/$PROXY_SITE /etc/nginx/sites-enabled/
|
||||
|
||||
# Make sure default Nginx site is unlinked
|
||||
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!
|
||||
sudo sed -i '/pattern="%h %l %u %t "%r" %s %b"/a \ <!-- Allow host IP to pass through to guacamole.-->\n <Valve className="org.apache.catalina.valves.RemoteIpValve"\n internalProxies="127\.0\.0\.1|0:0:0:0:0:0:0:1"\n remoteIpHeader="x-forwarded-for"\n remoteIpProxiesHeader="x-forwarded-by"\n protocolHeader="x-forwarded-proto" />' /etc/$TOMCAT_VERSION/server.xml
|
||||
echo -e "${GREY}Configuring Apache Tomcat's internal proxy valve to support proxy client IP4 & IPv6 address passthough for correct logging and ACL support...${GREY}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Allow large file transfers through Nginx
|
||||
sudo sed -i '/client_max_body_size/d' /etc/nginx/nginx.conf # remove this line if it already exists to prevent duplicates
|
||||
sudo sed -i "/Basic Settings/a \ client_max_body_size 100000000M;" /etc/nginx/nginx.conf # Add the larger file transfer size
|
||||
echo -e "${GREY}Boosting Nginx's 'maximum body size' parameter to support file transfers > 100 TB through the proxy...${GREY}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Bind guacd to localhost and force all Guacamole connections via reverse proxy
|
||||
echo -e "${GREY}Binding guacd to 127.0.0.1 port 4822..."
|
||||
cat > /etc/guacamole/guacd.conf <<- "EOF"
|
||||
[server]
|
||||
bind_host = 127.0.0.1
|
||||
bind_port = 4822
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Update general ufw rules so force traffic via reverse proxy. Only Nginx and SSH will be available over the network.
|
||||
echo -e "${GREY}Updating firewall rules to allow only SSH and tcp 80/443..."
|
||||
sudo ufw default allow outgoing &>> ${LOG_LOCATION}
|
||||
sudo ufw default deny incoming &>> ${LOG_LOCATION}
|
||||
sudo ufw delete allow 8080/tcp &>> ${LOG_LOCATION}
|
||||
sudo ufw allow OpenSSH &>> ${LOG_LOCATION}
|
||||
sudo ufw allow 80/tcp &>> ${LOG_LOCATION}
|
||||
sudo ufw allow 443/tcp &>> ${LOG_LOCATION}
|
||||
echo "y" | sudo ufw enable &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Reload everything
|
||||
echo -e "${GREY}Restaring Guacamole & Ngnix..."
|
||||
sudo systemctl restart $TOMCAT_VERSION &>> ${LOG_LOCATION}
|
||||
sudo systemctl restart guacd &>> ${LOG_LOCATION}
|
||||
sudo systemctl restart nginx &>> ${LOG_LOCATION}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Done
|
||||
echo -e ${NC}
|
||||
219
4a-install-ssl-self-signed-nginx.sh
Normal file
219
4a-install-ssl-self-signed-nginx.sh
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add self signed SSL certificates to Guacamole with Nginx reverse proxy
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# 4a of 4
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# To run manually and regenerate certificates, this script must be run in the current user enviroment [-E switch]
|
||||
# to provide certifacate outputs correctly. Runing just as sudo will save certs to sudo's home path
|
||||
# sudo -E ./4a-install-ssl-self-signed-nginx.sh [your-dns-name.local] [3650]
|
||||
|
||||
# Hack to assist with displaying "$" symbols and " ' quotes in a (cut/pasteable) bash screen output format for Nginx configs
|
||||
SHOWASTEXT1='$mypwd'
|
||||
SHOWASTEXT2='"Cert:\LocalMachine\Root"'
|
||||
|
||||
# Discover all IPv4 interfaces addresses to bind to new SSL certficates
|
||||
echo
|
||||
echo -e "${GREY}Discovering the default route interface and DNS names to bind with the new SSL certificate..."
|
||||
# Dump interface info and copy this output to a temp file
|
||||
DUMP_IPS=$(ip -o addr show up primary scope global | while read -r num dev fam addr rest; do echo ${addr%/*}; done)
|
||||
echo $DUMP_IPS > $TMP_DIR/dump_ips.txt
|
||||
|
||||
# Filter out anything but numerical characters, then add output to a temporary list
|
||||
grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" $TMP_DIR/dump_ips.txt > $TMP_DIR/ip_list.txt
|
||||
|
||||
# Separate each row in the temporary ip_list.txt file and further split each single row into a separate new temp file for each individual IP address found
|
||||
sed -n '1p' $TMP_DIR/ip_list.txt > $TMP_DIR/1st_ip.txt
|
||||
#sed -n '2p' $TMP_DIR/ip_list.txt > $TMP_DIR/2nd_ip.txt # uncomment for 2nd interface
|
||||
#sed -n '3p' $TMP_DIR/ip_list.txt > $TMP_DIR/3rd_ip.txt # uncomment for 3rd interface etc
|
||||
|
||||
# Assign each individual IP address temp file a discreet variable for use in the certificate parameters setup
|
||||
IP1=$(cat $TMP_DIR/1st_ip.txt)
|
||||
#IP2=$(cat $TMP_DIR/2nd_ip.txt) # uncomment for 2nd interface
|
||||
#IP3=$(cat $TMP_DIR/3rd_ip.txt) # uncomment for 3rd interface etc
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e "${GREY}New self signed SSL certificate attributes are shown below...${GREY}"
|
||||
echo -e "${DGREY}"
|
||||
|
||||
# Display the new SSL cert parameters. Prompt for change if required
|
||||
cat <<EOF | tee -a $TMP_DIR/cert_attributes.txt
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
x509_extensions = v3_req
|
||||
prompt = no
|
||||
string_mask = utf8only
|
||||
|
||||
[req_distinguished_name]
|
||||
C = $CERT_COUNTRY
|
||||
ST = $CERT_STATE
|
||||
L = $CERT_LOCATION
|
||||
O = $CERT_ORG
|
||||
OU = $CERT_OU
|
||||
CN = $PROXY_SITE
|
||||
|
||||
[v3_req]
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = $PROXY_SITE
|
||||
IP.1 = $IP1
|
||||
EOF
|
||||
# Add IP.2 & IP.3 into the above cat <<EOF as needed.
|
||||
#IP.2 = $IP3
|
||||
#IP.3 = $IP3
|
||||
# Additional DNS names can also be manually added into the above cat <<EOF as needed.
|
||||
#DNS.2 =
|
||||
#DNS.3 =
|
||||
|
||||
# Set default certificate file destinations. These can be adapted for any other SSL application.
|
||||
DIR_SSL_CERT="/etc/nginx/ssl/cert"
|
||||
DIR_SSL_KEY="/etc/nginx/ssl/private"
|
||||
|
||||
# Setup SSL certificate variables
|
||||
SSLNAME=$1
|
||||
SSLDAYS=$2
|
||||
|
||||
if [[ $SSLDAYS == "" ]]; then
|
||||
$SSLDAYS = 3650
|
||||
fi
|
||||
|
||||
echo "Creating a new Certificate ..."
|
||||
openssl req -x509 -nodes -newkey rsa:2048 -keyout $SSLNAME.key -out $SSLNAME.crt -days $SSLDAYS -config $TMP_DIR/cert_attributes.txt
|
||||
|
||||
# Make directories to place SSL Certificate if they don't exist
|
||||
if [[ ! -d $DIR_SSL_KEY ]]; then
|
||||
sudo mkdir -p $DIR_SSL_KEY
|
||||
fi
|
||||
|
||||
if [[ ! -d $DIR_SSL_CERT ]]; then
|
||||
sudo mkdir -p $DIR_SSL_CERT
|
||||
fi
|
||||
|
||||
# Place SSL Certificate within defined path
|
||||
sudo cp $SSLNAME.key $DIR_SSL_KEY/$SSLNAME.key
|
||||
sudo cp $SSLNAME.crt $DIR_SSL_CERT/$SSLNAME.crt
|
||||
|
||||
# Create a PFX formatted key for easier import to Windows hosts and change permissions to enable copying elsewhere
|
||||
sudo openssl pkcs12 -export -out $SSLNAME.pfx -inkey $SSLNAME.key -in $SSLNAME.crt -password pass:1234
|
||||
sudo chmod 0774 $SSLNAME.pfx
|
||||
echo -e "${GREY}Creating a selection of self signed certificates for Nginx and Windows/Linux browser clients...${GREY}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Backup the current Nginx config before update
|
||||
cp /etc/nginx/sites-enabled/${PROXY_SITE} $DOWNLOAD_DIR/${PROXY_SITE}-nginx.bak
|
||||
echo -e "${GREY}Backing up previous Nginx proxy to $DOWNLOAD_DIR/$PROXY_SITE-nginx.bak"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Update Nginx config to accept the new certificates
|
||||
cat > /etc/nginx/sites-available/$PROXY_SITE <<EOL | > /dev/null
|
||||
server {
|
||||
#listen 80 default_server;
|
||||
root /var/www/html;
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
server_name $PROXY_SITE;
|
||||
location / {
|
||||
proxy_pass $GUAC_URL;
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
access_log off;
|
||||
}
|
||||
listen 443 ssl;
|
||||
ssl_certificate /etc/nginx/ssl/cert/$SSLNAME.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/private/$SSLNAME.key;
|
||||
ssl_session_cache shared:SSL:1m;
|
||||
ssl_session_timeout 5m;
|
||||
}
|
||||
server {
|
||||
return 301 https://\$host\$request_uri;
|
||||
listen 80 default_server;
|
||||
root /var/www/html;
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
server_name $PROXY_SITE;
|
||||
location / {
|
||||
proxy_pass $GUAC_URL;
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
echo -e "${GREY}Configuring Nginx proxy to use self signed SSL certificates and setting up automatic HTTP to HTTPS redirect...${GREY}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
printf "${GREY}+-------------------------------------------------------------------------------------------------------------
|
||||
${GREEN}+ WINDOWS CLIENT SELF SIGNED SSL BROWSER CONFIG - SAVE THIS BEFORE CONTINUING!${GREY}
|
||||
+
|
||||
+ 1. In ${DOWNLOAD_DIR} is a Windows friendly version of the new certificate ${LYELLOW}$SSLNAME.pfx${GREY}
|
||||
+ 2. Copy this .pfx file to a location accessible by Windows.
|
||||
+ 3. Import the PFX file into your Windows client with the below Powershell commands (as administrator):
|
||||
\n"
|
||||
echo -e "${SHOWASTEXT1} = ConvertTo-SecureString -String "1234" -Force -AsPlainText"
|
||||
echo -e "Import-pfxCertificate -FilePath $SSLNAME.pfx -Password "${SHOWASTEXT1}" -CertStoreLocation "${SHOWASTEXT2}""
|
||||
echo -e "(Clear your browser cache and restart your browser to test.)"
|
||||
printf "${GREY}+-------------------------------------------------------------------------------------------------------------
|
||||
${GREEN}+ LINUX CLIENT SELF SIGNED SSL BROWSER CONFIG - SAVE THIS BEFORE CONTINUING!${GREY}
|
||||
+
|
||||
+ 1. In In ${DOWNLOAD_DIR} is also the Linux native OpenSSL certificate ${LYELLOW}$SSLNAME.crt${GREY}
|
||||
+ 2. Copy this file to a location accessible by Linux.
|
||||
+ 3. Import the CRT file into your Linux client certificate store with the below command (as sudo):
|
||||
\n"
|
||||
echo -e "certutil -d sql:$HOME/.pki/nssdb -A -t "CT,C,c" -n $SSLNAME -i $SSLNAME.crt"
|
||||
echo -e "(If certutil is not installed, run apt-get install libnss3-tools)"
|
||||
printf "+-------------------------------------------------------------------------------------------------------------\n"
|
||||
echo
|
||||
echo -e "${LYELLOW}The above SSL browser config instructions are also saved in ${LGREEN}$LOG_LOCATION${GREY}"
|
||||
echo
|
||||
|
||||
# Reload everything
|
||||
echo -e "${GREY}Restaring Guacamole & Ngnix..."
|
||||
sudo systemctl restart $TOMCAT_VERSION
|
||||
sudo systemctl restart guacd
|
||||
sudo systemctl restart nginx
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Done
|
||||
echo -e ${NC}
|
||||
158
4b-install-ssl-letsencrypt-nginx.sh
Normal file
158
4b-install-ssl-letsencrypt-nginx.sh
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add Let's Encrypt SSL Certificates to Guacamole with Nginx reverse proxy
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# 4b of 4
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
GREY='\033[0;37m'
|
||||
RED='\033[0;31m'
|
||||
LGREEN='\033[0;92m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
# Announce which script you're running
|
||||
echo -e "${GREY}"
|
||||
echo -e "Let's Encrypt SSL configuration for Nginx.."
|
||||
|
||||
############################################################################
|
||||
# If running this script standalone un-comment entire below section as we need
|
||||
# the correct $PROXY_SITE, LE_DNS_NAME and LE_EMAIL values to reconfigure Nginx
|
||||
|
||||
#TOMCAT_VERSION="tomcat9"
|
||||
#LOG_LOCATION=$(eval echo ~${SUDO_USER})/lets-encrypt-inst.log
|
||||
#DOWNLOAD_DIR=$(eval echo ~${SUDO_USER})
|
||||
#GUAC_URL=http://localhost:8080/guacamole/
|
||||
#for file in "/etc/nginx/sites-enabled"/*
|
||||
#do
|
||||
#PROXY_SITE="${file##*/}"
|
||||
#done
|
||||
#echo
|
||||
#echo -e "${GREY}Discovering exising proxy sites to configure with SSL...${GREY}"
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
# exit 1
|
||||
# else
|
||||
# echo -e "${LGREEN}OK${GREY}"
|
||||
#fi
|
||||
|
||||
# Get domain name for new Let's encrypt certificate
|
||||
#while true
|
||||
#do
|
||||
#echo -e "${LGREEN}"
|
||||
#read -p "Enter the public FQDN for your proxy site: " LE_DNS_NAME
|
||||
#echo
|
||||
# [ "${LE_DNS_NAME}" != "" ] && break
|
||||
#done
|
||||
|
||||
# Get admin email for Let's encrypt certificate notifications
|
||||
#while true
|
||||
#do
|
||||
#echo -e "${LGREEN}"
|
||||
#read -p "Enter the email address for Let's Encrypt notifications : " LE_EMAIL
|
||||
#echo
|
||||
# [ "${LE_EMAIL}" != "" ] && break
|
||||
#done
|
||||
|
||||
#echo -e "${GREY}"
|
||||
|
||||
############################################################################
|
||||
|
||||
# Install nginx
|
||||
apt-get update
|
||||
apt-get install nginx certbot python3-certbot-nginx -y &>> ${LOG_LOCATION}
|
||||
|
||||
# Backup the current Nginx config
|
||||
cp /etc/nginx/sites-enabled/${PROXY_SITE} $DOWNLOAD_DIR/${PROXY_SITE}-nginx.bak
|
||||
echo
|
||||
echo -e "${GREY}Backing up previous Nginx proxy to $DOWNLOAD_DIR/$PROXY_SITE-nginx.bak"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Configure Nginx to accept the new certificates
|
||||
cat > /etc/nginx/sites-available/$PROXY_SITE <<EOL
|
||||
server {
|
||||
listen 80 default_server;
|
||||
#listen [::]:80 default_server;
|
||||
root /var/www/html;
|
||||
index index.html index.htm index.nginx-debian.html;
|
||||
server_name $PROXY_SITE;
|
||||
location / {
|
||||
proxy_pass $GUAC_URL;
|
||||
proxy_buffering off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
echo -e "${GREY}Configuring Nginx proxy for Let's Encrypt SSL and setting up automatic HTTP redirect...${GREY}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Bounce Nginx to reload the new Nginx config so certbot config can start continue
|
||||
systemctl restart nginx
|
||||
|
||||
# Run certbot to create and associate certificates with currenly public IP (must have tcp 80 and 443 open to work)
|
||||
certbot --nginx -n -d $LE_DNS_NAME --email $LE_EMAIL --agree-tos --redirect --hsts
|
||||
echo -e
|
||||
echo -e "${GREY}Let's Encrypt successfully installed. Check for errors above (DNS & firewall are usual culprits).${GREY}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Select a random daily time to schedule a daily check for Let's Encrypt certificates due to expire in next 30 days.
|
||||
# If are any due to expire within a 30 day window, Certbot will attempt to renew automatically renew.
|
||||
echo -e "${GREY}Scheduling automatic certificate renewals for certificates with < 30 days till expiry.)${GREY}"
|
||||
#Dump out the current crontab
|
||||
crontab -l > cron_1 &>> ${LOG_LOCATION}
|
||||
# Remove any previosly added certbot renewal entries
|
||||
sed -i '/# certbot renew/d' cron_1
|
||||
# Randomly choose a daily update schedule and append this to the cron schedule
|
||||
HOUR=$(shuf -i 0-23 -n 1)
|
||||
MINUTE=$(shuf -i 0-59 -n 1)
|
||||
echo "${MINUTE} ${HOUR} * * * /usr/bin/certbot renew --quiet --pre-hook 'service nginx stop' --post-hook 'service nginx start'" >> cron_1
|
||||
# Overwrite old cron settings and cleanup
|
||||
crontab cron_1 &>> ${LOG_LOCATION}
|
||||
rm cron_1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Reload everything once again
|
||||
echo -e "${GREY}Restaring Guacamole & Ngnix..."
|
||||
sudo systemctl restart $TOMCAT_VERSION
|
||||
sudo systemctl restart guacd
|
||||
sudo systemctl restart nginx
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed. See ${LOG_LOCATION}${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}OK${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# Done
|
||||
echo -e ${NC}
|
||||
53
README.md
Normal file
53
README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Guacamole 1.5.0 RDP jump server appliance with MFA, Active Directory integration & Nginx SSL reverse proxy
|
||||
|
||||
## Automatic build, install & config script:
|
||||
|
||||
wget https://raw.githubusercontent.com/itiligent/Guacamole-Setup/main/1-setup.sh && chmod +x 1-setup.sh && ./1-setup.sh
|
||||
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
Ubuntu / Debian / Raspian
|
||||
Min 8GB RAM, 40GB HDD
|
||||
Public or private DNS entries matching the default physical interface IP address. (needed for SSL)
|
||||
Incoming access on tcp 22, 80 & 443
|
||||
|
||||
|
||||
### All install variables can be set from the first setup script. i.e. Guacamole, Tomcat & MySQL connector versions etc. Follow on screen prompts to install Guacamole, Nginx & SSL.
|
||||
|
||||
### Scripted setup options are:
|
||||
|
||||
### 1. Install default Guacamole with either a local MySQL database or with a remote MySQL instance
|
||||
|
||||
a. Add Guacamole MFA and Auth extensions (DUO, TOTP, LDAP)
|
||||
b. Add MySQL mysql_secure_installation settings
|
||||
|
||||
### 2. Optionally add a reverse proxy front end to Guacamole of either:
|
||||
|
||||
a) None: Skip Nginx and keep the default Guacamole front end e.g. http://hostname:8080/guacamole
|
||||
b) Install Nginx with NO SSL (http 80) e.g. http://hostname.local
|
||||
c) Install Nginx with SELF SIGNED SSL certificates e.g. https://hostname.local
|
||||
- includes client certificates for Windows & Linux browsers with final SSL client setup instructions.
|
||||
d) Install Nginx with LET'S ENCRYPT certificates e.g. https://public.site.com
|
||||
|
||||
### 3. After installation, optional hardening scripts are included for :
|
||||
a. Adding a fail2ban lockdown policy for Guacamole
|
||||
b. Encryption of internal traffic between the Gaucamole client and Guacd deamon with SSL
|
||||
To do list: Create hardening scripts for Nginx & MFA for shell access)
|
||||
|
||||
### Items downloaded with the setup command above are setup are placed in the $DOWNLOAD_DIR/guacamole-setup dir as follows
|
||||
1. 1-setup.sh - the parent install script itself
|
||||
2. 2-install-guacamole.sh - Guacamole install script (inspired by https://github.com/MysticRyuujin/guac-install)
|
||||
3. 3-install-nginx.sh - Installs Nginx and auto configures as a front end for Guacamole (optional)
|
||||
4. 4a-install-ssl-self-signed-nginx.sh - Configures self signed ssl certs for Nginx (optional)
|
||||
5. 4b-install-ssl-letsencrypt-nginx.sh - Installs and configures Let's Encrypt with Guacamole and Nginx (optional)
|
||||
6. add-auth-duo.sh - Adds the Duo MFA extensions if not selected at install (optional)
|
||||
7. add-auth-ldap.sh - Adds the LDAP Active Directory extension and guides the specific LDAP setup requirements (optional)
|
||||
8. add-auth-totp.sh - Adds the TOTP MFA extension if not selected at install (optional)
|
||||
9. add-ssl-guac-gaucd.sh - A hardening script to wrap an extra ssl layer between the guacd server and the Guacamole client (optional)
|
||||
10. add-fail2ban.sh - Adds and configures fail2ban to secure Guacamole against brute force attacks
|
||||
11. backup-guacamole.sh - A simple Guacamole backup script
|
||||
12. branding.jar - An extension to customise the Guacomole login screen (optional)
|
||||
see: https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension
|
||||
|
||||
Special acknowledgement to MysticRyuujin @ https://github.com/MysticRyuujin/guac-install and Zer0CoolX @ https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension whos repos were a helpful source of ideas in assembling this project.
|
||||
67
add-auth-duo.sh
Normal file
67
add-auth-duo.sh
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add Duo (MFA) support to Guacamole
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
clear
|
||||
|
||||
if ! [ $( id -u ) = 0 ]; then
|
||||
echo
|
||||
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GUAC_VERSION=
|
||||
TOMCAT_VERSION=
|
||||
GUAC_SOURCE_LINK=
|
||||
echo
|
||||
wget -q --show-progress -O guacamole-auth-duo-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-duo-${GUAC_VERSION}.tar.gz
|
||||
tar -xzf guacamole-auth-duo-${GUAC_VERSION}.tar.gz
|
||||
echo
|
||||
mv -f guacamole-auth-duo-${GUAC_VERSION}/guacamole-auth-duo-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
chmod 664 /etc/guacamole/extensions/guacamole-auth-duo-${GUAC_VERSION}.jar
|
||||
echo "duo-integration-key: " >> /etc/guacamole/guacamole.properties
|
||||
echo "duo-secret-key: " >> /etc/guacamole/guacamole.properties
|
||||
echo "duo-api-hostname: " >> /etc/guacamole/guacamole.properties
|
||||
echo "duo-application-key: " >> /etc/guacamole/guacamole.properties
|
||||
|
||||
systemctl restart ${TOMCAT_VERSION}
|
||||
sudo systemctl restart guacd
|
||||
|
||||
echo -e "${LYELLOW}You must now set up your online Duo account with a new 'Web SDK' application."
|
||||
echo
|
||||
echo "Next you must copy the API settings from your Duo account into /etc/guacamole/guacamole.properties in the EXACT below format."
|
||||
echo -e "Be VERY careful to avoid extra trailing spaces or other line feed characters when pasting!${GREY}"
|
||||
echo
|
||||
echo "duo-integration-key: ??????????"
|
||||
echo "duo-api-hostname: ??????????"
|
||||
echo "duo-secret-key: ??????????"
|
||||
echo "duo-application-key: (this is locally created - run 'pwgen 40 1' to manually generate this 40 char random value)"
|
||||
echo
|
||||
echo "Once this change is complete, restart Guacamole with sudo systemctl restart tomcat9"
|
||||
|
||||
rm -rf guacamole-*
|
||||
|
||||
echo
|
||||
echo -e ${NC}
|
||||
80
add-auth-ldap.sh
Normal file
80
add-auth-ldap.sh
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add Active Directory integration with Guacamole
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
clear
|
||||
|
||||
# Check if user is root or sudo
|
||||
|
||||
if ! [ $( id -u ) = 0 ]; then
|
||||
echo
|
||||
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GUAC_VERSION=
|
||||
TOMCAT_VERSION=
|
||||
GUAC_SOURCE_LINK=
|
||||
echo
|
||||
echo -e "${LYELLOW}Have you updated this script to reflect your Active Directory settings?${NC}"
|
||||
|
||||
read -p "Do you want to proceed? (yes/no) " yn
|
||||
echo
|
||||
case $yn in
|
||||
y ) echo Beginning LDAP auth config...;;
|
||||
n ) echo exiting...;
|
||||
exit;;
|
||||
* ) echo invalid response;
|
||||
exit 1;;
|
||||
esac
|
||||
|
||||
echo
|
||||
wget -q --show-progress -O guacamole-auth-ldap-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-ldap-${GUAC_VERSION}.tar.gz
|
||||
tar -xzf guacamole-auth-ldap-${GUAC_VERSION}.tar.gz
|
||||
echo
|
||||
echo Adding the below config to /etc/guacamole/guacamole.properties
|
||||
cat <<EOF | sudo tee -a /etc/guacamole/guacamole.properties
|
||||
ldap-hostname: dc1.yourdomain.com dc2.yourdomain.com
|
||||
ldap-port: 389
|
||||
ldap-username-attribute: sAMAccountName
|
||||
ldap-encryption-method: none
|
||||
ldap-search-bind-dn: ad-account@yourdomain.com
|
||||
ldap-search-bind-password: ad-account-password
|
||||
ldap-config-base-dn: dc=domain,dc=com
|
||||
ldap-user-base-dn: OU=SomeOU,DC=domain,DC=com
|
||||
ldap-user-search-filter:(objectClass=user)(!(objectCategory=computer))
|
||||
ldap-max-search-results:200
|
||||
EOF
|
||||
|
||||
mv -f guacamole-auth-ldap-${GUAC_VERSION}/guacamole-auth-ldap-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
sudo chmod 664 /etc/guacamole/extensions/guacamole-auth-ldap-${GUAC_VERSION}.jar
|
||||
sudo systemctl restart ${TOMCAT_VERSION}
|
||||
sudo systemctl restart guacd
|
||||
|
||||
rm -rf guacamole-*
|
||||
|
||||
echo
|
||||
echo "Done!"
|
||||
echo -e ${NC}
|
||||
50
add-auth-totp.sh
Normal file
50
add-auth-totp.sh
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add TOTP (MFA) support for Guacamole
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
clear
|
||||
|
||||
if ! [ $( id -u ) = 0 ]; then
|
||||
echo
|
||||
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GUAC_VERSION=
|
||||
TOMCAT_VERSION=
|
||||
GUAC_SOURCE_LINK=
|
||||
echo
|
||||
wget -q --show-progress -O guacamole-auth-totp-${GUAC_VERSION}.tar.gz ${GUAC_SOURCE_LINK}/binary/guacamole-auth-totp-${GUAC_VERSION}.tar.gz
|
||||
tar -xzf guacamole-auth-totp-${GUAC_VERSION}.tar.gz
|
||||
mv -f guacamole-auth-totp-${GUAC_VERSION}/guacamole-auth-totp-${GUAC_VERSION}.jar /etc/guacamole/extensions/
|
||||
chmod 664 /etc/guacamole/extensions/guacamole-auth-totp-${GUAC_VERSION}.jar
|
||||
systemctl restart ${TOMCAT_VERSION}
|
||||
systemctl restart guacd
|
||||
|
||||
rm -rf guacamole-*
|
||||
|
||||
echo
|
||||
echo "Done!"
|
||||
echo -e ${NC}
|
||||
276
add-fail2ban.sh
Normal file
276
add-fail2ban.sh
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Add fail2ban restrictions to Guacamole
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
clear
|
||||
|
||||
if ! [ $( id -u ) = 0 ]; then
|
||||
echo
|
||||
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialise variables
|
||||
FAIL2BAN_BASE=""
|
||||
FAIL2BAN_GUAC=""
|
||||
FAIL2BAN_NGINX=""
|
||||
FAIL2BAN_SSH=""
|
||||
TOMCAT_VERSION=
|
||||
|
||||
#Clean up from any previous runs
|
||||
rm -f /tmp/fail2ban.conf
|
||||
rm -f /tmp/ip_list.txt
|
||||
rm -f /tmp/netaddr.txt
|
||||
rm -f /tmp/fail2ban.update
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Start setup prompts #################################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
# Prompt to install fail2ban base app, default of yes
|
||||
if [[ -z ${FAIL2BAN_BASE} ]]; then
|
||||
echo
|
||||
echo -e -n "${LGREEN}Install Fail2ban? [default y]: ${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Nn]$ ]]; then
|
||||
FAIL2BAN_BASE=false
|
||||
else
|
||||
FAIL2BAN_BASE=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt to install Guacamole fail2ban config defaults, default of no
|
||||
if [[ -z ${FAIL2BAN_GUAC} ]] && [[ "${FAIL2BAN_BASE}" = true ]]; then
|
||||
echo -e -n "${GREY}POLICY: Apply Guacamole fail2ban security policy? (y/n) [default n]:${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
FAIL2BAN_GUAC=true
|
||||
else
|
||||
FAIL2BAN_GUAC=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt to install Nginx fail2ban config defaults , default of no
|
||||
if [[ -z ${FAIL2BAN_NGINX} ]] && [[ "${FAIL2BAN_BASE}" = true ]]; then
|
||||
echo -e -n "${GREY}POLICY: Apply Nginx fail2ban security policy? (y/n) [default n]:${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
FAIL2BAN_NGINX=true
|
||||
else
|
||||
FAIL2BAN_NGINX=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prompt to install SSH fail2ban config defaults , default of no
|
||||
if [[ -z ${FAIL2BAN_SSH} ]] && [[ "${FAIL2BAN_BASE}" = true ]]; then
|
||||
echo -e -n "${GREY}POLICY: Apply SSH fail2ban security policy? (y/n) [default n]:${GREY}"
|
||||
read PROMPT
|
||||
if [[ ${PROMPT} =~ ^[Yy]$ ]]; then
|
||||
FAIL2BAN_SSH=true
|
||||
else
|
||||
FAIL2BAN_SSH=false
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Fail2ban base setup #################################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
# Install base fail2ban base application (no policy defined yet)
|
||||
if [ "${FAIL2BAN_BASE}" = true ]; then
|
||||
|
||||
#Update and install fail2ban (and john for management of config file updates)
|
||||
sudo apt-get update > /dev/null 2>&1
|
||||
sudo apt-get install fail2ban john -y > /dev/null 2>&1
|
||||
|
||||
# Create the basic jail.local template
|
||||
cat > /tmp/fail2ban.conf <<EOF
|
||||
[DEFAULT]
|
||||
destemail = yourname@example.com
|
||||
sender = yourname@example.com
|
||||
action = %(action_mwl)s
|
||||
ignoreip =
|
||||
EOF
|
||||
|
||||
# We need to discover all interfaces to ascertain what network ranges to add to fail2ban "ignoreip" policy override defaults
|
||||
ip -o addr show up primary scope global | while read -r num dev fam addr rest; do echo ${addr%*}; done | cat > /tmp/ip_list.txt
|
||||
|
||||
# Loop the list of discovered ips and extract the subnet ID addresses for each interface
|
||||
FILE=/tmp/ip_list.txt
|
||||
LINES=$(cat $FILE)
|
||||
for LINE in $LINES
|
||||
|
||||
do
|
||||
|
||||
tonum() {
|
||||
if [[ $LINE =~ ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+) ]]; then
|
||||
addr=$(( (${BASH_REMATCH[1]} << 24) + (${BASH_REMATCH[2]} << 16) + (${BASH_REMATCH[3]} << 8) + ${BASH_REMATCH[4]} ))
|
||||
eval "$2=\$addr"
|
||||
fi
|
||||
}
|
||||
toaddr() {
|
||||
b1=$(( ($1 & 0xFF000000) >> 24))
|
||||
b2=$(( ($1 & 0xFF0000) >> 16))
|
||||
b3=$(( ($1 & 0xFF00) >> 8))
|
||||
b4=$(( $1 & 0xFF ))
|
||||
eval "$2=\$b1.\$b2.\$b3.\$b4"
|
||||
}
|
||||
|
||||
if [[ $LINE =~ ^([0-9\.]+)/([0-9]+)$ ]]; then
|
||||
# CIDR notation
|
||||
IPADDR=${BASH_REMATCH[1]}
|
||||
NETMASKLEN=${BASH_REMATCH[2]}
|
||||
PREFIX=$NETMASKLEN
|
||||
zeros=$((32-NETMASKLEN))
|
||||
NETMASKNUM=0
|
||||
for (( i=0; i<$zeros; i++ )); do
|
||||
NETMASKNUM=$(( (NETMASKNUM << 1) ^ 1 ))
|
||||
done
|
||||
NETMASKNUM=$((NETMASKNUM ^ 0xFFFFFFFF))
|
||||
toaddr $NETMASKNUM NETMASK
|
||||
else
|
||||
IPADDR=${1:-192.168.1.1}
|
||||
NETMASK=${2:-255.255.255.0}
|
||||
fi
|
||||
|
||||
tonum $IPADDR IPADDRNUM
|
||||
tonum $NETMASK NETMASKNUM
|
||||
|
||||
# The logic to calculate network and broadcast
|
||||
INVNETMASKNUM=$(( 0xFFFFFFFF ^ NETMASKNUM ))
|
||||
NETWORKNUM=$(( IPADDRNUM & NETMASKNUM ))
|
||||
BROADCASTNUM=$(( INVNETMASKNUM | NETWORKNUM ))
|
||||
|
||||
toaddr $NETWORKNUM NETWORK
|
||||
toaddr $BROADCASTNUM BROADCAST
|
||||
|
||||
# Reverse engineer the subnet ID from the calcualted IP address and subnet prefix
|
||||
IFS=. read -r i1 i2 i3 i4 <<< "$IPADDR"
|
||||
IFS=. read -r m1 m2 m3 m4 <<< "$NETMASK"
|
||||
|
||||
# Lay out the subnet ID address as a variable
|
||||
printf -v NETADDR "%d.%d.%d.%d" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
|
||||
|
||||
#Dump out the calcualted subnet IDs to a file
|
||||
echo $NETADDR"/"$NETMASKLEN | tr '\n' ' ' | cat >> /tmp/netaddr.txt
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if [ "${FAIL2BAN_BASE}" = true ]; then
|
||||
# Now the above loop is done, append the single loopback address to all the discovered the subnet IDs in a single line
|
||||
sed -i 's/^/127.0.0.1\/24 /' /tmp/netaddr.txt
|
||||
|
||||
# Finally assemble the entire syntaxt of the ignoreip whitelist for insertion into the base fail2ban config
|
||||
SED_IGNORE=$(echo "ignoreip = ")
|
||||
SED_NETADDR=$(cat /tmp/netaddr.txt)
|
||||
sed -i "s|ignoreip \=|${SED_IGNORE}${SED_NETADDR}|g" /tmp/fail2ban.conf
|
||||
|
||||
# Move the new base fail2ban config to the jail.local file
|
||||
touch /etc/fail2ban/jail.local
|
||||
|
||||
# Apply thhe 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'
|
||||
|
||||
# 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 relaod the new config
|
||||
sudo systemctl restart fail2ban
|
||||
|
||||
# Done
|
||||
echo
|
||||
echo -e "${LGREEN}Fail2ban installed.${GREY}"
|
||||
echo
|
||||
|
||||
else
|
||||
echo -e "${LGREEN}Fail2ban setup cancelled.${GREY}"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
#######################################################################################################################
|
||||
# Fail2ban optional setup items #######################################################################################
|
||||
#######################################################################################################################
|
||||
|
||||
# Create the Guacamole jail.local policy template
|
||||
cat > /tmp/fail2ban.conf <<EOF
|
||||
[guacamole]
|
||||
enabled = true
|
||||
port = http,https
|
||||
logpath = /var/log/$TOMCAT_VERSION/catalina.out
|
||||
bantime = 10m
|
||||
findtime = 60m
|
||||
maxretry = 5
|
||||
EOF
|
||||
|
||||
# Apply the new Guacamole jail 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'
|
||||
|
||||
# Backup the defualt Fail2ban Guacamole filter
|
||||
cp /etc/fail2ban/filter.d/guacamole.conf /etc/fail2ban/filter.d/guacamole.conf.bak
|
||||
|
||||
# Remove the default log search regex
|
||||
sudo bash -c 'sed -e "/Authentication attempt from/ s/^#*/#/" -i /etc/fail2ban/filter.d/guacamole.conf'
|
||||
|
||||
# Create a new log search regex specific for tomcat logs (as a variable due to complexity of characters for sed syntax)
|
||||
REGEX='failregex = ^.*WARN o\.a\.g\.r\.auth\.AuthenticationService - Authentication attempt from <HOST> for user "[^"]*" failed\.$'
|
||||
#Insert the new regex
|
||||
sed -i -e "/Authentication attempt from/a ${REGEX}" /etc/fail2ban/filter.d/guacamole.conf
|
||||
|
||||
# Bounce the service to relaod the new config
|
||||
sudo systemctl restart fail2ban
|
||||
|
||||
# Clean up
|
||||
rm -f /tmp/fail2ban.conf
|
||||
rm -f /tmp/ip_list.txt
|
||||
rm -f /tmp/netaddr.txt
|
||||
rm -f /tmp/fail2ban.update
|
||||
|
||||
# Done
|
||||
echo -e "${LGREEN}Guacamole security policy applied${GREY}\n-${SED_NETADDR}are whitelisted from all IP bans.\n- To alter the whitelist edit /etc/fail2ban/jail.local & sudo systemctl restart fail2ban"
|
||||
echo
|
||||
|
||||
|
||||
############## Start Fail2ban NGINX security policy option ###############
|
||||
if [ "${FAIL2BAN_NGINX}" = true ]; then
|
||||
echo -e "${LGREEN}Nginx Fail2ban policy not implemented yet.${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
############### Start Fail2ban SSH security policy option ################
|
||||
if [ "${FAIL2BAN_SSH}" = true ]; then
|
||||
echo -e "${LGREEN}SSH Fail2ban policy not implemented yet..${GREY}"
|
||||
echo
|
||||
fi
|
||||
|
||||
#Done
|
||||
echo -e ${NC}
|
||||
96
add-ssl-guac-gaucd.sh
Normal file
96
add-ssl-guac-gaucd.sh
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Harden Guacd <-> Guac client traffic in SSL wrapper
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
clear
|
||||
|
||||
if ! [ $( id -u ) = 0 ]; then
|
||||
echo
|
||||
echo -e "${LGREEN}Please run this script as sudo or root${NC}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create the special directory for guacd ssl certfifacte and key.
|
||||
sudo mkdir /etc/guacamole/ssl
|
||||
echo
|
||||
cat <<EOF | tee -a cert_attributes.txt
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
x509_extensions = v3_req
|
||||
prompt = no
|
||||
string_mask = utf8only
|
||||
|
||||
[req_distinguished_name]
|
||||
C = AU
|
||||
ST = Victoria
|
||||
L = Melbourne
|
||||
O = Itiligent
|
||||
OU = I.T.
|
||||
CN = localhost
|
||||
|
||||
[v3_req]
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = localhost
|
||||
IP.1 = 127.0.0.1
|
||||
EOF
|
||||
|
||||
# Create the self signining request, certificate & key
|
||||
sudo openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /etc/guacamole/ssl/guacd.key -out /etc/guacamole/ssl/guacd.crt -config cert_attributes.txt
|
||||
rm -f cert_attributes.txt
|
||||
|
||||
# Point Gaucamole config file to certificate any key
|
||||
sudo cat <<EOF | sudo tee /etc/guacamole/guacd.conf
|
||||
[server]
|
||||
bind_host = 127.0.0.1
|
||||
bind_port = 4822
|
||||
[ssl]
|
||||
server_certificate = /etc/guacamole/ssl/guacd.crt
|
||||
server_key = /etc/guacamole/ssl/guacd.key
|
||||
EOF
|
||||
|
||||
# Enable SSL backend
|
||||
sudo cat <<EOF | sudo tee -a /etc/guacamole/guacamole.properties
|
||||
guacd-ssl: true
|
||||
EOF
|
||||
|
||||
# Fix required permissions as guacd only runs as daemon
|
||||
sudo chown daemon:daemon /etc/guacamole/ssl
|
||||
sudo chown daemon:daemon /etc/guacamole/ssl/guacd.key
|
||||
sudo chown daemon:daemon /etc/guacamole/ssl/guacd.crt
|
||||
sudo chmod 644 /etc/guacamole/ssl/guacd.crt
|
||||
sudo chmod 644 /etc/guacamole/ssl/guacd.key
|
||||
|
||||
# Add the new certificate into the Java Runtime certificate store and set JRE to trust it.
|
||||
cd /etc/guacamole/ssl
|
||||
sudo keytool -importcert -alias guacd -noprompt -cacerts -storepass changeit -file guacd.crt
|
||||
sudo systemctl restart guacd
|
||||
|
||||
echo
|
||||
echo "Done!"
|
||||
echo -e ${NC}
|
||||
75
backup-guac.sh
Normal file
75
backup-guac.sh
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#!/bin/bash
|
||||
#######################################################################################################################
|
||||
# Guacamole MySQL Database Backup
|
||||
# For Ubuntu / Debian / Raspian
|
||||
# David Harrop
|
||||
# April 2023
|
||||
#######################################################################################################################
|
||||
|
||||
# Prepare text output colours
|
||||
GREY='\033[0;37m'
|
||||
DGREY='\033[0;90m'
|
||||
GREYB='\033[1;37m'
|
||||
RED='\033[0;31m'
|
||||
LRED='\033[0;91m'
|
||||
GREEN='\033[0;32m'
|
||||
LGREEN='\033[0;92m'
|
||||
YELLOW='\033[0;33m'
|
||||
LYELLOW='\033[0;93m'
|
||||
BLUE='\033[0;34m'
|
||||
LBLUE='\033[0;94m'
|
||||
CYAN='\033[0;36m'
|
||||
LCYAN='\033[0;96m'
|
||||
MAGENTA='\033[0;35m'
|
||||
LMAGENTA='\033[0;95m'
|
||||
NC='\033[0m' #No Colour
|
||||
|
||||
clear
|
||||
|
||||
export PATH=/bin:/usr/bin:/usr/local/bin
|
||||
TODAY=`date +%Y-%m-%d`
|
||||
MYSQL_HOST=
|
||||
MYSQL_PORT=
|
||||
GUAC_USER=
|
||||
GUAC_PWD=
|
||||
GUAC_DB=
|
||||
DB_BACKUP_DIR=
|
||||
ALERT_EMAIL=
|
||||
BACKUP_RETAIN_DAYS=
|
||||
|
||||
# Protect disk space and remove backups older than {BACKUP_RETAIN_DAYS} days
|
||||
find ${DB_BACKUP_DIR} -mtime +${BACKUP_RETAIN_DAYS} -delete
|
||||
|
||||
# Backup code
|
||||
mkdir -p ${DB_BACKUP_DIR}
|
||||
echo
|
||||
echo -e "${LGREEN}Backup started for database - ${GUAC_DB}"
|
||||
echo
|
||||
|
||||
mysqldump -h ${MYSQL_HOST} \
|
||||
-P ${MYSQL_PORT} \
|
||||
-u ${GUAC_USER} \
|
||||
-p${GUAC_PWD} \
|
||||
${GUAC_DB} \
|
||||
--single-transaction --quick --lock-tables=false > \
|
||||
${DB_BACKUP_DIR}${GUAC_DB}-${TODAY}.sql
|
||||
SQLFILE=${DB_BACKUP_DIR}${GUAC_DB}-${TODAY}.sql
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Backup failed.${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}Backup completed ok.${GREY}"
|
||||
echo
|
||||
fi
|
||||
gzip -f ${SQLFILE}
|
||||
# Error check and email alerts
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Backup failed.${GREY}" 1>&2
|
||||
exit 1
|
||||
else
|
||||
echo -e "${LGREEN}${GUAC_DB} backup was successfully copied to ${DB_BACKUP_DIR}"
|
||||
#mailx -s "Guacamomle Database Backup Success" ${ALERT_EMAIL}
|
||||
echo "${GUAC_DB} backup was successfully copied to $DB_BACKUP_DIR}" | mailx -s "Guacamole backup " ${ALERT_EMAIL}
|
||||
fi
|
||||
|
||||
echo -e ${NC}
|
||||
BIN
branding.jar
Normal file
BIN
branding.jar
Normal file
Binary file not shown.
39
useful-commands.txt
Normal file
39
useful-commands.txt
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
kill Nginx!! (slow loris load testing)
|
||||
|
||||
https://ourcodeworld.com/articles/read/949/how-to-perform-a-dos-attack-slow-http-with-slowhttptest-test-your-server-slowloris-protection-in-kali-linux
|
||||
|
||||
slowhttptest -c 10000 -H -g -o ./output_file -i 3 -r 500 -t GET -u http://jumpbox.domain.com -x 24 -p 2
|
||||
|
||||
|
||||
## UAudit Guacamole Connections and User access.##
|
||||
|
||||
Query current connection profile allocations
|
||||
|
||||
mysql -u root -p guacamole_db
|
||||
|
||||
select
|
||||
guacamole_entity.name,
|
||||
guacamole_connection.connection_name,
|
||||
guacamole_connection_permission.permission
|
||||
from
|
||||
guacamole_connection
|
||||
left join guacamole_connection_permission on guacamole_connection_permission.connection_id = guacamole_connection.connection_id
|
||||
left join guacamole_entity on guacamole_entity.entity_id = guacamole_connection_permission.entity_id
|
||||
where
|
||||
guacamole_connection_permission.permission = 'READ'
|
||||
and guacamole_entity.name != 'guacadmin';
|
||||
|
||||
Quit to exit
|
||||
|
||||
|
||||
## Reset TOTP configuration for a user account
|
||||
## This is likely not needed in Gucamole 1.40 as the gui provides an option to reset. Kept for reference.
|
||||
|
||||
mysql -u root -p
|
||||
|
||||
use guacamol_db;
|
||||
|
||||
SELECT user_id FROM guacamole_user INNER JOIN guacamole_entity ON guacamole_entity.entity_id = guacamole_user.entity_id WHERE guacamole_entity.name = 'guacadmin';
|
||||
|
||||
UPDATE guacamole_user_attribute SET attribute_value='false' WHERE attribute_name = 'guac-totp-key-confirmed' and user_id = '1';
|
||||
quit;
|
||||
Loading…
Add table
Reference in a new issue