View on GitHub

bioit

Services Setup

Introduction

The following guide sets up various web services with SSL via NGINX and some other nice stuff.

Rstudio Server Install

Download the installer:

Rocky Linux 8

wget https://download2.rstudio.org/server/rhel8/x86_64/rstudio-server-rhel-2025.05.0-496-x86_64.rpm

Rocky Linux 9

wget https://download2.rstudio.org/server/rhel9/x86_64/rstudio-server-rhel-2025.05.0-496-x86_64.rpm

Rocky Linux 8 and 9

You need to specify where R is by doing the following before installing the rstudio server package:

sudo mkdir /etc/rstudio
sudo vi /etc/rstudio/rserver.conf

Paste the following into the rserver.conf file you’re creating (changing the version of R as necessary):

# Location of R
rsession-which-r=/opt/bioit/R-core/4.5.0/bin/R
# R library path
rsession-ld-library-path=/opt/bioit/R-core/4.5.0/lib64/R/lib
# Only listen localhost
www-address=localhost
# Connection port
www-port=9797

Note that this will cause the server to only listen to localhost and port 9797. You should add the localhost option even if using a vanilla install as the free RStudio Server package doesn’t support SSL and we need to use NGINX to provide that.

Install the server:

sudo yum install rstudio-server-rhel-2025.05.0-496-x86_64.rpm

For better performance you should edit the /etc/rstudio/rsession.conf file and add the following:

# R Session Configuration File

session-save-action-default=no

# overrides the user/project restore workspace setting
r-restore-workspace=0

If SELinux is enabled, do the following to allow the server to actually work and any time you upgrade versions:

sudo chcon -R -t bin_t /usr/lib/rstudio-server/bin/

If you want to store the R session data on a local drive such as in /usr/local/rstudio/$USER you should create that directory and directories for each user inside here. Then shut down the rstudio-server and run this sudo systemctl edit rstudio-server and add the following:

[Service]
Environment="RSTUDIO_DATA_HOME=/usr/local/rstudio/$USER/rstudio"

You can create a full set of directories based on your /home/ directory using the following:

( cd /home && find . -maxdepth 1 -type d -not -name . -exec sh -c 'for d do mkdir -p "/usr/local/rstudio/$d/rstudio" ; user="${d:2}" ; chown $user:$user -R /usr/local/rstudio/$d ; chmod 700 /usr/local/rstudio/$d ; done ' sh {} + )

If you add new users, don’t forget to create this directory because the new user won’t be able to log in. Set the ownership to their account and permissions to 700 like their regular home directory is. If you’re migrating from having the rstudio directory in user’s home directories, you can move the file from /home/$USER/.local/share/rstudio into /usr/local/rstudio/$USER/rstudio and then start the rstudio-server again.

Restart the service to make config channges take effect:

sudo systemctl restart rstudio-server

You should now be able to open the RStudio Server interface by going to http://localhost:9797 using Firefox inside the X2Go remote desktop.

JupyterLab Install

Create the directory for the install:

sudo mkdir /opt/jupyter
sudo chown build:build jupyter

Make sure password free sudo is enabled as per the installation page. JupyterLab is installed by running the script in ~/bioit/bin

build_jupyterlab 4.4.3

If you want to include jupyter-ai, uncomment that line in this script before running it. You’ll also need ollama.service installed and set up some LLMs for it to use.

If it fails, you can remove it using:

destroy_jupyterlab

Once running you can test it from Firefox in X2Go by going to http://localhost:8080 and you will get an SSL warning but we’ll deal with that via NGINX.

If you have SELinux enabled you’ll find that you can’t log in, or if you can you should log out and log back in again when you should get a failure. Once you’ve had this, you need to do the following to allow authentication to work:

sudo setenforce permissive

Now try and log in and it will let you but audit.log will contain the information necessary to allow it to work in enforcing mode. You need to create a module using this:

sudo grep denied /var/log/audit/audit.log | audit2allow -M jupyter-module
sudo semodule -i jupyter-module.pp
sudo setenforce enforcing
sudo systemctl restart jupyterhub
sudo systemctl restart nginx

At this point, SELinux should allow JupyterHub access to authentication and will continue to work.

Jupyter Remote Desktop

It might be useful to have a remote desktop solution inside Jupyterhub. Assuming the Mate Desktop is already installed as per the installation page and X2Go config, you can do the following to add a launcher inside JupyterHub as the build user:

sudo dnf -y install tigervnc tigervnc-server tigervnc-selinux
cd /opt/jupyter/jupyterlab/4.4.3/jupyterlab_4.4.3/bin/
./pip install jupyter-remote-desktop-proxy

Set mate-session instead of xfce4-session in this file:

sed -i -e 's/xfce4/mate/g' /opt/jupyter/jupyterlab/4.4.3/jupyterlab_4.4.3/lib/python3.10/site-packages/jupyter_remote_desktop_proxy/share/xstartup

Restart the JupyterHub and nginx services

sudo systemctl restart jupyterhub
sudo systemctl restart nginx

Log in again and there will be a new desktop launcher. Clicking that will open a new tab with a Mate desktop session for the user.

If you’re running selinux you’ll need to enable this again with:

sudo setenforce permissive
sudo grep denied /var/log/audit/audit.log | audit2allow -M vnc-module
sudo semodule -i vnc-module.pp
sudo setenforce enforcing
sudo systemctl restart jupyterhub

Note: When a user logs ouf of this remote desktop they will need to stop their server in Hub Control otherwise they won’t be able to start a new desktop. If they just close the tab, the remote desktop will continue running and they can reconnect with the desktop button in JupyterHub. They also need to make sure they don’t open a JupyterHub session inside this desktop and connect to the desktop because that will go into a recursive image. They should also not use this and another desktop session such as X2Go as there will be clashes in the files.

NGINX config

Install nginx:

sudo dnf -y install nginx

Edit the /etc/nginx/nginx.conf file using the reference provided in ~/bioit/bin

You need SSL certs, these can be generated like this:

openssl genrsa -des3 -out private.key 2048
openssl req -key private.key -new -out server.csr
openssl x509 -signkey private.key -in server.csr -req -days 365 -out server.crt

If you want the key to last longer, set more than 365 days.

Put the crt and key files inside /etc/nginx/ssl and reference them from nginx.conf

If you created the key with a passphrase, create global.pass inside /etc/nginx/ssl and make it only readable by root. Put the passphrase inside this which will allow nginx to decrypt the certs and serve them. Uncomment the relevant line in the nginx.conf file.

A DNS entry needs to exist for the aliases used in the conf file so make sure that’s done.

Lastly, you need to start nginx:

sudo systemctl enable nginx
sudo systemctl start nginx

If you have SELinux enabled, it will fail to work with a bad gateway message so set SELinux to permissive as we’ve already seen:

sudo setenforce permissive
sudo grep denied /var/log/audit/audit.log | audit2allow -M nginx-module
sudo semodule -i nginx-module.pp
sudo setenforce enforcing
sudo systemctl restart nginx

It should now work and you won’t get the warning from JupyterHub about it not being SSL. It should also be accessible from external machines. If you still get the bad gateway message on the new HTTPS connection, redo the SELinux audit step and restart nginx. If it also happens with RStudio Server, do this again until it all works.

If you still can’t connect from outside and the firewall is running do the following:

sudo firewall-cmd --zone=public --permanent --add-service=https
sudo firewall-cmd --reload

Now any machine on the local network should be able to access the server (assuming the various aliases have been registered in DNS of course.)

Nice login banner

Having a nice banner about the machine can be done as follows:

sudo dnf -y install neofetch figlet
echo `hostname -s` | figlet > /etc/hostname-banner
sudo echo -e "This server is the property of\nXXXX Ltd.\n\nAll access is monitored." >> /etc/hostname-banner
sudo mkdir /etc/neofetch

Now set up neofetch for a non-gpu server:

sudo cp /home/build/bioit/bin/neofetch.conf /etc/neofetch/neofetch.conf

or for a gpu server:

sudo cp /home/build/bioit/bin/neofetch_gpu.conf /etc/neofetch/neofetch.conf

