Custom scripts triggered on the server and node events explained (NX 3.5.0)
The server and the node allows administrators to add custom scripts that will be triggered by server and/or node according to the executed event.
A number of keys, respectively in the server and node configuration files (on Linux the /usr/NX/etc/server.cfg and /usr/NX/etc/node.cfg files), allows to specify path of the script to be executed. Each script can accept a number of parameters, depending on which event it is associated. For example, a script to be executed by the server before the user login can accept the remote IP from which the user is connecting, while a script to be executed before the session start-up can acceptsession id, username, node host, node port and display.
A detailed list of configuration keys and accepted parameters is available in the Server Administrator Guide:
for NX 3.5 chapter 10 in
https://www.nomachine.com/DT12I00014
and for NoMachine 4 chapter 9 in
https://www.nomachine.com/DT01L00064
If the execution of any of the custom scripts fails, either the server or the node will terminate. If you might want to modify this default behaviour, you could write your script to always terminate with exit code 0, ensuring in this way that NX server and node operations are carried on regardless of the result of your script. In a similar way, you might want to to set-up your script for being run in background. You can find some more basic examples below. They are suitable for NX 3.5.0, but can be easily extended to version 4.
Custom scripts give you more flexibility over the NX system allowing you, for example, to export environment variables, to log specific information at a certain stage, to forbid access to the NX system for a certain remote IP or running a specific command for that user (when the script is executed by the node) or for all users (when the script is executed by the server).
Some examples for NX 3.5.0
1) How to export an environment variable by using your own script
The following example allows you to export an environment variable, let's name it NX_SESSIONDIR, pointing at the user's session directory. Please note that, since NX server is executed as user nx, it doesn't have permissions to write to user's files as .bashrc. If you need instead to write to user's files, you need to create custom scripts to be executed on NX node events, since NX Node is running as the user starting the session.
In the node configuration file, namely /usr/NX/etc/node.cfg set the following key:
UserScriptBeforeSessionStart = "/tmp/nxscript/export.sh"
where export.sh is
#!/bin/bash
nxsessiondir="NX_SESSIONDIR="$NX_ROOT/C-`hostname`-$4-$1""
cleanupfile()
command="grep NX_SESSIONDIR $1"
outCommand=`/bin/bash -c "$command" 2>&1`
if [ $? == 0 ]
then
grep -v NX_SESSIONDIR $1 > $1.tmp
mv $1.tmp $1
fi
setupfile ()
cleanupfile $1
echo $nxsessiondir >> $1
# Select the file you use for setting evironment variables:
if [ -f /home/$2/.bash_profile ]
then
setupfile "/home/$2/.bash_profile"
exit 0
fi
if [ -f /home/$2/.bashrc ]
then
setupfile "/home/$2/.bashrc"
exit 0
fi
if [ -f /home/$2/.profile ]
then
setupfile "/home/$2/.profile"
exit 0
fi
And then to remove these settings after session exit:
Set the following key in node.cfg
UserScriptAfterSessionClose = "/tmp/nxscript/cleanup.sh"
where cleanup.sh is
#!/bin/bash
cleanupfile()
command="grep NX_SESSIONDIR $1"
outCommand=`/bin/bash -c "$command" 2>&1`
if [ $? == 0 ]
then
grep -v NX_SESSIONDIR $1 > $1.tmp
mv $1.tmp $1
fi
cleanupfile "/home/$2/.bash_profile"
cleanupfile "/home/$2/.bashrc"
cleanupfile "/home/$2/.profile"
Both scripts would need to have execute rights.
2) How to setup a personal CUPS server by using your own script
There may be a situation where the main CUPS server does not reside on the NX server. This architecture is not currently supported for NX. In this situation, you could use the following script to add a personal CUPS server:
start_private_cups.sh
#!/bin/sh
#variables
CupsEtcDir="/etc/cups"
CupsServer="/usr/sbin/cupsd"
User="$USER"
CupsPrvDir="$HOME/.nx/server_cups";
#create dirs
for dirname in "$HOME/.cups" "$CupsPrvDir" "$CupsPrvDir/spool" "$CupsPrvDir/spool/tmp" "$CupsPrvDir/certs" "$CupsPrvDir/cache"
do
if (! [ -d "$dirname" ] )
then
mkdir "$dirname"
fi
done
#copy mime files
if ( ! [ -f "$CupsPrvDir/mime.types" ] )
then
cp "$CupsEtcDir/mime.types" "$CupsPrvDir"
fi
if ( ! [ -f "$CupsPrvDir/mime.convs" ] )
then
cp "$CupsEtcDir/mime.convs" "$CupsPrvDir"
fi
#create client.conf
if [ -f "$HOME/.cups/client.conf" ]
then
content=`cat $HOME/.cups/client.conf`
if ( ! [ "$content" = "ServerName $CupsPrvDir/socket" ] )
then
mv "$HOME/.cups/client.conf" "$HOME/.cups/client.conf.$PPID.backup"
echo "ServerName $CupsPrvDir/socket" > "$HOME/.cups/client.conf"
fi
else
echo "ServerName $CupsPrvDir/socket" > "$HOME/.cups/client.conf"
fi
To use the script, you have to do the following:
1. Customize the paths inside the script.
2. Modify '/usr/NX/etc/node.cfg' to enable the script:
Insert the key
UserScriptBeforeSessionStart = "/usr/NX/scripts/custom/start_private_cups.sh"
3. Check 'ipp' backend permissions. It should be 755 to allow printing from user sessions. The default path to 'ipp' is: /usr/lib/cups/backend/ipp. So if permissions are wrong, fix them with:
# chmod 755 /usr/lib/cups/backend/ipp
4. Try to print inside a new session.
This script starts a private 'cupsd' which works even after the end of the session and can be reused by the next session. To stop 'cupsd' at the end of the session you can write a separate script and enable it with the following key in /usr/NX/etc/node.cfg: "UserScriptBeforeSessionClose".
3) How to provide additional info about the system to the end-userby showing a dialog message
In some cases, the administrator might want to provide additional information to the end-user. For example, in case of multi-node support, the administrator might need that users know about hostname of the NX node machine where the session has been started or reconnected.
The sample below explains how to create custom scripts for issuing a dialog message via NX client inside the NX session to provide info about hostname and display. This has to be done for each node.
1. Create the displayMessageStart.sh script and place it in a directory that is accessible by NX Node (which runs as the user). The script should be similar to:
#! /bin/sh
#variables
userName=$2
displayNumber=$4
host=`hostname`
message="$userName@$host:$displayNumber"
/usr/NX/bin/nxclient --dialog ok --caption "System information" --message $message --display :$displayNumber
2. In the node configuration file, namely /usr/NX/etc/node.cfg set the following key:
UserScriptAfterSessionStart = "/usr/NX/scripts/custom/displayMessageStart.sh"
3. Create the displayMessageReconnect.sh script and place it in a directory accessible by the NX Node (which runs as the user). The script should be similar to:
#! /bin/sh
#variables
userName=$2
displayNumber=$3
host=`hostname`
message="$userName@$host:$displayNumber"
/usr/NX/bin/nxclient --dialog ok --caption "System information" --message $message --display :$displayNumber
4. In the node configuration file, namely /usr/NX/etc/node.cfg set the following key:
UserScriptAfterSessionReconnect = "/usr/NX/scripts/custom/displayMessageReconnect.sh"
Both scripts should have execute rights.
4) How to determine IP address of a client machine and correlate it to the username
The username and IP address are available for the script configured into the variable UserScriptAfterLogin in /usr/NX/etc/server.cfg .
The username is passed to that script as the first argument.
Username and IP are also available in the script configured into the variable UserScriptAfterSessionClose in /usr/NX/etc/server.cfg .
A solution consists of the following steps:
1. create a directory writable by the nx user, world readable, in which the nxserver will drop rc a rc file upon connect ($USERSCRIPTS)
2. create a directory writable by root, readable for the nx user in which scripts triggered at logon / logoff will reside ($NXSCRIPTS)
3. place the following script as UserScriptAfterLogin.sh into the directory $NXSCRIPTS, executable by the user nx:
#!/bin/bash
USERSCRIPTS=/path/to/NX/userscripts
case $0 in
*UserScriptAfterLogin.sh)
U=$1
set $SSH_CONNECTION
nxsessioninfo="export NX_REMOTE_IP=$1"
echo $nxsessioninfo > $USERSCRIPTS/$U
break
;;
*UserScriptAfterSessionClose.sh)
U=$2
test -f $USERSCRIPTS/$U && rm $USERSCRIPTS/$U
break
;;
esac
exit 0
4. hard link UserScriptAfterLogin.sh to UserScriptAfterSessionClose.sh
5. stick the following four lines into /etc/bash.bash_rc
USERSCRIPTS=/path/to/NX/userscripts
if [ -f USERSCRIPTS/$LOGNAME ]; then
. USERSCRIPTS/$LOGNAME
fi
Done that, the originating IP address as seen by the nx server on initial connect will show up as the NX_REMOTE_IP environment variable.
If a user supends the session and reconnects later with a different IP address, the rc file will be rewritten upon reconnect. Just source the rc file again. You can also create an alias to source the file and output the ip address:
alias nx_ip='. $USERSCRIPTS/$LOGNAME; echo $NX_REMOTE_IP'
in /etc/bash.bashrc to have a nice shortcut.
