(Updated September 10, 2025)
New RHEL 9.x workstation install
You will receive an IP from the DHCP free pool.
Connect to Red Hat and register!
Installation Destination
* Select Disk
* Select Custom, then Done
* Select LVM, then Click here to create them automatically.
* Delete /home
* Set /boot to ext4 and 2048MiB
* Keep swap at ~16GiB
* Set / (root) to ext4 and ~458.89GiB
* Select Done, then Accept Changes.
Leave root disabled!
Create User
* Full Name -> Odin
* User Name -> odin
* Select Make Admin and Require Password. Set the PW (rT!).
Software Selection
* Base Environment – Workstation
Additional Software
* Office Suite & Productivity
* Internet Applications
* Gnome Applications
* Smart Card Support
* Console Internet Tools
* System Tools
* Security Tools
* Scientific Support
* Development Tools
* Graphical Admin Tools
And INSTALL! (Should take about 20 minutes…)
After reboot:
grubby --update-kernel ALL --args 'selinux=0 ipv6.disable=1' --remove-args="quiet"
REBOOT!
Insert the BUILD USB drive.
#!/bin/bash
BASE=/run/media/odin/BUILD
[ -d $BASE ] || {
cat <<EOF
Cannot find the BUILD USB drive.
EOF
exit 1
}
selinuxenabled && {
cat <<EOF
Ummm, you missed a step! You need to disable SELinux!
Running grubby for you now...
EOF
grubby --update-kernel ALL --args 'selinux=0 ipv6.disable=1'
echo "Pausing for you to be able to read this."
echo "Press ENTER to reboot, then you can re-run this script."
read ans
reboot
}
#Disable Wayland
perl -i -p -e "s/#WaylandEnable=false/WaylandEnable=false/g;" /etc/gdm/custom.conf
cp /usr/share/accountsservice/user-templates/standard /etc/accountsservice/user-templates/
perl -i -p -e "s/Session=gnome/Session=gnome-classic/g;" /etc/accountsservice/user-templates/standard
# NOPE!
# Add /usr/local/bin to PATH at boot.
#cat </etc/profile.d/local_bin.sh
#export PATH=$PATH:/usr/local/bin
#EOF
#chmod +x /etc/profile.d/local_bin.sh
#
# Let's fix the network!
#
eth=$(nmcli -t device | grep "ethernet:connected" | cut -f1 -d':')
# need to resolve our subdomain
nmcli connection modify "$eth" \
ipv4.dns "141.222.36.200,141.222.36.196"
mac=$(nmcli -t device show $eth | grep "GENERAL.HWADDR" | cut -f2- -d: | sed 's/://g')
res=$(curl http://141.222.36.46/code-for-images/get.php?mac=$mac)
if [ "$res" = "INVALID" ]; then
echo "BAD MAC ADDRESS '$mac'"
elif [ "$res" = "NOTFOUND" ]; then
echo "MAC NOT FOUND '$mac'"
else
host=$(echo $res | cut -f1 -d:)
ip=$(echo $res | cut -f2 -d:)
fi
echo -e "HOSTNAME = $host, IP = $ip"
nmcli connection modify "$eth" \
ipv4.method manual \
ipv4.addresses "$ip/22" \
ipv4.gateway "141.222.36.1" \
ipv4.dns "141.222.36.200,141.222.36.196"
nmcli networking off && nmcli connection reload && nmcli networking on
#systemctl restart NetworkManager
sleep 6
ip addr show
echo "Pausing to confirm network. If you see errors, press CTRL-C."
echo "Otherwise, press ENTER."
read ans
# Add printing
dnf -y install hplip hplip-common hplip-libs cups-devel gutenprint-cups
#
# Standard pile of stuff...
#
subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -y
dnf install autossh -y
dnf install nfs-utils -y
dnf install ipa-client -y
dnf install vlc -y
dnf install chromium -y
dnf install gparted -y
#dnf install mplayer -y
dnf install smplayer -y
#dnf install dnf-plugins-core -y
dnf config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
rpm --import https://brave-browser-rpm-release.s3.brave.com/brave-core.asc
dnf install brave-browser -y
dnf install okular -y
dnf install kile -y
# Def DR
dnf install java-17-openjdk-devel -y
dnf install java-21-openjdk-devel -y
dnf install ant -y
tar -zxvf $BASE/bq.tgz -C /usr/local
# Clojure for DR, plus Leiningen
dnf install rlwrap -y
curl -L -O https://github.com/clojure/brew-install/releases/latest/download/linux-install.sh
chmod +x linux-install.sh
./linux-install.sh #this auto-cleans the installer
wget -P /usr/local/bin https://codeberg.org/leiningen/leiningen/releases/download/2.11.2/leiningen-2.11.2-standalone.jar
ln -s /usr/local/bin/leiningen-2.11.2-standalone.jar /usr/local/bin/leiningen.jar
chmod +x /usr/local/bin/leiningen.jar
# CR and AP?
dnf -y install qemu-img valgrind ### CR
dnf -y install wireshark wireshark-cli.x86_64 ### AP
dnf -y install tzdata-java tzdata ### las
dnf -y install exfatprogs #### for usb access, gg
echo "Pausing... If you see errors, press CTRL-C."
echo "Otherwise, press ENTER."
read ans
# CR
dnf -y install clang llvm llvm-libs dkms
# Install Redshift
dnf -y install redshift redshift-gtk
dnf install snapd -y
systemctl daemon-reload
systemctl enable snapd.service
systemctl start snapd.service
#systemctl status snapd.service
ln -sf /var/lib/snapd/snap /snap
echo "Waiting for snap..."
sleep 10
snap install sublime-text --classic
snap install intellij-idea-community --classic
snap install pycharm-community --classic
#snap install clion --classic
snap install logisim-evolution
dnf install emacs -y
snap install code --classic
snap install eclipse --classic
snap install racket
snap install processing --classic
snap install gimp
#
# R and R Studio stuff...
#
dnf -y install R
dnf -y install sqlite
dnf -y install xdg-utils pcre-devel tcl tk-devel perl-File-Copy-Recursive
dnf -y install texinfo-tex postgresql-libs
wget -P /usr/local/bin https://github.com/texstudio-org/texstudio/releases/download/4.8.8/texstudio-4.8.8-x86_64.AppImage
chmod 755 /usr/local/bin/texstudio-*-x86_64.AppImage
dnf -y install R-core
wget -P /tmp https://download1.rstudio.org/electron/rhel9/x86_64/rstudio-2025.05.1-513-x86_64.rpm
rpm -ivh /tmp/rstudio-*-x86_64.rpm
echo "Pausing... If you see errors, press CTRL-C."
echo "Otherwise, press ENTER."
read ans
# Graphics support for other tools
dnf -y install glfw glfw-devel
dnf -y install libGLEW.x86_64 glew-devel
dnf -y install libpng12
#Menus
appmerge=/etc/xdg/menus/applications-merged
deskdirs=/usr/share/desktop-directories
deskapps=/usr/share/applications
appicons=/usr/share/icons
[ -d $appmerge ] || mkdir $appmerge
cp $BASE$appmerge/* $appmerge
cp $BASE$deskdirs/* $deskdirs
cp $BASE$deskapps/* $deskapps
cp $BASE$appicons/* $appicons
# Installed from package, add to Math
perl -i -p -e "s/Categories=/Categories=Mathematics;/;" /usr/share/applications/rstudio.desktop
#IDLE 3
wget -P /usr/local/bin http://hms.cs.skidmore.edu/code-for-images/src/idle3.sh
# user list
cat <<EOF >/etc/dconf/db/gdm.d/00-login-screen
# Do not show the user list
[org/gnome/login-screen]
disable-user-list=true
EOF
dconf update
# NX2 key.
#mkdir -p /root/.ssh
cat <<EOF >>/root/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKL6X6Ni5iDjwqvoGRaCvS16SQ1ZvSUPH1bv9HKsMD9Z root@nx2
EOF
chmod 600 /root/.ssh/authorized_keys
#Rsyslog
cat <<EOF >/etc/rsyslog.d/99-syslog.conf
*.* @141.222.36.199:514 # For UDP
*.* @@141.222.36.199:514 # For TCP
EOF
# NPRE
dnf install nrpe nagios-plugins-all -y
sed -i.bak 's/^allowed_hosts=.*$/allowed_hosts=nagios.cs.skidmore.edu/' /etc/nagios/nrpe.cfg
grep 'allowed_hosts=' /etc/nagios/nrpe.cfg
firewall-cmd --zone=public --add-port=5666/tcp --permanent
systemctl enable nrpe.service
for x in check_nfs_client check_sssd
do
wget -P /usr/lib64/nagios/plugins http://hms.cs.skidmore.edu/code-for-images/src/$x
chmod 755 /usr/lib64/nagios/plugins/$x
done
cat <<EOF >>/etc/nagios/nrpe.cfg
command[check_nfs_client]=/usr/lib64/nagios/plugins/check_nfs_client
command[check_sssd]=/usr/lib64/nagios/plugins/check_sssd
EOF
systemctl restart nrpe.service
# Mask power so it doesn't interfere with NVIDIA?
#systemctl mask power-profiles-daemon
#
# Setup dirs for remote NFS.
#
[ -d /students/home ] || mkdir -p /students/home
[ -d /students/shared ] || mkdir -p /students/shared
chmod -R 755 /students
[ -d /department/home ] || mkdir -p /department/home
[ -d /department/shared ] || mkdir -p /department/shared
chmod -R 755 /department
echo -e "\n\nUpdating /etc/fstab (copied to /etc/fstab.backup.$$)"
cp /etc/fstab /etc/fstab.backup.$$
grep "localhost:/home" /etc/fstab >/dev/null || cat <<EOF >> /etc/fstab
localhost:/home /department/home nfs tcp,vers=4.2,rsize=65536,wsize=65536,rw,bg,nosuid,nodev,port=2717,noauto,nolock 0 0
localhost:/home /students/home nfs tcp,vers=4.2,rsize=65536,wsize=65536,rw,bg,nosuid,nodev,port=2737,noauto,nolock 0 0
localhost:/shared /department/shared nfs tcp,vers=4.2,rsize=65536,wsize=65536,rw,bg,nosuid,nodev,port=4717,noauto,nolock 0 0
localhost:/shared /students/shared nfs tcp,vers=4.2,rsize=65536,wsize=65536,rw,bg,nosuid,nodev,port=3737,noauto,nolock 0 0
EOF
echo -e "\n\nAdding sleeper"
groupadd -g 251 sleeper
useradd -m -g 251 -u 251 -s /bin/bash sleeper
getent passwd sleeper && echo "sleeper has been added!"
mkdir /home/sleeper/.ssh
chmod 700 /home/sleeper/.ssh
cp $BASE/keys/id_*-rsa /home/sleeper/.ssh
cp $BASE/known_hosts /root/.ssh
chmod 600 /home/sleeper/.ssh/id_*-rsa
chmod 600 /root/.ssh/known_hosts
chown -R sleeper\: /home/sleeper/.ssh
echo -e "\n\nCopying NFS mount files."
for x in m8students-autossh.sh m9dept-autossh.sh mboth-autossh.sh uboth-autossh.sh udept-autossh.sh ustudents-autossh.sh
do
wget -P /usr/local/bin http://hms.cs.skidmore.edu/code-for-images/src/$x
chmod 700 /usr/local/bin/$x
done
wget -P /root http://hms.cs.skidmore.edu/code-for-images/src/set-host-info.sh
echo -e "\nEnabling and starting skidmore-nfs-mount.service"
wget -P /etc/systemd/system http://hms.cs.skidmore.edu/code-for-images/src/skidmore-nfs-mount.service
systemctl daemon-reload
systemctl enable skidmore-nfs-mount.service
systemctl start skidmore-nfs-mount.service
sleep 3
mount | grep nfs
echo -e "\n\nSetting snap homedirs"
snap set system homedirs=/students/home,/department/home
snap get system homedirs || echo -e "\n!!! Snap homedirs are NOT SET !!!"
#systemctl stop skidmore-nfs-mount.service
# Configure sysctl
wget -P /etc/sysctl.d http://hms.cs.skidmore.edu/code-for-images/src/99-ZZskidmore.conf
#ipa-client-install --user thejoiner@CS.SKIDMORE.EDU --password '' --hostname FQDN --domain cs.skidmore.edu --server idm1.cs.skidmore.edu --realm CS.SKIDMORE.EDU --unattended
NVIDIA & CUDA (ONLY IF THE HARDWARE SUPPORTS IT! OTHERWISE SKIP!)
#!/bin/bash
# Nvidia CUDA
dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo
dnf -y install kernel-devel-$(uname -r) kernel-headers-$(uname -r) # really?
#dnf module install -y nvidia-driver:open-dkms
dnf -y install nvidia-driver nvidia-settings
dnf -y install nvidia-driver-cuda
# somehow quiet creeps back in...
#grubby --update-kernel ALL --remove-args="quiet"
# Python CUDA
#!/bin/bash
nvidia-smi
echo "PRESS ENTER TO CONTINUE"
read CONT
# Do this as root!
# for Pillow fails to build (a dependency of vispy)
dnf install libjpeg-turbo-devel
dnf -y install python3-devel python3-numpy
dnf -y install hdf5 hdf5-devel
dnf -y install python3.11 python3.11-devel python3.11-idle
python3.11 -m venv /opt/venv_shared
chown -R odin\: /opt/venv_shared
# As odin!
source /opt/venv_shared/bin/activate
pip install scikit-build
pip install matplotlib jupyter
pip install opencv-python
pip install tensorflow mitdeeplearning pandas
pip install Keras
pip install tensorflow[and-cuda]
pip install tensorflow
deactivate
# And as root! (AGAIN, ONLY IF YOU HAVE NVIDIA SUPPORT! OTHERWISE SKIP!)
dnf install cuda-toolkit -y
dnf install nvidia-gds -y
# REBOOT NOW!
# Additional Python Packages.
#!/bin/bash
# as odin!
source /opt/venv_shared/bin/activate
pip install scikit-learn
pip install scipy
pip install tables mock
pip install Theano
pip install Keras
pip install torch torchvision ### This uninstalls some nvidia-cuda stuff??? NOPE! LIES!
pip install cython vispy p5
pip install six
#pip install bpy # blender lib ends up downgrading numpy from 2.2.6 to 1.26. Dumb...
#python3 -c "import six, blender" #### blender fails to import
#python3 -c "import matplotlib,jupyter,numpy,pandas,scipy,sklearn,cv2"
#python3 -c "import theano,torch"
#python3 -c "import sklearn,tensorflow,cv2,mitdeeplearning"
#python3 -c "import tensorflow"
#python3 -c "import blender"
Download B-PROLOG https://www.picat-lang.org/bprolog/download.html
(TBD)
Mathematica
MATLAB
ipa-client-install --user thejoiner@CS.SKIDMORE.EDU--password '' --hostname FQDN --domain cs.skidmore.edu --server idm1.cs.skidmore.edu --realm CS.SKIDMORE.EDU --unattended
/kickstart/Config/Software2024/rhel9/home/sleeper/.ssh <=== Keys!
mboth-autossh.sh
================
#!/bin/bash
/usr/local/bin/m8students-autossh.sh
/usr/local/bin/m9dept-autossh.sh
m8students-autossh.sh
=====================
#!/bin/bash
# Switched tunnelling from ssh to autossh - 20250604
#ssh -N -4 -f -i /home/sleeper/.ssh/id_santos-rsa -c aes256-ctr -L 2737:localhost:2049 -L 2045:localhost:24157 -l sleeper santos8 sleep 300d
autossh -M 5111 -nN4f -i /home/sleeper/.ssh/id_santos-rsa -c aes256-ctr -L 2737:localhost:2049 -L 2045:localhost:24157 -l sleeper santos8
#ssh -N -4 -f -i /home/sleeper/.ssh/id_santos-rsa -c aes256-ctr -L 3737:localhost:2049 -L 3045:localhost:24157 -l sleeper santos8 sleep 300d
autossh -M 5112 -nN4f -i /home/sleeper/.ssh/id_santos-rsa -c aes256-ctr -L 3737:localhost:2049 -L 3045:localhost:24157 -l sleeper santos8
mount /students/home
mount /students/shared
m9dept-autossh.sh
=================
#!/bin/bash
#ssh -N -4 -f -i /home/sleeper/.ssh/id_bailey-rsa -c aes256-ctr -L 2717:localhost:2049 -L 2025:localhost:24157 -l sleeper bailey9 sleep 300d
autossh -M 5113 -nN4f -i /home/sleeper/.ssh/id_bailey-rsa -c aes256-ctr -L 2717:localhost:2049 -L 2025:localhost:24157 -l sleeper bailey9
#ssh -N -4 -f -i /home/sleeper/.ssh/id_bailey-rsa -c aes256-ctr -L 4717:localhost:2049 -L 4025:localhost:24157 -l sleeper bailey9 sleep 300d
autossh -M 5114 -nN4f -i /home/sleeper/.ssh/id_bailey-rsa -c aes256-ctr -L 4717:localhost:2049 -L 4025:localhost:24157 -l sleeper bailey9
mount /department/home
mount /department/shared
uboth-autossh.sh
================
#!/bin/bash
# Updated to kill autossh and ssh processes - 20250604
umount -l /department/home
umount -l /department/shared
echo "kill ssh tunnel for /department/home"
KPID=`ps -ef | grep 2717 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
echo "kill ssh tunnel for /department/shared"
KPID=`ps -ef | grep 4717 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
umount -l /students/home
umount -l /students/shared
echo "kill ssh tunnel for /students/home"
KPID=`ps -ef | grep 2737 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
echo "kill ssh tunnel for /students/shared"
KPID=`ps -ef | grep 3737 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
udept-autossh.sh
================
#!/bin/bash
# Updated to kill autossh and ssh processes - 20250604
umount -l /department/home
umount -l /department/shared
echo "kill ssh tunnel for /department/home"
KPID=`ps -ef | grep 2717 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
echo "kill ssh tunnel for /department/shared"
KPID=`ps -ef | grep 4717 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
ustudents-autossh.sh
====================
#!/bin/bash
# Updated to kill autossh and ssh processes - 20250604
umount -l /students/home
umount -l /students/shared
echo "kill ssh tunnel for /students/home"
KPID=`ps -ef | grep 2737 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
echo "kill ssh tunnel for /students/shared"
KPID=`ps -ef | grep 3737 | grep aes256-ctr | awk '!/grep/{print$2}'`
while IFS= read -r PID; do
echo "kill ssh tunnel with pid = $PID"
kill -9 $PID
done <<< "$KPID"
What firewall rules are needed for the IdM client?
firewall-cmd --zone=public --add-port={80,443,389,636,88,464}/tcp --add-port={88,464,123}/udp --permanent firewall-cmd --zone=public --add-port={5666}/tcp --add-port={88,464,123}/udp --permanent #???? firewall-cmd --reload
ipa-client-install This program will set up IPA client. Version 4.12.2 Discovery was successful! Do you want to configure chrony with NTP server or pool address? [no]: Client hostname: cslabtest.cs.skidmore.edu Realm: CS.SKIDMORE.EDU DNS Domain: cs.skidmore.edu IPA Server: idm2.cs.skidmore.edu BaseDN: dc=cs,dc=skidmore,dc=edu Continue to configure the system with these values? [no]: yes Synchronizing time No SRV records of NTP servers found and no NTP server or pool address was provided. Using default chrony configuration. Attempting to sync time with chronyc. Time synchronization was successful. User authorized to enroll computers: admin Password for admin@CS.SKIDMORE.EDU: Successfully retrieved CA cert Subject: CN=Certificate Authority,O=CS.SKIDMORE.EDU Issuer: CN=Certificate Authority,O=CS.SKIDMORE.EDU Valid From: 2025-08-11 13:56:54+00:00 Valid Until: 2045-08-11 13:56:54+00:00 Enrolled in IPA realm CS.SKIDMORE.EDU Created /etc/ipa/default.conf Configured /etc/sssd/sssd.conf Systemwide CA database updated. Adding SSH public key from /etc/ssh/ssh_host_ecdsa_key.pub Adding SSH public key from /etc/ssh/ssh_host_rsa_key.pub Adding SSH public key from /etc/ssh/ssh_host_ed25519_key.pub Could not update DNS SSHFP records. SSSD enabled Configured /etc/openldap/ldap.conf Configured /etc/ssh/ssh_config Configured /etc/ssh/sshd_config.d/04-ipa.conf Configuring cs.skidmore.edu as NIS domain. Configured /etc/krb5.conf for IPA realm CS.SKIDMORE.EDU Client configuration complete. The ipa-client-install command was successful [root@cslabtest bin]# getent passwd wjojo wjojo:*:1034:1034:Jojo,William:/department/home/wjojo:/bin/bash[root@cslabtest ~]# cat /etc/systemd/system/skidmore-nfs-mount.service
[Unit] Description=Manage remote NFS mounts #After=network.target # These are ESSENTIAL to a smooth shutdown! Requires=sshd.service After=sshd.service [Service] Type=oneshot RemainAfterExit=yes #ExecStart=/usr/local/bin/m8students-autossh.sh #ExecStart=/usr/local/bin/m9dept-autossh.sh ExecStart=/usr/local/bin/mboth-autossh.sh ExecStop=/usr/local/bin/uboth-autossh.sh User=root Group=root Restart=no [Install] WantedBy=multi-user.target
Finishing
#!/bin/bash
eth=$(nmcli -t device | grep "ethernet:connected" | cut -f1 -d':')
mac=$(nmcli -t device show $eth | grep "GENERAL.HWADDR" | cut -f2- -d: | sed 's/://g')
res=$(curl http://hms.cs.skidmore.edu/code-for-images/get.php?mac=$mac)
if [ "$res" = "INVALID" ]; then
echo "BAD MAC ADDRESS '$mac'"
elif [ "$res" = "NOTFOUND" ]; then
echo "MAC NOT FOUND '$mac'"
else
host=$(echo $res | cut -f1 -d:)
ip=$(echo $res | cut -f2 -d:)
fi
echo -e "HOSTNAME = $host, IP = $ip"
nmcli connection modify "$eth" \
ipv4.method manual \
ipv4.addresses "$ip/22" \
ipv4.gateway "141.222.36.1" \
ipv4.dns "141.222.36.200,141.222.36.196"
MatLab.desktop
[Desktop Entry] Encoding=UTF-8 Name=MatLab Exec=/usr/bin/matlab -desktop Icon=/students/home/MCS-APPS/.icons/matlab.png Terminal=false Type=Application Categories=Mathematics; StartupNotify=true