[X2Go-Dev] Bug#1459: X2GoMiniSSHBroker
Stefan Baur
X2Go-ML-1 at baur-itcs.de
Sun Apr 19 15:47:44 CEST 2020
package: x2gobroker
priority: wishlist
Hi everyone,
A while ago, I wrote a small broker demo in bash.
I would like to get this added to X2Go's official repository, in the
x2gobroker.git tree, as a separate binpkg (maybe called
x2gobroker-ssh-mini).
Limitations:
1) This script is not suitable for a multi-server setup.
It needs to run on the only X2GoServer there is.
(There's an idea in the comments how to overcome this limitation,
though.)
This is, however, also its advantage: You don't need to mess with
LDAP, postgres and NFS just to be able to use a central configuration
for your X2GoClients.
2) It does not offer all the ACL options of the "big" broker
implementations.
Problems:
1) There's currently no manpage for it. All documentation is in the
comments in the bash script.
2) IIRC, Alex made some changes to X2GoClient and/or X2GoServer that
will cause this script to break - however, these changes are not part
of our stable release yet. So it should be possible to release this
package right now, but it needs to be kept in mind that it will have
to be adapted once Alex' changes make it to stable.
This was related to more "chatter" about "Access granted" and similar
status messages being exchanged between server/broker/client.
Script attached.
Kind Regards,
Stefan Baur
--
BAUR-ITCS UG (haftungsbeschränkt)
Geschäftsführer: Stefan Baur
Eichenäckerweg 10, 89081 Ulm | Registergericht Ulm, HRB 724364
Fon/Fax 0731 40 34 66-36/-35 | USt-IdNr.: DE268653243
-------------- next part --------------
#!/bin/bash
# This file is part of the X2Go Project - http://www.x2go.org
# Copyright (C) 2018 by Stefan Baur <X2Go-ML-1 at baur-itcs.de>
#
# X2Go Mini SSH Session Broker is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# X2Go Mini SSH Session Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
# Features and Limitations
# You can add sessions as for-everyone (defaultsessions), per-group, and per-user
# You cannot add sessions based on IP range
# You cannot deny sessions based on group, user, or IP range
# Checking for suspended sessions and resuming them only works if you are logged in
# to the broker with the same credentials that you want to use to start/resume
# the session AND
# if broker and X2Go server are one and the same machine
# (This could be expanded so it works with separate machines, as long as ssh
# public/private key authentication and autologin is used.)
# Config goes here - always only one session per file!
# /etc/x2go/x2go-mini-sshbroker/defaultsessions/*.session
# /etc/x2go/x2go-mini-sshbroker/${USER}/*.session
# /etc/x2go/x2go-mini-sshbroker/groups/${GROUP}/*.session
### init ###
# make a list of the parameters we received on the command line
PARAMLIST=$(echo -e "$@" | sed -e 's/ --/\n--/g')
# make sure we have a directory to write our config file to
mkdir -p ~/.x2go
### main ###
# check if we were asked to list sessions
if (echo -e "$PARAMLIST" | grep -q -- '--task listsessions'); then
# this is so we can request data for a username that is different from the one we used
# to log in and run this script with
REQUESTEDUSER=$(echo -e "$PARAMLIST" | awk '$1 == "--user" { print $2}')
if [ -n "$REQUESTEDUSER" ]; then
USER=$REQUESTEDUSER
fi
# fetch default sessions
if [ -d /etc/x2go/x2go-mini-sshbroker/defaultsessions ]; then
for SINGLESESSIONFILE in /etc/x2go/x2go-mini-sshbroker/defaultsessions/*.session ; do
# add session file name to the list of sessionfiles
SESSIONFILES+="$SINGLESESSIONFILE\n"
# figure out what the name of the session should be, based on the filename
SINGLESESSIONNAME=$(basename $SINGLESESSIONFILE | sed -e 's/\.session$//')
# check if the session file already contains a proper header block
if (grep -q "^\[$SINGLESESSIONNAME\]" $SINGLESESSIONFILE); then
# if it does, all we do is replace the user name
SESSIONLIST+="\n$(grep -v '^user=' $SINGLESESSIONFILE)\nuser=$USER\n"
else
# if it does not, we add a header based on the file name, and replace the user name
SESSIONLIST+="\n[$SINGLESESSIONNAME]\n$(grep -v '^\[' $SINGLESESSIONFILE | grep -v '^user=')\nuser=$USER\n"
fi
done
fi
# fetch user-specific sessions
if [ -d /etc/x2go/x2go-mini-sshbroker/$USER ]; then
for SINGLESESSIONFILE in /etc/x2go/x2go-mini-sshbroker/$USER/*.session ; do
# add session file name to the list of sessionfiles
SESSIONFILES+="$SINGLESESSIONFILE\n"
# figure out what the name of the session should be, based on the filename
SINGLESESSIONNAME=$(basename $SINGLESESSIONFILE | sed -e 's/\.session$//')
# check if the session file already contains a proper header block
if (grep -q "^\[$SINGLESESSIONNAME\]" $SINGLESESSIONFILE); then
# if it does, all we do is replace the user name
SESSIONLIST+="\n$(grep -v '^user=' $SINGLESESSIONFILE)\nuser=$USER\n"
else
# if it does not, we add a header based on the file name, and replace the user name
SESSIONLIST+="\n[$SINGLESESSIONNAME]\n$(grep -v '^\[' $SINGLESESSIONFILE | grep -v '^user=')\nuser=$USER\n"
fi
done
fi
# fetch group-specific sessions
if [ -d /etc/x2go/x2go-mini-sshbroker/groups ]; then
# determine groups for this user and work through the list
for SINGLEGROUP in $(id -Gn $USER) ; do
if [ -d /etc/x2go/x2go-mini-sshbroker/groups/$SINGLEGROUP ]; then
for SINGLESESSIONFILE in /etc/x2go/x2go-mini-sshbroker/groups/$SINGLEGROUP/*.session ; do
# add session file name to the list of sessionfiles
SESSIONFILES+="$SINGLESESSIONFILE\n"
# figure out what the name of the session should be, based on the filename
SINGLESESSIONNAME=$(basename $SINGLESESSIONFILE | sed -e 's/\.session$//')
# check if the session file already contains a proper header block
if (grep -q "^\[$SINGLESESSIONNAME\]" $SINGLESESSIONFILE); then
# if it does, all we do is replace the user name
SESSIONLIST+="\n$(grep -v '^user=' $SINGLESESSIONFILE)\nuser=$USER\n"
else
# if it does not, we add a header based on the file name, and replace the user name
SESSIONLIST+="\n[$SINGLESESSIONNAME]\n$(grep -v '^\[' $SINGLESESSIONFILE | grep -v '^user=')\nuser=$USER\n"
fi
done
fi
done
fi
# store list of session files
TEMPBROKERSESSIONFILE=$(mktemp -p ~/.x2go)
echo -e "$SESSIONFILES">$TEMPBROKERSESSIONFILE
# atomic transaction, so it is always complete when accessed, even when multiple instances are run in parallel
mv $TEMPBROKERSESSIONFILE ~/.x2go/brokersessionfile-${USER} # needs user name, in case we ssh'ed into the broker using different credentials
# output all session data
echo -e "Access granted"
echo -e "START_USER_SESSIONS"
echo -e "$SESSIONLIST"
echo -e "END_USER_SESSIONS"
# check if we were asked to provide a server name/IP and port for a specific session
elif (echo -e "$PARAMLIST" | grep -q -- '--task selectsession'); then
SESSIONID=$(echo -e "$PARAMLIST" | awk '$1 == "--sid" { print $2 }')
# search for the line with the corresponding session file in our stored list of files
SESSIONFILE=$(grep "$SESSIONID" ~/.x2go/brokersessionfile-${USER})
# determine server name/IP and port from this file
SERVER=$(awk -F '=' '$1 == "host" { print $2 }' $SESSIONFILE)
PORT=$(awk -F '=' '$1 == "sshport" { print $2 }' $SESSIONFILE)
# if this failed, set default values
if [ -z "$SERVER" ] && [ -f /etc/x2go/x2go-mini-sshbroker/defaulthost ]; then
# determine default hostname/IP
read DEFAULTHOST </etc/x2go/x2go-mini-sshbroker/defaulthost
SERVER=$DEFAULTHOST
fi
if [ -z "PORT" ]; then
PORT=22
fi
# output all data
echo -e "Access granted"
echo -e "SERVER:$SERVER:$PORT"
# check for suspended sessions
SESSIONLIST=$(x2golistsessions)
# NOTE: at present, this only checks for local sessions (X2GoBroker==X2GoServer)
# to make this work with a separate X2GoServer, we would need something like
#if [ -z "$SESSIONLIST" ] && [ -n "$SSH_AUTH_SOCK" ]; then
# # very hackish and not safe! Try to add hosts to a shared known_hosts file in advance, and place it in /etc/x2go/x2go-mini-sshbroker/
# # then point UserKnownHostsFile at that and get rid of the StrictHostKeyChecking=false
# SESSIONLIST=$(ssh -oStrictHostKeyChecking=false -oUserKnownHostsFile=/dev/null -p $PORT -A $USER@$SERVER x2golistsessions 2>/dev/null)
#fi
# but the problem is, that it seems SSH_AUTH_SOCK is not set by the broker when logging in
# one way around this might be an ssh private key stored in /etc/x2go/x2go-mini-sshbroker/, that is added as a limited key with
# "forced-command=x2golistsessions_root" to /root/.ssh/authorized_keys to all servers - the output would then have to be filtered for the
# username in question, as _root shows the data of all users on that particular host
if [ -n "$SESSIONLIST" ]; then
echo "SESSION_INFO:$SESSIONLIST"
fi
fi
# DEBUG echo "$@" >>/tmp/x2go-mini-sshbroker-commands
More information about the x2go-dev
mailing list