Skip to content

Instantly share code, notes, and snippets.

@eddsalkield
Last active November 1, 2021 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eddsalkield/fbbf892dff417cffb4aaac4b91062997 to your computer and use it in GitHub Desktop.
Save eddsalkield/fbbf892dff417cffb4aaac4b91062997 to your computer and use it in GitHub Desktop.
#!/bin/sh
# Grant remote access to your local machine through an SSH tunnel
# Configures an ssh server that runs at the privilege level of your user
# Starts a remote proxy to a remote server running frps
# Installs a pre-configured SSH key
# Enforces that logins to the server connect through tmux for logging purposes
# Only writes files to temporary locations, cleaning up after itself upon exit
set -e
# Look for programs in common locations, and in the temporary install directory
PATH=$PATH:/usr/sbin:${XDG_CACHE_HOME:-$HOME/.cache}/grant_remote_access/bin
if [ $# -ge 2 ]; then
echo "Usage: ./grant_remote_access [--debug]"
exit 1
fi
if [ $# -eq 1 ]; then
if [ $1 = "--debug" ]; then
DEBUG_MODE=1
else
echo "Usage: ./grant_remote_access [--debug]"
exit 1
fi
else
DEBUG_MODE=0
fi
SERVER_ADDRESS="salkield.uk"
SERVER_PORT="8001" # The port that we open the connection to on the server
SERVER_ENTRY_PORT="8000" # The port that gets bound to our tunnel on the server
TMUX_SOCKET_NAME="$(awk -v min=1000 -v max=10000 'BEGIN{srand(); print int(min+rand()*(max-min+1))}')" # Generate random socket name POSIX-ly
# Ensure that a random TMUX socket name was created
if [ -z "$TMUX_SOCKET_NAME" ]; then
echo "Failed to generate random TMUX socket name with sed. Exiting..."
exit 1
fi
AUTHORIZED_KEYS="restrict,command=\"tmux -L $TMUX_SOCKET_NAME a\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDH8hl/CBVZvSxlhJ6V2M9POegIQ8mKqJaJlrEjnQxEcb7/9Z8s+PfIUv7EfaVb73kiiENL4cAnTeaN8WRWX5O9SL0B84tOghDsupzN+B2ETbdDRPNpiaXmQu1l/RAJohNjhO3cOGQe5mDlJ2L+0hwUGpkNCP7eRn4kpW6/1LSmdEdTK+pPzTd/Jp5H2ZdbwZ5fZKTBI9Zpg4vBtjtO+s3KdIkvD40pCuvtiw5hwM2kZrCA1Ibfx7b6nlCgadS4L2Rq+2szjg8YxulX4siOhZx5D7oKoJSLBUQDnb6tDnPnPXoic6sDw4aSTi3dcwvMldR+5DA8i6ZivmidgacATlRVimvpVapW9MMBB3R7IrwRxWeHGmii8YupnjAtJHKeZiLLedhshL35biQTqSdRaik7xeWMeI+Oe9vVGh99Ts89d3VcQnnVMPORS14mFbfYUsKg04EGv43clIVe787X9Tcp/BF/4Q/nmqpDBxJUY5y3J66r1nWXhrFr3O3T+mosn7E= edd@public-hexadecanibbler"
SSHD_PORT="8000"
# Create working directories
TEMP_DIR=$(mktemp --tmpdir="/tmp" -d "grant_remote_access.XXX")
SSHD_CONFIG_FILE="$TEMP_DIR/sshd_config"
SSHD_HOST_KEY_FILE="$TEMP_DIR/id_rsa"
SSHD_PID_FILE="$TEMP_DIR/sshd.pid"
FRP_CONFIG_FILE="$TEMP_DIR/frpc.ini"
FRP_TEMP_FILE="$TEMP_DIR/frpc_status"
touch "$SSHD_PID_FILE"
SSHD_AUTHORIZED_KEYS_FILE="$TEMP_DIR/authorized_keys"
# Remove temp files on exit unless in debug mode
exit_handler_1 () { if [ $DEBUG_MODE -eq 0 ]; then rm -rf "$TEMP_DIR"; fi }
trap exit_handler_1 EXIT
# Configure SSHD
SSHD_CONFIG="
AuthorizedKeysFile $SSHD_AUTHORIZED_KEYS_FILE
PidFile $SSHD_PID_FILE
ListenAddress 127.0.0.1
StrictModes no
"
# Configure frp
FRP_CONFIG="
[common]
server_addr = $SERVER_ADDRESS
server_port = $SERVER_PORT
admin_addr = 127.0.0.1
admin_port = 7400
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = $SSHD_PORT
remote_port = $SERVER_ENTRY_PORT
"
# Check that the correct programs are installed
if ! command -v sshd >/dev/null 2>&1; then
echo "sshd not installed. Exiting..."
exit 1
fi
if ! command -v tmux >/dev/null 2>&1; then
echo "tmux not installed. Exiting..."
exit 1
fi
if ! command -v frpc >/dev/null 2>&1; then
echo "frpc not installed. Exiting..."
exit 1
fi
# Configure sshd
printf '%b\n' "$SSHD_CONFIG" > $SSHD_CONFIG_FILE
touch $SSHD_AUTHORIZED_KEYS_FILE
chmod 600 $SSHD_AUTHORIZED_KEYS_FILE
chmod 700 $TEMP_DIR
echo $AUTHORIZED_KEYS > $SSHD_AUTHORIZED_KEYS_FILE
fingerprint=$(ssh-keygen -t rsa -f $SSHD_HOST_KEY_FILE -N "" | sed -n '5p' | cut -d " " -f1)
# Run sshd as background job
if [ $DEBUG_MODE -eq 0 ]; then
$(whereis sshd | cut -d " " -f 2) -D -f "$SSHD_CONFIG_FILE" -h $SSHD_HOST_KEY_FILE -p $SSHD_PORT &
SSHD_PID=$!
else
$(whereis sshd | cut -d " " -f 2) -dddD -f "$SSHD_CONFIG_FILE" -h $SSHD_HOST_KEY_FILE -p $SSHD_PORT &
SSHD_PID=$!
fi
echo "ssh server launched"
# Kill sshd on script exit
exit_handler_2 () { if [ -d "/proc/$SSHD_PID" ]; then kill "$SSHD_PID"; fi; exit_handler_1; }
trap exit_handler_2 EXIT
# Configure frp
printf '%b\n' "$FRP_CONFIG" > $FRP_CONFIG_FILE
# Open tunnel to server as background job
frpc -c $FRP_CONFIG_FILE > $FRP_TEMP_FILE &
FRP_PID=$!
exit_handler_3 () { if [ -d "/proc/$FRP_PID" ]; then kill "$FRP_PID"; fi; exit_handler_2; }
trap exit_handler_3 EXIT
# Wait until the connection has been established
set +e
while true; do
# If the process is still running
if kill -0 "$FRP_PID" >/dev/null 2>&1; then
cat "$FRP_TEMP_FILE" | grep "\[ssh\] start proxy success"
# And the proxy started, exit
if [ $? -eq 0 ]; then
break
fi
else
echo "could not establish a connection to $SERVER_ADDRESS"
exit 1
fi
sleep 1
done
set -e
echo "connection to $SERVER_ADDRESS established"
set +e # Don't quit part way through killing the services during cleanup
# Open tmux under custom socket, reporting the ssh fingerprint
if [ $DEBUG_MODE -eq 0 ]; then
tmux -L $TMUX_SOCKET_NAME new "printf '%b\n' \"$fingerprint\nusername: $(whoami)\"; eval ${SHELL:-/bin/sh}"
else
while true; do :; done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment