#!/bin/bash set -euo pipefail # ============================================================ # Guacamole Install Script (Ubuntu 24.04+, ARM/AMD) # With built-in monitoring (screen + htop + iftop + logs) # ============================================================ GUACVERSION="1.5.5" GUAC_USER="guacamole_user" GUAC_DB="guacamole_db" TOMCAT_VER=9.0.109 CRED_FILE="/root/guacamole-credentials.txt" # Temporary bootstrap passwords MYSQL_ROOT_PWD="root" GUAC_PWD="guac" YELLOW='\033[1;33m' BLUE='\033[0;34m' RED='\033[0;31m' GREEN='\033[0;32m' NC='\033[0m' log() { echo -e "$@"; } # ============================================================ # Monitoring setup (tmux split screen) # ============================================================ if [ -z "${INSIDE_TMUX:-}" ]; then apt-get update -y apt-get install -y tmux htop iftop export INSIDE_TMUX=1 SCRIPT_CMD="INSIDE_TMUX=1 $(realpath $0) $@" tmux new-session -d -s guac-install "echo '>>> Running: $SCRIPT_CMD'; sleep 3; $SCRIPT_CMD" tmux split-window -h "htop" tmux split-window -v -t 0 "iftop -i \$(ip -o -4 route show to default | awk '{print \$5}' | head -n1)" tmux split-window -v -t 1 "tail -f /var/log/syslog" tmux select-layout tiled tmux attach -t guac-install exit 0 fi # ============================================================ # Hostname detection (reverse DNS of IPv4) # ============================================================ SERVER_NAME=${SERVER_NAME:-} if [ -z "$SERVER_NAME" ]; then PUBIP=$(curl -4 -s ifconfig.me || echo "") if [ -n "$PUBIP" ]; then apt-get install -y -qq dnsutils >/dev/null 2>&1 || true REVNAME=$(dig +short -x $PUBIP @8.8.8.8 | sed 's/\.$//' || true) DEFAULT_NAME=${REVNAME:-$PUBIP} else DEFAULT_NAME="localhost" fi if [ -t 0 ]; then read -p "Enter server name for Nginx/Let's Encrypt [${DEFAULT_NAME}]: " SERVER_NAME SERVER_NAME=${SERVER_NAME:-$DEFAULT_NAME} else SERVER_NAME=$DEFAULT_NAME log "${YELLOW}No SERVER_NAME provided, using default: ${SERVER_NAME}${NC}" fi fi # ============================================================ # Base packages # ============================================================ log "${BLUE}>>> Installing base packages...${NC}" apt-get update -y DEBIAN_FRONTEND=noninteractive apt-get install -yq \ xfce4 xfce4-goodies tightvncserver ufw curl wget zsh dnsutils \ build-essential libjpeg-turbo8-dev libpng-dev libossp-uuid-dev \ libavcodec-dev libavformat-dev libavutil-dev libswscale-dev \ freerdp2-dev libpango1.0-dev libssh2-1-dev libtelnet-dev \ libvncserver-dev libpulse-dev libssl-dev libvorbis-dev libwebp-dev \ libwebsockets-dev freerdp2-x11 libtool-bin ghostscript dpkg-dev crudini \ mariadb-server mariadb-client nginx certbot python3-certbot-nginx openssl # ============================================================ # Java # ============================================================ if ! command -v java >/dev/null 2>&1; then apt-get install -y openjdk-17-jre-headless fi JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java)))) log "${GREEN}JAVA_HOME=${JAVA_HOME}${NC}" # ============================================================ # Firewall # ============================================================ ufw --force enable ufw allow ssh ufw allow 80/tcp ufw allow 443/tcp ufw reload # ============================================================ # Tomcat # ============================================================ if [ ! -d /opt/apache-tomcat-${TOMCAT_VER} ]; then log "${BLUE}>>> Installing Tomcat ${TOMCAT_VER}...${NC}" cd /opt wget -q https://downloads.apache.org/tomcat/tomcat-9/v${TOMCAT_VER}/bin/apache-tomcat-${TOMCAT_VER}.tar.gz tar -xzf apache-tomcat-${TOMCAT_VER}.tar.gz ln -sfn apache-tomcat-${TOMCAT_VER} tomcat9 useradd -r -s /usr/sbin/nologin tomcat || true chown -R tomcat:tomcat /opt/apache-tomcat-${TOMCAT_VER} cat > /etc/systemd/system/tomcat9.service </dev/null 2>&1; then cd guacamole-server-${GUACVERSION} ./configure --with-systemd-dir=/etc/systemd/system make -j$(nproc) make install ldconfig cd .. fi if [ ! -f /etc/systemd/system/guacd.service ]; then cat > /etc/systemd/system/guacd.service <>> Installing JDBC driver for MySQL/MariaDB...${NC}" if apt-cache show libmariadb-java 2>/dev/null | grep -q Package; then apt-get install -y libmariadb-java ln -sf /usr/share/java/mariadb-java-client.jar /etc/guacamole/lib/mysql-connector-java.jar log "${GREEN}MariaDB JDBC connector installed.${NC}" else cd /tmp wget -q https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-8.3.0.tar.gz tar -xzf mysql-connector-j-8.3.0.tar.gz cp mysql-connector-j-8.3.0/mysql-connector-j-8.3.0.jar /etc/guacamole/lib/mysql-connector-java.jar log "${GREEN}MySQL Connector/J installed.${NC}" fi # ============================================================ # MySQL setup # ============================================================ mysql -u root </dev/null; then mysql -u root -p${MYSQL_ROOT_PWD} -e "CREATE DATABASE ${GUAC_DB};" fi USER_EXISTS=$(mysql -u root -p${MYSQL_ROOT_PWD} -e "SELECT COUNT(*) FROM mysql.user WHERE user='${GUAC_USER}';" -s --skip-column-names) if [ "$USER_EXISTS" -eq 0 ]; then mysql -u root -p${MYSQL_ROOT_PWD} -e "CREATE USER '${GUAC_USER}'@'localhost' IDENTIFIED BY '${GUAC_PWD}';" mysql -u root -p${MYSQL_ROOT_PWD} -e "GRANT SELECT,INSERT,UPDATE,DELETE ON ${GUAC_DB}.* TO '${GUAC_USER}'@'localhost'; FLUSH PRIVILEGES;" fi if ! mysql -u root -p${MYSQL_ROOT_PWD} -D ${GUAC_DB} -e "SHOW TABLES;" | grep -q guacamole_user; then cat guacamole-auth-jdbc-${GUACVERSION}/mysql/schema/*.sql | mysql -u root -p${MYSQL_ROOT_PWD} ${GUAC_DB} fi # Inject default VNC and SSH connections mysql -u root -p${MYSQL_ROOT_PWD} ${GUAC_DB} <<'EOF' INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('Default VNC', 'vnc'); SET @CID = LAST_INSERT_ID(); INSERT INTO guacamole_connection_parameter (connection_id, parameter_name, parameter_value) VALUES (@CID, 'hostname', 'localhost'), (@CID, 'port', '5901'); INSERT INTO guacamole_connection_permission (entity_id, connection_id, permission) SELECT entity_id, @CID, perm FROM guacamole_entity, (SELECT 'READ' AS perm UNION ALL SELECT 'UPDATE' UNION ALL SELECT 'DELETE' UNION ALL SELECT 'ADMINISTER') p WHERE name='guacadmin'; INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('Default SSH', 'ssh'); SET @CID = LAST_INSERT_ID(); INSERT INTO guacamole_connection_parameter (connection_id, parameter_name, parameter_value) VALUES (@CID, 'hostname', 'localhost'), (@CID, 'port', '22'); INSERT INTO guacamole_connection_permission (entity_id, connection_id, permission) SELECT entity_id, @CID, perm FROM guacamole_entity, (SELECT 'READ' AS perm UNION ALL SELECT 'UPDATE' UNION ALL SELECT 'DELETE' UNION ALL SELECT 'ADMINISTER') p WHERE name='guacadmin'; EOF mkdir -p /etc/guacamole cat > /etc/guacamole/guacamole.properties < /etc/nginx/sites-available/guacamole < /etc/nginx/sites-available/guacamole <>> Installing Tailscale...${NC}" curl -fsSL https://tailscale.com/install.sh | sh systemctl enable --now tailscaled if [ -t 0 ]; then read -p "Enter Tailscale auth key (leave blank for interactive login): " TSKEY || true else TSKEY="" fi if [ -n "${TSKEY:-}" ]; then tailscale up --authkey=${TSKEY} --ssh else tailscale up --ssh fi # ============================================================ # Rotate MySQL passwords at the end # ============================================================ FINAL_MYSQL_ROOT_PWD=$(openssl rand -base64 20) FINAL_GUAC_PWD=$(openssl rand -base64 20) mysql -u root -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${FINAL_MYSQL_ROOT_PWD}';" mysql -u root -p${FINAL_MYSQL_ROOT_PWD} -e "ALTER USER '${GUAC_USER}'@'localhost' IDENTIFIED BY '${FINAL_GUAC_PWD}'; FLUSH PRIVILEGES;" crudini --set /etc/guacamole/guacamole.properties '' mysql-password "${FINAL_GUAC_PWD}" systemctl restart tomcat9 # ============================================================ # Save credentials # ============================================================ cat > ${CRED_FILE} <