From cbe3bd4158118bf250bc1557d30939f7c2bc0a99 Mon Sep 17 00:00:00 2001 From: saurav Date: Sat, 11 Apr 2026 16:26:14 -0700 Subject: [PATCH 01/23] added mezzsh scripts --- scripts/mezzsh/mezzsh_connect.sh | 43 ++++++++++++++++++++++++ scripts/mezzsh/mezzsh_keygen.sh | 41 +++++++++++++++++++++++ scripts/mezzsh/mezzsh_keystore.sh | 28 ++++++++++++++++ scripts/mezzsh/mezzsh_server.sh | 44 +++++++++++++++++++++++++ scripts/mezzsh/mezzsh_setup.sh | 54 +++++++++++++++++++++++++++++++ scripts/mezzsh/mezzsh_warn.sh | 21 ++++++++++++ 6 files changed, 231 insertions(+) create mode 100644 scripts/mezzsh/mezzsh_connect.sh create mode 100644 scripts/mezzsh/mezzsh_keygen.sh create mode 100644 scripts/mezzsh/mezzsh_keystore.sh create mode 100644 scripts/mezzsh/mezzsh_server.sh create mode 100644 scripts/mezzsh/mezzsh_setup.sh create mode 100644 scripts/mezzsh/mezzsh_warn.sh diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh new file mode 100644 index 0000000000..648daad577 --- /dev/null +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Connects to the Mezz PC +# Receives safety check results from the server, and warns +# the user if other users are currently connected remotely or using in person +# Allows user to force a connection + +TARGET="mezzsh" + +# flag used to force a connection despite warnings +FORCE_FLAG="NORMAL" + +# first, check server status (if other users are using the PC) +RESPONSE=$(ssh -o SendEnv=SSH_CHECK_MODE -t $TARGET "check_status" 2>&1) + +RED='\e[1;31m' +NC='\e[0m' + +# someone is using IRL +if [[ "$RESPONSE" == *"STATUS_BUSY_LOCAL"* ]]; then + echo -e "⚠️ {RED}WARNING{NC}: Someone is physically logged into the PC onsite." + read -p "Do you want to force the connection? (y/n): " choice + + # exits if user does not want to force + [[ "$choice" == [yY] ]] && FORCE_FLAG="FORCE" || exit 1 + +# someone is connected remotely +elif [[ "$RESPONSE" == *"STATUS_BUSY_REMOTE"* ]]; then + echo -e "⚠️ {RED}WARNING{NC}: Other SSH users are connected:" + echo "$RESPONSE" | grep "Connected:" + read -p "Do you want to force the connection? (y/n): " choice + + # exits if user does not want to force + [[ "$choice" == [yY] ]] && FORCE_FLAG="FORCE" || exit 1 +fi + +# if the user wanted to force the connection, does it here +if [ "$FORCE_FLAG" == "FORCE" ]; then + echo "Force connecting..." + ssh -o SendEnv=FORCE_CONNECT=1 -t $TARGET +else + ssh -t $TARGET +fi \ No newline at end of file diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh new file mode 100644 index 0000000000..a2338164ce --- /dev/null +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +PC_ALIAS="mezzsh" + +GREEN='\e[1;32m' +NC='\e[0m' + +# Check for root privileges +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (use sudo)" + exit 1 +fi + +read -p "Enter the PC's IP address: " PC_IP +read -p "Enter a username for yourself. Please make it somewhat recognizable, preferably just your first name: " USERNAME + +KEY_NAME="id_rsa_$PC_ALIAS" +KEY_PATH="$HOME/.ssh/$KEY_NAME" + +echo -e "\n--- Generating SSH Key Pair ---" +ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -C "$USERNAME" -N "" + +echo -e "\n--- Configuring SSH Alias ---" +cat <> "$HOME/.ssh/config" + +Host $PC_ALIAS + HostName $PC_IP + User $USERNAME + IdentityFile $KEY_PATH + SetEnv USERNAME=$USERNAME + SendEnv USERNAME SSH_CHECK_MODE FORCE_CONNECT +EOF + +echo "Adding $PC_IP $PC_ALIAS to /etc/hosts..." +echo "$PC_IP $PC_ALIAS" | sudo tee -a /etc/hosts + +echo -e "\n--- PUBLIC KEY ---" +cat "${KEY_PATH}.pub" +echo "--------------------------------------------" + +echo -e "{GREEN}Success!{NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" \ No newline at end of file diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/mezzsh_keystore.sh new file mode 100644 index 0000000000..696cbab8de --- /dev/null +++ b/scripts/mezzsh/mezzsh_keystore.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Configuration +AUTH_KEYS="$HOME/.ssh/authorized_keys" +SERVER_SCRIPT="./mezzsh_server.sh" + +if [ "$#" -ne 2 ]; then + echo "Usage: sudo ./register_user.sh \"PUBLIC_KEY_STRING\"" + exit 1 +fi + +PUB_KEY="$1" + +echo "--- Registering New Remote User ---" + +# Add to authorized_keys with a command restriction +# We prepend the SERVER_SCRIPT command to the key +ENTRY="command=\"$SERVER_SCRIPT\",environment=\"SSH_CHECK_MODE=1\" $PUB_KEY" + +if grep -q "$PUB_KEY" "$AUTH_KEYS"; then + echo "Error: This public key is already registered." +else + echo "$ENTRY" >> "$AUTH_KEYS" + chmod 600 "$AUTH_KEYS" + echo "Key added to authorized_keys." +fi + +echo "Registration complete." \ No newline at end of file diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/mezzsh_server.sh new file mode 100644 index 0000000000..b3ea382eb2 --- /dev/null +++ b/scripts/mezzsh/mezzsh_server.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# The `who` command returns all logged in users (IRL and remote) +# Finds IRL users by looking for the physical monitor +LOCAL_USER=$(who | grep -E '(:0|tty7)') + +# Finds remote users, who are marked with `pts` +# for each one, finds their username, to make identifying them easier +# excludes the current user, otherwise server will always seem busy +REMOTE_USERS_LIST=$(who | grep pts | grep -v "$(basename $(tty))" | awk '{print $1}') + +# if the client requested a check, return the user info from above +if [ "$SSH_CHECK_MODE" == "1" ]; then + if [ ! -z "$LOCAL_USER" ]; then + echo "STATUS_BUSY_LOCAL" + exit 0 + elif [ ! -z "$REMOTE_USERS" ]; then + echo "STATUS_BUSY_REMOTE" + echo "Connected: $REMOTE_USERS" + exit 0 + fi + exit 0 +fi + +# If the user actually wanted to connect, make sure: +# 1. no other users (IRL or remote) are using the PC +# OR +# 2. the force flag is provided +if ([ ! -z "$LOCAL_USER" ] || [ ! -z "$REMOTE_USERS" ]) && [ "$FORCE_CONNECT" != "1" ]; then + echo "The Mezz Computer is in use! Please use the connect script to see who is currently using it." + + # we technically hae already have an active connection at this point + # just no shell is provided + # close the connection after 1 min + sleep 60 + echo "Connection timed out." + exit 1 +fi + +# Trigger the visual warning dialog if someone is using the PC IRL +./mezzsh_warn.sh & + +# if we get here, start a normal shell +exec $SHELL \ No newline at end of file diff --git a/scripts/mezzsh/mezzsh_setup.sh b/scripts/mezzsh/mezzsh_setup.sh new file mode 100644 index 0000000000..95cda4c379 --- /dev/null +++ b/scripts/mezzsh/mezzsh_setup.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +SERVER_SCRIPT="./mezzsh_server.sh" +TIMEOUT_SECONDS=3600 # 1 hour +SSHD_CONFIG="/etc/ssh/sshd_config" + +# Check for root privileges +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (use sudo)" + exit 1 +fi + +echo "--- Initializing On-Site PC SSH Security Setup ---" + +echo "[1/5] Installing Dependencies" +sudo apt install zenity + +echo "[2/5] Configuring SSH service to start on boot..." +systemctl enable ssh +systemctl start ssh + +echo "[3/5] Modifying sshd_config for custom Environment variables, and to perform safety checks on new connections......" + +# Backup original config +cp $SSHD_CONFIG "${SSHD_CONFIG}.bak" + +# This step uses a match block to modify these ssh settings for only 1 user +# Clean up any previous global ForceCommand we might have added +sed -i '/ForceCommand \/usr\/local\/bin\/gatekeeper.sh/d' $SSHD_CONFIG + +# Append the Match block to the end of the file +cat <> $SSHD_CONFIG +Match User $TARGET_USER + ForceCommand $SERVER_SCRIPT + AcceptEnv USERNAME SSH_CHECK_MODE FORCE_CONNECT +EOF + +echo "[4/5] Setting 1-hour shell timeout..." + +USER_HOME=$(eval echo "~$TARGET_USER") +TIMEOUT_LINE="export TMOUT=$TIMEOUT_SECONDS && readonly TMOUT" + +if [ -d "$USER_HOME" ]; then + # Remove old TMOUT lines if they exist and append new one + sed -i '/TMOUT/d' "$USER_HOME/.bashrc" + echo "$TIMEOUT_LINE" >> "$USER_HOME/.bashrc" + chown $TARGET_USER:$TARGET_USER "$USER_HOME/.bashrc" +else + echo "ERROR: Home directory for $TARGET_USER not found. Timeout not set." +fi + +# 4. Finalizing and Restarting Service +echo "[5/5] Restarting SSH service to apply changes..." +systemctl restart ssh \ No newline at end of file diff --git a/scripts/mezzsh/mezzsh_warn.sh b/scripts/mezzsh/mezzsh_warn.sh new file mode 100644 index 0000000000..cdac4321d3 --- /dev/null +++ b/scripts/mezzsh/mezzsh_warn.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# find the username of the person logged in physically +# we look for someone attached to the main display (:0) +LOCAL_USER=$(who | grep -m 1 "(:0)" | awk '{print $1}') + +# if no one is logged in locally, just exit +if [ -z "$LOCAL_USER" ]; then + exit 0 +fi + +# get the User ID of the local user to access their "session bus" +LOCAL_UID=$(id -u "$LOCAL_USER") + +# Trigger the dialog +# We must set DISPLAY and DBUS_SESSION_BUS_ADDRESS so the script knows +# WHICH screen to pop up on. +sudo -u "$LOCAL_USER" DISPLAY=:0 \ + DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$LOCAL_UID/bus \ + zenity --warning --title="Remote Connection" \ + --text="⚠️ User $USER has just connected via SSH." --timeout=10 & \ No newline at end of file From 7d427178f8d571dd29cb510c5299d7ba9a2c62e5 Mon Sep 17 00:00:00 2001 From: saurav Date: Mon, 13 Apr 2026 22:47:50 -0700 Subject: [PATCH 02/23] add files --- scripts/mezzsh/mezzsh_connect.sh | 2 +- scripts/mezzsh/mezzsh_keygen.sh | 2 +- scripts/mezzsh/mezzsh_keystore.sh | 2 +- scripts/mezzsh/mezzsh_server.sh | 2 +- scripts/mezzsh/mezzsh_setup.sh | 2 +- scripts/mezzsh/mezzsh_warn.sh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index 648daad577..f5175c5cc8 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -40,4 +40,4 @@ if [ "$FORCE_FLAG" == "FORCE" ]; then ssh -o SendEnv=FORCE_CONNECT=1 -t $TARGET else ssh -t $TARGET -fi \ No newline at end of file +fi diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index a2338164ce..d029f75521 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -38,4 +38,4 @@ echo -e "\n--- PUBLIC KEY ---" cat "${KEY_PATH}.pub" echo "--------------------------------------------" -echo -e "{GREEN}Success!{NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" \ No newline at end of file +echo -e "{GREEN}Success!{NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/mezzsh_keystore.sh index 696cbab8de..0b8e3528bb 100644 --- a/scripts/mezzsh/mezzsh_keystore.sh +++ b/scripts/mezzsh/mezzsh_keystore.sh @@ -25,4 +25,4 @@ else echo "Key added to authorized_keys." fi -echo "Registration complete." \ No newline at end of file +echo "Registration complete." diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/mezzsh_server.sh index b3ea382eb2..c01ee14bb8 100644 --- a/scripts/mezzsh/mezzsh_server.sh +++ b/scripts/mezzsh/mezzsh_server.sh @@ -41,4 +41,4 @@ fi ./mezzsh_warn.sh & # if we get here, start a normal shell -exec $SHELL \ No newline at end of file +exec $SHELL diff --git a/scripts/mezzsh/mezzsh_setup.sh b/scripts/mezzsh/mezzsh_setup.sh index 95cda4c379..4d30ee4d8c 100644 --- a/scripts/mezzsh/mezzsh_setup.sh +++ b/scripts/mezzsh/mezzsh_setup.sh @@ -51,4 +51,4 @@ fi # 4. Finalizing and Restarting Service echo "[5/5] Restarting SSH service to apply changes..." -systemctl restart ssh \ No newline at end of file +systemctl restart ssh diff --git a/scripts/mezzsh/mezzsh_warn.sh b/scripts/mezzsh/mezzsh_warn.sh index cdac4321d3..0832ef4443 100644 --- a/scripts/mezzsh/mezzsh_warn.sh +++ b/scripts/mezzsh/mezzsh_warn.sh @@ -18,4 +18,4 @@ LOCAL_UID=$(id -u "$LOCAL_USER") sudo -u "$LOCAL_USER" DISPLAY=:0 \ DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$LOCAL_UID/bus \ zenity --warning --title="Remote Connection" \ - --text="⚠️ User $USER has just connected via SSH." --timeout=10 & \ No newline at end of file + --text="⚠️ User $USER has just connected via SSH." --timeout=10 & From 30e0cd9242a3f07574ec9feb4a7889cecfee668a Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 13 Apr 2026 23:34:30 -0700 Subject: [PATCH 03/23] use tailscale instead --- scripts/mezzsh/mezzsh_connect.sh | 26 +++++++++++++++++++++----- scripts/mezzsh/mezzsh_setup.sh | 18 +++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index f5175c5cc8..fcdbcfd58b 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -3,15 +3,31 @@ # Connects to the Mezz PC # Receives safety check results from the server, and warns # the user if other users are currently connected remotely or using in person -# Allows user to force a connection +# Allows user to force a connection -TARGET="mezzsh" +TAILSCALE_HOSTNAME="thunderbots" + +# 1. Check if tailscale is installed +if ! command -v tailscale &> /dev/null; then + echo "Tailscale not found. Installing..." + curl -fsSL https://tailscale.com/install.sh | sh + sudo tailscale up +fi + +# 2. Get the Tailscale IP of the Main PC +TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) + +if [ -z "$TARGET_IP" ]; then + echo "Could not find Main PC on Tailscale. Are you logged in?" + exit 1 +fi # flag used to force a connection despite warnings FORCE_FLAG="NORMAL" +SSH_TARGET="thunderbots@$TARGET_IP" # first, check server status (if other users are using the PC) -RESPONSE=$(ssh -o SendEnv=SSH_CHECK_MODE -t $TARGET "check_status" 2>&1) +RESPONSE=$(ssh -o SendEnv=SSH_CHECK_MODE -t $SSH_TARGET "check_status" 2>&1) RED='\e[1;31m' NC='\e[0m' @@ -37,7 +53,7 @@ fi # if the user wanted to force the connection, does it here if [ "$FORCE_FLAG" == "FORCE" ]; then echo "Force connecting..." - ssh -o SendEnv=FORCE_CONNECT=1 -t $TARGET + ssh -o SendEnv=FORCE_CONNECT=1 -t $SSH_TARGET else - ssh -t $TARGET + ssh -t $SSH_TARGET fi diff --git a/scripts/mezzsh/mezzsh_setup.sh b/scripts/mezzsh/mezzsh_setup.sh index 4d30ee4d8c..c946d7d859 100644 --- a/scripts/mezzsh/mezzsh_setup.sh +++ b/scripts/mezzsh/mezzsh_setup.sh @@ -1,8 +1,9 @@ #!/bin/bash -SERVER_SCRIPT="./mezzsh_server.sh" +SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/mezzsh_server.sh" TIMEOUT_SECONDS=3600 # 1 hour SSHD_CONFIG="/etc/ssh/sshd_config" +TARGET_USER="thunderbots" # Check for root privileges if [[ $EUID -ne 0 ]]; then @@ -13,10 +14,16 @@ fi echo "--- Initializing On-Site PC SSH Security Setup ---" echo "[1/5] Installing Dependencies" +sudo apt update +sudo apt install openssh-server sudo apt install zenity +# Install Tailscale +curl -fsSL https://tailscale.com/install.sh | sh +sudo tailscale up --hostname=$TARGET_USER --operator=$USER + echo "[2/5] Configuring SSH service to start on boot..." -systemctl enable ssh +systemctl enable --now ssh systemctl start ssh echo "[3/5] Modifying sshd_config for custom Environment variables, and to perform safety checks on new connections......" @@ -26,7 +33,7 @@ cp $SSHD_CONFIG "${SSHD_CONFIG}.bak" # This step uses a match block to modify these ssh settings for only 1 user # Clean up any previous global ForceCommand we might have added -sed -i '/ForceCommand \/usr\/local\/bin\/gatekeeper.sh/d' $SSHD_CONFIG +sed -i '/Match User $TARGET_USER/,/AcceptEnv USERNAME SSH_CHECK_MODE FORCE_CONNECT/d' $SSHD_CONFIG # Append the Match block to the end of the file cat <> $SSHD_CONFIG @@ -38,13 +45,14 @@ EOF echo "[4/5] Setting 1-hour shell timeout..." USER_HOME=$(eval echo "~$TARGET_USER") -TIMEOUT_LINE="export TMOUT=$TIMEOUT_SECONDS && readonly TMOUT" +TIMEOUT_BLOCK='if [ -n "$SSH_TTY" ]; then export TMOUT='$TIMEOUT_SECONDS' && readonly TMOUT; fi' if [ -d "$USER_HOME" ]; then # Remove old TMOUT lines if they exist and append new one sed -i '/TMOUT/d' "$USER_HOME/.bashrc" - echo "$TIMEOUT_LINE" >> "$USER_HOME/.bashrc" + echo $TIMEOUT_BLOCK >> "$USER_HOME/.bashrc" chown $TARGET_USER:$TARGET_USER "$USER_HOME/.bashrc" + echo "Success: SSH timeout set for $TARGET_USER." else echo "ERROR: Home directory for $TARGET_USER not found. Timeout not set." fi From bbfceb580b0f1078433ee4515964e96d5d74b40b Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Fri, 17 Apr 2026 23:16:52 -0700 Subject: [PATCH 04/23] use auth key instead --- scripts/mezzsh/mezzsh_connect.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index fcdbcfd58b..ce6f27efd6 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -11,9 +11,13 @@ TAILSCALE_HOSTNAME="thunderbots" if ! command -v tailscale &> /dev/null; then echo "Tailscale not found. Installing..." curl -fsSL https://tailscale.com/install.sh | sh - sudo tailscale up fi +read -p "Enter the auth key. Please contact a software lead if you don't have one: " AUTH_KEY + +echo "Starting Tailscale..." +sudo tailscale up --auth-key=$AUTH_KEY + # 2. Get the Tailscale IP of the Main PC TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) From b6256963b732e92820dac8eda5741fb16f2b0055 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Fri, 17 Apr 2026 23:40:07 -0700 Subject: [PATCH 05/23] remove uneeded env + add key to pc automatically --- scripts/mezzsh/mezzsh_connect.sh | 11 +------- scripts/mezzsh/mezzsh_keygen.sh | 36 ++++++++++++++----------- scripts/mezzsh/utils/check_tailscale.sh | 26 ++++++++++++++++++ 3 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 scripts/mezzsh/utils/check_tailscale.sh diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index ce6f27efd6..b7668dc440 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -7,16 +7,7 @@ TAILSCALE_HOSTNAME="thunderbots" -# 1. Check if tailscale is installed -if ! command -v tailscale &> /dev/null; then - echo "Tailscale not found. Installing..." - curl -fsSL https://tailscale.com/install.sh | sh -fi - -read -p "Enter the auth key. Please contact a software lead if you don't have one: " AUTH_KEY - -echo "Starting Tailscale..." -sudo tailscale up --auth-key=$AUTH_KEY +bash ./utils/check_tailscale.sh # 2. Get the Tailscale IP of the Main PC TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index d029f75521..abf859c04e 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -1,6 +1,7 @@ #!/bin/bash -PC_ALIAS="mezzsh" +PC_NAME="thunderbots" +ALIAS="mezzsh" GREEN='\e[1;32m' NC='\e[0m' @@ -11,10 +12,19 @@ if [[ $EUID -ne 0 ]]; then exit 1 fi -read -p "Enter the PC's IP address: " PC_IP +bash ./utils/check_tailscale.sh + +# Get the Tailscale IP of the Main PC +TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) + +if [ -z "$TARGET_IP" ]; then + echo "Could not find Main PC on Tailscale. Are you logged in?" + exit 1 +fi + read -p "Enter a username for yourself. Please make it somewhat recognizable, preferably just your first name: " USERNAME -KEY_NAME="id_rsa_$PC_ALIAS" +KEY_NAME="id_rsa_$ALIAS" KEY_PATH="$HOME/.ssh/$KEY_NAME" echo -e "\n--- Generating SSH Key Pair ---" @@ -23,19 +33,15 @@ ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -C "$USERNAME" -N "" echo -e "\n--- Configuring SSH Alias ---" cat <> "$HOME/.ssh/config" -Host $PC_ALIAS - HostName $PC_IP - User $USERNAME +Host $ALIAS + HostName $PC_NAME + User $PC_NAME IdentityFile $KEY_PATH - SetEnv USERNAME=$USERNAME - SendEnv USERNAME SSH_CHECK_MODE FORCE_CONNECT + IdentitiesOnly yes + SendEnv SSH_CHECK_MODE FORCE_CONNECT EOF -echo "Adding $PC_IP $PC_ALIAS to /etc/hosts..." -echo "$PC_IP $PC_ALIAS" | sudo tee -a /etc/hosts - -echo -e "\n--- PUBLIC KEY ---" -cat "${KEY_PATH}.pub" -echo "--------------------------------------------" +echo -e "\n--- Adding SSH Key to Mezz PC ---" +ssh-copy-id -i $KEY_PATH $PC_NAME@$TARGET_IP -echo -e "{GREEN}Success!{NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" +echo "Setup Done! Connect to the Mezz PC using the mezzsh_connect.sh script!" diff --git a/scripts/mezzsh/utils/check_tailscale.sh b/scripts/mezzsh/utils/check_tailscale.sh new file mode 100644 index 0000000000..a26bd902a4 --- /dev/null +++ b/scripts/mezzsh/utils/check_tailscale.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Check if tailscale is installed +if ! command -v tailscale &> /dev/null; then + echo "Tailscale not found. Installing..." + curl -fsSL https://tailscale.com/install.sh | sh +fi + +# Check if the Tailscale daemon (tailscaled) is even running +if ! systemctl is-active --quiet tailscaled; then + echo "tailscaled is not running. Starting service..." + sudo systemctl start tailscaled +fi + +# Check if the node is authenticated and connected to the tailnet +# 'tailscale status' returns 0 if connected, non-zero otherwise +if ! tailscale status >/dev/null 2>&1; then + echo "Tailscale is down or unauthenticated. Running 'up'..." + + read -p "Enter the auth key. Please contact a software lead if you don't have one: " AUTH_KEY + + # Replace with your actual auth key and desired hostname + sudo tailscale up --auth-key=$AUTH_KEY +else + echo "Tailscale is already up and running." +fi \ No newline at end of file From 97f2cdc066999eb180da96805d374649cd217110 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Fri, 17 Apr 2026 23:52:47 -0700 Subject: [PATCH 06/23] removed ssh copy id doesn't work --- scripts/mezzsh/mezzsh_keygen.sh | 7 ++++--- scripts/mezzsh/mezzsh_keystore.sh | 2 +- scripts/mezzsh/mezzsh_setup.sh | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index abf859c04e..e3fb759169 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -41,7 +41,8 @@ Host $ALIAS SendEnv SSH_CHECK_MODE FORCE_CONNECT EOF -echo -e "\n--- Adding SSH Key to Mezz PC ---" -ssh-copy-id -i $KEY_PATH $PC_NAME@$TARGET_IP +echo -e "\n--- PUBLIC KEY ---" +cat "${KEY_PATH}.pub" +echo "--------------------------------------------" -echo "Setup Done! Connect to the Mezz PC using the mezzsh_connect.sh script!" +echo -e "{GREEN}Success!{NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/mezzsh_keystore.sh index 0b8e3528bb..79779e9041 100644 --- a/scripts/mezzsh/mezzsh_keystore.sh +++ b/scripts/mezzsh/mezzsh_keystore.sh @@ -15,7 +15,7 @@ echo "--- Registering New Remote User ---" # Add to authorized_keys with a command restriction # We prepend the SERVER_SCRIPT command to the key -ENTRY="command=\"$SERVER_SCRIPT\",environment=\"SSH_CHECK_MODE=1\" $PUB_KEY" +ENTRY="command=\"$SERVER_SCRIPT\",environment=\"SSH_CHECK_MODE=1 FORCE_CONNECT=1\" $PUB_KEY" if grep -q "$PUB_KEY" "$AUTH_KEYS"; then echo "Error: This public key is already registered." diff --git a/scripts/mezzsh/mezzsh_setup.sh b/scripts/mezzsh/mezzsh_setup.sh index c946d7d859..19db6c76a0 100644 --- a/scripts/mezzsh/mezzsh_setup.sh +++ b/scripts/mezzsh/mezzsh_setup.sh @@ -33,13 +33,13 @@ cp $SSHD_CONFIG "${SSHD_CONFIG}.bak" # This step uses a match block to modify these ssh settings for only 1 user # Clean up any previous global ForceCommand we might have added -sed -i '/Match User $TARGET_USER/,/AcceptEnv USERNAME SSH_CHECK_MODE FORCE_CONNECT/d' $SSHD_CONFIG +sed -i '/Match User $TARGET_USER/,/AcceptEnv SSH_CHECK_MODE FORCE_CONNECT/d' $SSHD_CONFIG # Append the Match block to the end of the file cat <> $SSHD_CONFIG Match User $TARGET_USER ForceCommand $SERVER_SCRIPT - AcceptEnv USERNAME SSH_CHECK_MODE FORCE_CONNECT + AcceptEnv SSH_CHECK_MODE FORCE_CONNECT EOF echo "[4/5] Setting 1-hour shell timeout..." From 17ba258747dfb057f25b5debd31cbe60a2afb206 Mon Sep 17 00:00:00 2001 From: saurav Date: Fri, 17 Apr 2026 23:59:09 -0700 Subject: [PATCH 07/23] fix user home --- scripts/mezzsh/mezzsh_keygen.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index e3fb759169..a861ffbf7f 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -6,6 +6,8 @@ ALIAS="mezzsh" GREEN='\e[1;32m' NC='\e[0m' +USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) + # Check for root privileges if [[ $EUID -ne 0 ]]; then echo "This script must be run as root (use sudo)" @@ -25,13 +27,13 @@ fi read -p "Enter a username for yourself. Please make it somewhat recognizable, preferably just your first name: " USERNAME KEY_NAME="id_rsa_$ALIAS" -KEY_PATH="$HOME/.ssh/$KEY_NAME" +KEY_PATH="$USER_HOME/.ssh/$KEY_NAME" echo -e "\n--- Generating SSH Key Pair ---" ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -C "$USERNAME" -N "" echo -e "\n--- Configuring SSH Alias ---" -cat <> "$HOME/.ssh/config" +cat <> "$USER_HOME/.ssh/config" Host $ALIAS HostName $PC_NAME From 8f2e4dc73c7422c645d55b6dc9b354a06c2311d6 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Sat, 18 Apr 2026 00:02:05 -0700 Subject: [PATCH 08/23] fixed user home in keystore + arg number bug --- scripts/mezzsh/mezzsh_keystore.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/mezzsh_keystore.sh index 79779e9041..8164a098bc 100644 --- a/scripts/mezzsh/mezzsh_keystore.sh +++ b/scripts/mezzsh/mezzsh_keystore.sh @@ -1,11 +1,13 @@ #!/bin/bash +USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) + # Configuration -AUTH_KEYS="$HOME/.ssh/authorized_keys" +AUTH_KEYS="$USER_HOME/.ssh/authorized_keys" SERVER_SCRIPT="./mezzsh_server.sh" -if [ "$#" -ne 2 ]; then - echo "Usage: sudo ./register_user.sh \"PUBLIC_KEY_STRING\"" +if [ "$#" -ne 1 ]; then + echo "Usage: sudo ./mezzsh_keystore.sh \"PUBLIC_KEY_STRING\"" exit 1 fi From f26fefcbb7bdb774ec679caf2022146361636d01 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 02:03:52 -0700 Subject: [PATCH 09/23] fixed permissions issues with ssh script --- scripts/mezzsh/mezzsh_keygen.sh | 12 +++++++----- scripts/mezzsh/mezzsh_keystore.sh | 2 +- scripts/mezzsh/mezzsh_server.sh | 8 ++++---- scripts/mezzsh/mezzsh_setup.sh | 2 ++ 4 files changed, 14 insertions(+), 10 deletions(-) mode change 100644 => 100755 scripts/mezzsh/mezzsh_server.sh diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index a861ffbf7f..09976c6f8d 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -27,18 +27,20 @@ fi read -p "Enter a username for yourself. Please make it somewhat recognizable, preferably just your first name: " USERNAME KEY_NAME="id_rsa_$ALIAS" -KEY_PATH="$USER_HOME/.ssh/$KEY_NAME" +KEY_PATH="/.ssh/$KEY_NAME" +USER_KEY_PATH="$USER_HOME/.ssh/$KEY_NAME" echo -e "\n--- Generating SSH Key Pair ---" -ssh-keygen -t rsa -b 4096 -f "$KEY_PATH" -C "$USERNAME" -N "" +ssh-keygen -t rsa -b 4096 -f "$USER_KEY_PATH" -C "$USERNAME" -N "" + +sudo chown $SUDO_USER:$SUDO_USER $USER_KEY_PATH echo -e "\n--- Configuring SSH Alias ---" cat <> "$USER_HOME/.ssh/config" -Host $ALIAS - HostName $PC_NAME +Host $TARGET_IP User $PC_NAME - IdentityFile $KEY_PATH + IdentityFile ~/$KEY_PATH IdentitiesOnly yes SendEnv SSH_CHECK_MODE FORCE_CONNECT EOF diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/mezzsh_keystore.sh index 8164a098bc..05c7bb8584 100644 --- a/scripts/mezzsh/mezzsh_keystore.sh +++ b/scripts/mezzsh/mezzsh_keystore.sh @@ -4,7 +4,7 @@ USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) # Configuration AUTH_KEYS="$USER_HOME/.ssh/authorized_keys" -SERVER_SCRIPT="./mezzsh_server.sh" +SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/mezzsh_server.sh" if [ "$#" -ne 1 ]; then echo "Usage: sudo ./mezzsh_keystore.sh \"PUBLIC_KEY_STRING\"" diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/mezzsh_server.sh old mode 100644 new mode 100755 index c01ee14bb8..020bb7e16e --- a/scripts/mezzsh/mezzsh_server.sh +++ b/scripts/mezzsh/mezzsh_server.sh @@ -2,21 +2,21 @@ # The `who` command returns all logged in users (IRL and remote) # Finds IRL users by looking for the physical monitor -LOCAL_USER=$(who | grep -E '(:0|tty7)') +LOCAL_USER=$(who | grep -E '(:0|tty2)') # Finds remote users, who are marked with `pts` # for each one, finds their username, to make identifying them easier # excludes the current user, otherwise server will always seem busy -REMOTE_USERS_LIST=$(who | grep pts | grep -v "$(basename $(tty))" | awk '{print $1}') +#REMOTE_USERS_LIST=$(who | grep pts | grep -v "$(basename $(tty))" | awk '{print $1}') # if the client requested a check, return the user info from above if [ "$SSH_CHECK_MODE" == "1" ]; then if [ ! -z "$LOCAL_USER" ]; then echo "STATUS_BUSY_LOCAL" exit 0 - elif [ ! -z "$REMOTE_USERS" ]; then + elif [ ! -z "$REMOTE_USERS_LIST" ]; then echo "STATUS_BUSY_REMOTE" - echo "Connected: $REMOTE_USERS" + echo "Connected: $REMOTE_USERS_LIST" exit 0 fi exit 0 diff --git a/scripts/mezzsh/mezzsh_setup.sh b/scripts/mezzsh/mezzsh_setup.sh index 19db6c76a0..f5ce4a14b0 100644 --- a/scripts/mezzsh/mezzsh_setup.sh +++ b/scripts/mezzsh/mezzsh_setup.sh @@ -42,6 +42,8 @@ Match User $TARGET_USER AcceptEnv SSH_CHECK_MODE FORCE_CONNECT EOF +sudo chmod +x $SERVER_SCRIPT + echo "[4/5] Setting 1-hour shell timeout..." USER_HOME=$(eval echo "~$TARGET_USER") From 19b2b38325365b77bf1c985ddd0e2a9c81e0c537 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 02:05:13 -0700 Subject: [PATCH 10/23] made keyfile read only for user --- scripts/mezzsh/mezzsh_keygen.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index 09976c6f8d..ef873845be 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -34,6 +34,7 @@ echo -e "\n--- Generating SSH Key Pair ---" ssh-keygen -t rsa -b 4096 -f "$USER_KEY_PATH" -C "$USERNAME" -N "" sudo chown $SUDO_USER:$SUDO_USER $USER_KEY_PATH +sudo chmod 400 $USER_KEY_PATH echo -e "\n--- Configuring SSH Alias ---" cat <> "$USER_HOME/.ssh/config" From 5da44d2d7a0439475ecac6baea059436390ef351 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 02:13:49 -0700 Subject: [PATCH 11/23] fix color issue --- scripts/mezzsh/mezzsh_connect.sh | 4 ++-- scripts/mezzsh/mezzsh_keygen.sh | 2 +- scripts/mezzsh/mezzsh_keystore.sh | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index b7668dc440..66e4c031fb 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -29,7 +29,7 @@ NC='\e[0m' # someone is using IRL if [[ "$RESPONSE" == *"STATUS_BUSY_LOCAL"* ]]; then - echo -e "⚠️ {RED}WARNING{NC}: Someone is physically logged into the PC onsite." + echo -e "⚠️ ${RED}WARNING${NC}: Someone is physically logged into the PC onsite." read -p "Do you want to force the connection? (y/n): " choice # exits if user does not want to force @@ -37,7 +37,7 @@ if [[ "$RESPONSE" == *"STATUS_BUSY_LOCAL"* ]]; then # someone is connected remotely elif [[ "$RESPONSE" == *"STATUS_BUSY_REMOTE"* ]]; then - echo -e "⚠️ {RED}WARNING{NC}: Other SSH users are connected:" + echo -e "⚠️ ${RED}WARNING${NC}: Other SSH users are connected:" echo "$RESPONSE" | grep "Connected:" read -p "Do you want to force the connection? (y/n): " choice diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index ef873845be..8c67233558 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -50,4 +50,4 @@ echo -e "\n--- PUBLIC KEY ---" cat "${KEY_PATH}.pub" echo "--------------------------------------------" -echo -e "{GREEN}Success!{NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" +echo -e "${GREEN}Success!${NC} Please provide the whole public key above (at "$KEY_PATH.pub") to a software lead to finish setup\n" diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/mezzsh_keystore.sh index 05c7bb8584..78ed123d13 100644 --- a/scripts/mezzsh/mezzsh_keystore.sh +++ b/scripts/mezzsh/mezzsh_keystore.sh @@ -1,6 +1,6 @@ #!/bin/bash -USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) +USER_HOME=$(tmp=$(getent passwd "$SUDO_USER" | cut -d: -f6); echo "${tmp:-/home/thunderbots}") # Configuration AUTH_KEYS="$USER_HOME/.ssh/authorized_keys" @@ -17,7 +17,9 @@ echo "--- Registering New Remote User ---" # Add to authorized_keys with a command restriction # We prepend the SERVER_SCRIPT command to the key -ENTRY="command=\"$SERVER_SCRIPT\",environment=\"SSH_CHECK_MODE=1 FORCE_CONNECT=1\" $PUB_KEY" +ENTRY="$PUB_KEY +command=\"$SERVER_SCRIPT\" +environment=\"SSH_CHECK_MODE=1 FORCE_CONNECT=1\"" if grep -q "$PUB_KEY" "$AUTH_KEYS"; then echo "Error: This public key is already registered." From d4703a031bf4960fe707b0ae7eeaa7600cb622c1 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 02:23:37 -0700 Subject: [PATCH 12/23] update how env vars are sent --- scripts/mezzsh/mezzsh_connect.sh | 4 ++-- scripts/mezzsh/mezzsh_keygen.sh | 5 +++-- scripts/mezzsh/mezzsh_server.sh | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index 66e4c031fb..031411bb2d 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -22,7 +22,7 @@ FORCE_FLAG="NORMAL" SSH_TARGET="thunderbots@$TARGET_IP" # first, check server status (if other users are using the PC) -RESPONSE=$(ssh -o SendEnv=SSH_CHECK_MODE -t $SSH_TARGET "check_status" 2>&1) +RESPONSE=$(SSH_CHECK_MODE=1 ssh -o SendEnv=SSH_CHECK_MODE -t $SSH_TARGET "check_status" 2>&1) RED='\e[1;31m' NC='\e[0m' @@ -48,7 +48,7 @@ fi # if the user wanted to force the connection, does it here if [ "$FORCE_FLAG" == "FORCE" ]; then echo "Force connecting..." - ssh -o SendEnv=FORCE_CONNECT=1 -t $SSH_TARGET + FORCE_CONNECT=1 ssh -o SendEnv=FORCE_CONNECT -t $SSH_TARGET else ssh -t $SSH_TARGET fi diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index 8c67233558..875c6ec54a 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -17,7 +17,7 @@ fi bash ./utils/check_tailscale.sh # Get the Tailscale IP of the Main PC -TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) +TARGET_IP=$(tailscale ip -4 $PC_NAME) if [ -z "$TARGET_IP" ]; then echo "Could not find Main PC on Tailscale. Are you logged in?" @@ -35,13 +35,14 @@ ssh-keygen -t rsa -b 4096 -f "$USER_KEY_PATH" -C "$USERNAME" -N "" sudo chown $SUDO_USER:$SUDO_USER $USER_KEY_PATH sudo chmod 400 $USER_KEY_PATH +sudo chmod 400 "$USER_KEY_PATH.pub" echo -e "\n--- Configuring SSH Alias ---" cat <> "$USER_HOME/.ssh/config" Host $TARGET_IP User $PC_NAME - IdentityFile ~/$KEY_PATH + IdentityFile ~$KEY_PATH IdentitiesOnly yes SendEnv SSH_CHECK_MODE FORCE_CONNECT EOF diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/mezzsh_server.sh index 020bb7e16e..4f7623e807 100755 --- a/scripts/mezzsh/mezzsh_server.sh +++ b/scripts/mezzsh/mezzsh_server.sh @@ -9,6 +9,9 @@ LOCAL_USER=$(who | grep -E '(:0|tty2)') # excludes the current user, otherwise server will always seem busy #REMOTE_USERS_LIST=$(who | grep pts | grep -v "$(basename $(tty))" | awk '{print $1}') +echo $SSH_CHECK_MODE +echo "????" + # if the client requested a check, return the user info from above if [ "$SSH_CHECK_MODE" == "1" ]; then if [ ! -z "$LOCAL_USER" ]; then From 8a4ba500f947880b24aed150fbfa67375f31f9e3 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 03:03:30 -0700 Subject: [PATCH 13/23] fixed how users are detected + named --- scripts/mezzsh/mezzsh_connect.sh | 2 +- scripts/mezzsh/mezzsh_server.sh | 9 +++---- scripts/mezzsh/utils/get_connected_users.sh | 26 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 scripts/mezzsh/utils/get_connected_users.sh diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index 031411bb2d..a319222007 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -38,7 +38,7 @@ if [[ "$RESPONSE" == *"STATUS_BUSY_LOCAL"* ]]; then # someone is connected remotely elif [[ "$RESPONSE" == *"STATUS_BUSY_REMOTE"* ]]; then echo -e "⚠️ ${RED}WARNING${NC}: Other SSH users are connected:" - echo "$RESPONSE" | grep "Connected:" + echo "$RESPONSE" | grep "List" read -p "Do you want to force the connection? (y/n): " choice # exits if user does not want to force diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/mezzsh_server.sh index 4f7623e807..89bef4bd96 100755 --- a/scripts/mezzsh/mezzsh_server.sh +++ b/scripts/mezzsh/mezzsh_server.sh @@ -7,10 +7,7 @@ LOCAL_USER=$(who | grep -E '(:0|tty2)') # Finds remote users, who are marked with `pts` # for each one, finds their username, to make identifying them easier # excludes the current user, otherwise server will always seem busy -#REMOTE_USERS_LIST=$(who | grep pts | grep -v "$(basename $(tty))" | awk '{print $1}') - -echo $SSH_CHECK_MODE -echo "????" +REMOTE_USERS_LIST=$(bash /home/thunderbots/Software/scripts/mezzsh/utils/get_connected_users.sh) # if the client requested a check, return the user info from above if [ "$SSH_CHECK_MODE" == "1" ]; then @@ -19,7 +16,7 @@ if [ "$SSH_CHECK_MODE" == "1" ]; then exit 0 elif [ ! -z "$REMOTE_USERS_LIST" ]; then echo "STATUS_BUSY_REMOTE" - echo "Connected: $REMOTE_USERS_LIST" + echo "List of Users: $REMOTE_USERS_LIST" exit 0 fi exit 0 @@ -41,7 +38,7 @@ if ([ ! -z "$LOCAL_USER" ] || [ ! -z "$REMOTE_USERS" ]) && [ "$FORCE_CONNECT" != fi # Trigger the visual warning dialog if someone is using the PC IRL -./mezzsh_warn.sh & +bash /home/thunderbots/Software/scripts/mezzsh/mezzsh_warn.sh & # if we get here, start a normal shell exec $SHELL diff --git a/scripts/mezzsh/utils/get_connected_users.sh b/scripts/mezzsh/utils/get_connected_users.sh new file mode 100644 index 0000000000..970f58aa9b --- /dev/null +++ b/scripts/mezzsh/utils/get_connected_users.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Get fingerprints and comments from authorized_keys +KEYS_FILE="/home/thunderbots/.ssh/authorized_keys" +declare -A key_comments + +while read -r line; do + # Skip the line if it doesn't start with "ssh" + [[ ! $line =~ ^ssh ]] && continue + + # Get fingerprint for each key in authorized_keys + fp=$(echo "$line" | ssh-keygen -l -f - | awk '{print $2}') + comment=$(echo "$line" | awk '{print $NF}') + key_comments["$fp"]="$comment" +done < "$KEYS_FILE" + +# Find currently active SSH PIDs and match them to log entries +pgrep -u "root" sshd | tail -n +2 | while read -r pid; do + # Look for the 'Accepted publickey' log entry for this specific PID + fp_match=$(grep "sshd\[$pid\]" /var/log/auth.log | grep "Accepted publickey" | grep -oE "SHA256:[^ ]+") + + if [ -n "$fp_match" ]; then + comment=${key_comments[$fp_match]} + echo "${comment}" + fi +done \ No newline at end of file From 94e47b8d07ef3e4b56f43d459d02460ea32dada1 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 03:23:13 -0700 Subject: [PATCH 14/23] fixed connection warn dialog --- scripts/mezzsh/mezzsh_server.sh | 4 ++-- .../mezzsh/{mezzsh_warn.sh => utils/connection_warn.sh} | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) rename scripts/mezzsh/{mezzsh_warn.sh => utils/connection_warn.sh} (66%) diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/mezzsh_server.sh index 89bef4bd96..e5edcfbbcd 100755 --- a/scripts/mezzsh/mezzsh_server.sh +++ b/scripts/mezzsh/mezzsh_server.sh @@ -2,7 +2,7 @@ # The `who` command returns all logged in users (IRL and remote) # Finds IRL users by looking for the physical monitor -LOCAL_USER=$(who | grep -E '(:0|tty2)') +LOCAL_USER=$(who | grep -E '(tty2)') # Finds remote users, who are marked with `pts` # for each one, finds their username, to make identifying them easier @@ -38,7 +38,7 @@ if ([ ! -z "$LOCAL_USER" ] || [ ! -z "$REMOTE_USERS" ]) && [ "$FORCE_CONNECT" != fi # Trigger the visual warning dialog if someone is using the PC IRL -bash /home/thunderbots/Software/scripts/mezzsh/mezzsh_warn.sh & +bash /home/thunderbots/Software/scripts/mezzsh/utils/connection_warn.sh & # if we get here, start a normal shell exec $SHELL diff --git a/scripts/mezzsh/mezzsh_warn.sh b/scripts/mezzsh/utils/connection_warn.sh similarity index 66% rename from scripts/mezzsh/mezzsh_warn.sh rename to scripts/mezzsh/utils/connection_warn.sh index 0832ef4443..ef11dd2346 100644 --- a/scripts/mezzsh/mezzsh_warn.sh +++ b/scripts/mezzsh/utils/connection_warn.sh @@ -2,7 +2,7 @@ # find the username of the person logged in physically # we look for someone attached to the main display (:0) -LOCAL_USER=$(who | grep -m 1 "(:0)" | awk '{print $1}') +LOCAL_USER=$(who | grep -m 1 "(tty2)" | awk '{print $1}') # if no one is logged in locally, just exit if [ -z "$LOCAL_USER" ]; then @@ -15,7 +15,10 @@ LOCAL_UID=$(id -u "$LOCAL_USER") # Trigger the dialog # We must set DISPLAY and DBUS_SESSION_BUS_ADDRESS so the script knows # WHICH screen to pop up on. -sudo -u "$LOCAL_USER" DISPLAY=:0 \ +sudo -u "$LOCAL_USER" DISPLAY=tty2 \ DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$LOCAL_UID/bus \ + XDG_RUNTIME_DIR="/run/user/$LOCAL_UID" \ + WAYLAND_DISPLAY="wayland-0" \ + GDK_BACKEND="wayland" \ zenity --warning --title="Remote Connection" \ - --text="⚠️ User $USER has just connected via SSH." --timeout=10 & + --text="A new has just connected remotely (via SSH)." --timeout=10 & From d8bba651d60bbd1301cea37dfe59ecb5dba6b6b6 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 03:35:41 -0700 Subject: [PATCH 15/23] move into dirs, fix file paths --- scripts/mezzsh/mezzsh_connect.sh | 7 ++++--- scripts/mezzsh/mezzsh_keygen.sh | 5 +++++ scripts/mezzsh/{ => server}/mezzsh_keystore.sh | 5 ++++- scripts/mezzsh/{ => server}/mezzsh_server.sh | 6 ++++++ scripts/mezzsh/{ => server}/mezzsh_setup.sh | 8 ++++++-- scripts/mezzsh/utils/check_tailscale.sh | 2 ++ scripts/mezzsh/utils/get_connected_users.sh | 4 ++++ 7 files changed, 31 insertions(+), 6 deletions(-) rename scripts/mezzsh/{ => server}/mezzsh_keystore.sh (80%) rename scripts/mezzsh/{ => server}/mezzsh_server.sh (83%) rename scripts/mezzsh/{ => server}/mezzsh_setup.sh (83%) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index a319222007..9c785ed9ad 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -5,11 +5,12 @@ # the user if other users are currently connected remotely or using in person # Allows user to force a connection -TAILSCALE_HOSTNAME="thunderbots" +PC_NAME="thunderbots" +TAILSCALE_HOSTNAME="$PC_NAME" bash ./utils/check_tailscale.sh -# 2. Get the Tailscale IP of the Main PC +# Get the Tailscale IP of the Main PC TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) if [ -z "$TARGET_IP" ]; then @@ -45,7 +46,7 @@ elif [[ "$RESPONSE" == *"STATUS_BUSY_REMOTE"* ]]; then [[ "$choice" == [yY] ]] && FORCE_FLAG="FORCE" || exit 1 fi -# if the user wanted to force the connection, does it here +# if the user wanted to force the connection if [ "$FORCE_FLAG" == "FORCE" ]; then echo "Force connecting..." FORCE_CONNECT=1 ssh -o SendEnv=FORCE_CONNECT -t $SSH_TARGET diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index 875c6ec54a..941281ab15 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -1,5 +1,10 @@ #!/bin/bash +# Generates a private / public key pair for connecting via ssh +# Adds the Mezz PC's IP to the ssh config file, and sets the new key as the identity to use +# And sets the key file's permissions correctly +# Each key also has a username attached to it for easier identification + PC_NAME="thunderbots" ALIAS="mezzsh" diff --git a/scripts/mezzsh/mezzsh_keystore.sh b/scripts/mezzsh/server/mezzsh_keystore.sh similarity index 80% rename from scripts/mezzsh/mezzsh_keystore.sh rename to scripts/mezzsh/server/mezzsh_keystore.sh index 78ed123d13..897a2893d6 100644 --- a/scripts/mezzsh/mezzsh_keystore.sh +++ b/scripts/mezzsh/server/mezzsh_keystore.sh @@ -1,10 +1,13 @@ #!/bin/bash +# Adds a single public key to the Mezz PC's authorized_keys file +# along with other necessary config options + USER_HOME=$(tmp=$(getent passwd "$SUDO_USER" | cut -d: -f6); echo "${tmp:-/home/thunderbots}") # Configuration AUTH_KEYS="$USER_HOME/.ssh/authorized_keys" -SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/mezzsh_server.sh" +SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/server/mezzsh_server.sh" if [ "$#" -ne 1 ]; then echo "Usage: sudo ./mezzsh_keystore.sh \"PUBLIC_KEY_STRING\"" diff --git a/scripts/mezzsh/mezzsh_server.sh b/scripts/mezzsh/server/mezzsh_server.sh similarity index 83% rename from scripts/mezzsh/mezzsh_server.sh rename to scripts/mezzsh/server/mezzsh_server.sh index e5edcfbbcd..cc4635281e 100755 --- a/scripts/mezzsh/mezzsh_server.sh +++ b/scripts/mezzsh/server/mezzsh_server.sh @@ -1,5 +1,11 @@ #!/bin/bash +# Script to intercept all incoming ssh connections to the Mezz PC +# Checks for both IRL users and any connected remote users who are currently using the PC +# and warns the new connection accordingly +# If the new connection wants to force, opens the connection +# and also warns any IRL users if present + # The `who` command returns all logged in users (IRL and remote) # Finds IRL users by looking for the physical monitor LOCAL_USER=$(who | grep -E '(tty2)') diff --git a/scripts/mezzsh/mezzsh_setup.sh b/scripts/mezzsh/server/mezzsh_setup.sh similarity index 83% rename from scripts/mezzsh/mezzsh_setup.sh rename to scripts/mezzsh/server/mezzsh_setup.sh index f5ce4a14b0..08f33aa5ea 100644 --- a/scripts/mezzsh/mezzsh_setup.sh +++ b/scripts/mezzsh/server/mezzsh_setup.sh @@ -1,6 +1,10 @@ #!/bin/bash -SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/mezzsh_server.sh" +# Sets up the Mezz PC to accept new SSH connections +# Uses Tailscale as a VPN to get around connections being blocked at the router level +# Sets up Tailscale, ssh, and links the server script to intercept new connections + +SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/server/mezzsh_server.sh" TIMEOUT_SECONDS=3600 # 1 hour SSHD_CONFIG="/etc/ssh/sshd_config" TARGET_USER="thunderbots" @@ -26,7 +30,7 @@ echo "[2/5] Configuring SSH service to start on boot..." systemctl enable --now ssh systemctl start ssh -echo "[3/5] Modifying sshd_config for custom Environment variables, and to perform safety checks on new connections......" +echo "[3/5] Modifying sshd_config for custom Environment variables, and links script to perform safety checks on new connections......" # Backup original config cp $SSHD_CONFIG "${SSHD_CONFIG}.bak" diff --git a/scripts/mezzsh/utils/check_tailscale.sh b/scripts/mezzsh/utils/check_tailscale.sh index a26bd902a4..4a0a8ee2af 100644 --- a/scripts/mezzsh/utils/check_tailscale.sh +++ b/scripts/mezzsh/utils/check_tailscale.sh @@ -1,5 +1,7 @@ #!/bin/bash +# Checks if Tailscale is installed, the daemon is up and running, and we are logged in (connected) to the VPN + # Check if tailscale is installed if ! command -v tailscale &> /dev/null; then echo "Tailscale not found. Installing..." diff --git a/scripts/mezzsh/utils/get_connected_users.sh b/scripts/mezzsh/utils/get_connected_users.sh index 970f58aa9b..84285fd157 100644 --- a/scripts/mezzsh/utils/get_connected_users.sh +++ b/scripts/mezzsh/utils/get_connected_users.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Gets the names of all currently connected SSH users +# Each user has their name attached to their SSH public key in authorized_keys +# So we find the key each person used to connect, and then the corresponding name + # Get fingerprints and comments from authorized_keys KEYS_FILE="/home/thunderbots/.ssh/authorized_keys" declare -A key_comments From b6cecf524310a7b42c8047c3d985bc94fe714021 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 03:44:19 -0700 Subject: [PATCH 16/23] remove comment + unneeded echo --- scripts/mezzsh/utils/check_tailscale.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/mezzsh/utils/check_tailscale.sh b/scripts/mezzsh/utils/check_tailscale.sh index 4a0a8ee2af..671f8dcf63 100644 --- a/scripts/mezzsh/utils/check_tailscale.sh +++ b/scripts/mezzsh/utils/check_tailscale.sh @@ -21,8 +21,5 @@ if ! tailscale status >/dev/null 2>&1; then read -p "Enter the auth key. Please contact a software lead if you don't have one: " AUTH_KEY - # Replace with your actual auth key and desired hostname sudo tailscale up --auth-key=$AUTH_KEY -else - echo "Tailscale is already up and running." fi \ No newline at end of file From 6cb0fbe82ff1c5db5ccac420fdb337101f9e2311 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 03:46:35 -0700 Subject: [PATCH 17/23] remove comments --- scripts/mezzsh/server/mezzsh_server.sh | 2 +- scripts/mezzsh/utils/connection_warn.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mezzsh/server/mezzsh_server.sh b/scripts/mezzsh/server/mezzsh_server.sh index cc4635281e..529d7a99f9 100755 --- a/scripts/mezzsh/server/mezzsh_server.sh +++ b/scripts/mezzsh/server/mezzsh_server.sh @@ -7,7 +7,7 @@ # and also warns any IRL users if present # The `who` command returns all logged in users (IRL and remote) -# Finds IRL users by looking for the physical monitor +# Finds IRL users by looking for the physical monitor (tty2) LOCAL_USER=$(who | grep -E '(tty2)') # Finds remote users, who are marked with `pts` diff --git a/scripts/mezzsh/utils/connection_warn.sh b/scripts/mezzsh/utils/connection_warn.sh index ef11dd2346..0521a4f29e 100644 --- a/scripts/mezzsh/utils/connection_warn.sh +++ b/scripts/mezzsh/utils/connection_warn.sh @@ -9,12 +9,12 @@ if [ -z "$LOCAL_USER" ]; then exit 0 fi -# get the User ID of the local user to access their "session bus" +# get the User ID of the local user LOCAL_UID=$(id -u "$LOCAL_USER") # Trigger the dialog -# We must set DISPLAY and DBUS_SESSION_BUS_ADDRESS so the script knows -# WHICH screen to pop up on. +# these environment variables must be set to trigger the dialog +# specifically on our wayland setup sudo -u "$LOCAL_USER" DISPLAY=tty2 \ DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$LOCAL_UID/bus \ XDG_RUNTIME_DIR="/run/user/$LOCAL_UID" \ From e67fa4ad805176f440028256557bbb20a8d1fa51 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 10:55:28 +0000 Subject: [PATCH 18/23] [pre-commit.ci lite] apply automatic fixes --- scripts/mezzsh/utils/check_tailscale.sh | 2 +- scripts/mezzsh/utils/get_connected_users.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mezzsh/utils/check_tailscale.sh b/scripts/mezzsh/utils/check_tailscale.sh index 671f8dcf63..974b8892df 100644 --- a/scripts/mezzsh/utils/check_tailscale.sh +++ b/scripts/mezzsh/utils/check_tailscale.sh @@ -22,4 +22,4 @@ if ! tailscale status >/dev/null 2>&1; then read -p "Enter the auth key. Please contact a software lead if you don't have one: " AUTH_KEY sudo tailscale up --auth-key=$AUTH_KEY -fi \ No newline at end of file +fi diff --git a/scripts/mezzsh/utils/get_connected_users.sh b/scripts/mezzsh/utils/get_connected_users.sh index 84285fd157..8d8770fefe 100644 --- a/scripts/mezzsh/utils/get_connected_users.sh +++ b/scripts/mezzsh/utils/get_connected_users.sh @@ -27,4 +27,4 @@ pgrep -u "root" sshd | tail -n +2 | while read -r pid; do comment=${key_comments[$fp_match]} echo "${comment}" fi -done \ No newline at end of file +done From b7ae3a3202e42d70c20900e0f79ca2cd486caf21 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Mon, 20 Apr 2026 04:03:24 -0700 Subject: [PATCH 19/23] add comments --- scripts/mezzsh/mezzsh_keygen.sh | 5 ++++ scripts/mezzsh/server/mezzsh_keystore.sh | 6 ++-- scripts/mezzsh/server/mezzsh_server.sh | 3 +- scripts/mezzsh/server/mezzsh_setup.sh | 2 +- scripts/mezzsh/utils/connection_warn.sh | 4 +++ scripts/mezzsh/utils/get_connected_users.sh | 31 +++++++++++++-------- 6 files changed, 35 insertions(+), 16 deletions(-) diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index 941281ab15..8e420bd6c9 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -11,6 +11,7 @@ ALIAS="mezzsh" GREEN='\e[1;32m' NC='\e[0m' +# get the actual current user despite running in sudo USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) # Check for root privileges @@ -36,8 +37,12 @@ KEY_PATH="/.ssh/$KEY_NAME" USER_KEY_PATH="$USER_HOME/.ssh/$KEY_NAME" echo -e "\n--- Generating SSH Key Pair ---" + +# username is appended as a comment to the key ssh-keygen -t rsa -b 4096 -f "$USER_KEY_PATH" -C "$USERNAME" -N "" +# ssh is particular about permissions on the key file +# specifically, the private key file should be owned and should only be readable by the current user sudo chown $SUDO_USER:$SUDO_USER $USER_KEY_PATH sudo chmod 400 $USER_KEY_PATH sudo chmod 400 "$USER_KEY_PATH.pub" diff --git a/scripts/mezzsh/server/mezzsh_keystore.sh b/scripts/mezzsh/server/mezzsh_keystore.sh index 897a2893d6..0d08ad2826 100644 --- a/scripts/mezzsh/server/mezzsh_keystore.sh +++ b/scripts/mezzsh/server/mezzsh_keystore.sh @@ -3,9 +3,10 @@ # Adds a single public key to the Mezz PC's authorized_keys file # along with other necessary config options +# the script is run as sudo, but we want to modify the current user's authorized_keys +# defaults to the "thunderbots" user USER_HOME=$(tmp=$(getent passwd "$SUDO_USER" | cut -d: -f6); echo "${tmp:-/home/thunderbots}") -# Configuration AUTH_KEYS="$USER_HOME/.ssh/authorized_keys" SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/server/mezzsh_server.sh" @@ -19,10 +20,9 @@ PUB_KEY="$1" echo "--- Registering New Remote User ---" # Add to authorized_keys with a command restriction -# We prepend the SERVER_SCRIPT command to the key ENTRY="$PUB_KEY command=\"$SERVER_SCRIPT\" -environment=\"SSH_CHECK_MODE=1 FORCE_CONNECT=1\"" +environment=\"SSH_CHECK_MODE=1 FORCE_CONNECT=0\"" if grep -q "$PUB_KEY" "$AUTH_KEYS"; then echo "Error: This public key is already registered." diff --git a/scripts/mezzsh/server/mezzsh_server.sh b/scripts/mezzsh/server/mezzsh_server.sh index 529d7a99f9..01b2881930 100755 --- a/scripts/mezzsh/server/mezzsh_server.sh +++ b/scripts/mezzsh/server/mezzsh_server.sh @@ -10,13 +10,14 @@ # Finds IRL users by looking for the physical monitor (tty2) LOCAL_USER=$(who | grep -E '(tty2)') -# Finds remote users, who are marked with `pts` +# Finds remote users currently connected # for each one, finds their username, to make identifying them easier # excludes the current user, otherwise server will always seem busy REMOTE_USERS_LIST=$(bash /home/thunderbots/Software/scripts/mezzsh/utils/get_connected_users.sh) # if the client requested a check, return the user info from above if [ "$SSH_CHECK_MODE" == "1" ]; then + # local user check takes priority if [ ! -z "$LOCAL_USER" ]; then echo "STATUS_BUSY_LOCAL" exit 0 diff --git a/scripts/mezzsh/server/mezzsh_setup.sh b/scripts/mezzsh/server/mezzsh_setup.sh index 08f33aa5ea..a1f5f0ea7b 100644 --- a/scripts/mezzsh/server/mezzsh_setup.sh +++ b/scripts/mezzsh/server/mezzsh_setup.sh @@ -46,6 +46,7 @@ Match User $TARGET_USER AcceptEnv SSH_CHECK_MODE FORCE_CONNECT EOF +# Script has to be executable for it to be triggered on new connections sudo chmod +x $SERVER_SCRIPT echo "[4/5] Setting 1-hour shell timeout..." @@ -63,6 +64,5 @@ else echo "ERROR: Home directory for $TARGET_USER not found. Timeout not set." fi -# 4. Finalizing and Restarting Service echo "[5/5] Restarting SSH service to apply changes..." systemctl restart ssh diff --git a/scripts/mezzsh/utils/connection_warn.sh b/scripts/mezzsh/utils/connection_warn.sh index 0521a4f29e..bece1ed75b 100644 --- a/scripts/mezzsh/utils/connection_warn.sh +++ b/scripts/mezzsh/utils/connection_warn.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Script to trigger a dialog on the Mezz PC monitor that someone +# has just connected remotely + # find the username of the person logged in physically # we look for someone attached to the main display (:0) LOCAL_USER=$(who | grep -m 1 "(tty2)" | awk '{print $1}') @@ -14,6 +17,7 @@ LOCAL_UID=$(id -u "$LOCAL_USER") # Trigger the dialog # these environment variables must be set to trigger the dialog +# from a background script (i.e our SSH server script) # specifically on our wayland setup sudo -u "$LOCAL_USER" DISPLAY=tty2 \ DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$LOCAL_UID/bus \ diff --git a/scripts/mezzsh/utils/get_connected_users.sh b/scripts/mezzsh/utils/get_connected_users.sh index 84285fd157..16962caa8a 100644 --- a/scripts/mezzsh/utils/get_connected_users.sh +++ b/scripts/mezzsh/utils/get_connected_users.sh @@ -2,29 +2,38 @@ # Gets the names of all currently connected SSH users # Each user has their name attached to their SSH public key in authorized_keys -# So we find the key each person used to connect, and then the corresponding name +# So we find the key each current connection used to connect, and then the corresponding name -# Get fingerprints and comments from authorized_keys +# Get keys and comments from authorized_keys KEYS_FILE="/home/thunderbots/.ssh/authorized_keys" -declare -A key_comments +declare -A key_to_names while read -r line; do # Skip the line if it doesn't start with "ssh" + # to skip over the extra flags attached to each key on separate lines [[ ! $line =~ ^ssh ]] && continue - # Get fingerprint for each key in authorized_keys - fp=$(echo "$line" | ssh-keygen -l -f - | awk '{print $2}') - comment=$(echo "$line" | awk '{print $NF}') - key_comments["$fp"]="$comment" + # the line consists of + + # Get fingerprint for the ssh key + fingerprint=$(echo "$line" | ssh-keygen -l -f - | awk '{print $2}') + + # get the username part of the line + username=$(echo "$line" | awk '{print $NF}') + + # map fingerprint to username + key_to_names["$fingerprint"]="$username" done < "$KEYS_FILE" # Find currently active SSH PIDs and match them to log entries pgrep -u "root" sshd | tail -n +2 | while read -r pid; do # Look for the 'Accepted publickey' log entry for this specific PID - fp_match=$(grep "sshd\[$pid\]" /var/log/auth.log | grep "Accepted publickey" | grep -oE "SHA256:[^ ]+") + # there should be a log entry with the text "sshd[] + # log entry contains the fingerprint within the text "SHA256: + fingerprint_match=$(grep "sshd\[$pid\]" /var/log/auth.log | grep "Accepted publickey" | grep -oE "SHA256:[^ ]+") - if [ -n "$fp_match" ]; then - comment=${key_comments[$fp_match]} - echo "${comment}" + if [ -n "$fingerprint_match" ]; then + username=${key_to_names[$fingerprint_match]} + echo "${username}" fi done \ No newline at end of file From 7ef0e0d7a8b359bb805d6a6764ba21672faa50d5 Mon Sep 17 00:00:00 2001 From: Thunderbots Date: Fri, 24 Apr 2026 17:16:01 -0700 Subject: [PATCH 20/23] fix server script path + made it copy to usr bin --- scripts/mezzsh/server/mezzsh_setup.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mezzsh/server/mezzsh_setup.sh b/scripts/mezzsh/server/mezzsh_setup.sh index a1f5f0ea7b..716fbb2bd5 100644 --- a/scripts/mezzsh/server/mezzsh_setup.sh +++ b/scripts/mezzsh/server/mezzsh_setup.sh @@ -4,7 +4,8 @@ # Uses Tailscale as a VPN to get around connections being blocked at the router level # Sets up Tailscale, ssh, and links the server script to intercept new connections -SERVER_SCRIPT="/home/thunderbots/Software/scripts/mezzsh/server/mezzsh_server.sh" +SCRIPT_PATH="/home/thunderbots/Software/scripts/mezzsh/server/mezzsh_server.sh" +SERVER_SCRIPT="/usr/local/bin/mezzsh_server.sh" TIMEOUT_SECONDS=3600 # 1 hour SSHD_CONFIG="/etc/ssh/sshd_config" TARGET_USER="thunderbots" @@ -39,6 +40,9 @@ cp $SSHD_CONFIG "${SSHD_CONFIG}.bak" # Clean up any previous global ForceCommand we might have added sed -i '/Match User $TARGET_USER/,/AcceptEnv SSH_CHECK_MODE FORCE_CONNECT/d' $SSHD_CONFIG +# copies the script from repo to script location +cp $SCRIPT_PATH $SERVER_SCRIPT + # Append the Match block to the end of the file cat <> $SSHD_CONFIG Match User $TARGET_USER From 5fda9cf96057999bb9dab3e424c9a63919d61ae6 Mon Sep 17 00:00:00 2001 From: saurav Date: Wed, 29 Apr 2026 13:12:52 -0700 Subject: [PATCH 21/23] remove relative paths --- scripts/mezzsh/mezzsh_connect.sh | 4 +++- scripts/mezzsh/mezzsh_keygen.sh | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/mezzsh/mezzsh_connect.sh b/scripts/mezzsh/mezzsh_connect.sh index 9c785ed9ad..8cde44193f 100644 --- a/scripts/mezzsh/mezzsh_connect.sh +++ b/scripts/mezzsh/mezzsh_connect.sh @@ -5,10 +5,12 @@ # the user if other users are currently connected remotely or using in person # Allows user to force a connection +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) + PC_NAME="thunderbots" TAILSCALE_HOSTNAME="$PC_NAME" -bash ./utils/check_tailscale.sh +bash "$SCRIPT_DIR/utils/check_tailscale.sh" # Get the Tailscale IP of the Main PC TARGET_IP=$(tailscale ip -4 $TAILSCALE_HOSTNAME) diff --git a/scripts/mezzsh/mezzsh_keygen.sh b/scripts/mezzsh/mezzsh_keygen.sh index 8e420bd6c9..651d2efa95 100644 --- a/scripts/mezzsh/mezzsh_keygen.sh +++ b/scripts/mezzsh/mezzsh_keygen.sh @@ -20,7 +20,9 @@ if [[ $EUID -ne 0 ]]; then exit 1 fi -bash ./utils/check_tailscale.sh +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) + +bash "$SCRIPT_DIR/utils/check_tailscale.sh" # Get the Tailscale IP of the Main PC TARGET_IP=$(tailscale ip -4 $PC_NAME) From 5dadeed72b27ab0d17d19bf87719fc2592227286 Mon Sep 17 00:00:00 2001 From: saurav Date: Tue, 12 May 2026 23:13:09 -0700 Subject: [PATCH 22/23] addressing changes, fixing quoting bugs + naming bugs + pulled out check local users into own file --- scripts/mezzsh/server/mezzsh_server.sh | 8 +------- scripts/mezzsh/server/mezzsh_setup.sh | 2 +- scripts/mezzsh/utils/connection_warn.sh | 5 ++--- scripts/mezzsh/utils/get_local_user.sh | 7 +++++++ 4 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 scripts/mezzsh/utils/get_local_user.sh diff --git a/scripts/mezzsh/server/mezzsh_server.sh b/scripts/mezzsh/server/mezzsh_server.sh index 01b2881930..57e1e1d49f 100755 --- a/scripts/mezzsh/server/mezzsh_server.sh +++ b/scripts/mezzsh/server/mezzsh_server.sh @@ -33,14 +33,8 @@ fi # 1. no other users (IRL or remote) are using the PC # OR # 2. the force flag is provided -if ([ ! -z "$LOCAL_USER" ] || [ ! -z "$REMOTE_USERS" ]) && [ "$FORCE_CONNECT" != "1" ]; then +if ([ ! -z "$LOCAL_USER" ] || [ ! -z "$REMOTE_USERS_LIST" ]) && [ "$FORCE_CONNECT" != "1" ]; then echo "The Mezz Computer is in use! Please use the connect script to see who is currently using it." - - # we technically hae already have an active connection at this point - # just no shell is provided - # close the connection after 1 min - sleep 60 - echo "Connection timed out." exit 1 fi diff --git a/scripts/mezzsh/server/mezzsh_setup.sh b/scripts/mezzsh/server/mezzsh_setup.sh index 716fbb2bd5..b36e9807f1 100644 --- a/scripts/mezzsh/server/mezzsh_setup.sh +++ b/scripts/mezzsh/server/mezzsh_setup.sh @@ -38,7 +38,7 @@ cp $SSHD_CONFIG "${SSHD_CONFIG}.bak" # This step uses a match block to modify these ssh settings for only 1 user # Clean up any previous global ForceCommand we might have added -sed -i '/Match User $TARGET_USER/,/AcceptEnv SSH_CHECK_MODE FORCE_CONNECT/d' $SSHD_CONFIG +sed -i "/Match User $TARGET_USER/,/AcceptEnv SSH_CHECK_MODE FORCE_CONNECT/d" $SSHD_CONFIG # copies the script from repo to script location cp $SCRIPT_PATH $SERVER_SCRIPT diff --git a/scripts/mezzsh/utils/connection_warn.sh b/scripts/mezzsh/utils/connection_warn.sh index bece1ed75b..219c651dea 100644 --- a/scripts/mezzsh/utils/connection_warn.sh +++ b/scripts/mezzsh/utils/connection_warn.sh @@ -3,9 +3,8 @@ # Script to trigger a dialog on the Mezz PC monitor that someone # has just connected remotely -# find the username of the person logged in physically -# we look for someone attached to the main display (:0) -LOCAL_USER=$(who | grep -m 1 "(tty2)" | awk '{print $1}') +# Finds IRL users +LOCAL_USER=$(bash /home/thunderbots/Software/scripts/mezzsh/utils/get_local_user.sh) # if no one is logged in locally, just exit if [ -z "$LOCAL_USER" ]; then diff --git a/scripts/mezzsh/utils/get_local_user.sh b/scripts/mezzsh/utils/get_local_user.sh new file mode 100644 index 0000000000..b29cc378f2 --- /dev/null +++ b/scripts/mezzsh/utils/get_local_user.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Script to check if there's a person logged in physically +# at the Mezz PC +# The `who` command returns all logged in users (IRL and remote) +# Finds IRL users by looking for the physical monitor (tty2) +who | grep -m 1 "(tty2)" | awk '{print $1}' \ No newline at end of file From 9ccd5b689ebf684e55ac1664645e7057be0a3b04 Mon Sep 17 00:00:00 2001 From: saurav Date: Tue, 12 May 2026 23:13:30 -0700 Subject: [PATCH 23/23] format --- scripts/mezzsh/utils/get_local_user.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mezzsh/utils/get_local_user.sh b/scripts/mezzsh/utils/get_local_user.sh index b29cc378f2..03f3842968 100644 --- a/scripts/mezzsh/utils/get_local_user.sh +++ b/scripts/mezzsh/utils/get_local_user.sh @@ -4,4 +4,4 @@ # at the Mezz PC # The `who` command returns all logged in users (IRL and remote) # Finds IRL users by looking for the physical monitor (tty2) -who | grep -m 1 "(tty2)" | awk '{print $1}' \ No newline at end of file +who | grep -m 1 "(tty2)" | awk '{print $1}'