Finally create the motd.sh script in /etc/profile.d:

 sudo echo '#!/bin/bash' > /etc/profile.d/motd.sh; sudo echo 'printf "\n"' >> /etc/profile.d/motd.sh ; sudo echo 'neofetch --config /etc/neofetch/neofetch.conf --ascii /etc/hostname-banner' >> /etc/profile.d/motd.sh

Now when you log in you’ll see a nice banner and updated stats on the machine.

Nagios Install

Before doing anything, make sure crony is enabled otherwise logs will be funky:

systemctl enable --now chronyd

Check you date, time and timezone are correct using timedatectl,

To ease the install of nagios and plugins, switch SELinux into permissive mode otherwise things will fail:

sudo setenforce permissive

We’ll turn SELinux on again once things are working.

Install dependencies for Nagios as root:

Rocky Linux 8 and 9

sudo -s
dnf clean all
dnf update
dnf install -y php perl @httpd wget unzip glibc automake glibc-common gettext autoconf php php-cli gcc gd gd-devel net-snmp openssl-devel unzip net-snmp postfix net-snmp-utils

Before starting httpd remove the ssl.conf because we’re going to put this behind NGINX.

cd /etc/httpd/conf.d
mv ssl.conf ssl.conf.bak

Also, we need to modify the /etc/httpd/conf/httpd.conf file to get Apache to listen on a non standard port by commenting out Listen 80 and adding Listen localhost:8282 otherwise Apache won’t start.

Now start HTTPD and PHP

systemctl enable httpd php-fpm
systemctl enable php-fpm
systemctl start httpd
systemctl start php-fpm

Verify the services are running correctly and if not you’ve probably forgotten to switch SELinux into permissive mode.

systemctl status httpd
systemctl status php-fpm

You can also test that Apache is running via a browser in X2Go and going to http://localhost:8282 and you should see the HTTP Server Test Page.

If Apache and PHP are running correctly, move on to installing Nagios by first downloading and building the source code:

cd /root
wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.5.9.tar.gz
tar -xzf nagios-4.5.9.tar.gz
cd nagios-4.5.9
./configure

This is going to do the install in /usr/local and is better than using the RPM packages as it will be more configurable and easy to debug. Next build the source (assuming the previous step looks to have found all the dependencies it needed:

make all

If that compiles successfully (Check the Compile finished output) we next need to create the nagios user account:

make install-groups-users
usermod -aG nagios apache

Next, install the software itself:

make install
make install-init
make install-daemoninit
make install-commandmode
make install-config
make install-webconf

Create the Nagios Web user account nagiosadmin(which will be used to log into the interface) giving it a password you can remember:

htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin

Now set permissions for this file so Apache can use it:

chmod 640 /usr/local/nagios/etc/htpasswd.users
chown nagios:nagios /usr/local/nagios/etc/htpasswd.users
systemctl restart httpd

Start Nagios:

systemctl enable nagios --now

Check the service is running:

systemctl status nagios

Note that it still won’t work properly because there are no plugins but you should be able to get into the interface via a brwoser in X2Go at http://localhost:8282/nagios using the nagiosadmin account and the password you set for it. Once passed the login you’ll get an error in services but that’s because of the missing plugins so we’ll fix that next.

Nagios plugins install

Install the dependencies for plugins (still as root):

dnf -y install gcc glibc glibc-common make gettext automake autoconf wget openssl-devel

Download and unpack the plugins:

cd /root
wget http://www.nagios-plugins.org/download/nagios-plugins-2.4.11.tar.gz
tar xzf nagios-plugins-2.4.11.tar.gz

Build the plugins:

cd nagios-plugins-2.4.11
./configure --with-nagios-user=nagios --with-nagios-group=nagios
make
make install

Restart Nagios and try the web interface again.

systemctl restart nagios

Now you should be able to go into the services for localhost and get OKs for the default set of services as they refresh. Services can be customised later.

Nagios pnp4nagios install

Install required dependencies for PNP4Nagios:

dnf -y install rrdtool rrdtool-perl perl-Time-HiRes perl-GD php-xml php-gd php-json php-mbstring

Download and install PNP4Nagios:

cd /root
wget https://github.com/pnp4nagios/pnp4nagios/archive/refs/tags/v0.6.27-5.tar.gz
tar xvf v0.6.27-5.tar.gz
cd pnp4nagios-0.6.27-5
./configure
make all
make fullinstall

Now we need to modify the /usr/local/nagios/etc/nagios.cfg file adding the following:

process_performance_data=1
# service performance data
service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
service_perfdata_file_mode=a
service_perfdata_file_processing_interval=15
service_perfdata_file_processing_command=process-service-perfdata-file

# host performance data
host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
host_perfdata_file_mode=a
host_perfdata_file_processing_interval=15
host_perfdata_file_processing_command=process-host-perfdata-file

Edit /usr/local/nagios/etc/objects/commands.cfg and comment out the process-host-perfdata and process-service-perfdata commands then append the following:

define command{
       command_name    process-service-perfdata-file
       command_line    /bin/mv /usr/local/pnp4nagios/var/service-perfdata /usr/local/pnp4nagios/var/spool/service-perfdata.$TIMET$
}

define command{
       command_name    process-host-perfdata-file
       command_line    /bin/mv /usr/local/pnp4nagios/var/host-perfdata /usr/local/pnp4nagios/var/spool/host-perfdata.$TIMET$
}

Also edit /usr/local/nagios/etc/objects/templates.cfg and append the following:

define host {
    name host-pnp
    action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel=/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    register 0
}

define service {
    name srv-pnp
    action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel=/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    register 0
}

Lastly, edit /usr/local/nagios/etc/objects/localhost.cfg and for each service modify the use local-service line to be use local-service,srv-pnp and write out the file. Restart Nagios:

Edit /usr/local/pnp4nagios/etc/npcd.cfg and change the perfdata_spool_dir = definition to:

perfdata_spool_dir = /usr/local/pnp4nagios/var/spool

Enable npcd service

/usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
systemctl enable npcd.service --now

Restart Nagios and HTTPD

systemctl restart nagios.service
systemctl restart httpd.service

Open http://localhost:8282/pnp4nagios/ in your browser via X2Go and check everything passes. If it starts again OK remove install.php file

rm -f /usr/local/pnp4nagios/share/install.php

Create missing directory to store the data for localhost and set ownerships for nagios and pnp4nagios to avoid permissions issues:

mkdir /usr/local/pnp4nagios/var/log/pnp4nagios/rrd/localhost
chown -R nagios:nagios /usr/local/nagios /usr/local/pnp4nagios

Restart Nagios and HTTPD again:

systemctl restart nagios.service
systemctl restart httpd.service

As usual, it will take a while for the charts to show up as Nagios cycles through refreshes so be patient.

Also need to re-enable SELinux now that everything is working so do the following:

cd /root
grep denied /var/log/audit/audit.log | audit2allow -M nagios-module
semodule -i nagios-module.pp
setenforce enforcing
systemctl restart nagios
systemctl restart httpd

Check you can still interact with Nagios with SELinux enabled now.

At this point, all the local services are running but now we need NGINX to provide SSL Nagios so edit /etc/nginx/nginx.conf and add a server entry for the nagios DNS alias just as for jupyterhub and rstudio. You’ll again need to do the SELinux work for nginx too:

cd /root
sudo setenforce permissive
sudo grep denied /var/log/audit/audit.log | audit2allow -M nginx-module
sudo semodule -i nginx-module.pp
sudo setenforce enforcing
sudo systemctl restart nginx

Now you should be able to go to the nagios alias from outside localhost. Check all the other services too and redo this process any time you hit an error until it all works. Reboot the machine to make sure it all comes back correctly too.

To avoid having to put in hostname/nagios you can copy the example index.html.example from the bin/nagios_examples directory to /var/www/html/index.html making sure you change HOSTNAME to the actual nagios server hostname alias. Once you’ve done that, restart apache (httpd) and you should now be able to go to your nagios alias and arrive at the home page directly.

Also note that you’ll need to open port 80 for this to work from outside the host:

sudo firewall-cmd --zone=public --permanent --add-service=http
sudo firewall-cmd --reload

It isn’t a security risk because the server immediately bounces the user over to the HTTPS port but it needs to be open for this redirect to work. Otherwise, just stick with appending /nagios if it is a worry.

Next Step

Go to the Updating page.