<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.csclub.uwaterloo.ca/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=K95ma</id>
	<title>CSCWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.csclub.uwaterloo.ca/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=K95ma"/>
	<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/Special:Contributions/K95ma"/>
	<updated>2026-10-10T11:03:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.5</generator>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=New_CSC_Machine&amp;diff=5689</id>
		<title>New CSC Machine</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=New_CSC_Machine&amp;diff=5689"/>
		<updated>2026-09-04T22:18:25Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* General */ +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Firmware Updates =&lt;br /&gt;
&lt;br /&gt;
Vendors such as Dell provide firmware updates that should be applied before putting new machines into service. Even if the machine&#039;s warranty has expired, security updates are still made available.&lt;br /&gt;
&lt;br /&gt;
It is recommended to use the following sequence when updating firmware on the Dell PowerEdge servers ([https://downloads.dell.com/solutions/general-solution-resources/White%20Papers/Recommended%20Workflow%20for%20Performing%20Firmware%20Updates%20on%20PowerEdge%20Servers.pdf]):&lt;br /&gt;
&lt;br /&gt;
# iDRAC&lt;br /&gt;
# Lifecycle Controller&lt;br /&gt;
# BIOS&lt;br /&gt;
# Diagnostics&lt;br /&gt;
# OS Driver Pack&lt;br /&gt;
# RAID&lt;br /&gt;
# NIC&lt;br /&gt;
# PSU&lt;br /&gt;
# CPLD&lt;br /&gt;
# Other update&lt;br /&gt;
For consumer grade hardware, go to the motherboard vendor&#039;s website and find the way to upgrade the firmware.&lt;br /&gt;
&lt;br /&gt;
= Booting =&lt;br /&gt;
&lt;br /&gt;
* Put the TFTP image in place (if dist-arch pair installed before, you may skip this).&lt;br /&gt;
e.g. extract http://mirror.csclub.uwaterloo.ca/ubuntu/dists/oneiric/main/installer-amd64/current/images/netboot/netboot.tar.gz to caffeine:/srv/tftp/oneiric-amd64&lt;br /&gt;
&lt;br /&gt;
* Force network boot in the BIOS. This may be called &amp;quot;Legacy LAN&amp;quot; or other such cryptic things. If this doesn&#039;t work, boot from CD or USB instead.&lt;br /&gt;
&lt;br /&gt;
It is preferred to use the &amp;quot;alternate&amp;quot; Ubuntu installer image, based on debian-installer, instead of the Ubiquity installer. This installer supports software RAID and LVM out of the box, and will generally make your life easier. If installing Debian, this is the usual installer, so don&#039;t sweat it.&lt;br /&gt;
&lt;br /&gt;
* Most of our newer servers (e.g. PowerEdge R815) need non-free firmware in order to boot. This means that if you are using a new netboot image, it is highly recommended to include the entire non-free firmware bundle in the boot image. See [https://wiki.debian.org/DebianInstaller/NetbootFirmware] for more information.&lt;br /&gt;
* For office terminals, create a boot USB (via dd, for example) and boot from USB.&lt;br /&gt;
&lt;br /&gt;
= Installing =&lt;br /&gt;
&lt;br /&gt;
== debian-installer ==&lt;br /&gt;
&lt;br /&gt;
At least in expert mode, you can choose a custom mirror (top of the countries list) and give the path for mirror directly. This will make installation super-fast compared to installing from anywhere else.&lt;br /&gt;
&lt;br /&gt;
Please install to LVM volumes, as this is our standard configuration on all machines where possible. It allows more flexible partitioning across available volumes. Since GRUB 2, even /boot may be on LVM; this is the preferred configuration for simplicity, except when legacy partitioning setups make this inconvenient.&lt;br /&gt;
&lt;br /&gt;
You may enable unattended upgrades, but do not enable Canonical&#039;s remote management service or any such nonsense. This is mostly a straightforward Debian/Ubuntu install.&lt;br /&gt;
&lt;br /&gt;
= After Installing =&lt;br /&gt;
&lt;br /&gt;
Add the machine&#039;s name to ~git/public/hosts.git, and run the ansible playbook (https://git.uwaterloo.ca/csc/playbooks/blob/master/update-hosts.yml) to distribute the updated hosts file to all machines.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
Make sure to setup the IPMI on the mso-private VLAN (I think VLAN 520, check under networking page), and pleaseee set it up as a static IP.&lt;br /&gt;
&lt;br /&gt;
Then fetch the MAC address from the normal network interface, then on Caffine there&#039;s a dhcp server running. You&#039;ll need to add it there ({{code|/etc/dhcp/dhcpd.conf}}), just look for where all the servers are, and add it there. Make sure to assign it an IP there, otherwise it &#039;&#039;won&#039;t&#039;&#039; be assigned one. &lt;br /&gt;
&lt;br /&gt;
Then using IPAM give it a name and stuff, and a domain name.&lt;br /&gt;
&lt;br /&gt;
== apt ==&lt;br /&gt;
&lt;br /&gt;
Delete/clear the file &amp;lt;tt&amp;gt;/etc/apt/sources.list&amp;lt;/tt&amp;gt; and paste something like the following into &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/debian.sources&amp;lt;/tt&amp;gt; (replace &amp;quot;bookworm&amp;quot; by the the current Debian stable codename):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://mirror.csclub.uwaterloo.ca/debian&lt;br /&gt;
Suites: bookworm bookworm-updates bookworm-backports&lt;br /&gt;
Components: main contrib non-free non-free-firmware&lt;br /&gt;
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://mirror.csclub.uwaterloo.ca/debian-security&lt;br /&gt;
Suites: bookworm-security&lt;br /&gt;
Components: main contrib non-free non-free-firmware&lt;br /&gt;
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install the CSC archive signing key:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget -O /etc/apt/keyrings/csclub.gpg http://debian.csclub.uwaterloo.ca/csclub.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/csclub.sources&amp;lt;/tt&amp;gt; (or copy from another host):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://debian.csclub.uwaterloo.ca&lt;br /&gt;
Suites: bookworm&lt;br /&gt;
Components: main&lt;br /&gt;
Signed-By: /etc/apt/keyrings/csclub.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to make Debian use packages in our repository by default, set our repository to the highest priority. Create &amp;lt;code&amp;gt;/etc/apt/preferences.d/99-csclub&amp;lt;/code&amp;gt;: &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Package: *&lt;br /&gt;
Pin: origin debian.csclub.uwaterloo.ca&lt;br /&gt;
Pin-Priority: 1001&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now run &amp;lt;tt&amp;gt;apt-get update&amp;lt;/tt&amp;gt; to reflect these changes.&lt;br /&gt;
&lt;br /&gt;
For unattended upgrades in the future, install the &amp;lt;tt&amp;gt;unattended-upgrades&amp;lt;/tt&amp;gt; package and copy &amp;lt;tt&amp;gt;/etc/apt/apt.conf&amp;lt;/tt&amp;gt; from another host.&lt;br /&gt;
&lt;br /&gt;
== Network ==&lt;br /&gt;
&lt;br /&gt;
Note that debian 11 will use NetworkManager or &amp;lt;code&amp;gt;/etc/interfaces&amp;lt;/code&amp;gt; by default if you install a desktop environment, which doesn&#039;t seem to do DHCPv6 nicely. For simplicity and consistency across machines, we will use &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;. First stop and disable NetworkManager:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl disable --now NetworkManager.service networking.service&lt;br /&gt;
apt autoremove NetworkManager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then, create a network configuration file at &amp;lt;code&amp;gt;/etc/systemd/network/10-wired.network&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[Match]&lt;br /&gt;
# Check the interface name using `ip a`&lt;br /&gt;
Name=enp3s0&lt;br /&gt;
&lt;br /&gt;
[Network]&lt;br /&gt;
# DHCP for IPv4 should work just fine&lt;br /&gt;
DHCP=ipv4&lt;br /&gt;
# IPv6 doesn&#039;t seem to work properly. Manually set them here&lt;br /&gt;
Address=ALLOCATED_IPv6_ADDRESS&lt;br /&gt;
Gateway=IPv6_GATEWAY&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then start and enable &amp;lt;code&amp;gt;systemd-networkd.service&amp;lt;/code&amp;gt;. Also remember to specify the campus DNS at &amp;lt;code&amp;gt;/etc/resolve.conf&amp;lt;/code&amp;gt;. You can copy it from another CSC machine.&lt;br /&gt;
&lt;br /&gt;
== Kerberos keys ==&lt;br /&gt;
&lt;br /&gt;
If this is a reinstall of an existing host, copy back the SSH host keys and &amp;lt;tt&amp;gt;/etc/krb5.keytab&amp;lt;/tt&amp;gt; from its former incarnation. Otherwise, create a new Kerberos principal and copy the keytab over, as follows (run from the host in question):&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
kadmin -p sysadmin/admin   # or any other admin principal; the password for this one is the usual root password&lt;br /&gt;
addprinc -randkey host/[hostname].csclub.uwaterloo.ca&lt;br /&gt;
ktadd host/[hostname].csclub.uwaterloo.ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;This will generate a new principal (you can skip this step if one already exists) and add it to the local Kerberos keytab.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
Install packages that we will need:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install krb5-user nfs-common nslcd sudo-ldap&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Installing nsclcd will pop a dialog for configuring LDAP servers. Enter the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ldaps://ldap1.csclub.uwaterloo.ca ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following config files are needed to work in the CSC environment (examples given below for an office terminal; perhaps refer to another host if preferred).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/etc/nsswitch.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# /etc/nsswitch.conf&lt;br /&gt;
#&lt;br /&gt;
# Example configuration of GNU Name Service Switch functionality.&lt;br /&gt;
# If you have the `glibc-doc-reference&#039; and `info&#039; packages installed, try:&lt;br /&gt;
# `info libc &amp;quot;Name Service Switch&amp;quot;&#039; for information about this file.&lt;br /&gt;
&lt;br /&gt;
passwd:         files systemd ldap&lt;br /&gt;
group:          files systemd ldap&lt;br /&gt;
shadow:         files ldap&lt;br /&gt;
gshadow:        files ldap&lt;br /&gt;
sudoers:        files ldap&lt;br /&gt;
&lt;br /&gt;
hosts:          files dns&lt;br /&gt;
networks:       files&lt;br /&gt;
&lt;br /&gt;
protocols:      db files&lt;br /&gt;
services:       db files&lt;br /&gt;
ethers:         db files&lt;br /&gt;
rpc:            db files&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;tt&amp;gt;/etc/ldap/ldap.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# LDAP Defaults&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# See ldap.conf(5) for details&lt;br /&gt;
# This file should be world readable but not world writable.&lt;br /&gt;
&lt;br /&gt;
BASE    dc=csclub, dc=uwaterloo, dc=ca&lt;br /&gt;
URI     ldaps://ldap1.csclub.uwaterloo.ca ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&lt;br /&gt;
SIZELIMIT       0&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
TLS_CACERTFILE  /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
SUDOERS_BASE ou=SUDOers,dc=csclub,dc=uwaterloo,dc=ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Also make &amp;lt;tt&amp;gt;/etc/sudo-ldap.conf&amp;lt;/tt&amp;gt; a symlink to the above. On debian, install &amp;lt;tt&amp;gt;sudo-ldap&amp;lt;/tt&amp;gt; package too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/etc/nslcd.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# /etc/nslcd.conf&lt;br /&gt;
# nslcd configuration file. See nslcd.conf(5)&lt;br /&gt;
# for details.&lt;br /&gt;
&lt;br /&gt;
# The user and group nslcd should run as.&lt;br /&gt;
uid nslcd&lt;br /&gt;
gid nslcd&lt;br /&gt;
&lt;br /&gt;
# The location at which the LDAP server(s) should be reachable.&lt;br /&gt;
uri ldaps://ldap1.csclub.uwaterloo.ca&lt;br /&gt;
uri ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&lt;br /&gt;
# The search base that will be used for all queries.&lt;br /&gt;
base dc=csclub, dc=uwaterloo, dc=ca&lt;br /&gt;
&lt;br /&gt;
# The LDAP protocol version to use.&lt;br /&gt;
#ldap_version 3&lt;br /&gt;
&lt;br /&gt;
# The DN to bind with for normal lookups.&lt;br /&gt;
#binddn cn=annonymous,dc=example,dc=net&lt;br /&gt;
#bindpw secret&lt;br /&gt;
&lt;br /&gt;
# The DN used for password modifications by root.&lt;br /&gt;
#rootpwmoddn cn=admin,dc=example,dc=com&lt;br /&gt;
&lt;br /&gt;
# SSL options&lt;br /&gt;
#ssl off&lt;br /&gt;
tls_reqcert demand&lt;br /&gt;
tls_cacertfile /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
# The search scope.&lt;br /&gt;
#scope sub&lt;br /&gt;
&lt;br /&gt;
map group member uniqueMember&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;tt&amp;gt;/etc/krb5.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[libdefaults]&lt;br /&gt;
  default_realm = CSCLUB.UWATERLOO.CA&lt;br /&gt;
  forwardable = true&lt;br /&gt;
  proxiable = true&lt;br /&gt;
  dns_lookup_kdc = false&lt;br /&gt;
  dns_lookup_realm = false&lt;br /&gt;
  allow_weak_crypto = true&lt;br /&gt;
&lt;br /&gt;
[realms]&lt;br /&gt;
  CSCLUB.UWATERLOO.CA = {&lt;br /&gt;
    kdc = kdc1.csclub.uwaterloo.ca&lt;br /&gt;
    kdc = kdc2.csclub.uwaterloo.ca&lt;br /&gt;
    admin_server = kadmin.csclub.uwaterloo.ca&lt;br /&gt;
  }&lt;br /&gt;
(rest omitted for brevity, see any CSC machine)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Notably, &amp;lt;tt&amp;gt;allow_weak_crypto&amp;lt;/tt&amp;gt; is currently needed to mount &amp;lt;tt&amp;gt;/users&amp;lt;/tt&amp;gt; (/music and &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; is sec=sys and thus will always mount, even when krb5 is down and/or broken). Otherwise, you will get a mysterious &amp;quot;permission denied&amp;quot; error (even though the server claims to have authenticated the mount successfully).&lt;br /&gt;
&lt;br /&gt;
Furthermore, the lines &amp;lt;tt&amp;gt;dns_lookup_kdc&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;dns_lookup_realm&amp;lt;/tt&amp;gt; have been added - they are needed to stop the KDC from throwing its arms in the air and giving up if IST&#039;s DNS servers ever explode - an event that has happened in the recent past far more often than I&#039;d like it to.&lt;br /&gt;
&lt;br /&gt;
Change all lines in &amp;lt;tt&amp;gt;/etc/pam.d/common-*&amp;lt;/tt&amp;gt; to have &amp;lt;tt&amp;gt;minimum_uid=10000&amp;lt;/tt&amp;gt; so that Kerberos won&#039;t interfere with local users. Note that pam configs are notably different on syscom-only hosts. Look at an existing syscom-only host to see the difference.&lt;br /&gt;
&lt;br /&gt;
Alter &amp;lt;tt&amp;gt;/etc/default/nfs-common&amp;lt;/tt&amp;gt; &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# Alter these lines:&lt;br /&gt;
NEED_STATD=1&lt;br /&gt;
NEED_GSSD=1&lt;br /&gt;
# -l for gssd is to allow legacy crypto suites&lt;br /&gt;
RPCGSSDOPTS=&amp;quot;-v -l&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;to enable &amp;lt;tt&amp;gt;statd&amp;lt;/tt&amp;gt;, and more importantly &amp;lt;tt&amp;gt;gssd&amp;lt;/tt&amp;gt; (needed for Kerberos NFS mounts). Start &amp;lt;code&amp;gt;rpc-statd.service&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rpc-gssd.service&amp;lt;/code&amp;gt; manually for now.&lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;/users&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;/music&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;/etc/fstab&amp;lt;/tt&amp;gt; (as appropriate for the machine&#039;s role), make their mount points and mount them. Note that &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; are sec=sys whereas &amp;lt;tt&amp;gt;/music&amp;lt;/tt&amp;gt; and /users is sec=krb5p (with exceptions granted on a case-by-case basis for servers only, office terminals are always sec=krb5p for security reasons).&lt;br /&gt;
&lt;br /&gt;
To allow single sign-on as &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (primarily useful for pushing files to all machines simultaneously), put the following in &amp;lt;tt&amp;gt;/root/.k5login&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 sysadmin/admin@CSCLUB.UWATERLOO.CA&lt;br /&gt;
&lt;br /&gt;
Also copy the following files from another CSC host:&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/ssh/ssh_config&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/etc/ssh/sshd_config&amp;lt;/tt&amp;gt; (for single sign-on)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/ssh/ssh_known_hosts&amp;lt;/tt&amp;gt; (to remove hostkey warnings within our network)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/hosts&amp;lt;/tt&amp;gt; (for host tab completion and emergency name resolution)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/resolv.conf&amp;lt;/tt&amp;gt; (to use IST&#039;s nameservers and search csclub/uwaterloo domains. Only required if you are not using &amp;lt;tt&amp;gt;/etc/network/interfaces&amp;lt;/tt&amp;gt; to configure DNS)&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
On an office terminal, copy &amp;lt;tt&amp;gt;/etc/pulse/default.pa&amp;lt;/tt&amp;gt; from another office terminal.&lt;br /&gt;
&lt;br /&gt;
If this is to be the machine that actually plays audio (currently &amp;lt;tt&amp;gt;nullsleep&amp;lt;/tt&amp;gt;), the setup is slightly more complicated. You&#039;ll need to set up MPD and PipeWire to receive connections, and store the PulseAudio cookie in &amp;lt;tt&amp;gt;~audio&amp;lt;/tt&amp;gt;, with appropriate permissions so that only the &amp;lt;tt&amp;gt;audio&amp;lt;/tt&amp;gt; group can access it. If this is a new audio machine, you&#039;ll also need to change &amp;lt;tt&amp;gt;default.pa&amp;lt;/tt&amp;gt; on all office terminals to point to it.&lt;br /&gt;
&lt;br /&gt;
=== Password ===&lt;br /&gt;
Change the root password to the specified password in the usual place under the termcom user. If it&#039;s an office terminal, change the local user&#039;s password to the one specified in the usual place.&lt;br /&gt;
&lt;br /&gt;
=== Prevent suspend and hibernation (Office Terminal) ===&lt;br /&gt;
Set &amp;lt;code&amp;gt;AllowSuspend&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;AllowHibernation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;AllowSuspendThenHibernate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;AllowHybridSleep&amp;lt;/code&amp;gt; all to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/systemd/sleep.conf&amp;lt;/code&amp;gt;, and reboot.&lt;br /&gt;
&lt;br /&gt;
== Records ==&lt;br /&gt;
&lt;br /&gt;
You probably already created the host in the University IPAM system beforehand. If not, please do so.&lt;br /&gt;
&lt;br /&gt;
Please also add the host to the [[Machine List]] here on the Wiki.&lt;br /&gt;
&lt;br /&gt;
== Munin (System Monitoring) ==&lt;br /&gt;
&lt;br /&gt;
If the new machine is not a container, you probably want to have it participate in the Munin cluster. Run &amp;lt;tt&amp;gt;apt-get install munin-node&amp;lt;/tt&amp;gt; to install the monitoring client, then&lt;br /&gt;
edit the file /etc/munin/munin-node.conf. Look for a line that says &amp;lt;tt&amp;gt;allow ^127\.0\.0\.1$&amp;lt;/tt&amp;gt; and add the following on a new line immediately below it:&lt;br /&gt;
&amp;lt;tt&amp;gt;allow ^129\.97\.134\.51$&amp;lt;/tt&amp;gt; (this is the IP address for munin.csclub). Save the file, then &amp;lt;tt&amp;gt;/etc/init.d/munin-node restart&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;update-rc.d munin-node defaults&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Then, ssh into munin.csclub and edit the file /etc/munin/munin.conf and add the following lines to the end:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[NEW-MACHINE-NAME.csclub] &amp;lt;br/&amp;gt;&lt;br /&gt;
addr 129.97.134.### &amp;lt;br /&amp;gt;&lt;br /&gt;
use_node_name yes&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prometheus (System Monitoring) ==&lt;br /&gt;
&lt;br /&gt;
We are currently using Prometheus to monitor our systems. On the new machine, install &amp;lt;tt&amp;gt;prometheus-node-exporter&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;stunnel&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change &amp;lt;tt&amp;gt;/etc/default/prometheus-node-exporter&amp;lt;/tt&amp;gt; to this: &lt;br /&gt;
&lt;br /&gt;
 ARGS=&amp;quot;--web.listen-address=localhost:9101&amp;quot;&lt;br /&gt;
&lt;br /&gt;
and start &amp;lt;tt&amp;gt;prometheus-node-exporter.service&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Then set up stunnel. Create &amp;lt;tt&amp;gt;/etc/stunnel/prometheus-node-exporter.conf&amp;lt;/tt&amp;gt; with this content:&lt;br /&gt;
&lt;br /&gt;
 setuid = stunnel4&lt;br /&gt;
 setgid = stunnel4&lt;br /&gt;
 pid = /var/run/stunnel4/exporter.pid&lt;br /&gt;
 &lt;br /&gt;
 debug = 7&lt;br /&gt;
 &lt;br /&gt;
 [prometheus-node-exporter]&lt;br /&gt;
 accept = 0.0.0.0:9100&lt;br /&gt;
 connect = 127.0.0.1:9101&lt;br /&gt;
 CAfile = /etc/stunnel/tls/server.crt&lt;br /&gt;
 cert = /etc/stunnel/tls/node.crt&lt;br /&gt;
 key = /etc/stunnel/tls/node.key&lt;br /&gt;
 verifyPeer = yes&lt;br /&gt;
&lt;br /&gt;
Copy &amp;lt;tt&amp;gt;/etc/stunnel/{node.crt, node.key, server.crt}&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;prometheus:/opt/prometheus/tls&amp;lt;/tt&amp;gt; or the same location on other machines.&lt;br /&gt;
&lt;br /&gt;
Finally, start &amp;lt;tt&amp;gt;stunnel4.service&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If it&#039;s a new machine, you&#039;ll also need to add it to the list of monitoring at &amp;lt;tt&amp;gt;prometheus:/opt/prometheus/prometheus.yml&amp;lt;/tt&amp;gt;. Add it under a suitable label (or create a new label) in &#039;node_exporter&#039; job.&lt;br /&gt;
&lt;br /&gt;
= New Distribution =&lt;br /&gt;
&lt;br /&gt;
If you&#039;re adding a new distribution, there a couple of steps you&#039;ll need to take in updating the CSClub Debian repository on [[Machine_List#sodium_benzoate|sodium-benzoate/mirror]]. &lt;br /&gt;
&lt;br /&gt;
The steps to add a new Debian release (in the examples, jessie) is as follows, modify as necessary:&lt;br /&gt;
&lt;br /&gt;
=== Step 0: Create a GPG key ===&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;gpg --gen-key&amp;quot; or something like that. Skip this if you already have one.&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Add to Uploaders ===&lt;br /&gt;
&lt;br /&gt;
The /srv/debian/conf/uploaders file on mirror contains the list of people who can upload. Add your GPG key id to this file.  Use &amp;quot;gpg --list-secret-keys&amp;quot; to find out the key ID. You also need to import your key into the mirror&#039;s gpg homedir as follows:&lt;br /&gt;
&lt;br /&gt;
 gpg --export $KEYID | sudo env GNUPGHOME=/srv/debian/gpg gpg --import&lt;br /&gt;
&lt;br /&gt;
You only need to do this step once.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Add Distro ===&lt;br /&gt;
&lt;br /&gt;
Add a new section to /srv/debian/conf/distributions:&lt;br /&gt;
&lt;br /&gt;
 Origin: CSC&lt;br /&gt;
 Label: Debian&lt;br /&gt;
 Codename: &#039;&#039;&#039;jessie&#039;&#039;&#039;&lt;br /&gt;
 Architectures: alpha amd64 i386 mips mipsel sparc powerpc armel source&lt;br /&gt;
 Components: main contrib non-free&lt;br /&gt;
 Uploaders: uploaders&lt;br /&gt;
 Update: dell chrome&lt;br /&gt;
 SignWith: yes&lt;br /&gt;
 Log: &#039;&#039;&#039;jessie&#039;&#039;&#039;.log&lt;br /&gt;
  --changes notifier&lt;br /&gt;
&lt;br /&gt;
And update the &#039;&#039;&#039;Allow&#039;&#039;&#039; line in /srv/debian/conf/incoming:&lt;br /&gt;
&lt;br /&gt;
 Allow: &#039;&#039;&#039;jessie&amp;gt;jessie&#039;&#039;&#039; oldstable&amp;gt;squeeze stable&amp;gt;wheezy lucid&amp;gt;lucid maverick&amp;gt;maverick oneiric&amp;gt;oneiric precise&amp;gt;precise quantal&amp;gt;quantal&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Update from Sources ===&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
 sudo env GNUPGHOME=/srv/debian/gpg /srv/debian/bin/rrr-update&lt;br /&gt;
&lt;br /&gt;
If all went well you should see the new distribution listed at http://debian.csclub.uwaterloo.ca/dists/&lt;br /&gt;
&lt;br /&gt;
=== Step 4: CSC Packages ===&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our new distribution set up we need to generate our packages and have them uploaded. Namely, ceo and libpam-csc. For libpam-csc:&lt;br /&gt;
&lt;br /&gt;
Get the package:&lt;br /&gt;
&lt;br /&gt;
 git clone https://git.csclub.uwaterloo.ca/public/libpam-csc.git&lt;br /&gt;
 cd libpam-csc&lt;br /&gt;
&lt;br /&gt;
Update change log:&lt;br /&gt;
&lt;br /&gt;
 EMAIL=[you]@csclub.uwaterloo.ca NAME=&amp;quot;Your Name&amp;quot; dch -i&lt;br /&gt;
&lt;br /&gt;
Update as necessary, i.e:&lt;br /&gt;
&lt;br /&gt;
 libpam-csc (1.10&#039;&#039;&#039;jessie0&#039;&#039;&#039;) &#039;&#039;&#039;jessie&#039;&#039;&#039;; urgency=low&lt;br /&gt;
 &lt;br /&gt;
   * Packaging for jessie.&lt;br /&gt;
 &lt;br /&gt;
  -- Your Name &amp;lt;[you]@csclub.uwaterloo.ca&amp;gt;  Thu, 10 Oct 2013 22:08:48 -0400&lt;br /&gt;
&lt;br /&gt;
Build! (You may need to install various dependencies, which it will yell at you if you don&#039;t have.)&lt;br /&gt;
&lt;br /&gt;
 debuild -k&#039;&#039;&#039;YOURKEYID&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yay, it built now let&#039;s upload it to the repo. The build process which create a PACKAGE.changes file in the parent directory (replace PACKAGE with the actual package name).&lt;br /&gt;
&lt;br /&gt;
Copy the dupload file from corn-syrup and dupload:&lt;br /&gt;
&lt;br /&gt;
 mv /etc/dupload /etc/dupload.bak&lt;br /&gt;
 scp corn-syrup:/etc/dupload /etc/dupload&lt;br /&gt;
 dupload libpam-csc_1.10jessie0_amd64.changes&lt;br /&gt;
&lt;br /&gt;
Finally, log into mirror and type &amp;quot;sudo /srv/debian/bin/rrr-incoming&amp;quot;. This is supposed to happen once every few minutes however it is always faster to run it manually.&lt;br /&gt;
&lt;br /&gt;
And you&#039;re done. For CEO, see https://git.csclub.uwaterloo.ca/public/pyceo/src/branch/master/PACKAGING.md&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=New_CSC_Machine&amp;diff=5688</id>
		<title>New CSC Machine</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=New_CSC_Machine&amp;diff=5688"/>
		<updated>2026-09-04T22:16:39Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* General */ de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Firmware Updates =&lt;br /&gt;
&lt;br /&gt;
Vendors such as Dell provide firmware updates that should be applied before putting new machines into service. Even if the machine&#039;s warranty has expired, security updates are still made available.&lt;br /&gt;
&lt;br /&gt;
It is recommended to use the following sequence when updating firmware on the Dell PowerEdge servers ([https://downloads.dell.com/solutions/general-solution-resources/White%20Papers/Recommended%20Workflow%20for%20Performing%20Firmware%20Updates%20on%20PowerEdge%20Servers.pdf]):&lt;br /&gt;
&lt;br /&gt;
# iDRAC&lt;br /&gt;
# Lifecycle Controller&lt;br /&gt;
# BIOS&lt;br /&gt;
# Diagnostics&lt;br /&gt;
# OS Driver Pack&lt;br /&gt;
# RAID&lt;br /&gt;
# NIC&lt;br /&gt;
# PSU&lt;br /&gt;
# CPLD&lt;br /&gt;
# Other update&lt;br /&gt;
For consumer grade hardware, go to the motherboard vendor&#039;s website and find the way to upgrade the firmware.&lt;br /&gt;
&lt;br /&gt;
= Booting =&lt;br /&gt;
&lt;br /&gt;
* Put the TFTP image in place (if dist-arch pair installed before, you may skip this).&lt;br /&gt;
e.g. extract http://mirror.csclub.uwaterloo.ca/ubuntu/dists/oneiric/main/installer-amd64/current/images/netboot/netboot.tar.gz to caffeine:/srv/tftp/oneiric-amd64&lt;br /&gt;
&lt;br /&gt;
* Force network boot in the BIOS. This may be called &amp;quot;Legacy LAN&amp;quot; or other such cryptic things. If this doesn&#039;t work, boot from CD or USB instead.&lt;br /&gt;
&lt;br /&gt;
It is preferred to use the &amp;quot;alternate&amp;quot; Ubuntu installer image, based on debian-installer, instead of the Ubiquity installer. This installer supports software RAID and LVM out of the box, and will generally make your life easier. If installing Debian, this is the usual installer, so don&#039;t sweat it.&lt;br /&gt;
&lt;br /&gt;
* Most of our newer servers (e.g. PowerEdge R815) need non-free firmware in order to boot. This means that if you are using a new netboot image, it is highly recommended to include the entire non-free firmware bundle in the boot image. See [https://wiki.debian.org/DebianInstaller/NetbootFirmware] for more information.&lt;br /&gt;
* For office terminals, create a boot USB (via dd, for example) and boot from USB.&lt;br /&gt;
&lt;br /&gt;
= Installing =&lt;br /&gt;
&lt;br /&gt;
== debian-installer ==&lt;br /&gt;
&lt;br /&gt;
At least in expert mode, you can choose a custom mirror (top of the countries list) and give the path for mirror directly. This will make installation super-fast compared to installing from anywhere else.&lt;br /&gt;
&lt;br /&gt;
Please install to LVM volumes, as this is our standard configuration on all machines where possible. It allows more flexible partitioning across available volumes. Since GRUB 2, even /boot may be on LVM; this is the preferred configuration for simplicity, except when legacy partitioning setups make this inconvenient.&lt;br /&gt;
&lt;br /&gt;
You may enable unattended upgrades, but do not enable Canonical&#039;s remote management service or any such nonsense. This is mostly a straightforward Debian/Ubuntu install.&lt;br /&gt;
&lt;br /&gt;
= After Installing =&lt;br /&gt;
&lt;br /&gt;
Add the machine&#039;s name to ~git/public/hosts.git, and run the ansible playbook (https://git.uwaterloo.ca/csc/playbooks/blob/master/update-hosts.yml) to distribute the updated hosts file to all machines.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
Make sure to setup the IPMI on the mso-private VLAN (I think VLAN 520, check under networking page), and pleaseee set it up as a static IP.&lt;br /&gt;
&lt;br /&gt;
Then fetch the MAC address from the normal network interface, then on Caffine there&#039;s a dhcp server running. You&#039;ll need to add it there ({{code|/etc/dhcp/dhcpd.conf}}), just look for where all the servers are, and add it there. Make sure to assign it an IP there, otherwise it &#039;&#039;won&#039;t&#039;&#039; be assigned one. &lt;br /&gt;
&lt;br /&gt;
Then using IPAM give it a name and stuff, and a domain name.&lt;br /&gt;
&lt;br /&gt;
== apt ==&lt;br /&gt;
&lt;br /&gt;
Delete/clear the file &amp;lt;tt&amp;gt;/etc/apt/sources.list&amp;lt;/tt&amp;gt; and paste something like the following into &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/debian.sources&amp;lt;/tt&amp;gt; (replace &amp;quot;bookworm&amp;quot; by the the current Debian stable codename):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://mirror.csclub.uwaterloo.ca/debian&lt;br /&gt;
Suites: bookworm bookworm-updates bookworm-backports&lt;br /&gt;
Components: main contrib non-free non-free-firmware&lt;br /&gt;
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://mirror.csclub.uwaterloo.ca/debian-security&lt;br /&gt;
Suites: bookworm-security&lt;br /&gt;
Components: main contrib non-free non-free-firmware&lt;br /&gt;
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install the CSC archive signing key:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget -O /etc/apt/keyrings/csclub.gpg http://debian.csclub.uwaterloo.ca/csclub.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/csclub.sources&amp;lt;/tt&amp;gt; (or copy from another host):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://debian.csclub.uwaterloo.ca&lt;br /&gt;
Suites: bookworm&lt;br /&gt;
Components: main&lt;br /&gt;
Signed-By: /etc/apt/keyrings/csclub.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to make Debian use packages in our repository by default, set our repository to the highest priority. Create &amp;lt;code&amp;gt;/etc/apt/preferences.d/99-csclub&amp;lt;/code&amp;gt;: &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Package: *&lt;br /&gt;
Pin: origin debian.csclub.uwaterloo.ca&lt;br /&gt;
Pin-Priority: 1001&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now run &amp;lt;tt&amp;gt;apt-get update&amp;lt;/tt&amp;gt; to reflect these changes.&lt;br /&gt;
&lt;br /&gt;
For unattended upgrades in the future, install the &amp;lt;tt&amp;gt;unattended-upgrades&amp;lt;/tt&amp;gt; package and copy &amp;lt;tt&amp;gt;/etc/apt/apt.conf&amp;lt;/tt&amp;gt; from another host.&lt;br /&gt;
&lt;br /&gt;
== Network ==&lt;br /&gt;
&lt;br /&gt;
Note that debian 11 will use NetworkManager or &amp;lt;code&amp;gt;/etc/interfaces&amp;lt;/code&amp;gt; by default if you install a desktop environment, which doesn&#039;t seem to do DHCPv6 nicely. For simplicity and consistency across machines, we will use &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;. First stop and disable NetworkManager:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl disable --now NetworkManager.service networking.service&lt;br /&gt;
apt autoremove NetworkManager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then, create a network configuration file at &amp;lt;code&amp;gt;/etc/systemd/network/10-wired.network&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[Match]&lt;br /&gt;
# Check the interface name using `ip a`&lt;br /&gt;
Name=enp3s0&lt;br /&gt;
&lt;br /&gt;
[Network]&lt;br /&gt;
# DHCP for IPv4 should work just fine&lt;br /&gt;
DHCP=ipv4&lt;br /&gt;
# IPv6 doesn&#039;t seem to work properly. Manually set them here&lt;br /&gt;
Address=ALLOCATED_IPv6_ADDRESS&lt;br /&gt;
Gateway=IPv6_GATEWAY&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then start and enable &amp;lt;code&amp;gt;systemd-networkd.service&amp;lt;/code&amp;gt;. Also remember to specify the campus DNS at &amp;lt;code&amp;gt;/etc/resolve.conf&amp;lt;/code&amp;gt;. You can copy it from another CSC machine.&lt;br /&gt;
&lt;br /&gt;
== Kerberos keys ==&lt;br /&gt;
&lt;br /&gt;
If this is a reinstall of an existing host, copy back the SSH host keys and &amp;lt;tt&amp;gt;/etc/krb5.keytab&amp;lt;/tt&amp;gt; from its former incarnation. Otherwise, create a new Kerberos principal and copy the keytab over, as follows (run from the host in question):&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
kadmin -p sysadmin/admin   # or any other admin principal; the password for this one is the usual root password&lt;br /&gt;
addprinc -randkey host/[hostname].csclub.uwaterloo.ca&lt;br /&gt;
ktadd host/[hostname].csclub.uwaterloo.ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;This will generate a new principal (you can skip this step if one already exists) and add it to the local Kerberos keytab.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
Install packages that we will need:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install krb5-user nfs-common nslcd sudo-ldap&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The following config files are needed to work in the CSC environment (examples given below for an office terminal; perhaps refer to another host if preferred).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/etc/nsswitch.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# /etc/nsswitch.conf&lt;br /&gt;
#&lt;br /&gt;
# Example configuration of GNU Name Service Switch functionality.&lt;br /&gt;
# If you have the `glibc-doc-reference&#039; and `info&#039; packages installed, try:&lt;br /&gt;
# `info libc &amp;quot;Name Service Switch&amp;quot;&#039; for information about this file.&lt;br /&gt;
&lt;br /&gt;
passwd:         files systemd ldap&lt;br /&gt;
group:          files systemd ldap&lt;br /&gt;
shadow:         files ldap&lt;br /&gt;
gshadow:        files ldap&lt;br /&gt;
sudoers:        files ldap&lt;br /&gt;
&lt;br /&gt;
hosts:          files dns&lt;br /&gt;
networks:       files&lt;br /&gt;
&lt;br /&gt;
protocols:      db files&lt;br /&gt;
services:       db files&lt;br /&gt;
ethers:         db files&lt;br /&gt;
rpc:            db files&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;tt&amp;gt;/etc/ldap/ldap.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# LDAP Defaults&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# See ldap.conf(5) for details&lt;br /&gt;
# This file should be world readable but not world writable.&lt;br /&gt;
&lt;br /&gt;
BASE    dc=csclub, dc=uwaterloo, dc=ca&lt;br /&gt;
URI     ldaps://ldap1.csclub.uwaterloo.ca ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&lt;br /&gt;
SIZELIMIT       0&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
TLS_CACERTFILE  /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
SUDOERS_BASE ou=SUDOers,dc=csclub,dc=uwaterloo,dc=ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Also make &amp;lt;tt&amp;gt;/etc/sudo-ldap.conf&amp;lt;/tt&amp;gt; a symlink to the above. On debian, install &amp;lt;tt&amp;gt;sudo-ldap&amp;lt;/tt&amp;gt; package too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/etc/nslcd.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# /etc/nslcd.conf&lt;br /&gt;
# nslcd configuration file. See nslcd.conf(5)&lt;br /&gt;
# for details.&lt;br /&gt;
&lt;br /&gt;
# The user and group nslcd should run as.&lt;br /&gt;
uid nslcd&lt;br /&gt;
gid nslcd&lt;br /&gt;
&lt;br /&gt;
# The location at which the LDAP server(s) should be reachable.&lt;br /&gt;
uri ldaps://ldap1.csclub.uwaterloo.ca&lt;br /&gt;
uri ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&lt;br /&gt;
# The search base that will be used for all queries.&lt;br /&gt;
base dc=csclub, dc=uwaterloo, dc=ca&lt;br /&gt;
&lt;br /&gt;
# The LDAP protocol version to use.&lt;br /&gt;
#ldap_version 3&lt;br /&gt;
&lt;br /&gt;
# The DN to bind with for normal lookups.&lt;br /&gt;
#binddn cn=annonymous,dc=example,dc=net&lt;br /&gt;
#bindpw secret&lt;br /&gt;
&lt;br /&gt;
# The DN used for password modifications by root.&lt;br /&gt;
#rootpwmoddn cn=admin,dc=example,dc=com&lt;br /&gt;
&lt;br /&gt;
# SSL options&lt;br /&gt;
#ssl off&lt;br /&gt;
tls_reqcert demand&lt;br /&gt;
tls_cacertfile /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
# The search scope.&lt;br /&gt;
#scope sub&lt;br /&gt;
&lt;br /&gt;
map group member uniqueMember&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;tt&amp;gt;/etc/krb5.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[libdefaults]&lt;br /&gt;
  default_realm = CSCLUB.UWATERLOO.CA&lt;br /&gt;
  forwardable = true&lt;br /&gt;
  proxiable = true&lt;br /&gt;
  dns_lookup_kdc = false&lt;br /&gt;
  dns_lookup_realm = false&lt;br /&gt;
  allow_weak_crypto = true&lt;br /&gt;
&lt;br /&gt;
[realms]&lt;br /&gt;
  CSCLUB.UWATERLOO.CA = {&lt;br /&gt;
    kdc = kdc1.csclub.uwaterloo.ca&lt;br /&gt;
    kdc = kdc2.csclub.uwaterloo.ca&lt;br /&gt;
    admin_server = kadmin.csclub.uwaterloo.ca&lt;br /&gt;
  }&lt;br /&gt;
(rest omitted for brevity, see any CSC machine)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Notably, &amp;lt;tt&amp;gt;allow_weak_crypto&amp;lt;/tt&amp;gt; is currently needed to mount &amp;lt;tt&amp;gt;/users&amp;lt;/tt&amp;gt; (/music and &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; is sec=sys and thus will always mount, even when krb5 is down and/or broken). Otherwise, you will get a mysterious &amp;quot;permission denied&amp;quot; error (even though the server claims to have authenticated the mount successfully).&lt;br /&gt;
&lt;br /&gt;
Furthermore, the lines &amp;lt;tt&amp;gt;dns_lookup_kdc&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;dns_lookup_realm&amp;lt;/tt&amp;gt; have been added - they are needed to stop the KDC from throwing its arms in the air and giving up if IST&#039;s DNS servers ever explode - an event that has happened in the recent past far more often than I&#039;d like it to.&lt;br /&gt;
&lt;br /&gt;
Change all lines in &amp;lt;tt&amp;gt;/etc/pam.d/common-*&amp;lt;/tt&amp;gt; to have &amp;lt;tt&amp;gt;minimum_uid=10000&amp;lt;/tt&amp;gt; so that Kerberos won&#039;t interfere with local users. Note that pam configs are notably different on syscom-only hosts. Look at an existing syscom-only host to see the difference.&lt;br /&gt;
&lt;br /&gt;
Alter &amp;lt;tt&amp;gt;/etc/default/nfs-common&amp;lt;/tt&amp;gt; &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# Alter these lines:&lt;br /&gt;
NEED_STATD=1&lt;br /&gt;
NEED_GSSD=1&lt;br /&gt;
# -l for gssd is to allow legacy crypto suites&lt;br /&gt;
RPCGSSDOPTS=&amp;quot;-v -l&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;to enable &amp;lt;tt&amp;gt;statd&amp;lt;/tt&amp;gt;, and more importantly &amp;lt;tt&amp;gt;gssd&amp;lt;/tt&amp;gt; (needed for Kerberos NFS mounts). Start &amp;lt;code&amp;gt;rpc-statd.service&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rpc-gssd.service&amp;lt;/code&amp;gt; manually for now.&lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;/users&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;/music&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;/etc/fstab&amp;lt;/tt&amp;gt; (as appropriate for the machine&#039;s role), make their mount points and mount them. Note that &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; are sec=sys whereas &amp;lt;tt&amp;gt;/music&amp;lt;/tt&amp;gt; and /users is sec=krb5p (with exceptions granted on a case-by-case basis for servers only, office terminals are always sec=krb5p for security reasons).&lt;br /&gt;
&lt;br /&gt;
To allow single sign-on as &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (primarily useful for pushing files to all machines simultaneously), put the following in &amp;lt;tt&amp;gt;/root/.k5login&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 sysadmin/admin@CSCLUB.UWATERLOO.CA&lt;br /&gt;
&lt;br /&gt;
Also copy the following files from another CSC host:&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/ssh/ssh_config&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/etc/ssh/sshd_config&amp;lt;/tt&amp;gt; (for single sign-on)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/ssh/ssh_known_hosts&amp;lt;/tt&amp;gt; (to remove hostkey warnings within our network)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/hosts&amp;lt;/tt&amp;gt; (for host tab completion and emergency name resolution)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/resolv.conf&amp;lt;/tt&amp;gt; (to use IST&#039;s nameservers and search csclub/uwaterloo domains. Only required if you are not using &amp;lt;tt&amp;gt;/etc/network/interfaces&amp;lt;/tt&amp;gt; to configure DNS)&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
On an office terminal, copy &amp;lt;tt&amp;gt;/etc/pulse/default.pa&amp;lt;/tt&amp;gt; from another office terminal.&lt;br /&gt;
&lt;br /&gt;
If this is to be the machine that actually plays audio (currently &amp;lt;tt&amp;gt;nullsleep&amp;lt;/tt&amp;gt;), the setup is slightly more complicated. You&#039;ll need to set up MPD and PipeWire to receive connections, and store the PulseAudio cookie in &amp;lt;tt&amp;gt;~audio&amp;lt;/tt&amp;gt;, with appropriate permissions so that only the &amp;lt;tt&amp;gt;audio&amp;lt;/tt&amp;gt; group can access it. If this is a new audio machine, you&#039;ll also need to change &amp;lt;tt&amp;gt;default.pa&amp;lt;/tt&amp;gt; on all office terminals to point to it.&lt;br /&gt;
&lt;br /&gt;
=== Password ===&lt;br /&gt;
Change the root password to the specified password in the usual place under the termcom user. If it&#039;s an office terminal, change the local user&#039;s password to the one specified in the usual place.&lt;br /&gt;
&lt;br /&gt;
=== Prevent suspend and hibernation (Office Terminal) ===&lt;br /&gt;
Set &amp;lt;code&amp;gt;AllowSuspend&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;AllowHibernation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;AllowSuspendThenHibernate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;AllowHybridSleep&amp;lt;/code&amp;gt; all to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/systemd/sleep.conf&amp;lt;/code&amp;gt;, and reboot.&lt;br /&gt;
&lt;br /&gt;
== Records ==&lt;br /&gt;
&lt;br /&gt;
You probably already created the host in the University IPAM system beforehand. If not, please do so.&lt;br /&gt;
&lt;br /&gt;
Please also add the host to the [[Machine List]] here on the Wiki.&lt;br /&gt;
&lt;br /&gt;
== Munin (System Monitoring) ==&lt;br /&gt;
&lt;br /&gt;
If the new machine is not a container, you probably want to have it participate in the Munin cluster. Run &amp;lt;tt&amp;gt;apt-get install munin-node&amp;lt;/tt&amp;gt; to install the monitoring client, then&lt;br /&gt;
edit the file /etc/munin/munin-node.conf. Look for a line that says &amp;lt;tt&amp;gt;allow ^127\.0\.0\.1$&amp;lt;/tt&amp;gt; and add the following on a new line immediately below it:&lt;br /&gt;
&amp;lt;tt&amp;gt;allow ^129\.97\.134\.51$&amp;lt;/tt&amp;gt; (this is the IP address for munin.csclub). Save the file, then &amp;lt;tt&amp;gt;/etc/init.d/munin-node restart&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;update-rc.d munin-node defaults&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Then, ssh into munin.csclub and edit the file /etc/munin/munin.conf and add the following lines to the end:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[NEW-MACHINE-NAME.csclub] &amp;lt;br/&amp;gt;&lt;br /&gt;
addr 129.97.134.### &amp;lt;br /&amp;gt;&lt;br /&gt;
use_node_name yes&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prometheus (System Monitoring) ==&lt;br /&gt;
&lt;br /&gt;
We are currently using Prometheus to monitor our systems. On the new machine, install &amp;lt;tt&amp;gt;prometheus-node-exporter&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;stunnel&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change &amp;lt;tt&amp;gt;/etc/default/prometheus-node-exporter&amp;lt;/tt&amp;gt; to this: &lt;br /&gt;
&lt;br /&gt;
 ARGS=&amp;quot;--web.listen-address=localhost:9101&amp;quot;&lt;br /&gt;
&lt;br /&gt;
and start &amp;lt;tt&amp;gt;prometheus-node-exporter.service&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Then set up stunnel. Create &amp;lt;tt&amp;gt;/etc/stunnel/prometheus-node-exporter.conf&amp;lt;/tt&amp;gt; with this content:&lt;br /&gt;
&lt;br /&gt;
 setuid = stunnel4&lt;br /&gt;
 setgid = stunnel4&lt;br /&gt;
 pid = /var/run/stunnel4/exporter.pid&lt;br /&gt;
 &lt;br /&gt;
 debug = 7&lt;br /&gt;
 &lt;br /&gt;
 [prometheus-node-exporter]&lt;br /&gt;
 accept = 0.0.0.0:9100&lt;br /&gt;
 connect = 127.0.0.1:9101&lt;br /&gt;
 CAfile = /etc/stunnel/tls/server.crt&lt;br /&gt;
 cert = /etc/stunnel/tls/node.crt&lt;br /&gt;
 key = /etc/stunnel/tls/node.key&lt;br /&gt;
 verifyPeer = yes&lt;br /&gt;
&lt;br /&gt;
Copy &amp;lt;tt&amp;gt;/etc/stunnel/{node.crt, node.key, server.crt}&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;prometheus:/opt/prometheus/tls&amp;lt;/tt&amp;gt; or the same location on other machines.&lt;br /&gt;
&lt;br /&gt;
Finally, start &amp;lt;tt&amp;gt;stunnel4.service&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If it&#039;s a new machine, you&#039;ll also need to add it to the list of monitoring at &amp;lt;tt&amp;gt;prometheus:/opt/prometheus/prometheus.yml&amp;lt;/tt&amp;gt;. Add it under a suitable label (or create a new label) in &#039;node_exporter&#039; job.&lt;br /&gt;
&lt;br /&gt;
= New Distribution =&lt;br /&gt;
&lt;br /&gt;
If you&#039;re adding a new distribution, there a couple of steps you&#039;ll need to take in updating the CSClub Debian repository on [[Machine_List#sodium_benzoate|sodium-benzoate/mirror]]. &lt;br /&gt;
&lt;br /&gt;
The steps to add a new Debian release (in the examples, jessie) is as follows, modify as necessary:&lt;br /&gt;
&lt;br /&gt;
=== Step 0: Create a GPG key ===&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;gpg --gen-key&amp;quot; or something like that. Skip this if you already have one.&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Add to Uploaders ===&lt;br /&gt;
&lt;br /&gt;
The /srv/debian/conf/uploaders file on mirror contains the list of people who can upload. Add your GPG key id to this file.  Use &amp;quot;gpg --list-secret-keys&amp;quot; to find out the key ID. You also need to import your key into the mirror&#039;s gpg homedir as follows:&lt;br /&gt;
&lt;br /&gt;
 gpg --export $KEYID | sudo env GNUPGHOME=/srv/debian/gpg gpg --import&lt;br /&gt;
&lt;br /&gt;
You only need to do this step once.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Add Distro ===&lt;br /&gt;
&lt;br /&gt;
Add a new section to /srv/debian/conf/distributions:&lt;br /&gt;
&lt;br /&gt;
 Origin: CSC&lt;br /&gt;
 Label: Debian&lt;br /&gt;
 Codename: &#039;&#039;&#039;jessie&#039;&#039;&#039;&lt;br /&gt;
 Architectures: alpha amd64 i386 mips mipsel sparc powerpc armel source&lt;br /&gt;
 Components: main contrib non-free&lt;br /&gt;
 Uploaders: uploaders&lt;br /&gt;
 Update: dell chrome&lt;br /&gt;
 SignWith: yes&lt;br /&gt;
 Log: &#039;&#039;&#039;jessie&#039;&#039;&#039;.log&lt;br /&gt;
  --changes notifier&lt;br /&gt;
&lt;br /&gt;
And update the &#039;&#039;&#039;Allow&#039;&#039;&#039; line in /srv/debian/conf/incoming:&lt;br /&gt;
&lt;br /&gt;
 Allow: &#039;&#039;&#039;jessie&amp;gt;jessie&#039;&#039;&#039; oldstable&amp;gt;squeeze stable&amp;gt;wheezy lucid&amp;gt;lucid maverick&amp;gt;maverick oneiric&amp;gt;oneiric precise&amp;gt;precise quantal&amp;gt;quantal&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Update from Sources ===&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
 sudo env GNUPGHOME=/srv/debian/gpg /srv/debian/bin/rrr-update&lt;br /&gt;
&lt;br /&gt;
If all went well you should see the new distribution listed at http://debian.csclub.uwaterloo.ca/dists/&lt;br /&gt;
&lt;br /&gt;
=== Step 4: CSC Packages ===&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our new distribution set up we need to generate our packages and have them uploaded. Namely, ceo and libpam-csc. For libpam-csc:&lt;br /&gt;
&lt;br /&gt;
Get the package:&lt;br /&gt;
&lt;br /&gt;
 git clone https://git.csclub.uwaterloo.ca/public/libpam-csc.git&lt;br /&gt;
 cd libpam-csc&lt;br /&gt;
&lt;br /&gt;
Update change log:&lt;br /&gt;
&lt;br /&gt;
 EMAIL=[you]@csclub.uwaterloo.ca NAME=&amp;quot;Your Name&amp;quot; dch -i&lt;br /&gt;
&lt;br /&gt;
Update as necessary, i.e:&lt;br /&gt;
&lt;br /&gt;
 libpam-csc (1.10&#039;&#039;&#039;jessie0&#039;&#039;&#039;) &#039;&#039;&#039;jessie&#039;&#039;&#039;; urgency=low&lt;br /&gt;
 &lt;br /&gt;
   * Packaging for jessie.&lt;br /&gt;
 &lt;br /&gt;
  -- Your Name &amp;lt;[you]@csclub.uwaterloo.ca&amp;gt;  Thu, 10 Oct 2013 22:08:48 -0400&lt;br /&gt;
&lt;br /&gt;
Build! (You may need to install various dependencies, which it will yell at you if you don&#039;t have.)&lt;br /&gt;
&lt;br /&gt;
 debuild -k&#039;&#039;&#039;YOURKEYID&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yay, it built now let&#039;s upload it to the repo. The build process which create a PACKAGE.changes file in the parent directory (replace PACKAGE with the actual package name).&lt;br /&gt;
&lt;br /&gt;
Copy the dupload file from corn-syrup and dupload:&lt;br /&gt;
&lt;br /&gt;
 mv /etc/dupload /etc/dupload.bak&lt;br /&gt;
 scp corn-syrup:/etc/dupload /etc/dupload&lt;br /&gt;
 dupload libpam-csc_1.10jessie0_amd64.changes&lt;br /&gt;
&lt;br /&gt;
Finally, log into mirror and type &amp;quot;sudo /srv/debian/bin/rrr-incoming&amp;quot;. This is supposed to happen once every few minutes however it is always faster to run it manually.&lt;br /&gt;
&lt;br /&gt;
And you&#039;re done. For CEO, see https://git.csclub.uwaterloo.ca/public/pyceo/src/branch/master/PACKAGING.md&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=New_CSC_Machine&amp;diff=5687</id>
		<title>New CSC Machine</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=New_CSC_Machine&amp;diff=5687"/>
		<updated>2026-09-04T22:12:06Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Networking */ +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Firmware Updates =&lt;br /&gt;
&lt;br /&gt;
Vendors such as Dell provide firmware updates that should be applied before putting new machines into service. Even if the machine&#039;s warranty has expired, security updates are still made available.&lt;br /&gt;
&lt;br /&gt;
It is recommended to use the following sequence when updating firmware on the Dell PowerEdge servers ([https://downloads.dell.com/solutions/general-solution-resources/White%20Papers/Recommended%20Workflow%20for%20Performing%20Firmware%20Updates%20on%20PowerEdge%20Servers.pdf]):&lt;br /&gt;
&lt;br /&gt;
# iDRAC&lt;br /&gt;
# Lifecycle Controller&lt;br /&gt;
# BIOS&lt;br /&gt;
# Diagnostics&lt;br /&gt;
# OS Driver Pack&lt;br /&gt;
# RAID&lt;br /&gt;
# NIC&lt;br /&gt;
# PSU&lt;br /&gt;
# CPLD&lt;br /&gt;
# Other update&lt;br /&gt;
For consumer grade hardware, go to the motherboard vendor&#039;s website and find the way to upgrade the firmware.&lt;br /&gt;
&lt;br /&gt;
= Booting =&lt;br /&gt;
&lt;br /&gt;
* Put the TFTP image in place (if dist-arch pair installed before, you may skip this).&lt;br /&gt;
e.g. extract http://mirror.csclub.uwaterloo.ca/ubuntu/dists/oneiric/main/installer-amd64/current/images/netboot/netboot.tar.gz to caffeine:/srv/tftp/oneiric-amd64&lt;br /&gt;
&lt;br /&gt;
* Force network boot in the BIOS. This may be called &amp;quot;Legacy LAN&amp;quot; or other such cryptic things. If this doesn&#039;t work, boot from CD or USB instead.&lt;br /&gt;
&lt;br /&gt;
It is preferred to use the &amp;quot;alternate&amp;quot; Ubuntu installer image, based on debian-installer, instead of the Ubiquity installer. This installer supports software RAID and LVM out of the box, and will generally make your life easier. If installing Debian, this is the usual installer, so don&#039;t sweat it.&lt;br /&gt;
&lt;br /&gt;
* Most of our newer servers (e.g. PowerEdge R815) need non-free firmware in order to boot. This means that if you are using a new netboot image, it is highly recommended to include the entire non-free firmware bundle in the boot image. See [https://wiki.debian.org/DebianInstaller/NetbootFirmware] for more information.&lt;br /&gt;
* For office terminals, create a boot USB (via dd, for example) and boot from USB.&lt;br /&gt;
&lt;br /&gt;
= Installing =&lt;br /&gt;
&lt;br /&gt;
== debian-installer ==&lt;br /&gt;
&lt;br /&gt;
At least in expert mode, you can choose a custom mirror (top of the countries list) and give the path for mirror directly. This will make installation super-fast compared to installing from anywhere else.&lt;br /&gt;
&lt;br /&gt;
Please install to LVM volumes, as this is our standard configuration on all machines where possible. It allows more flexible partitioning across available volumes. Since GRUB 2, even /boot may be on LVM; this is the preferred configuration for simplicity, except when legacy partitioning setups make this inconvenient.&lt;br /&gt;
&lt;br /&gt;
You may enable unattended upgrades, but do not enable Canonical&#039;s remote management service or any such nonsense. This is mostly a straightforward Debian/Ubuntu install.&lt;br /&gt;
&lt;br /&gt;
= After Installing =&lt;br /&gt;
&lt;br /&gt;
Add the machine&#039;s name to ~git/public/hosts.git, and run the ansible playbook (https://git.uwaterloo.ca/csc/playbooks/blob/master/update-hosts.yml) to distribute the updated hosts file to all machines.&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
Make sure to setup the IPMI on the mso-private VLAN (I think VLAN 520, check under networking page), and pleaseee set it up as a static IP.&lt;br /&gt;
&lt;br /&gt;
Then fetch the MAC address from the normal network interface, then on Caffine there&#039;s a dhcp server running. You&#039;ll need to add it there ({{code|/etc/dhcp/dhcpd.conf}}), just look for where all the servers are, and add it there. Make sure to assign it an IP there, otherwise it &#039;&#039;won&#039;t&#039;&#039; be assigned one. &lt;br /&gt;
&lt;br /&gt;
Then using IPAM give it a name and stuff, and a domain name.&lt;br /&gt;
&lt;br /&gt;
== apt ==&lt;br /&gt;
&lt;br /&gt;
Delete/clear the file &amp;lt;tt&amp;gt;/etc/apt/sources.list&amp;lt;/tt&amp;gt; and paste something like the following into &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/debian.sources&amp;lt;/tt&amp;gt; (replace &amp;quot;bookworm&amp;quot; by the the current Debian stable codename):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://mirror.csclub.uwaterloo.ca/debian&lt;br /&gt;
Suites: bookworm bookworm-updates bookworm-backports&lt;br /&gt;
Components: main contrib non-free non-free-firmware&lt;br /&gt;
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://mirror.csclub.uwaterloo.ca/debian-security&lt;br /&gt;
Suites: bookworm-security&lt;br /&gt;
Components: main contrib non-free non-free-firmware&lt;br /&gt;
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install the CSC archive signing key:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget -O /etc/apt/keyrings/csclub.gpg http://debian.csclub.uwaterloo.ca/csclub.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into &amp;lt;tt&amp;gt;/etc/apt/sources.list.d/csclub.sources&amp;lt;/tt&amp;gt; (or copy from another host):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: http://debian.csclub.uwaterloo.ca&lt;br /&gt;
Suites: bookworm&lt;br /&gt;
Components: main&lt;br /&gt;
Signed-By: /etc/apt/keyrings/csclub.gpg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to make Debian use packages in our repository by default, set our repository to the highest priority. Create &amp;lt;code&amp;gt;/etc/apt/preferences.d/99-csclub&amp;lt;/code&amp;gt;: &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Package: *&lt;br /&gt;
Pin: origin debian.csclub.uwaterloo.ca&lt;br /&gt;
Pin-Priority: 1001&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;You should now run &amp;lt;tt&amp;gt;apt-get update&amp;lt;/tt&amp;gt; to reflect these changes.&lt;br /&gt;
&lt;br /&gt;
For unattended upgrades in the future, install the &amp;lt;tt&amp;gt;unattended-upgrades&amp;lt;/tt&amp;gt; package and copy &amp;lt;tt&amp;gt;/etc/apt/apt.conf&amp;lt;/tt&amp;gt; from another host.&lt;br /&gt;
&lt;br /&gt;
== Network ==&lt;br /&gt;
&lt;br /&gt;
Note that debian 11 will use NetworkManager or &amp;lt;code&amp;gt;/etc/interfaces&amp;lt;/code&amp;gt; by default if you install a desktop environment, which doesn&#039;t seem to do DHCPv6 nicely. For simplicity and consistency across machines, we will use &amp;lt;code&amp;gt;systemd-networkd&amp;lt;/code&amp;gt;. First stop and disable NetworkManager:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
systemctl disable --now NetworkManager.service networking.service&lt;br /&gt;
apt autoremove NetworkManager&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then, create a network configuration file at &amp;lt;code&amp;gt;/etc/systemd/network/10-wired.network&amp;lt;/code&amp;gt;:&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[Match]&lt;br /&gt;
# Check the interface name using `ip a`&lt;br /&gt;
Name=enp3s0&lt;br /&gt;
&lt;br /&gt;
[Network]&lt;br /&gt;
# DHCP for IPv4 should work just fine&lt;br /&gt;
DHCP=ipv4&lt;br /&gt;
# IPv6 doesn&#039;t seem to work properly. Manually set them here&lt;br /&gt;
Address=ALLOCATED_IPv6_ADDRESS&lt;br /&gt;
Gateway=IPv6_GATEWAY&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then start and enable &amp;lt;code&amp;gt;systemd-networkd.service&amp;lt;/code&amp;gt;. Also remember to specify the campus DNS at &amp;lt;code&amp;gt;/etc/resolve.conf&amp;lt;/code&amp;gt;. You can copy it from another CSC machine.&lt;br /&gt;
&lt;br /&gt;
== Kerberos keys ==&lt;br /&gt;
&lt;br /&gt;
If this is a reinstall of an existing host, copy back the SSH host keys and &amp;lt;tt&amp;gt;/etc/krb5.keytab&amp;lt;/tt&amp;gt; from its former incarnation. Otherwise, create a new Kerberos principal and copy the keytab over, as follows (run from the host in question):&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
kadmin -p sysadmin/admin   # or any other admin principal; the password for this one is the usual root password&lt;br /&gt;
addprinc -randkey host/[hostname].csclub.uwaterloo.ca&lt;br /&gt;
ktadd host/[hostname].csclub.uwaterloo.ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;This will generate a new principal (you can skip this step if one already exists) and add it to the local Kerberos keytab.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
Install packages that we will need:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install krb5-user nfs-common nslcd sudo-ldap&lt;br /&gt;
# This package are automatically installed already, but we need to install our version so that NFS can connect to our crappy NetApp server&lt;br /&gt;
apt install --reinstall libk5crypto3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;The following config files are needed to work in the CSC environment (examples given below for an office terminal; perhaps refer to another host if preferred).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/etc/nsswitch.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# /etc/nsswitch.conf&lt;br /&gt;
#&lt;br /&gt;
# Example configuration of GNU Name Service Switch functionality.&lt;br /&gt;
# If you have the `glibc-doc-reference&#039; and `info&#039; packages installed, try:&lt;br /&gt;
# `info libc &amp;quot;Name Service Switch&amp;quot;&#039; for information about this file.&lt;br /&gt;
&lt;br /&gt;
passwd:         files systemd ldap&lt;br /&gt;
group:          files systemd ldap&lt;br /&gt;
shadow:         files ldap&lt;br /&gt;
gshadow:        files ldap&lt;br /&gt;
sudoers:        files ldap&lt;br /&gt;
&lt;br /&gt;
hosts:          files dns&lt;br /&gt;
networks:       files&lt;br /&gt;
&lt;br /&gt;
protocols:      db files&lt;br /&gt;
services:       db files&lt;br /&gt;
ethers:         db files&lt;br /&gt;
rpc:            db files&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;tt&amp;gt;/etc/ldap/ldap.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# LDAP Defaults&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# See ldap.conf(5) for details&lt;br /&gt;
# This file should be world readable but not world writable.&lt;br /&gt;
&lt;br /&gt;
BASE    dc=csclub, dc=uwaterloo, dc=ca&lt;br /&gt;
URI     ldaps://ldap1.csclub.uwaterloo.ca ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&lt;br /&gt;
SIZELIMIT       0&lt;br /&gt;
&lt;br /&gt;
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
TLS_CACERTFILE  /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
SUDOERS_BASE ou=SUDOers,dc=csclub,dc=uwaterloo,dc=ca&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Also make &amp;lt;tt&amp;gt;/etc/sudo-ldap.conf&amp;lt;/tt&amp;gt; a symlink to the above. On debian, install &amp;lt;tt&amp;gt;sudo-ldap&amp;lt;/tt&amp;gt; package too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;/etc/nslcd.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# /etc/nslcd.conf&lt;br /&gt;
# nslcd configuration file. See nslcd.conf(5)&lt;br /&gt;
# for details.&lt;br /&gt;
&lt;br /&gt;
# The user and group nslcd should run as.&lt;br /&gt;
uid nslcd&lt;br /&gt;
gid nslcd&lt;br /&gt;
&lt;br /&gt;
# The location at which the LDAP server(s) should be reachable.&lt;br /&gt;
uri ldaps://ldap1.csclub.uwaterloo.ca&lt;br /&gt;
uri ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
&lt;br /&gt;
# The search base that will be used for all queries.&lt;br /&gt;
base dc=csclub, dc=uwaterloo, dc=ca&lt;br /&gt;
&lt;br /&gt;
# The LDAP protocol version to use.&lt;br /&gt;
#ldap_version 3&lt;br /&gt;
&lt;br /&gt;
# The DN to bind with for normal lookups.&lt;br /&gt;
#binddn cn=annonymous,dc=example,dc=net&lt;br /&gt;
#bindpw secret&lt;br /&gt;
&lt;br /&gt;
# The DN used for password modifications by root.&lt;br /&gt;
#rootpwmoddn cn=admin,dc=example,dc=com&lt;br /&gt;
&lt;br /&gt;
# SSL options&lt;br /&gt;
#ssl off&lt;br /&gt;
tls_reqcert demand&lt;br /&gt;
tls_cacertfile /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;
&lt;br /&gt;
# The search scope.&lt;br /&gt;
#scope sub&lt;br /&gt;
&lt;br /&gt;
map group member uniqueMember&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;tt&amp;gt;/etc/krb5.conf&amp;lt;/tt&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[libdefaults]&lt;br /&gt;
  default_realm = CSCLUB.UWATERLOO.CA&lt;br /&gt;
  forwardable = true&lt;br /&gt;
  proxiable = true&lt;br /&gt;
  dns_lookup_kdc = false&lt;br /&gt;
  dns_lookup_realm = false&lt;br /&gt;
  allow_weak_crypto = true&lt;br /&gt;
&lt;br /&gt;
[realms]&lt;br /&gt;
  CSCLUB.UWATERLOO.CA = {&lt;br /&gt;
    kdc = kdc1.csclub.uwaterloo.ca&lt;br /&gt;
    kdc = kdc2.csclub.uwaterloo.ca&lt;br /&gt;
    admin_server = kadmin.csclub.uwaterloo.ca&lt;br /&gt;
  }&lt;br /&gt;
(rest omitted for brevity, see any CSC machine)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Notably, &amp;lt;tt&amp;gt;allow_weak_crypto&amp;lt;/tt&amp;gt; is currently needed to mount &amp;lt;tt&amp;gt;/users&amp;lt;/tt&amp;gt; (/music and &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; is sec=sys and thus will always mount, even when krb5 is down and/or broken). Otherwise, you will get a mysterious &amp;quot;permission denied&amp;quot; error (even though the server claims to have authenticated the mount successfully).&lt;br /&gt;
&lt;br /&gt;
Furthermore, the lines &amp;lt;tt&amp;gt;dns_lookup_kdc&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;dns_lookup_realm&amp;lt;/tt&amp;gt; have been added - they are needed to stop the KDC from throwing its arms in the air and giving up if IST&#039;s DNS servers ever explode - an event that has happened in the recent past far more often than I&#039;d like it to.&lt;br /&gt;
&lt;br /&gt;
Change all lines in &amp;lt;tt&amp;gt;/etc/pam.d/common-*&amp;lt;/tt&amp;gt; to have &amp;lt;tt&amp;gt;minimum_uid=10000&amp;lt;/tt&amp;gt; so that Kerberos won&#039;t interfere with local users. Note that pam configs are notably different on syscom-only hosts. Look at an existing syscom-only host to see the difference.&lt;br /&gt;
&lt;br /&gt;
Alter &amp;lt;tt&amp;gt;/etc/default/nfs-common&amp;lt;/tt&amp;gt; &amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# Alter these lines:&lt;br /&gt;
NEED_STATD=1&lt;br /&gt;
NEED_GSSD=1&lt;br /&gt;
# -l for gssd is to allow legacy crypto suites&lt;br /&gt;
RPCGSSDOPTS=&amp;quot;-v -l&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;to enable &amp;lt;tt&amp;gt;statd&amp;lt;/tt&amp;gt;, and more importantly &amp;lt;tt&amp;gt;gssd&amp;lt;/tt&amp;gt; (needed for Kerberos NFS mounts). Start &amp;lt;code&amp;gt;rpc-statd.service&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;rpc-gssd.service&amp;lt;/code&amp;gt; manually for now.&lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;tt&amp;gt;/users&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;/music&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;/etc/fstab&amp;lt;/tt&amp;gt; (as appropriate for the machine&#039;s role), make their mount points and mount them. Note that &amp;lt;tt&amp;gt;/scratch&amp;lt;/tt&amp;gt; are sec=sys whereas &amp;lt;tt&amp;gt;/music&amp;lt;/tt&amp;gt; and /users is sec=krb5p (with exceptions granted on a case-by-case basis for servers only, office terminals are always sec=krb5p for security reasons).&lt;br /&gt;
&lt;br /&gt;
To allow single sign-on as &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (primarily useful for pushing files to all machines simultaneously), put the following in &amp;lt;tt&amp;gt;/root/.k5login&amp;lt;/tt&amp;gt;:&lt;br /&gt;
 sysadmin/admin@CSCLUB.UWATERLOO.CA&lt;br /&gt;
&lt;br /&gt;
Also copy the following files from another CSC host:&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/ssh/ssh_config&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/etc/ssh/sshd_config&amp;lt;/tt&amp;gt; (for single sign-on)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/ssh/ssh_known_hosts&amp;lt;/tt&amp;gt; (to remove hostkey warnings within our network)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/hosts&amp;lt;/tt&amp;gt; (for host tab completion and emergency name resolution)&lt;br /&gt;
* &amp;lt;tt&amp;gt;/etc/resolv.conf&amp;lt;/tt&amp;gt; (to use IST&#039;s nameservers and search csclub/uwaterloo domains. Only required if you are not using &amp;lt;tt&amp;gt;/etc/network/interfaces&amp;lt;/tt&amp;gt; to configure DNS)&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
On an office terminal, copy &amp;lt;tt&amp;gt;/etc/pulse/default.pa&amp;lt;/tt&amp;gt; from another office terminal.&lt;br /&gt;
&lt;br /&gt;
If this is to be the machine that actually plays audio (currently &amp;lt;tt&amp;gt;nullsleep&amp;lt;/tt&amp;gt;), the setup is slightly more complicated. You&#039;ll need to set up MPD and PipeWire to receive connections, and store the PulseAudio cookie in &amp;lt;tt&amp;gt;~audio&amp;lt;/tt&amp;gt;, with appropriate permissions so that only the &amp;lt;tt&amp;gt;audio&amp;lt;/tt&amp;gt; group can access it. If this is a new audio machine, you&#039;ll also need to change &amp;lt;tt&amp;gt;default.pa&amp;lt;/tt&amp;gt; on all office terminals to point to it.&lt;br /&gt;
&lt;br /&gt;
=== Password ===&lt;br /&gt;
Change the root password to the specified password in the usual place under the termcom user. If it&#039;s an office terminal, change the local user&#039;s password to the one specified in the usual place.&lt;br /&gt;
&lt;br /&gt;
=== Prevent suspend and hibernation (Office Terminal) ===&lt;br /&gt;
Set &amp;lt;code&amp;gt;AllowSuspend&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;AllowHibernation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;AllowSuspendThenHibernate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;AllowHybridSleep&amp;lt;/code&amp;gt; all to &amp;lt;code&amp;gt;no&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/systemd/sleep.conf&amp;lt;/code&amp;gt;, and reboot.&lt;br /&gt;
&lt;br /&gt;
== Records ==&lt;br /&gt;
&lt;br /&gt;
You probably already created the host in the University IPAM system beforehand. If not, please do so.&lt;br /&gt;
&lt;br /&gt;
Please also add the host to the [[Machine List]] here on the Wiki.&lt;br /&gt;
&lt;br /&gt;
== Munin (System Monitoring) ==&lt;br /&gt;
&lt;br /&gt;
If the new machine is not a container, you probably want to have it participate in the Munin cluster. Run &amp;lt;tt&amp;gt;apt-get install munin-node&amp;lt;/tt&amp;gt; to install the monitoring client, then&lt;br /&gt;
edit the file /etc/munin/munin-node.conf. Look for a line that says &amp;lt;tt&amp;gt;allow ^127\.0\.0\.1$&amp;lt;/tt&amp;gt; and add the following on a new line immediately below it:&lt;br /&gt;
&amp;lt;tt&amp;gt;allow ^129\.97\.134\.51$&amp;lt;/tt&amp;gt; (this is the IP address for munin.csclub). Save the file, then &amp;lt;tt&amp;gt;/etc/init.d/munin-node restart&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;update-rc.d munin-node defaults&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Then, ssh into munin.csclub and edit the file /etc/munin/munin.conf and add the following lines to the end:&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[NEW-MACHINE-NAME.csclub] &amp;lt;br/&amp;gt;&lt;br /&gt;
addr 129.97.134.### &amp;lt;br /&amp;gt;&lt;br /&gt;
use_node_name yes&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prometheus (System Monitoring) ==&lt;br /&gt;
&lt;br /&gt;
We are currently using Prometheus to monitor our systems. On the new machine, install &amp;lt;tt&amp;gt;prometheus-node-exporter&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;stunnel&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Change &amp;lt;tt&amp;gt;/etc/default/prometheus-node-exporter&amp;lt;/tt&amp;gt; to this: &lt;br /&gt;
&lt;br /&gt;
 ARGS=&amp;quot;--web.listen-address=localhost:9101&amp;quot;&lt;br /&gt;
&lt;br /&gt;
and start &amp;lt;tt&amp;gt;prometheus-node-exporter.service&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Then set up stunnel. Create &amp;lt;tt&amp;gt;/etc/stunnel/prometheus-node-exporter.conf&amp;lt;/tt&amp;gt; with this content:&lt;br /&gt;
&lt;br /&gt;
 setuid = stunnel4&lt;br /&gt;
 setgid = stunnel4&lt;br /&gt;
 pid = /var/run/stunnel4/exporter.pid&lt;br /&gt;
 &lt;br /&gt;
 debug = 7&lt;br /&gt;
 &lt;br /&gt;
 [prometheus-node-exporter]&lt;br /&gt;
 accept = 0.0.0.0:9100&lt;br /&gt;
 connect = 127.0.0.1:9101&lt;br /&gt;
 CAfile = /etc/stunnel/tls/server.crt&lt;br /&gt;
 cert = /etc/stunnel/tls/node.crt&lt;br /&gt;
 key = /etc/stunnel/tls/node.key&lt;br /&gt;
 verifyPeer = yes&lt;br /&gt;
&lt;br /&gt;
Copy &amp;lt;tt&amp;gt;/etc/stunnel/{node.crt, node.key, server.crt}&amp;lt;/tt&amp;gt; from &amp;lt;tt&amp;gt;prometheus:/opt/prometheus/tls&amp;lt;/tt&amp;gt; or the same location on other machines.&lt;br /&gt;
&lt;br /&gt;
Finally, start &amp;lt;tt&amp;gt;stunnel4.service&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If it&#039;s a new machine, you&#039;ll also need to add it to the list of monitoring at &amp;lt;tt&amp;gt;prometheus:/opt/prometheus/prometheus.yml&amp;lt;/tt&amp;gt;. Add it under a suitable label (or create a new label) in &#039;node_exporter&#039; job.&lt;br /&gt;
&lt;br /&gt;
= New Distribution =&lt;br /&gt;
&lt;br /&gt;
If you&#039;re adding a new distribution, there a couple of steps you&#039;ll need to take in updating the CSClub Debian repository on [[Machine_List#sodium_benzoate|sodium-benzoate/mirror]]. &lt;br /&gt;
&lt;br /&gt;
The steps to add a new Debian release (in the examples, jessie) is as follows, modify as necessary:&lt;br /&gt;
&lt;br /&gt;
=== Step 0: Create a GPG key ===&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;gpg --gen-key&amp;quot; or something like that. Skip this if you already have one.&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Add to Uploaders ===&lt;br /&gt;
&lt;br /&gt;
The /srv/debian/conf/uploaders file on mirror contains the list of people who can upload. Add your GPG key id to this file.  Use &amp;quot;gpg --list-secret-keys&amp;quot; to find out the key ID. You also need to import your key into the mirror&#039;s gpg homedir as follows:&lt;br /&gt;
&lt;br /&gt;
 gpg --export $KEYID | sudo env GNUPGHOME=/srv/debian/gpg gpg --import&lt;br /&gt;
&lt;br /&gt;
You only need to do this step once.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Add Distro ===&lt;br /&gt;
&lt;br /&gt;
Add a new section to /srv/debian/conf/distributions:&lt;br /&gt;
&lt;br /&gt;
 Origin: CSC&lt;br /&gt;
 Label: Debian&lt;br /&gt;
 Codename: &#039;&#039;&#039;jessie&#039;&#039;&#039;&lt;br /&gt;
 Architectures: alpha amd64 i386 mips mipsel sparc powerpc armel source&lt;br /&gt;
 Components: main contrib non-free&lt;br /&gt;
 Uploaders: uploaders&lt;br /&gt;
 Update: dell chrome&lt;br /&gt;
 SignWith: yes&lt;br /&gt;
 Log: &#039;&#039;&#039;jessie&#039;&#039;&#039;.log&lt;br /&gt;
  --changes notifier&lt;br /&gt;
&lt;br /&gt;
And update the &#039;&#039;&#039;Allow&#039;&#039;&#039; line in /srv/debian/conf/incoming:&lt;br /&gt;
&lt;br /&gt;
 Allow: &#039;&#039;&#039;jessie&amp;gt;jessie&#039;&#039;&#039; oldstable&amp;gt;squeeze stable&amp;gt;wheezy lucid&amp;gt;lucid maverick&amp;gt;maverick oneiric&amp;gt;oneiric precise&amp;gt;precise quantal&amp;gt;quantal&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Update from Sources ===&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
 sudo env GNUPGHOME=/srv/debian/gpg /srv/debian/bin/rrr-update&lt;br /&gt;
&lt;br /&gt;
If all went well you should see the new distribution listed at http://debian.csclub.uwaterloo.ca/dists/&lt;br /&gt;
&lt;br /&gt;
=== Step 4: CSC Packages ===&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our new distribution set up we need to generate our packages and have them uploaded. Namely, ceo and libpam-csc. For libpam-csc:&lt;br /&gt;
&lt;br /&gt;
Get the package:&lt;br /&gt;
&lt;br /&gt;
 git clone https://git.csclub.uwaterloo.ca/public/libpam-csc.git&lt;br /&gt;
 cd libpam-csc&lt;br /&gt;
&lt;br /&gt;
Update change log:&lt;br /&gt;
&lt;br /&gt;
 EMAIL=[you]@csclub.uwaterloo.ca NAME=&amp;quot;Your Name&amp;quot; dch -i&lt;br /&gt;
&lt;br /&gt;
Update as necessary, i.e:&lt;br /&gt;
&lt;br /&gt;
 libpam-csc (1.10&#039;&#039;&#039;jessie0&#039;&#039;&#039;) &#039;&#039;&#039;jessie&#039;&#039;&#039;; urgency=low&lt;br /&gt;
 &lt;br /&gt;
   * Packaging for jessie.&lt;br /&gt;
 &lt;br /&gt;
  -- Your Name &amp;lt;[you]@csclub.uwaterloo.ca&amp;gt;  Thu, 10 Oct 2013 22:08:48 -0400&lt;br /&gt;
&lt;br /&gt;
Build! (You may need to install various dependencies, which it will yell at you if you don&#039;t have.)&lt;br /&gt;
&lt;br /&gt;
 debuild -k&#039;&#039;&#039;YOURKEYID&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yay, it built now let&#039;s upload it to the repo. The build process which create a PACKAGE.changes file in the parent directory (replace PACKAGE with the actual package name).&lt;br /&gt;
&lt;br /&gt;
Copy the dupload file from corn-syrup and dupload:&lt;br /&gt;
&lt;br /&gt;
 mv /etc/dupload /etc/dupload.bak&lt;br /&gt;
 scp corn-syrup:/etc/dupload /etc/dupload&lt;br /&gt;
 dupload libpam-csc_1.10jessie0_amd64.changes&lt;br /&gt;
&lt;br /&gt;
Finally, log into mirror and type &amp;quot;sudo /srv/debian/bin/rrr-incoming&amp;quot;. This is supposed to happen once every few minutes however it is always faster to run it manually.&lt;br /&gt;
&lt;br /&gt;
And you&#039;re done. For CEO, see https://git.csclub.uwaterloo.ca/public/pyceo/src/branch/master/PACKAGING.md&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5686</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5686"/>
		<updated>2026-09-02T20:58:00Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Setting up the system flake */ fix template variable names&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We&#039;re trying to explore different options for running services, and &#039;&#039;&#039;NixOS on Proxmox containers&#039;&#039;&#039; is one of them. Here&#039;s how it is supposed to work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Malleable&#039;&#039;&#039;: it should be relatively easy to modify an existing service config, update software version, and migrate one software to another, as everything are written in Nix configuration files.&lt;br /&gt;
* &#039;&#039;&#039;Recoverable&#039;&#039;&#039;: NixOS keeps old copies of the system, which can be reverted if we see any immediate issues.&lt;br /&gt;
* &#039;&#039;&#039;Discoverable&#039;&#039;&#039;: Services are located in one canonical, centralized location. This reduces the time needed to find the specific config for a specific software, and also makes it easy for someone to know what services are running.&lt;br /&gt;
* &#039;&#039;&#039;Replicable&#039;&#039;&#039;: As NixOS service configuration files are written in a human readable format, anyone wishing to use the &amp;quot;normal&amp;quot; way to configure their service should be able to understand how to setup their service in a similar way.&lt;br /&gt;
* &#039;&#039;&#039;Trackable&#039;&#039;&#039;: Easy to manage and track changes using Git, maybe even with CI.&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Proxmox VM ===&lt;br /&gt;
&lt;br /&gt;
If there isn&#039;t a template already, use https://hydra.nixos.org/job/nixos/release-26.05/nixos.proxmoxLXC.x86_64-linux (replace 26.05 with the latest release)&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;Create CT&amp;quot;, add a SSH public key, and use the vmbr0 bridge. Start the container and look at its IP on the network tab. You should then be able to SSH into the container with a command like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ssh -J [WatIAM]@neotame.csclub.uwaterloo.ca root@129.97.[ACT.UAL]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Setting up the system flake ====&lt;br /&gt;
&lt;br /&gt;
Because the new proxmoxLXC tarball appears to not have &#039;&#039;anything&#039;&#039; under {{code|/etc/nixos/}}, a system flake needs to be created from scratch. First run {{code|nix-channel --update}} then get into a shell with your favorite editor, e.g. {{code|nix-shell -p vim}}. Then create a new empty directory, enter it, and run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
nix flake init --extra-experimental-features nix-command --extra-experimental-features flakes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In {{code|flake.nix}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nix&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  inputs = {&lt;br /&gt;
    nixpkgs.url = &amp;quot;github:nixos/nixpkgs?ref=nixos-26.05&amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  outputs = { nixpkgs, ... } @inputs: {&lt;br /&gt;
    nixosConfigurations.@@HOSTNAME@@ = nixpkgs.lib.nixosSystem {&lt;br /&gt;
      system = &amp;quot;x86_64-linux&amp;quot;;&lt;br /&gt;
      specialArgs = { inherit inputs; };&lt;br /&gt;
      modules = [ ./main.nix ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in {{code|main.nix}}:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nix&amp;quot;&amp;gt;&lt;br /&gt;
{ modulesPath, pkgs, ... }:&lt;br /&gt;
{&lt;br /&gt;
  imports = [&lt;br /&gt;
    (modulesPath + &amp;quot;/virtualisation/proxmox-lxc.nix&amp;quot;)&lt;br /&gt;
  ];&lt;br /&gt;
  boot.isContainer = true;&lt;br /&gt;
  # Supress systemd units that don&#039;t work because of LXC&lt;br /&gt;
  systemd.suppressedSystemUnits = [&lt;br /&gt;
    &amp;quot;dev-mqueue.mount&amp;quot;&lt;br /&gt;
    &amp;quot;sys-kernel-debug.mount&amp;quot;&lt;br /&gt;
    &amp;quot;sys-fs-fuse-connections.mount&amp;quot;&lt;br /&gt;
  ];&lt;br /&gt;
  system.stateVersion = &amp;quot;26.05&amp;quot;;&lt;br /&gt;
  nix.settings.experimental-features = [ &amp;quot;nix-command&amp;quot; &amp;quot;flakes&amp;quot; ];&lt;br /&gt;
  users.users.&amp;quot;root&amp;quot;.openssh.authorizedKeys.keys = [&lt;br /&gt;
    # syscom public key&lt;br /&gt;
    &amp;quot;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC+l5+EvUkm/+I96y4mOrgmQA4h40UDHB59xCok8q23zNgzeRNZQFT9dx9vLZXSuYaZaecaBkC6IF+jHSvQRAbAhPnVPzlabbBOmIuZek6vWEjvr726UJhitW+HV3KNy1BMU6FMUxIboYbo1/zSpQTiyOzcQ+KWiFETxMKYl5bejlLdZUyl6OPYIAp5fwFRVneQHUkhJ/+QufzJz+HNVSCtrPGfNfoVsFiu6zzBDH0EwVxs9Ks2alyE0GT3jYGq8CkFB5ejdgt9FjlW1QG2F3eIsYVZOQ5vd/4KxqnAXcM2zkCyRlSaFNCRG3G3bOWBndc/gp9b+duRXfZyNguo3SVBZpQ9jDYxCdxyvKJVFKMOHDuVjIyE56J/vLB+SI5bRdb/zyPo5psqZVuSgt91WjpH1izGEkYYQjeOhyk57OOLPqIWyXvCoxCM1NkYy8Ld3JebRo0KwEFsNtaq0JUuCtgitfdM9qc3UQHVaKfU1PVKhYoLRtUYq18LY/7jvdRvAMM= root@xylitol&amp;quot;&lt;br /&gt;
  ];&lt;br /&gt;
  users.users.@@USER@@ =&lt;br /&gt;
    {&lt;br /&gt;
      isNormalUser = true;&lt;br /&gt;
      extraGroups = [ &amp;quot;wheel&amp;quot; ];&lt;br /&gt;
      openssh.authorizedKeys.keys = [&lt;br /&gt;
        &amp;quot;@@KEY1@@&amp;quot;&lt;br /&gt;
        &amp;quot;@@KEY2@@&amp;quot;&lt;br /&gt;
      ];&lt;br /&gt;
      shell = pkgs.fish;&lt;br /&gt;
    };&lt;br /&gt;
  programs.fish.enable = true;&lt;br /&gt;
  programs.git.enable = true;&lt;br /&gt;
  services.openssh = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    settings.PasswordAuthentication = false;&lt;br /&gt;
    settings.KbdInteractiveAuthentication = false;&lt;br /&gt;
    settings.PermitRootLogin = &amp;quot;without-password&amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
  security.sudo.wheelNeedsPassword = false;&lt;br /&gt;
  environment.systemPackages = with pkgs; [ vim fish ];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run {{code|nixos-rebuild switch --flake .}} and the system flake should be setup. This can be used to create a non-root user that performs administration.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5685</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5685"/>
		<updated>2026-09-02T20:57:00Z</updated>

		<summary type="html">&lt;p&gt;K95ma: add more instructions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We&#039;re trying to explore different options for running services, and &#039;&#039;&#039;NixOS on Proxmox containers&#039;&#039;&#039; is one of them. Here&#039;s how it is supposed to work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Malleable&#039;&#039;&#039;: it should be relatively easy to modify an existing service config, update software version, and migrate one software to another, as everything are written in Nix configuration files.&lt;br /&gt;
* &#039;&#039;&#039;Recoverable&#039;&#039;&#039;: NixOS keeps old copies of the system, which can be reverted if we see any immediate issues.&lt;br /&gt;
* &#039;&#039;&#039;Discoverable&#039;&#039;&#039;: Services are located in one canonical, centralized location. This reduces the time needed to find the specific config for a specific software, and also makes it easy for someone to know what services are running.&lt;br /&gt;
* &#039;&#039;&#039;Replicable&#039;&#039;&#039;: As NixOS service configuration files are written in a human readable format, anyone wishing to use the &amp;quot;normal&amp;quot; way to configure their service should be able to understand how to setup their service in a similar way.&lt;br /&gt;
* &#039;&#039;&#039;Trackable&#039;&#039;&#039;: Easy to manage and track changes using Git, maybe even with CI.&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Proxmox VM ===&lt;br /&gt;
&lt;br /&gt;
If there isn&#039;t a template already, use https://hydra.nixos.org/job/nixos/release-26.05/nixos.proxmoxLXC.x86_64-linux (replace 26.05 with the latest release)&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;Create CT&amp;quot;, add a SSH public key, and use the vmbr0 bridge. Start the container and look at its IP on the network tab. You should then be able to SSH into the container with a command like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ssh -J [WatIAM]@neotame.csclub.uwaterloo.ca root@129.97.[ACT.UAL]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Setting up the system flake ====&lt;br /&gt;
&lt;br /&gt;
Because the new proxmoxLXC tarball appears to not have &#039;&#039;anything&#039;&#039; under {{code|/etc/nixos/}}, a system flake needs to be created from scratch. First run {{code|nix-channel --update}} then get into a shell with your favorite editor, e.g. {{code|nix-shell -p vim}}. Then create a new empty directory, enter it, and run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
nix flake init --extra-experimental-features nix-command --extra-experimental-features flakes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In {{code|flake.nix}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nix&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  inputs = {&lt;br /&gt;
    nixpkgs.url = &amp;quot;github:nixos/nixpkgs?ref=nixos-26.05&amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  outputs = { nixpkgs, ... } @inputs: {&lt;br /&gt;
    nixosConfigurations.[hostname] = nixpkgs.lib.nixosSystem {&lt;br /&gt;
      system = &amp;quot;x86_64-linux&amp;quot;;&lt;br /&gt;
      specialArgs = { inherit inputs; };&lt;br /&gt;
      modules = [ ./main.nix ];&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in {{code|main.nix}}:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nix&amp;quot;&amp;gt;&lt;br /&gt;
{ modulesPath, pkgs, ... }:&lt;br /&gt;
{&lt;br /&gt;
  imports = [&lt;br /&gt;
    (modulesPath + &amp;quot;/virtualisation/proxmox-lxc.nix&amp;quot;)&lt;br /&gt;
  ];&lt;br /&gt;
  boot.isContainer = true;&lt;br /&gt;
  # Supress systemd units that don&#039;t work because of LXC&lt;br /&gt;
  systemd.suppressedSystemUnits = [&lt;br /&gt;
    &amp;quot;dev-mqueue.mount&amp;quot;&lt;br /&gt;
    &amp;quot;sys-kernel-debug.mount&amp;quot;&lt;br /&gt;
    &amp;quot;sys-fs-fuse-connections.mount&amp;quot;&lt;br /&gt;
  ];&lt;br /&gt;
  system.stateVersion = &amp;quot;26.05&amp;quot;;&lt;br /&gt;
  nix.settings.experimental-features = [ &amp;quot;nix-command&amp;quot; &amp;quot;flakes&amp;quot; ];&lt;br /&gt;
  users.users.&amp;quot;root&amp;quot;.openssh.authorizedKeys.keys = [&lt;br /&gt;
    # syscom public key&lt;br /&gt;
    &amp;quot;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC+l5+EvUkm/+I96y4mOrgmQA4h40UDHB59xCok8q23zNgzeRNZQFT9dx9vLZXSuYaZaecaBkC6IF+jHSvQRAbAhPnVPzlabbBOmIuZek6vWEjvr726UJhitW+HV3KNy1BMU6FMUxIboYbo1/zSpQTiyOzcQ+KWiFETxMKYl5bejlLdZUyl6OPYIAp5fwFRVneQHUkhJ/+QufzJz+HNVSCtrPGfNfoVsFiu6zzBDH0EwVxs9Ks2alyE0GT3jYGq8CkFB5ejdgt9FjlW1QG2F3eIsYVZOQ5vd/4KxqnAXcM2zkCyRlSaFNCRG3G3bOWBndc/gp9b+duRXfZyNguo3SVBZpQ9jDYxCdxyvKJVFKMOHDuVjIyE56J/vLB+SI5bRdb/zyPo5psqZVuSgt91WjpH1izGEkYYQjeOhyk57OOLPqIWyXvCoxCM1NkYy8Ld3JebRo0KwEFsNtaq0JUuCtgitfdM9qc3UQHVaKfU1PVKhYoLRtUYq18LY/7jvdRvAMM= root@xylitol&amp;quot;&lt;br /&gt;
  ];&lt;br /&gt;
  users.users.[user] =&lt;br /&gt;
    {&lt;br /&gt;
      isNormalUser = true;&lt;br /&gt;
      extraGroups = [ &amp;quot;wheel&amp;quot; ];&lt;br /&gt;
      openssh.authorizedKeys.keys = [&lt;br /&gt;
        &amp;quot;[key1]&amp;quot;&lt;br /&gt;
        &amp;quot;[key2]&amp;quot;&lt;br /&gt;
      ];&lt;br /&gt;
      shell = pkgs.[shell];&lt;br /&gt;
    };&lt;br /&gt;
  programs.fish.enable = true;&lt;br /&gt;
  programs.git.enable = true;&lt;br /&gt;
  services.openssh = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    settings.PasswordAuthentication = false;&lt;br /&gt;
    settings.KbdInteractiveAuthentication = false;&lt;br /&gt;
    settings.PermitRootLogin = &amp;quot;without-password&amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
  security.sudo.wheelNeedsPassword = false;&lt;br /&gt;
  environment.systemPackages = with pkgs; [ vim fish ];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run {{code|nixos-rebuild switch --flake .}} and the system flake should be setup. This can be used to create a non-root user that performs administration.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Template:Todo&amp;diff=5683</id>
		<title>Template:Todo</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Template:Todo&amp;diff=5683"/>
		<updated>2026-09-02T01:45:52Z</updated>

		<summary type="html">&lt;p&gt;K95ma: include only+&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;sup class=&amp;quot;noprint Inline-Template&amp;quot; style=&amp;quot;white-space:nowrap;&amp;quot;&amp;gt;&amp;amp;#91;&amp;lt;i&amp;gt;[[:Category:Todo|&amp;lt;span title=&amp;quot;{{{note|todo}}&amp;quot;&amp;gt;{{{text|todo}}}&amp;lt;/span&amp;gt;]]&amp;lt;/i&amp;gt;&amp;amp;#93;&amp;lt;/sup&amp;gt;&amp;lt;includeonly&amp;gt;[[Category:Todo]]&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
We should really be using the template [https://www.mediawiki.org/wiki/Template:Fix Fix] from somewhere but im lazy {{todo}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Proxmox&amp;diff=5682</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Proxmox&amp;diff=5682"/>
		<updated>2026-09-02T01:43:57Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* SSH */ fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Proxmox Vitural Environment is a cluster hosted on sorbitol, tahini and teriyaki. The GUI can be accessed via the hostname of any machine on port 8006, e.g. [https://citric-acid.csclub.uwaterloo.ca:8006 https://tahini.csclub.uwaterloo.ca:8006].&lt;br /&gt;
&lt;br /&gt;
== LDAP ==&lt;br /&gt;
To setup LDAP, from `Server View`, open the `Datacenter` page. Then go to `Permissions -&amp;gt; Realms`.&lt;br /&gt;
&lt;br /&gt;
Then go to the LDAP page, add ldap realm, and input ldap1.csclub.uwaterloo.ca, and ldap2.csclub.uwaterloo.ca as the servers. Then make sure to sync both groups, and users.&lt;br /&gt;
&lt;br /&gt;
Label it `csclub`, and make sure to log in using that realm when logging in from web ui. &lt;br /&gt;
&lt;br /&gt;
== Joining the Cluster ==&lt;br /&gt;
To join the cluster, go to the existing CSC Cluster, from `Server View`, open the `Datacenter` page. Then go to `Cluster` and copy the join information.&lt;br /&gt;
&lt;br /&gt;
On the new node, from `Server View`, open the `Datacenter` page. Then go to `Cluster`, then `Join Cluster` and paste the join information. You will need to enter the root password of the host where you copied the join information.&lt;br /&gt;
&lt;br /&gt;
== SSH ==&lt;br /&gt;
&lt;br /&gt;
When creating a new container/VM, ensure that syscom has access by adding the following SSH public key to {{code|/root/.ssh/authorized_keys}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC+l5+EvUkm/+I96y4mOrgmQA4h40UDHB59xCok8q23zNgzeRNZQFT9dx9vLZXSuYaZaecaBkC6IF+jHSvQRAbAhPnVPzlabbBOmIuZek6vWEjvr726UJhitW+HV3KNy1BMU6FMUxIboYbo1/zSpQTiyOzcQ+KWiFETxMKYl5bejlLdZUyl6OPYIAp5fwFRVneQHUkhJ/+QufzJz+HNVSCtrPGfNfoVsFiu6zzBDH0EwVxs9Ks2alyE0GT3jYGq8CkFB5ejdgt9FjlW1QG2F3eIsYVZOQ5vd/4KxqnAXcM2zkCyRlSaFNCRG3G3bOWBndc/gp9b+duRXfZyNguo3SVBZpQ9jDYxCdxyvKJVFKMOHDuVjIyE56J/vLB+SI5bRdb/zyPo5psqZVuSgt91WjpH1izGEkYYQjeOhyk57OOLPqIWyXvCoxCM1NkYy8Ld3JebRo0KwEFsNtaq0JUuCtgitfdM9qc3UQHVaKfU1PVKhYoLRtUYq18LY/7jvdRvAMM= root@xylitol&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
When making virtual machines in proxmox please first consider whether a full vm is needed, or an lxc will do.&lt;br /&gt;
&lt;br /&gt;
Then go ahead, choose the node (reccomended to choose teriyaki, or tahini), and set a name.&lt;br /&gt;
&lt;br /&gt;
When setting the name, if it is for a member please use `[watiam]-whatever-they-want`. If it&#039;s for something else, please name it clearly. Then when you get to os [storage is still TBD, check syscom irc, same with ISO image].&lt;br /&gt;
&lt;br /&gt;
Add Qemu Agent, otherwise rest are fine with defaults.&lt;br /&gt;
&lt;br /&gt;
Disks [TBD]&lt;br /&gt;
&lt;br /&gt;
Network TBD&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
There are two ways to do networking: network bridge and NAT. Network bridge will put the container/virtual machine on the CSC network (basically side-by-side to proxmox itself), while NAT will encapsulate the container/VM inside a private subnet that is only visible to proxmox host itself.&lt;br /&gt;
&lt;br /&gt;
For services that only exposes HTTP/HTTPS, NAT is more desirable since multiple services can share a host nginx instance, only requiring the host IP to have 80/443 port opened to the Internet, thus saving some IP address in our pool and save some trips to the IST for firewall exemption. But for services that requires custom ports to be opened (for example, BigBlueButton requires a range of UDP ports to be exposed for relaying video streams), using the network bridge and giving the container/VM its own public IP might be easier.&lt;br /&gt;
&lt;br /&gt;
Currently, &amp;lt;code&amp;gt;vmbr0&amp;lt;/code&amp;gt; is used for bridged network and &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; is used for NAT (see [https://pve.proxmox.com/wiki/Network_Configuration#sysadmin_network_masquerading Proxmox&#039;s wiki on NAT networking] for setup instruction). &amp;lt;code&amp;gt;vmbr0&amp;lt;/code&amp;gt; uses the CSC DHCP server, so you can use DHCP there, but &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; requires manual IP assignment.&lt;br /&gt;
&lt;br /&gt;
Note that only using &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; requires you to use SSH ProxyJump via citric-acid to access the inner container, as it wouldn&#039;t have a public IP.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5681</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5681"/>
		<updated>2026-09-02T01:43:25Z</updated>

		<summary type="html">&lt;p&gt;K95ma: fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We&#039;re trying to explore different options for running services, and &#039;&#039;&#039;NixOS on Proxmox containers&#039;&#039;&#039; is one of them. Here&#039;s how it is supposed to work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Malleable&#039;&#039;&#039;: it should be relatively easy to modify an existing service config, update software version, and migrate one software to another, as everything are written in Nix configuration files.&lt;br /&gt;
* &#039;&#039;&#039;Recoverable&#039;&#039;&#039;: NixOS keeps old copies of the system, which can be reverted if we see any immediate issues.&lt;br /&gt;
* &#039;&#039;&#039;Discoverable&#039;&#039;&#039;: Services are located in one canonical, centralized location. This reduces the time needed to find the specific config for a specific software, and also makes it easy for someone to know what services are running.&lt;br /&gt;
* &#039;&#039;&#039;Replicable&#039;&#039;&#039;: As NixOS service configuration files are written in a human readable format, anyone wishing to use the &amp;quot;normal&amp;quot; way to configure their service should be able to understand how to setup their service in a similar way.&lt;br /&gt;
* &#039;&#039;&#039;Trackable&#039;&#039;&#039;: Easy to manage and track changes using Git, maybe even with CI.&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Proxmox VM ===&lt;br /&gt;
&lt;br /&gt;
If there isn&#039;t a template already, use https://hydra.nixos.org/job/nixos/release-25.05/nixos.proxmoxLXC.x86_64-linux (replace 25.05 with the latest release)&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;Create CT&amp;quot;, add a SSH public key, and use the vmbr0 bridge. Start the container and look at its IP on the network tab. You should then be able to SSH into the container with a command like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
ssh -J [WatIAM]@neotame.csclub.uwaterloo.ca root@129.97.[ACT.UAL]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5680</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5680"/>
		<updated>2026-09-02T01:42:58Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We&#039;re trying to explore different options for running services, and &#039;&#039;&#039;NixOS on Proxmox containers&#039;&#039;&#039; is one of them. Here&#039;s how it is supposed to work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Malleable&#039;&#039;&#039;: it should be relatively easy to modify an existing service config, update software version, and migrate one software to another, as everything are written in Nix configuration files.&lt;br /&gt;
* &#039;&#039;&#039;Recoverable&#039;&#039;&#039;: NixOS keeps old copies of the system, which can be reverted if we see any immediate issues.&lt;br /&gt;
* &#039;&#039;&#039;Discoverable&#039;&#039;&#039;: Services are located in one canonical, centralized location. This reduces the time needed to find the specific config for a specific software, and also makes it easy for someone to know what services are running.&lt;br /&gt;
* &#039;&#039;&#039;Replicable&#039;&#039;&#039;: As NixOS service configuration files are written in a human readable format, anyone wishing to use the &amp;quot;normal&amp;quot; way to configure their service should be able to understand how to setup their service in a similar way.&lt;br /&gt;
* &#039;&#039;&#039;Trackable&#039;&#039;&#039;: Easy to manage and track changes using Git, maybe even with CI.&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Proxmox VM ===&lt;br /&gt;
&lt;br /&gt;
If there isn&#039;t a template already, use https://hydra.nixos.org/job/nixos/release-25.05/nixos.proxmoxLXC.x86_64-linux (replace 25.05 with the latest release)&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;Create CT&amp;quot;, add a SSH public key, and use the vmbr0 bridge. Start the container and look at its IP on the network tab. You should then be able to SSH into the container with a command like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
ssh -J [WatIAM]@neotame.csclub.uwaterloo.ca root@129.97.[ACT.UAL]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5679</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5679"/>
		<updated>2026-09-02T00:54:42Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a [[Proxmox]] LXE container {{code|Proxmox}} on {{code|tahini}}. &lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured somewhere.{{todo}}&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord ===&lt;br /&gt;
&lt;br /&gt;
{{code|@beefbot:csclub.uwaterloo.ca}} is a Matrix account that is used to configure the actual mautrix-discord. It is logged into mautrix-discord via login-token bot (token saved, if it expires, login to CSC Exec and reset it). The login password of beefbot (the matrix account) is stored in the CSC vault on [[Vaultwarden]].&lt;br /&gt;
&lt;br /&gt;
{{code|Matrix Bridge#7477}} is the Discord bot that reads the messages on Discord and sends them to Matrix via puppeting. It needs read access to the channels for the Discord -&amp;gt; Matrix part to work properly.&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Invite the Discord bot to the bridged server using {{code|1=https://discord.com/oauth2/authorize?client_id=...&amp;amp;permissions=309774583872&amp;amp;scope=bot}}. client_id is found by logging in to the CSC Exec account on Discord and going to developer portal to find the ID of the Matrix Bridge bot.&lt;br /&gt;
* Login to User {{code|beefbot}} (password in VaultWarden, idk if there is a better place to put it) on our matrix instance&lt;br /&gt;
* &#039;&#039;Inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
* Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot (via beefbot on matrix) with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Category:Todo&amp;diff=5678</id>
		<title>Category:Todo</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Category:Todo&amp;diff=5678"/>
		<updated>2026-09-02T00:54:29Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;tracks pages with the template [[Template:todo]]&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Template:Todo&amp;diff=5677</id>
		<title>Template:Todo</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Template:Todo&amp;diff=5677"/>
		<updated>2026-09-02T00:53:30Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;sup class=&amp;quot;noprint Inline-Template&amp;quot; style=&amp;quot;white-space:nowrap;&amp;quot;&amp;gt;&amp;amp;#91;&amp;lt;i&amp;gt;[[:Category:Todo|&amp;lt;span title=&amp;quot;{{{note|todo}}&amp;quot;&amp;gt;{{{text|todo}}}&amp;lt;/span&amp;gt;]]&amp;lt;/i&amp;gt;&amp;amp;#93;&amp;lt;/sup&amp;gt;&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Proxmox&amp;diff=5676</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Proxmox&amp;diff=5676"/>
		<updated>2026-09-02T00:43:07Z</updated>

		<summary type="html">&lt;p&gt;K95ma: + ssh key note&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Proxmox Vitural Environment is a cluster hosted on sorbitol, tahini and teriyaki. The GUI can be accessed via the hostname of any machine on port 8006, e.g. [https://citric-acid.csclub.uwaterloo.ca:8006 https://tahini.csclub.uwaterloo.ca:8006].&lt;br /&gt;
&lt;br /&gt;
== LDAP ==&lt;br /&gt;
To setup LDAP, from `Server View`, open the `Datacenter` page. Then go to `Permissions -&amp;gt; Realms`.&lt;br /&gt;
&lt;br /&gt;
Then go to the LDAP page, add ldap realm, and input ldap1.csclub.uwaterloo.ca, and ldap2.csclub.uwaterloo.ca as the servers. Then make sure to sync both groups, and users.&lt;br /&gt;
&lt;br /&gt;
Label it `csclub`, and make sure to log in using that realm when logging in from web ui. &lt;br /&gt;
&lt;br /&gt;
== Joining the Cluster ==&lt;br /&gt;
To join the cluster, go to the existing CSC Cluster, from `Server View`, open the `Datacenter` page. Then go to `Cluster` and copy the join information.&lt;br /&gt;
&lt;br /&gt;
On the new node, from `Server View`, open the `Datacenter` page. Then go to `Cluster`, then `Join Cluster` and paste the join information. You will need to enter the root password of the host where you copied the join information.&lt;br /&gt;
&lt;br /&gt;
== SSH ==&lt;br /&gt;
&lt;br /&gt;
When creating a new container/VM, ensure that syscom has access by adding the following SSH public key to {{code|/root/.ssh/authorized_keys}}:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC+l5+EvUkm/+I96y4mOrgmQA4h40UDHB59xCok8q23zNgzeRNZQFT9dx9vLZXSuYaZaecaBkC6IF+jHSvQRAbAhPnVPzlabbBOmIuZek6vWEjvr726UJhitW+HV3KNy1BMU6FMUxIboYbo1/zSpQTiyOzcQ+KWiFETxMKYl5bejlLdZUyl6OPYIAp5fwFRVneQHUkhJ/+QufzJz+HNVSCtrPGfNfoVsFiu6zzBDH0EwVxs9Ks2alyE0GT3jYGq8CkFB5ejdgt9FjlW1QG2F3eIsYVZOQ5vd/4KxqnAXcM2zkCyRlSaFNCRG3G3bOWBndc/gp9b+duRXfZyNguo3SVBZpQ9jDYxCdxyvKJVFKMOHDuVjIyE56J/vLB+SI5bRdb/zyPo5psqZVuSgt91WjpH1izGEkYYQjeOhyk57OOLPqIWyXvCoxCM1NkYy8Ld3JebRo0KwEFsNtaq0JUuCtgitfdM9qc3UQHVaKfU1PVKhYoLRtUYq18LY/7jvdRvAMM= root@xylitol&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual Machines ==&lt;br /&gt;
When making virtual machines in proxmox please first consider whether a full vm is needed, or an lxc will do.&lt;br /&gt;
&lt;br /&gt;
Then go ahead, choose the node (reccomended to choose teriyaki, or tahini), and set a name.&lt;br /&gt;
&lt;br /&gt;
When setting the name, if it is for a member please use `[watiam]-whatever-they-want`. If it&#039;s for something else, please name it clearly. Then when you get to os [storage is still TBD, check syscom irc, same with ISO image].&lt;br /&gt;
&lt;br /&gt;
Add Qemu Agent, otherwise rest are fine with defaults.&lt;br /&gt;
&lt;br /&gt;
Disks [TBD]&lt;br /&gt;
&lt;br /&gt;
Network TBD&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
There are two ways to do networking: network bridge and NAT. Network bridge will put the container/virtual machine on the CSC network (basically side-by-side to proxmox itself), while NAT will encapsulate the container/VM inside a private subnet that is only visible to proxmox host itself.&lt;br /&gt;
&lt;br /&gt;
For services that only exposes HTTP/HTTPS, NAT is more desirable since multiple services can share a host nginx instance, only requiring the host IP to have 80/443 port opened to the Internet, thus saving some IP address in our pool and save some trips to the IST for firewall exemption. But for services that requires custom ports to be opened (for example, BigBlueButton requires a range of UDP ports to be exposed for relaying video streams), using the network bridge and giving the container/VM its own public IP might be easier.&lt;br /&gt;
&lt;br /&gt;
Currently, &amp;lt;code&amp;gt;vmbr0&amp;lt;/code&amp;gt; is used for bridged network and &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; is used for NAT (see [https://pve.proxmox.com/wiki/Network_Configuration#sysadmin_network_masquerading Proxmox&#039;s wiki on NAT networking] for setup instruction). &amp;lt;code&amp;gt;vmbr0&amp;lt;/code&amp;gt; uses the CSC DHCP server, so you can use DHCP there, but &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; requires manual IP assignment.&lt;br /&gt;
&lt;br /&gt;
Note that only using &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; requires you to use SSH ProxyJump via citric-acid to access the inner container, as it wouldn&#039;t have a public IP.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=MySQL&amp;diff=5675</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=MySQL&amp;diff=5675"/>
		<updated>2026-09-01T23:02:06Z</updated>

		<summary type="html">&lt;p&gt;K95ma: K95ma moved page MySQL to MariaDB: use the actual thing we use&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[MariaDB]]&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=MariaDB&amp;diff=5674</id>
		<title>MariaDB</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=MariaDB&amp;diff=5674"/>
		<updated>2026-09-01T23:02:06Z</updated>

		<summary type="html">&lt;p&gt;K95ma: K95ma moved page MySQL to MariaDB: use the actual thing we use&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== For members ==&lt;br /&gt;
&amp;lt;Currently both MariaDB and Postgres shows a 503 Service Unavailable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the database on caffeine is actually MariaDB, not MySQL. Although they are mostly compatible, there are some incompatibilities to be aware of. See [https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/ MariaDB versus MySQL: Compatibility] for details.&lt;br /&gt;
&lt;br /&gt;
=== Creating databases ===&lt;br /&gt;
&lt;br /&gt;
Users can create their own MySQL databases through [[ceo]]. Users emailing syscom asking for a MySQL database should be directed to do so. The process is as follows:&lt;br /&gt;
&lt;br /&gt;
# SSH into any [[Machine_List|CSC machine]].&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ceo&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Select &amp;quot;Create MySQL database&amp;quot; and follow the instructions.&lt;br /&gt;
# Login info will be stored in &amp;lt;tt&amp;gt;ceo-mysql-info&amp;lt;/tt&amp;gt; in your home directory.&lt;br /&gt;
# You can now connect to the MySQL database (from [[Machine_List#caffeine|caffeine]] only).&lt;br /&gt;
&lt;br /&gt;
=== Deleting databases ===&lt;br /&gt;
&lt;br /&gt;
Users can delete their own MySQL databases. &lt;br /&gt;
&lt;br /&gt;
SSH into [[Machine_List#caffeine|caffeine]].&lt;br /&gt;
 mysql -u yourusernamehere -p&lt;br /&gt;
 Enter password: ******&lt;br /&gt;
 DROP DATABASE database name goes here&lt;br /&gt;
Login info and database name was created on database creation in &amp;lt;tt&amp;gt;ceo-mysql-info&amp;lt;/tt&amp;gt; in your home directory.&lt;br /&gt;
&lt;br /&gt;
== For syscom ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a database manually ===&lt;br /&gt;
To create a MySQL database manually on caffeine, first connect to the database as root:&lt;br /&gt;
&lt;br /&gt;
 $ mysql -uroot -p&lt;br /&gt;
 Enter password: ******&lt;br /&gt;
&lt;br /&gt;
Then run the following SQL statements:&lt;br /&gt;
&lt;br /&gt;
 CREATE USER &#039;someuser&#039;@&#039;localhost&#039; IDENTIFIED VIA unix_socket;&lt;br /&gt;
 CREATE USER &#039;someuser&#039;@&#039;%&#039; IDENTIFIED BY &#039;longrandompassword&#039;;&lt;br /&gt;
 CREATE DATABASE someuser;&lt;br /&gt;
 GRANT ALL PRIVILEGES ON someusername.* to &#039;someuser&#039;@&#039;localhost&#039; IDENTIFIED VIA unix_socket;&lt;br /&gt;
 GRANT ALL PRIVILEGES ON someusername.* to &#039;someuser&#039;@&#039;%&#039;;&lt;br /&gt;
&lt;br /&gt;
This will allow users to connect locally without a password, and connect remotely with a password.&lt;br /&gt;
&lt;br /&gt;
For random passwords run &amp;lt;code&amp;gt;pwgen -s 20 1&amp;lt;/code&amp;gt;. For the administrative passwords see /users/sysadmin/passwords/mysql.&lt;br /&gt;
&lt;br /&gt;
Write a file (usually ~club/mysql) to the club&#039;s homedir readable only by them containing the following:&lt;br /&gt;
&lt;br /&gt;
 Username: clubuserid&lt;br /&gt;
 Password: longrandompassword&lt;br /&gt;
 Hostname: localhost&lt;br /&gt;
&lt;br /&gt;
Try not to send passwords via plaintext email.&lt;br /&gt;
&lt;br /&gt;
=== Replication ===&lt;br /&gt;
&lt;br /&gt;
See the history of this page for information on the previous replication setup.&lt;br /&gt;
&lt;br /&gt;
=== Backups ===&lt;br /&gt;
&lt;br /&gt;
We use [https://mariadb.com/kb/en/mariabackup-overview/ mariabackup] to take periodic backups. It is currently installed and configured on both caffeine and coffee.&lt;br /&gt;
&lt;br /&gt;
==== Installation ====&lt;br /&gt;
In the example below, we will be installing mariabackup on coffee, and sending the backups to corn-syrup.&lt;br /&gt;
&lt;br /&gt;
First, install the mariadb-backup package:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apt install mariadb-backup&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, create an SSH key pair for the mysql user:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir /var/mariadb&lt;br /&gt;
chown mysql:mysql /var/mariadb&lt;br /&gt;
su -s /bin/bash mysql&lt;br /&gt;
cd /var/mariadb&lt;br /&gt;
mkdir .ssh&lt;br /&gt;
chmod 700 .ssh&lt;br /&gt;
 # Choose /var/mariadb/.ssh/id_ed25519 for the path&lt;br /&gt;
ssh-keygen -t ed25519&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the public key (/var/mariadb/.ssh/id_ed25519.pub) into /users/syscom/.ssh/authorized_keys on corn-syrup:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
restrict ssh-ed25519 AAAAC3Nza... mysql@coffee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also create the folder &amp;lt;code&amp;gt;/users/syscom/backups/coffee/mariabackup&amp;lt;/code&amp;gt;. We will store the backups here.&lt;br /&gt;
&lt;br /&gt;
We will use a hacky bash script to try to emulate the same behaviour as pgBackRest. We will compress and stream each backup to a folder on corn-syrup in the format &amp;lt;code&amp;gt;1701678356-F&amp;lt;/code&amp;gt;, where the number is a Unix epoch timestamp and the letter at the end is one of F, D or I (for full, differential or incremental backups). Full backups do not depend on any other backups. Differential backups depend on the latest full backup before them. Incremental backups depend on the latest backup before them (of any type).&lt;br /&gt;
&lt;br /&gt;
On coffee, paste the following into e.g. /var/mariadb/bin/backup-mariadb.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
RETENTION_FULL=2&lt;br /&gt;
RETENTION_DIFF=4&lt;br /&gt;
SSH_KEY=/var/mariadb/.ssh/id_ed25519&lt;br /&gt;
SSH_USER=syscom&lt;br /&gt;
SSH_HOST=corn-syrup&lt;br /&gt;
SSH_FOLDER=/users/$SSH_USER/backups/$(hostname)/mariabackup&lt;br /&gt;
SSH_ARGS=&amp;quot;-i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null&amp;quot;&lt;br /&gt;
SSH=&amp;quot;ssh $SSH_ARGS $SSH_USER@$SSH_HOST&amp;quot;&lt;br /&gt;
&lt;br /&gt;
set -euxo pipefail&lt;br /&gt;
# $USER doesn&#039;t seem to be defined when we run this from cron&lt;br /&gt;
if [ &amp;quot;$(id -un)&amp;quot; != mysql ]; then&lt;br /&gt;
    echo &amp;quot;This script should run as the mysql user&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
if [ $# -ne 1 ]; then&lt;br /&gt;
    echo &amp;quot;Usage: $0 &amp;lt;full|diff|incr&amp;gt;&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
backup_type=$1&lt;br /&gt;
if [ &amp;quot;$backup_type&amp;quot; = full ]; then&lt;br /&gt;
    backup_type_letter=F&lt;br /&gt;
elif [ &amp;quot;$backup_type&amp;quot; = diff ]; then&lt;br /&gt;
    backup_type_letter=D&lt;br /&gt;
elif [ &amp;quot;$backup_type&amp;quot; = incr ]; then&lt;br /&gt;
    backup_type_letter=I&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Backup type must be one of &#039;full&#039;, &#039;diff&#039; or &#039;incr&#039;&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
if ! pgrep mariadbd &amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;MariaDB is not running&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
if pgrep mariabackup &amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;mariabackup is already running&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
# Delete temporary files left behind by previous run, if there are any&lt;br /&gt;
$SSH -- &amp;quot;rm -rf $SSH_FOLDER/*.tmp&amp;quot;&lt;br /&gt;
# Get a list of all backups in chronological order&lt;br /&gt;
mapfile -t backups &amp;lt; &amp;lt;($SSH -- &amp;quot;/bin/ls -1 $SSH_FOLDER | grep -P &#039;^\\d+-[FDI]$&#039; | sort&amp;quot;)&lt;br /&gt;
incremental_basedir_args=&lt;br /&gt;
old_checkpoint_dir=$(mktemp -d)&lt;br /&gt;
new_checkpoint_dir=$(mktemp -d)&lt;br /&gt;
trap &amp;quot;rm -rf $old_checkpoint_dir $new_checkpoint_dir&amp;quot; EXIT&lt;br /&gt;
if [ &amp;quot;$backup_type&amp;quot; = diff -o &amp;quot;$backup_type&amp;quot; = incr ]; then&lt;br /&gt;
    # Find a backup which we can use as a base.&lt;br /&gt;
    # For incr, this can be any type; for diff, this must be a full backup.&lt;br /&gt;
    base_backup=&lt;br /&gt;
    for ((i=${#backups[@]}-1; i&amp;gt;=0; i--)); do&lt;br /&gt;
        backup=${backups[i]}&lt;br /&gt;
        if [ $backup_type = incr ] || [[ $backup =~ -F$ ]]; then&lt;br /&gt;
            base_backup=$backup&lt;br /&gt;
            break&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
    if [ -z &amp;quot;$base_backup&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;Could not find base backup for $backup_type type&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
    # Copy the xtrabackup_checkpoints file from the base backup into a&lt;br /&gt;
    # temporary directory, and use it in the mariabackup command.&lt;br /&gt;
    scp $SSH_ARGS &amp;quot;$SSH_USER@$SSH_HOST:$SSH_FOLDER/$base_backup/xtrabackup_*&amp;quot; $old_checkpoint_dir/&lt;br /&gt;
    incremental_basedir_args=&amp;quot;--incremental-basedir=$old_checkpoint_dir&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
compress_level=6&lt;br /&gt;
if [ $backup_type = full ]; then&lt;br /&gt;
    # Use a lower compression level to go faster&lt;br /&gt;
    compress_level=5&lt;br /&gt;
fi&lt;br /&gt;
foldername=&amp;quot;$(date +%s)-$backup_type_letter&amp;quot;&lt;br /&gt;
# First copy to a temporary dir, then rename the temporary dir to the&lt;br /&gt;
# desired dir name (in case our process gets killed)&lt;br /&gt;
mariabackup --user=mysql --backup $incremental_basedir_args --stream=xbstream --extra-lsndir=$new_checkpoint_dir \&lt;br /&gt;
    | nice zstd -$compress_level -T4 \&lt;br /&gt;
    | $SSH -- &amp;quot;cd $SSH_FOLDER &amp;amp;&amp;amp; mkdir $foldername.tmp &amp;amp;&amp;amp; cat &amp;gt; $foldername.tmp/data.xb.zst&amp;quot;&lt;br /&gt;
scp $SSH_ARGS $new_checkpoint_dir/* $SSH_USER@$SSH_HOST:$SSH_FOLDER/$foldername.tmp/&lt;br /&gt;
$SSH -- &amp;quot;mv $SSH_FOLDER/$foldername.tmp $SSH_FOLDER/$foldername&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Delete old backups&lt;br /&gt;
if [ $backup_type = incr ]; then&lt;br /&gt;
    # We don&#039;t delete backups when making an incr backup, since we only&lt;br /&gt;
    # have retention limits for full and diff&lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
if [ $backup_type = full ]; then&lt;br /&gt;
    retention=$RETENTION_FULL&lt;br /&gt;
else&lt;br /&gt;
    retention=$RETENTION_DIFF&lt;br /&gt;
fi&lt;br /&gt;
num_backups_of_same_type=1&lt;br /&gt;
backups_to_delete=()&lt;br /&gt;
for ((i=${#backups[@]}-1; i&amp;gt;=0; i--)); do&lt;br /&gt;
    backup=${backups[i]}&lt;br /&gt;
    if ! [[ $backup =~ -${backup_type_letter}$ ]]; then&lt;br /&gt;
        continue&lt;br /&gt;
    fi&lt;br /&gt;
    ((num_backups_of_same_type++))&lt;br /&gt;
    if [ $num_backups_of_same_type -lt $retention ]; then&lt;br /&gt;
        continue&lt;br /&gt;
    fi&lt;br /&gt;
    if [ $backup_type = full ]; then&lt;br /&gt;
        # Delete everything before the last full backup which we want to&lt;br /&gt;
        # keep&lt;br /&gt;
        pat=&#039;^&#039;&lt;br /&gt;
    else&lt;br /&gt;
        # Delete all the diff and incr backups before the last diff backup&lt;br /&gt;
        # which we want to keep&lt;br /&gt;
        pat=&#039;-[DI]$&#039;&lt;br /&gt;
    fi&lt;br /&gt;
    for ((j=$i-1; j&amp;gt;=0; j--)); do&lt;br /&gt;
        backup=${backups[j]}&lt;br /&gt;
        if [[ $backup =~ $pat ]]; then&lt;br /&gt;
            backups_to_delete+=($backup)&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
    break&lt;br /&gt;
done&lt;br /&gt;
if [ ${#backups_to_delete[@]} -eq 0 ]; then&lt;br /&gt;
    echo &amp;quot;No backups to delete&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit&lt;br /&gt;
fi&lt;br /&gt;
$SSH -- &amp;quot;cd $SSH_FOLDER &amp;amp;&amp;amp; rm -r ${backups_to_delete[@]}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The script should be invoked with exactly one argument which must be one of &amp;quot;full&amp;quot;, &amp;quot;diff&amp;quot; or &amp;quot;incr&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Cron ====&lt;br /&gt;
We are going to use systemd timers because they are much nicer to use than cron. Install /usr/local/bin/csc-systemd-email and /etc/systemd/system/csc-email-on-failure@.service on the target machine so that we get emails for failed jobs (there should be a copy of this on caffeine).&lt;br /&gt;
&lt;br /&gt;
Paste the following into /etc/systemd/system/mariadb-backup@.service:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=MariaDB backup (%i)&lt;br /&gt;
Documentation=https://wiki.csclub.uwaterloo.ca/MySQL#Backups&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=oneshot&lt;br /&gt;
User=mysql&lt;br /&gt;
ExecStart=/var/mariadb/bin/backup-mariadb.sh %i&lt;br /&gt;
&lt;br /&gt;
[Unit]&lt;br /&gt;
OnFailure=csc-email-on-failure@%n.service&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into /etc/systemd/system/mariadb-backup-full.timer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=MariaDB backup (full)&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
# Full back up at 00:20 every Sunday and Wednesday&lt;br /&gt;
OnCalendar=Sun,Wed *-*-* 00:20:00&lt;br /&gt;
Unit=mariadb-backup@full.service&lt;br /&gt;
Persistent=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into /etc/systemd/system/mariadb-backup-diff.timer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=MariaDB backup (diff)&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
# Differential backup at 00:35 every day&lt;br /&gt;
OnCalendar=*-*-* 00:35:00&lt;br /&gt;
Unit=mariadb-backup@diff.service&lt;br /&gt;
Persistent=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Paste the following into /etc/systemd/system/mariadb-backup-incr.timer:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=MariaDB backup (incr)&lt;br /&gt;
&lt;br /&gt;
[Timer]&lt;br /&gt;
# Incremental backup at the 50th minute of every hour&lt;br /&gt;
OnCalendar=*-*-* *:50:00&lt;br /&gt;
Unit=mariadb-backup@incr.service&lt;br /&gt;
Persistent=true&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=timers.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, enable and start the timers:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
systemctl daemon-reload&lt;br /&gt;
systemctl enable --now mariadb-backup-full.timer&lt;br /&gt;
systemctl enable --now mariadb-backup-diff.timer&lt;br /&gt;
systemctl enable --now mariadb-backup-incr.timer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Restore ====&lt;br /&gt;
Paste the following into e.g. /var/mariadb/bin/restore-mariadb.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
SSH_KEY=/var/mariadb/.ssh/id_ed25519&lt;br /&gt;
SSH_USER=syscom&lt;br /&gt;
SSH_HOST=corn-syrup&lt;br /&gt;
SSH_FOLDER=/users/$SSH_USER/backups/$(hostname)/mariabackup&lt;br /&gt;
SSH_ARGS=&amp;quot;-i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null&amp;quot;&lt;br /&gt;
SSH=&amp;quot;ssh $SSH_ARGS $SSH_USER@$SSH_HOST&amp;quot;&lt;br /&gt;
&lt;br /&gt;
set -euxo pipefail&lt;br /&gt;
shopt -s dotglob&lt;br /&gt;
if [ &amp;quot;$(id -un)&amp;quot; != mysql ]; then&lt;br /&gt;
    echo &amp;quot;This script should run as the mysql user&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
if [ $# -gt 1 ]; then&lt;br /&gt;
    echo &amp;quot;Usage: $0 [0123456789-I]&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
if pgrep mariadbd &amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;Please stop MariaDB first&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
# Get a list of all backups in chronological order&lt;br /&gt;
mapfile -t backups &amp;lt; &amp;lt;($SSH -- &amp;quot;/bin/ls -1 $SSH_FOLDER | grep -P &#039;^\\d+-[FDI]$&#039; | sort&amp;quot;)&lt;br /&gt;
if [ ${#backups[@]} -eq 0 ]; then&lt;br /&gt;
    echo &amp;quot;No backups found&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
if [ $# -eq 1 ]; then&lt;br /&gt;
    last_backup_idx=&lt;br /&gt;
    for ((i=${#backups[@]}-1; i&amp;gt;=0; i--)); do&lt;br /&gt;
        if [ ${backups[i]} = &amp;quot;$1&amp;quot; ]; then&lt;br /&gt;
            last_backup_idx=$i&lt;br /&gt;
            break&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
    if [ -z &amp;quot;$last_backup_idx&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;Could not find $1 on remote&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
else&lt;br /&gt;
    last_backup_idx=$(( ${#backups[@]} - 1 ))&lt;br /&gt;
fi&lt;br /&gt;
last_full_backup_idx=&lt;br /&gt;
for ((i=$last_backup_idx; i&amp;gt;=0; i--)); do&lt;br /&gt;
    if [[ ${backups[i]} =~ -F$ ]]; then&lt;br /&gt;
        last_full_backup_idx=$i&lt;br /&gt;
        break&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
if [ -z &amp;quot;$last_full_backup_idx&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;Could not find full backup for ${backups[last_backup_idx]}&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
backups_to_use=()&lt;br /&gt;
if [[ ${backups[last_backup_idx]} =~ -F$ ]]; then&lt;br /&gt;
    # If we&#039;re restoring a full backup, we only need that one backup&lt;br /&gt;
    backups_to_use=(${backups[last_backup_idx]})&lt;br /&gt;
elif [[ ${backups[last_backup_idx]} =~ -D$ ]]; then&lt;br /&gt;
    # If we&#039;re restoring a diff backup, we only need that one backup and the&lt;br /&gt;
    # first full backup before it&lt;br /&gt;
    backups_to_use=(${backups[last_full_backup_idx]} ${backups[last_backup_idx]})&lt;br /&gt;
else&lt;br /&gt;
    # If we&#039;re restoring an incr backup, we need all the backups from it to&lt;br /&gt;
    # the first diff backup before it, and the first full backup before that.&lt;br /&gt;
    # If there is no diff backup between it and the last full backup, then&lt;br /&gt;
    # we need everything between it and the last full backup.&lt;br /&gt;
    for ((i=$last_backup_idx; i&amp;gt;=$last_full_backup_idx; i--)); do&lt;br /&gt;
        backups_to_use=(${backups[i]} ${backups_to_use[@]})&lt;br /&gt;
        if [[ ${backups[i]} =~ -D$ ]]; then&lt;br /&gt;
            backups_to_use=(${backups[last_full_backup_idx]} ${backups_to_use[@]})&lt;br /&gt;
            break&lt;br /&gt;
        fi&lt;br /&gt;
    done&lt;br /&gt;
fi&lt;br /&gt;
base_dir=$(mktemp -d)&lt;br /&gt;
incr_dir=$(mktemp -d)&lt;br /&gt;
trap &amp;quot;rm -rf $base_dir $incr_dir&amp;quot; EXIT&lt;br /&gt;
for backup in ${backups_to_use[@]}; do&lt;br /&gt;
    if [[ $backup =~ -F$ ]]; then&lt;br /&gt;
        backup_dir=$base_dir&lt;br /&gt;
    else&lt;br /&gt;
        backup_dir=$incr_dir&lt;br /&gt;
    fi&lt;br /&gt;
    $SSH -- &amp;quot;cat $SSH_FOLDER/$backup/data.xb.zst&amp;quot; | zstd -d | mbstream -x -C $backup_dir&lt;br /&gt;
    incremental_dir_args=&lt;br /&gt;
    if [ $backup_dir = $incr_dir ]; then&lt;br /&gt;
        incremental_dir_args=&amp;quot;--incremental-dir=$incr_dir&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    mariabackup --prepare --target-dir=$base_dir $incremental_dir_args&lt;br /&gt;
    if [ $backup_dir = $incr_dir ]; then&lt;br /&gt;
        rm -rf $incr_dir/*&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
if [ &amp;quot;$(/bin/ls -1 /var/lib/mysql | wc -l)&amp;quot; -gt 0 ]; then&lt;br /&gt;
    read -p &amp;quot;Everything under /var/lib/mysql will be deleted. Continue (y/n)? &amp;quot; yn&lt;br /&gt;
    yn=${yn,,}  # convert to lower case&lt;br /&gt;
    if [ &amp;quot;$yn&amp;quot; = y -o &amp;quot;$yn&amp;quot; = yes ]; then&lt;br /&gt;
        rm -rf /var/lib/mysql/*&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;Aborting.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
        exit 1&lt;br /&gt;
    fi&lt;br /&gt;
fi&lt;br /&gt;
mariabackup --move-back --target-dir=$base_dir&lt;br /&gt;
echo &amp;quot;Restoration succeeded, please restart MariaDB&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Make sure to stop MariaDB before restoring a backup. If this script is invoked without any arguments, the latest backup found on corn-syrup will be used; a single argument may also be specified, which must be the name of one of the backup folders stored on corn-syrup.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Ceo&amp;diff=5672</id>
		<title>Ceo</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Ceo&amp;diff=5672"/>
		<updated>2026-08-31T01:41:50Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Making Changes */ fix link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Pyceo.png|thumb|300px|right|&amp;lt;tt&amp;gt;pyceo&amp;lt;/tt&amp;gt;&#039;s main menu screen]]&lt;br /&gt;
&lt;br /&gt;
ceo is the CSC member creation and administration interface. It was originally written in perl by persons of mysterious-ness, was re-written in python by Michael Spang in early 2007, and re-written again (in Python) by Syscom in 2020-2021. The source-code for ceo can be found in git: [https://git.csclub.uwaterloo.ca/public/pyceo https://git.csclub.uwaterloo.ca/public/pyceo].&lt;br /&gt;
&lt;br /&gt;
= Instructions/Usage =&lt;br /&gt;
ceo can be accessed by running the &amp;quot;ceo&amp;quot; command from a terminal, or terminal emulator.&lt;br /&gt;
By default, a curses-based menu interface is presented. Use the arrow keys to navigate;&lt;br /&gt;
on many screens, pressing a letter will select the next menu item beginning with that letter.&lt;br /&gt;
&lt;br /&gt;
=== Command-line Mode ===&lt;br /&gt;
Run &amp;lt;tt&amp;gt;ceo --help&amp;lt;/tt&amp;gt; to see a list of command-line utilities.&lt;br /&gt;
&lt;br /&gt;
== Adding a New Member ==&lt;br /&gt;
After a new member has paid the membership fee and signed the Machine Usage Policy forms, a new member account is added to the CSC system by selecting &amp;quot;New Member&amp;quot; in ceo and following the on-screen instructions.  The new member&#039;s username is to be identical to their WatIAM username, if applicable.  For WatIAM users, the name and program fields will automatically be filled after a username is provided.&lt;br /&gt;
&lt;br /&gt;
== Renewing/Extending a Membership ==&lt;br /&gt;
A membership can be renewed or extended by selecting &amp;quot;Renew Membership&amp;quot; in the ceo interface.&lt;br /&gt;
&lt;br /&gt;
== Hosted Clubs ==&lt;br /&gt;
Clubs are hosted free of charge.  To create a new club account use the &amp;quot;New Club&amp;quot; option in the ceo interface.&lt;br /&gt;
&lt;br /&gt;
=== Club Representatives ===&lt;br /&gt;
At this time, there is no limit to the number of representatives a club may have, but representative accounts must be registered with the &amp;quot;New Club Rep&amp;quot; option, and renewed with the &amp;quot;Renew Club Rep&amp;quot; option.&lt;br /&gt;
&lt;br /&gt;
=== Other Club Features ===&lt;br /&gt;
For access to features beyond basic hosting (ie, databases), one of the club representatives will need to email the Systems Committee to have this set up.&lt;br /&gt;
&lt;br /&gt;
= raymo&#039;s guide on how to fix things after screwing up =&lt;br /&gt;
&lt;br /&gt;
== Changing a member to a nonmember (club rep) and vice-versa ==&lt;br /&gt;
&lt;br /&gt;
 ssh hfcs&lt;br /&gt;
 kinit # if you don&#039;t already have &amp;lt;u&amp;gt;[[Kerberos#raymo&#039;s guide to keytabs|keytabs]]&amp;lt;/u&amp;gt; set up&lt;br /&gt;
 ldapvi -Y GSSAPI&lt;br /&gt;
Use &amp;lt;code&amp;gt;/&amp;lt;username&amp;gt;&amp;lt;/code&amp;gt; to search for the user in vi and change &amp;lt;code&amp;gt;term&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;nonMemberTerm&amp;lt;/code&amp;gt; (or vice-versa) for the relevant terms. When you&#039;re done deleting the file should no longer contain the username. Save and quit (&amp;lt;code&amp;gt;:wq&amp;lt;/code&amp;gt;) and press &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; when prompted.&lt;br /&gt;
&lt;br /&gt;
== Deleting a member ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RULE: Never do this without good reason. We should NEVER delete accounts or groups that have been used before.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you accidentally created a club rep as a regular member instead, see the [previous section|Ceo#Changing a member to a nonmember (club rep) and vice-versa]. For another reason that doesn&#039;t break the &#039;&#039;&#039;RULE&#039;&#039;&#039; above, first follow the steps in the change membership section above, up to and including &amp;lt;code&amp;gt;ldapvi&amp;lt;/code&amp;gt;, then delete both the user and group LDAP records. These are separated by blank lines. When you&#039;re done deleting the file should no longer contain the username. Save and quit as if changing membership. Then:&lt;br /&gt;
 ssh auth1&lt;br /&gt;
 sudo kadmin.local&lt;br /&gt;
 delprinc &amp;lt;username&amp;gt;&lt;br /&gt;
 ssh phosphoric acid&lt;br /&gt;
 sudo rm -rfI /users/&amp;lt;username&amp;gt;&lt;br /&gt;
Unsubscribe the user from [https://mailman.csclub.uwaterloo.ca/postorius/lists/syscom.csclub.uwaterloo.ca/members/member/ csc-general on mailman]&lt;br /&gt;
&lt;br /&gt;
= Feature Requests and Ideas =&lt;br /&gt;
&lt;br /&gt;
* Create a graphical and/or online version of ceo&lt;br /&gt;
* Add new members to fuse and plugdev groups&lt;br /&gt;
&lt;br /&gt;
= Contributing to CEO =&lt;br /&gt;
&lt;br /&gt;
== Preliminary Steps ==&lt;br /&gt;
=== Generate a GPG Key ===&lt;br /&gt;
In order to sign the ceo packages you will need to generate yourself a GPG key if you do not already have one. Assuming you do not run&lt;br /&gt;
&lt;br /&gt;
 gpg --gen-key&lt;br /&gt;
&lt;br /&gt;
Choose option (2) DSA (sign only). Choose no expiration when prompted and then your full name and email when asked. It will ask you to confirm the information and then for a passphrase.&lt;br /&gt;
&lt;br /&gt;
=== Add Your Key To Mirror ===&lt;br /&gt;
 ssh mirror.csclub.uwaterloo.ca&lt;br /&gt;
 gpg --list-keys&lt;br /&gt;
&lt;br /&gt;
Locate the 8-character id string. For example &amp;quot;16E37635&amp;quot; in&lt;br /&gt;
 /users/m2ellis/.gnupg/pubring.gpg&lt;br /&gt;
 ---------------------------------&lt;br /&gt;
 pub   1024D/&#039;&#039;&#039;16E37635&#039;&#039;&#039; 2010-08-19&lt;br /&gt;
 uid                  Michael Ellis &amp;lt;m2ellis@csclub.uwaterloo.ca&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you must add this id into the file /srv/debian/conf/uploaders on mirror&lt;br /&gt;
 sudo vim /srv/debian/conf/uploaders&lt;br /&gt;
&lt;br /&gt;
Now in another terminal run&lt;br /&gt;
 gpg --export --armor $KEYID&lt;br /&gt;
&lt;br /&gt;
Now on mirror run&lt;br /&gt;
 sudo -s&lt;br /&gt;
 GNUPGHOME=/srv/debian/gpg gpg --import&lt;br /&gt;
&lt;br /&gt;
Then paste the output from gpg --export --armor $KEYID and end with CTRL-D. It should give you a confirmation, example&lt;br /&gt;
 gpg: key 16E37635: public key &amp;quot;Michael Ellis &amp;lt;m2ellis@csclub.uwaterloo.ca&amp;gt;&amp;quot; imported&lt;br /&gt;
 gpg: Total number processed: 1&lt;br /&gt;
 gpg:               imported: 1&lt;br /&gt;
&lt;br /&gt;
== Making Changes ==&lt;br /&gt;
The source-code for ceo can be found in git: [https://git.csclub.uwaterloo.ca/public/pyceo public/pyceo]. To checkout the code run&lt;br /&gt;
&lt;br /&gt;
 git clone ~git/public/pyceo.git&lt;br /&gt;
&lt;br /&gt;
When you are done making your change you need to update the changelog with dch. Assuming this is a minor incremental change run&lt;br /&gt;
&lt;br /&gt;
 dch -i&lt;br /&gt;
&lt;br /&gt;
Add a description of your change and then save and quit. Once you are sure of your changes commit them to the git repository and push them (test them first!).&lt;br /&gt;
&lt;br /&gt;
Make sure to set a distribution, like distribution UNRELEASED is NOT allowed. So change it to whatever distribution you&#039;re deploying to in the &amp;lt;code&amp;gt;debian/changelog&amp;lt;/code&amp;gt; file&lt;br /&gt;
&lt;br /&gt;
Then you&#039;ll need to make a tar.gz file&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tar czf ceo_&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;.orig.tar.gz pyceo/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;To build the package run debuild&lt;br /&gt;
&lt;br /&gt;
 debuild&lt;br /&gt;
&lt;br /&gt;
This will generate the *.deb files in the parent directory.&lt;br /&gt;
&lt;br /&gt;
This may try to auto-sign with whatever your first GPG key is, you can safely exist and debsign yourself.&lt;br /&gt;
&lt;br /&gt;
=== Uploading Changes to Mirror ===&lt;br /&gt;
After you make the package, you&#039;ll need to sign it, this can be via debsign. (You can find the .changes file in the parent directory)&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
debsign -k [GPG Key ID] [package].changes &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the directory containing the *.deb and *.changes files run&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
dput -c /path/to/dput.cf ceo_&amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;patch&amp;gt;-&amp;lt;distribution&amp;gt;1_amd64.changes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Here is a sample dput.cf&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[DEFAULT]&lt;br /&gt;
default_host_main = debian.csclub&lt;br /&gt;
&lt;br /&gt;
[debian.csclub]&lt;br /&gt;
fqdn = potassium-benzoate.csclub.uwaterloo.ca&lt;br /&gt;
method = scp&lt;br /&gt;
incoming = /srv/debian/incoming&lt;br /&gt;
run_install = 1&lt;br /&gt;
pre_upload_command = /bin/true&lt;br /&gt;
login = o32patel&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Then ssh to mirror and run&lt;br /&gt;
 reprepro --confdir /srv/debian/conf/ processincoming basic # use --ignore=longkeyid if you uploaded a long GPG id&lt;br /&gt;
&lt;br /&gt;
The package should now be uploaded and you can update in the usual way with apt-get/aptitude.&lt;br /&gt;
&lt;br /&gt;
== How to deploy CEO ==&lt;br /&gt;
Firstly, cry&lt;br /&gt;
&lt;br /&gt;
Secondly, check the usual place for all the passwords, install ceo. Install ceod if needed, and edit the configs to make sure the correct servers are contacted for the relevant services. Like install ceod on the management node of cloudstack.&lt;br /&gt;
&lt;br /&gt;
Then setup the kerberos tickets&lt;br /&gt;
&lt;br /&gt;
Then go to `/etc/csc`, and fill in all the ceo.ini, and ceod.ini configs&lt;br /&gt;
[[Category:Software]]&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=User:K95ma&amp;diff=5669</id>
		<title>User:K95ma</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=User:K95ma&amp;diff=5669"/>
		<updated>2026-08-13T03:32:43Z</updated>

		<summary type="html">&lt;p&gt;K95ma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Termcom person&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Vaultwarden&amp;diff=5668</id>
		<title>Vaultwarden</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Vaultwarden&amp;diff=5668"/>
		<updated>2026-08-13T03:26:46Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Can be found at; https://pass.csclub.uwaterloo.ca/&lt;br /&gt;
&lt;br /&gt;
You have to manually make an account by pressing &#039;Create Account&#039;&lt;br /&gt;
&lt;br /&gt;
It&#039;s doesn&#039;t integrate with OAuth, or LDAP so we can&#039;t auto-create the accounts (note: is this true? per https://bitwarden.com/help/directory-sync/ and https://github.com/dani-garcia/vaultwarden#features we should be able to set something up)&lt;br /&gt;
&lt;br /&gt;
It runs on tahini, as a docker-compose container in a [[Proxmox]] VM. To update its version, get access to it, then edit the docker-compose.yaml to the [https://hub.docker.com/r/vaultwarden/server/tags latest stable version] and pull and up:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /root/docker/vault&lt;br /&gt;
vim docker-compose.yaml&lt;br /&gt;
docker compose pull&lt;br /&gt;
docker compose up -d&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5666</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5666"/>
		<updated>2026-08-12T23:38:33Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Discord */ fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord ===&lt;br /&gt;
&lt;br /&gt;
{{code|@beefbot:csclub.uwaterloo.ca}} is a Matrix account that is used to configure the actual mautrix-discord. It is logged into mautrix-discord via login-token bot (token saved, if it expires, login to CSC Exec and reset it). The login password of beefbot (the matrix account) is stored in the CSC vault on [[Vaultwarden]].&lt;br /&gt;
&lt;br /&gt;
{{code|Matrix Bridge#7477}} is the Discord bot that reads the messages on Discord and sends them to Matrix via puppeting. It needs read access to the channels for the Discord -&amp;gt; Matrix part to work properly.&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Invite the Discord bot to the bridged server using {{code|1=https://discord.com/oauth2/authorize?client_id=...&amp;amp;permissions=309774583872&amp;amp;scope=bot}}. client_id is found by logging in to the CSC Exec account on Discord and going to developer portal to find the ID of the Matrix Bridge bot.&lt;br /&gt;
* Login to User {{code|beefbot}} (password in VaultWarden, idk if there is a better place to put it) on our matrix instance&lt;br /&gt;
* &#039;&#039;Inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
* Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot (via beefbot on matrix) with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5665</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5665"/>
		<updated>2026-08-12T23:37:53Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Discord */ link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord ===&lt;br /&gt;
&lt;br /&gt;
{{code|@beefbot:csclub.uwaterloo.ca}} is a Matrix account that is used to configure the actual mautrix-discord. It is logged into mautrix-discord via login-token bot (token saved, if it expires, login to CSC Exec and reset it). The login password of beefbot (the matrix account) is stored in the CSC vault on [[Vaultwarden]].&lt;br /&gt;
&lt;br /&gt;
{{code|Matrix Bridge#7477}} is the Discord bot that reads the messages on Discord and sends them to Matrix via puppeting. It needs read access to the channels for the Discord -&amp;gt; Matrix part to work properly.&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Invite the Discord bot to the bridged server using {{code|https://discord.com/oauth2/authorize?client_id=...&amp;amp;permissions=309774583872&amp;amp;scope=bot}}. client_id is found by logging in to the CSC Exec account on Discord and going to developer portal to find the ID of the Matrix Bridge bot.&lt;br /&gt;
* Login to User {{code|beefbot}} (password in VaultWarden, idk if there is a better place to put it) on our matrix instance&lt;br /&gt;
* &#039;&#039;Inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
* Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot (via beefbot on matrix) with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5664</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5664"/>
		<updated>2026-08-12T23:37:36Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Bridging */ expand&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord ===&lt;br /&gt;
&lt;br /&gt;
{{code|@beefbot:csclub.uwaterloo.ca}} is a Matrix account that is used to configure the actual mautrix-discord. It is logged into mautrix-discord via login-token bot (token saved, if it expires, login to CSC Exec and reset it). The login password of beefbot (the matrix account) is stored in the CSC vault on [[VaultWarden]].&lt;br /&gt;
&lt;br /&gt;
{{code|Matrix Bridge#7477}} is the Discord bot that reads the messages on Discord and sends them to Matrix via puppeting. It needs read access to the channels for the Discord -&amp;gt; Matrix part to work properly.&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Invite the Discord bot to the bridged server using {{code|https://discord.com/oauth2/authorize?client_id=...&amp;amp;permissions=309774583872&amp;amp;scope=bot}}. client_id is found by logging in to the CSC Exec account on Discord and going to developer portal to find the ID of the Matrix Bridge bot.&lt;br /&gt;
* Login to User {{code|beefbot}} (password in VaultWarden, idk if there is a better place to put it) on our matrix instance&lt;br /&gt;
* &#039;&#039;Inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
* Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot (via beefbot on matrix) with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5663</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5663"/>
		<updated>2026-08-12T23:21:22Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Bridging */ +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord Instructions ===&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@beefbot:csclub.uwaterloo.ca}} and {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Invite the Discord bot to the bridged server using {{code|https://discord.com/oauth2/authorize?client_id=...&amp;amp;permissions=309774583872&amp;amp;scope=bot}}. client_id is found by logging in to the CSC Exec account on Discord and going to developer portal to find the ID of the Matrix Bridge bot.&lt;br /&gt;
* Login to User {{code|beefbot}} (ask syscom for password) on our matrix instance (when we eventually disable password login, you will need to edit the nix config to re-enable it)&lt;br /&gt;
* &#039;&#039;Inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
*  Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Firewall&amp;diff=5662</id>
		<title>Firewall</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Firewall&amp;diff=5662"/>
		<updated>2026-08-07T03:14:07Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* General Use */ fix wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Our networks are behind the University&#039;s Campus firewall. This means that traffic to us is automatically dropped at the edge of campus unless we have exceptions added for it.&lt;br /&gt;
&lt;br /&gt;
= Current Exceptions =&lt;br /&gt;
&lt;br /&gt;
== Office Terminals ==&lt;br /&gt;
&lt;br /&gt;
No exceptions in the campus firewall.&lt;br /&gt;
&lt;br /&gt;
== General Use ==&lt;br /&gt;
&lt;br /&gt;
These ports are allowed:&lt;br /&gt;
&lt;br /&gt;
* Port 22 (SSH), plus additional SSH ports on taurine (21, 53, 80, 81, 443, 8000, 8080)&lt;br /&gt;
* Ports 60000–61000 (Mosh)&lt;br /&gt;
* Ports 28000-28500 (TCP/UDP general use)&lt;br /&gt;
&lt;br /&gt;
== Webserver ==&lt;br /&gt;
&lt;br /&gt;
* caffeine has ports 22 (SSH), 80 (HTTP), 443 (HTTPS), 11068 (HTTP for rridge) and UDP 60000–61000 (Mosh)&lt;br /&gt;
* wiki is now a CNAME for caffeine&lt;br /&gt;
* git has ports 80 (HTTP) and 443 (HTTPS)&lt;br /&gt;
* nextcloud has ports 80 (HTTP) and 443 (HTTPS)&lt;br /&gt;
&lt;br /&gt;
== Mail ==&lt;br /&gt;
&lt;br /&gt;
* mail has ports 25 (SMTP), 80 (HTTP), 143 (IMAP), 443 (HTTPS), 587 (MAIL SUBMISSION), 993 (IMAPS)&lt;br /&gt;
* mailman has ports 80 (HTTP) and 443 (HTTPS)&lt;br /&gt;
&lt;br /&gt;
== Mirror ==&lt;br /&gt;
&lt;br /&gt;
* mirror has ports 21 (FTP), 22 (SSH), 80 (HTTP), 443 (HTTPS), 873 (RSYNC)&lt;br /&gt;
&lt;br /&gt;
== IPv6 Test ==&lt;br /&gt;
&lt;br /&gt;
* ds.test-ipv6, mtu1280.test-ipv6 have ports 80 (HTTP), 443 (HTTPS)&lt;br /&gt;
* v6ns1.test-ipv6 has port 53 (DNS)&lt;br /&gt;
&lt;br /&gt;
== Cloud ==&lt;br /&gt;
* cloud.csclub.uwaterloo.ca (and csclub.cloud, and all of their subdomains): 80 (HTTP) and 443 (HTTPS) &lt;br /&gt;
* riboflavin (and possibly other cloud machines) have port 22 exempted from the campus firewall, but they are currently blocked via iptables on the hosts&lt;br /&gt;
&lt;br /&gt;
== BigBlueButton ==&lt;br /&gt;
&lt;br /&gt;
* bbb has TCP ports 80 (HTTP) and 443 (HTTPS)&lt;br /&gt;
* bbb has UDP ports 16384 - 32768 (for WebRTC)&lt;br /&gt;
&lt;br /&gt;
== drone.io (ci) ==&lt;br /&gt;
&lt;br /&gt;
* This has now moved to Kubernetes (same IP address as cloud.csclub.uwaterloo.ca).&lt;br /&gt;
&lt;br /&gt;
== progcom ==&lt;br /&gt;
* progcom has TCP ports 80 (HTTP) and 443 (HTTPS)&lt;br /&gt;
&lt;br /&gt;
== Other Web Services ==&lt;br /&gt;
&lt;br /&gt;
rt, munin, prometheus&lt;br /&gt;
&lt;br /&gt;
* 80 (HTTP) and 443 (HTTPS)&lt;br /&gt;
&lt;br /&gt;
= Adding Exceptions =&lt;br /&gt;
&lt;br /&gt;
Create a ticket on the [https://uwaterloo.atlassian.net/servicedesk/customer/portal/2/group/413/create/805 UWaterloo Help Portal]. Use the syscom account unless you already have an account and IST knows it.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Machine_List&amp;diff=5661</id>
		<title>Machine List</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Machine_List&amp;diff=5661"/>
		<updated>2026-08-07T03:13:19Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* General-Use Servers */ +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Most of our machines are in the E7, F7, G7 and H7 racks (as of Jan. 2022) in the MC 3015 server room. There is an additional rack in the DC 3558 machine room on the third floor. Our office terminals are in the CSC office, in MC 3036/3037.&lt;br /&gt;
&lt;br /&gt;
= Web Server =&lt;br /&gt;
You are highly encouraged to avoid running anything that&#039;s not directly related to your CSC webspace on our web server. We have plenty of general-use machines; please use those instead. You can even edit web pages from any other machine--usually the only reason you&#039;d *need* to be on caffeine is for database access.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;caffeine&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
Caffeine is the Computer Science Club&#039;s web server. It serves websites, databases for websites, and a large amount of other services.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(Redundant active backup coming soon...)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* QEMU virtual machine hosted on [[Machine List#Teriyaki|Teriyaki]] &lt;br /&gt;
** 32 vCPUs&lt;br /&gt;
** 64GB of RAM&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
* Club and member web sites with [https://www.apache.org/ Apache]&lt;br /&gt;
* [[MySQL]] databases&lt;br /&gt;
* [[PostgreSQL]] databases&lt;br /&gt;
* [[ceo]] daemon&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;mathnews&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
[[#xylitol|xylitol]] hosts a systemd-nspawn container which serves as the mathNEWS webserver. It is administered by mathNEWS, as a pilot for providing containers to select groups who have more specialized demands than the general-use infrastructure can meet.&lt;br /&gt;
&lt;br /&gt;
= General-Use Servers =&lt;br /&gt;
&lt;br /&gt;
These machines can be used for (nearly) anything you like (though be polite and remember that these are shared machines). Recall that when you signed the Machine Usage Agreement, you promised not to use these machines to generate profit (so no cryptocurrency mining).&lt;br /&gt;
&lt;br /&gt;
For computationally-intensive jobs (CPU/memory bound) we recommend running on high-fructose-corn-syrup, carbonated-water, sorbitol, mannitol, or corn-syrup, listed in roughly decreasing order of available resources. For low-intensity interactive jobs, such as IRC clients, we recommend running on neotame. &#039;&#039;&#039;&amp;lt;u&amp;gt;If you have a long-running computationally intensive job, it&#039;s good to nice[https://en.wikipedia.org/wiki/Nice_(Unix)] your process, and possibly let syscom know too.&amp;lt;/u&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: [[Firewall#General Use|firewall]] applies to these servers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;corn-syrup&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
Dell PowerEdge 2950&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 2 × Intel Xeon E5405 (2.00 GHz, 4 cores each)&lt;br /&gt;
* 32 GB RAM&lt;br /&gt;
* eth0 (&amp;quot;Gb0&amp;quot;) mac addr 00:24:e8:52:41:27&lt;br /&gt;
* eth1 (&amp;quot;Gb1&amp;quot;) mac addr 00:24:e8:52:41:29&lt;br /&gt;
* IPMI mac addr 00:24:e8:52:41:2b&lt;br /&gt;
* 3 &amp;amp;times; Western-Digital 160GB SATA hard drive (445 GB software RAID0 array)&lt;br /&gt;
&lt;br /&gt;
==== Notes ====&lt;br /&gt;
&lt;br /&gt;
* Use eth0/Gb0 for the mathstudentorgsnet connection&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
* Hosts 1 TB &amp;lt;tt&amp;gt;[[scratch|/scratch]]&amp;lt;/tt&amp;gt; and exports via NFS (sec=krb5)&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;high-fructose-corn-syrup&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
High-fructose-corn-syrup (or hfcs) is a large SuperMicro server. It&#039;s been in CSC service since April 2012.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 4x AMD Opteron 6272 (2.4 GHz, 16 cores each)&lt;br /&gt;
* 192 GB RAM&lt;br /&gt;
* Supermicro H8QGi+-F Motherboard Quad 1944-pin Socket [http://csclub.uwaterloo.ca/misc/manuals/motherboard-H8QGI+-F.pdf (Manual)]&lt;br /&gt;
* 500 GB Seagate Barracuda&lt;br /&gt;
* Supermicro Case Rackmount CSE-748TQ-R1400B 4U [http://csclub.uwaterloo.ca/misc/manuals/SC748.pdf (Manual)]&lt;br /&gt;
&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Missing moba IO shield (as of January 2024)&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;carbonated-water&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
carbonated-water is a Dell R815 provided by CSCF.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 4x AMD Opteron 6176 processors (2.3 GHz, 12 cores each)&lt;br /&gt;
* 128GB RAM&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;neotame&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
neotame is a SuperMicro server funded by MEF. It is the successor to taurine.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;We strongly discourage running computationally-intensive jobs&#039;&#039;&#039; on neotame as many users run interactive applications such as IRC clients on it and any significant service degradation will be more likely to affect other users (who will probably notice right away).&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2630 v4 processors (2.2 GHz, 10 cores/20 threads each)&lt;br /&gt;
* 64GB RAM&lt;br /&gt;
&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
* SSH server also listens on ports 21, 22, 53, 80, 81, 443, 8000, 8080 for your convenience.&lt;br /&gt;
== &#039;&#039;mannitol&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
mannitol is a SuperMicro server funded by MEF. CUDA is available on this node.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2630 v4 processors (2.2 GHz, 10 cores/20 threads each)&lt;br /&gt;
* 64GB RAM&lt;br /&gt;
* NVIDIA GeForce RTX 3050 6G&lt;br /&gt;
&lt;br /&gt;
= Office Terminals =&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to SSH into these machines, but we discourage you from trying to use these machines when you&#039;re not sitting in front of them. They are bounced at least every time our login manager, lightdm, throws a tantrum (which is several times a day). These are for use inside our physical office.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;cyanide&#039;&#039; ==&lt;br /&gt;
cyanide is a [https://support.apple.com/kb/sp710 Mac Mini (Late 2014)], identical in specification to powernap&lt;br /&gt;
&lt;br /&gt;
=== Spec ===&lt;br /&gt;
&lt;br /&gt;
* Intel i7-4578U (4) @ 3.500GHz&lt;br /&gt;
* 16GB RAM&lt;br /&gt;
* Intel Iris Graphics 5100&lt;br /&gt;
* 256GB On-board SSD&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;powernap&#039;&#039;==&lt;br /&gt;
powernap is a [https://support.apple.com/kb/sp710 Mac Mini (Late 2014)].&lt;br /&gt;
&lt;br /&gt;
=== Spec ===&lt;br /&gt;
&lt;br /&gt;
* Intel i7-4578U (4) @ 3.500GHz&lt;br /&gt;
* 16GB RAM&lt;br /&gt;
* Intel Iris Graphics 5100&lt;br /&gt;
* 256GB On-board SSD&lt;br /&gt;
&lt;br /&gt;
=== Speaker === &lt;br /&gt;
powernap has the office speakers (a pair of nice studio monitors) currently connected to it.&lt;br /&gt;
&lt;br /&gt;
=== Services ===&lt;br /&gt;
* MPD for playing music. Only office/termcom/syscom can log into powernap. Use `ncmpcpp` to control MPD.&lt;br /&gt;
** TODO: this is not the case anymore&lt;br /&gt;
* Bluetooth audio receiver. Only syscom can control bluetooth pairing. Use `bluetoothctl` to control bluetooth.&lt;br /&gt;
&lt;br /&gt;
Music is located in `/music` on the office terminals.&lt;br /&gt;
&lt;br /&gt;
= Progcom Only =&lt;br /&gt;
The Programme Committee has access to a VM on corn-syrup called &#039;progcom&#039;. They have sudo rights in this VM so they may install and run their own software inside it. This VM should only be accessible by members of progcom or syscom.&lt;br /&gt;
&lt;br /&gt;
The CI/CD stuff for the csclub.uwaterloo.ca runs on this vm (drone).&lt;br /&gt;
&lt;br /&gt;
= Codey Bot Only =&lt;br /&gt;
codey-prod: QEMU virtual machine hosted on [[Machine List#Teriyaki|Teriyaki]] &lt;br /&gt;
&lt;br /&gt;
codey-staging, codey-dev: Used to ran on Cloudstack, currently not deployed on Proxmox due to a lack of Codey Bot devs.&lt;br /&gt;
&lt;br /&gt;
= Syscom Only =&lt;br /&gt;
&lt;br /&gt;
The following systems are only be accessible to members of the [[Systems Committee]] for a variety of reasons; the most common of which being that some of these machines host [[Kerberos]] authentication services for the CSC.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;xylitol&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
xylitol is a Dell PowerEdge R815 donated by CSCF. It is primarily a container host for services previously hosted on aspartame and dextrose, including munin, rt, mathnews, auth1, and dns1. It was provisioned with the intent to replace both of those hosts.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* Dual AMD Opteron 6176 (2.3 GHz, 48 cores total)&lt;br /&gt;
* 128GB RAM&lt;br /&gt;
* 500GB volume group on RAID1 SSD (xylitol-mirrored)&lt;br /&gt;
* 500ish-GB volume group on RAID10 HDD (xylitol-raidten)&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
* [[Machine List#auth1|auth1]]&lt;br /&gt;
* [[Machine List#chat|chat]]&lt;br /&gt;
* [[Machine List#mail|mail]]&lt;br /&gt;
* mailman3&lt;br /&gt;
* [[Machine List#munin|munin]]&lt;br /&gt;
* [[BigBlueButton|bigbluebutton3]]&lt;br /&gt;
* dns1&lt;br /&gt;
* keycloak&lt;br /&gt;
* mathnews&lt;br /&gt;
* mattermost&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;auth1&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
Container on [[#xylitol|xylitol]].&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[[LDAP]] primary&lt;br /&gt;
*[[Kerberos]] primary&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;chat&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
Container on [[#xylitol|xylitol]].&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
* The Lounge web IRC client (https://chat.csclub.uwaterloo.ca)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;mail&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
mail is the CSC&#039;s mail server. It hosts mail delivery, imap(s), smtp(s), and mailman. It is also syscom-only. It is a [[Virtualization#Linux_Containers|Linux container]] at present.&lt;br /&gt;
&lt;br /&gt;
TODO: &amp;quot;HA&amp;quot;-ish configuration&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* currently hosted on [[#xylitol|xylitol]]&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[[Mail]] services&lt;br /&gt;
* mailman (web interface at [http://mailman.csclub.uwaterloo.ca/])&lt;br /&gt;
*[[Webmail]]&lt;br /&gt;
*[[ceo]] daemon&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;munin&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
munin is a syscom-only monitoring and accounting machine. It is a [[Virtualization#Linux_Containers|Linux container]] at present.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* currently hosted on [[#xylitol|xylitol]]&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[http://munin.csclub.uwaterloo.ca munin] systems monitoring daemon&lt;br /&gt;
==&#039;&#039;phosphoric-acid&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
phosphoric-acid is a Dell PowerEdge R815 donated by CSCF and is a clone of xylitol. It may be used to provide redundant cloud services in the future.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* (clone of Xylitol)&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[[#coffee|coffee]]&lt;br /&gt;
*[[Observability|prometheus]]&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;coffee&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
Virtual machine running on phosphoric-acid.&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[[Database#MySQL|MySQL]]&lt;br /&gt;
*[[Database#Postgres|Postgres]]&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;cobalamin&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
Dell PowerEdge 2950 donated to us by FEDS. Located in the Science machine room on the first floor of Physics, on Science Computing Rack 2. NICs are plugged into A1 and A2 on the adjacent rack. Acts as a backup server for many things.&lt;br /&gt;
&lt;br /&gt;
TODO: should replace with another Syscom server when Science Computing clears out the rack (ETA before 09/2024)&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 1 × Intel Xeon E5420 (2.50 GHz, 4 cores)&lt;br /&gt;
* 16GB RAM&lt;br /&gt;
* Broadcom NetworkXtreme II&lt;br /&gt;
* 2x73GB Hard Drives, hardware RAID1&lt;br /&gt;
** Soon to be 2x1TB in MegaRAID1&lt;br /&gt;
*http://www.dell.com/support/home/ca/en/cabsdt1/product-support/servicetag/51TYRG1/configuration&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
* Containers: [[#auth2|auth2]] (kerberos)&lt;br /&gt;
&lt;br /&gt;
==== Notes ====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;TODO: Mega unreliable.&#039;&#039;&#039; (Goes down once every few weeks... due to power outages in the PHYS server room)&lt;br /&gt;
** It is plugged into a UPS but the UPS has dead batteries.&lt;br /&gt;
* The network card requires non-free drivers. Be sure to use an installation disc with non-free.&lt;br /&gt;
&lt;br /&gt;
* We have separate IP ranges for cobalamin and its containers because the machine is located in a different building. They are:&lt;br /&gt;
** VLAN ID 506 (csc-data1): 129.97.18.16/29; gateway 129.97.18.17; mask 255.255.255.240&lt;br /&gt;
** VLAN ID 504 (csc-ipmi): 172.19.5.24/29; gateway 172.19.5.25; mask 255.255.255.248&lt;br /&gt;
* Physical access to the PHYS server rooms can be acquired by visiting Science Computing in PHYS 2006.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;auth2&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
Container on [[#cobalamin|cobalamin]].&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[[LDAP]] secondary&lt;br /&gt;
*[[Kerberos]] secondary&lt;br /&gt;
&lt;br /&gt;
MAC Address: c2:c0:00:00:00:a2&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;potassium-benzoate&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
potassium-benzoate is our mirror server, funded by MEF.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 36 drive Supermicro chassis (SSG-6048R-E1CR36L) &lt;br /&gt;
* 2 x Intel Xeon E5-2695 v4 (18 cores, 2.10GHz)&lt;br /&gt;
* 64 GB (4 x 16GB) of DDR4 (2133Mhz)  ECC RDIMM RAM&lt;br /&gt;
* 2 x 1 TB Samsung Evo 850 SSD drives&lt;br /&gt;
* 17 x 4 TB Western Digital Gold drives (separate funding from MEF)&lt;br /&gt;
* 9 x 18TB Seagate Exos X18 (8 ZFS, Z2,1 hot-spare)&lt;br /&gt;
* 10 Gbps SFP+ card (loaned from CSCF)&lt;br /&gt;
* 50 Gbps Mellanox QSFP card (from ginkgo; currently unconnected)&lt;br /&gt;
&lt;br /&gt;
Spec before 2025-03-27:&lt;br /&gt;
* 1 x Intel Xeon E5-2630 v3 (8 cores, 2.40 GHz)&lt;br /&gt;
&lt;br /&gt;
==== Network Connections ====&lt;br /&gt;
&lt;br /&gt;
potassium-benzoate has two connections to our network:&lt;br /&gt;
&lt;br /&gt;
* 1 Gbps to our switch (used for management)&lt;br /&gt;
* 2 x 10 Gbps (LACP bond) to mc-rt-3015-mso-a (for mirror)&lt;br /&gt;
&lt;br /&gt;
Mirror&#039;s bandwidth is limited to 1 Gbps on each of the 4 campus internet links. Mirror&#039;s bandwidth is not limited on campus.&lt;br /&gt;
&lt;br /&gt;
==== Services ====&lt;br /&gt;
&lt;br /&gt;
*[[Mirror]]&lt;br /&gt;
*[[Talks]] mirror&lt;br /&gt;
*[[Debian_Repository|CSClub packages repository]]&lt;br /&gt;
&lt;br /&gt;
= User Cloud (Proxmox) =&lt;br /&gt;
A [[Proxmox]] Cluster consistent of 3 nodes&lt;br /&gt;
&lt;br /&gt;
==== Services: ====&lt;br /&gt;
&lt;br /&gt;
* [[Machine List#caffeine|caffeine]]&lt;br /&gt;
* [https://pass.uwaterloo.ca/ pass.uwaterloo.ca], a university-wide password manager hosted by CSC as a demo service for all Nexus (ADFS) user.&lt;br /&gt;
* reverse-proxy&lt;br /&gt;
* k3s (in progress)&lt;br /&gt;
* [[Matrix]]&lt;br /&gt;
* pmc (Website for the Pure Math Club)&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;tahini&#039;&#039; ==&lt;br /&gt;
Server was funded via SLEF. Part of Proxmox Project, and mass migration.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
* 2x AMD EPYC 9654 96-Core Processor&lt;br /&gt;
* 256gb DDR5 ram&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;teriyaki&#039;&#039; ==&lt;br /&gt;
Server was funded via SLEF. Part of Proxmox Project, and mass migration. Located in DC 3558&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
* 2x AMD EPYC 9654 96-Core Processor&lt;br /&gt;
* 256gb DDR5 ram&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;sorbitol&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
sorbitol is a SuperMicro server funded by MEF. Used for Proxmox.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2630 v4 processors (2.2 GHz, 10 cores/20 threads each)&lt;br /&gt;
* 64GB RAM&lt;br /&gt;
&lt;br /&gt;
= Syscom Cloud (Proxmox) =&lt;br /&gt;
Syscom only [[Proxmox]] Cluster consistent of 3 nodes&lt;br /&gt;
&lt;br /&gt;
==== Services: ====&lt;br /&gt;
&lt;br /&gt;
* test-ipv6 (test-ipv6.csclub.uwaterloo.ca; a test-ipv6.com mirror)&lt;br /&gt;
&lt;br /&gt;
== rum ==&lt;br /&gt;
Dell PowerEdge R730 on loan by CSCF to replace our older Dells.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2697 v3&lt;br /&gt;
* 256 GB DDR4&lt;br /&gt;
* 2x 2TB Kingston KC3000 (KIN-SKC3000D2048G)&lt;br /&gt;
** Mounted on Startech Dual M.2 PCIE SSD Adapter Cards (STA-PEX8M2E2)&lt;br /&gt;
&lt;br /&gt;
== tequila ==&lt;br /&gt;
Dell PowerEdge R730 on loan by CSCF to replace our older Dells. Located in DC 3558.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2697 v3&lt;br /&gt;
* 256 GB DDR4&lt;br /&gt;
* LSI 9300-8e HBA + 2 NetApp DS4324 HDD shelves (24-disks each)&lt;br /&gt;
** 24 x 2TB HDDs (assorted brands/models)&lt;br /&gt;
** Dual IOM3 controllers.&lt;br /&gt;
&lt;br /&gt;
== vodka ==&lt;br /&gt;
Dell PowerEdge R730 on loan by CSCF to replace our older Dells.&lt;br /&gt;
&lt;br /&gt;
=== Specs ===&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2697 v3&lt;br /&gt;
* 256 GB DDR4&lt;br /&gt;
* 2x 2TB Kingston KC3000 (KIN-SKC3000D2048G)&lt;br /&gt;
** Mounted on Startech Dual M.2 PCIE SSD Adapter Cards (STA-PEX8M2E2)&lt;br /&gt;
&lt;br /&gt;
= Storage =&lt;br /&gt;
See also [[Filer]]&lt;br /&gt;
&lt;br /&gt;
== ranch ==&lt;br /&gt;
Dell PowerEdge R730 on loan by CSCF to replace our older Dells. &lt;br /&gt;
&lt;br /&gt;
=== Specs ===&lt;br /&gt;
&lt;br /&gt;
* 2x Intel Xeon E5-2697 v3&lt;br /&gt;
* 256 GB DDR4&lt;br /&gt;
* 2 NetApp DS4324 HDD shelves (24-disks each)&lt;br /&gt;
** 24 x 2TB HDDs (assorted brands/models)&lt;br /&gt;
** Dual IOM3 controllers.&lt;br /&gt;
&lt;br /&gt;
= UPS =&lt;br /&gt;
&lt;br /&gt;
All of the machines in the MC 3015 machine room are connected to one of our UPSs.&lt;br /&gt;
&lt;br /&gt;
All of our UPSs can be monitored via CSCF:&lt;br /&gt;
&lt;br /&gt;
* MC3015-UPS-B2&lt;br /&gt;
* mc-3015-e7-ups-1.cs.uwaterloo.ca (rbc55, batteries replaced July 2014) (https://metrics.cscf.uwaterloo.ca/grafana/dashboard/db/ups-statistics?orgId=1&amp;amp;var-UPS=mc-3015-e7-ups-1&amp;amp;var-Interval=30m)&lt;br /&gt;
* mc-3015-f7-ups-1.cs.uwaterloo.ca (rbc55, batteries replaced Feb 2017) (https://metrics.cscf.uwaterloo.ca/grafana/dashboard/db/ups-statistics?orgId=1&amp;amp;var-UPS=mc-3015-f7-ups-1&amp;amp;var-Interval=30m)&lt;br /&gt;
* mc-3015-g7-ups-1.cs.uwaterloo.ca (su5000t, batteries replaced 2010) (https://metrics.cscf.uwaterloo.ca/grafana/dashboard/db/ups-statistics?orgId=1&amp;amp;var-UPS=mc-3015-g7-ups-1&amp;amp;var-Interval=30m)&lt;br /&gt;
* mc-3015-g7-ups-2.cs.uwaterloo.ca (unknown) (https://metrics.cscf.uwaterloo.ca/grafana/dashboard/db/ups-statistics?orgId=1&amp;amp;var-UPS=mc-3015-g7-ups-2&amp;amp;var-Interval=30m)&lt;br /&gt;
* mc-3015-h7-ups-1.cs.uwaterloo.ca (su5000t, batteries replaced 2004) (https://metrics.cscf.uwaterloo.ca/grafana/dashboard/db/ups-statistics?orgId=1&amp;amp;var-UPS=mc-3015-h7-ups-1&amp;amp;var-Interval=30m)&lt;br /&gt;
* mc-3015-h7-ups-2.cs.uwaterloo.ca (unknown) (https://metrics.cscf.uwaterloo.ca/grafana/dashboard/db/ups-statistics?orgId=1&amp;amp;var-UPS=mc-3015-h7-ups-2&amp;amp;var-Interval=30m)&lt;br /&gt;
&lt;br /&gt;
We will receive email alerts for any issues with the UPS. Their status can be monitored via [[SNMP]].&lt;br /&gt;
&lt;br /&gt;
TODO: Fix labels &amp;amp; verify info is correct &amp;amp; figure out why we can&#039;t talk to cacti.&lt;br /&gt;
= Other =&lt;br /&gt;
&lt;br /&gt;
== ps3 ==&lt;br /&gt;
This is just a very wide PS3, the model that supported running Linux natively before it was removed. Firmware was updated to remove this feature, however it can still be done via. homebrew. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Specs&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* It&#039;s a PS3.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2022-10-24&#039;&#039;&#039; - Thermal paste replaced + firmware updated to latest supported version, also modded.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;binaerpilot&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
This is a Gumstix Overo Tide CPU on a Tobi expansion board. It is currently attached to corn-syrup in the machine room and even more currently turned off until someone can figure out what is wrong with it.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* TI OMAP 3530 750Mhz (ARM Cortex-A8)&lt;br /&gt;
* 512MB RAM&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;anamanaguchi&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
This is a Gumstix Overo Tide CPU on a Chestnut43 expansion board. It is currently in the hardware drawer in the CSC.&lt;br /&gt;
&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* TI OMAP 3530 750Mhz (ARM Cortex-A8)&lt;br /&gt;
* 512MB RAM&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: May have disappeared at some point&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;digital cutter&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
See [[Digital Cutter|here]].&lt;br /&gt;
==== Specs ====&lt;br /&gt;
&lt;br /&gt;
* Intel Core i7-6700k&lt;br /&gt;
* 2x8GB RAM&lt;br /&gt;
* 1x 64GB SanDisk SDSSDP064G SSD&lt;br /&gt;
* Cup Holder (DVD drive has power, but not connected to mother board)&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5453</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5453"/>
		<updated>2025-10-29T02:00:38Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Discord Instructions */ fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord Instructions ===&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@beefbot:csclub.uwaterloo.ca}} and {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Login to User {{code|beefbot}} (ask syscom for password) on our matrix instance (when we eventually disable password login, you will need to edit the nix config to re-enable it)&lt;br /&gt;
* &#039;&#039;Inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
*  Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5452</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5452"/>
		<updated>2025-10-29T01:57:23Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Discord Instructions */ italic&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord Instructions ===&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@beefbot:csclub.uwaterloo.ca}} and {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Login to User {{code|beefbot}} (ask syscom for password) on our matrix instance (when we eventually disable password login, you will need to edit the nix config to re-enable it)&lt;br /&gt;
*  Open the DM with {{code|@discordbot:csclub.uwaterloo.ca}} on beefbot&#039;s account, &#039;&#039;inside&#039;&#039; the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
*  Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5451</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5451"/>
		<updated>2025-10-29T01:56:15Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Discord Instructions */ fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord Instructions ===&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@beefbot:csclub.uwaterloo.ca}} and {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Login to User {{code|beefbot}} (ask syscom for password) on our matrix instance (when we eventually disable password login, you will need to edit the nix config to re-enable it)&lt;br /&gt;
*  Open the DM with {{code|@discordbot:csclub.uwaterloo.ca}} on beefbot&#039;s account, _inside_ the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
*  Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5450</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5450"/>
		<updated>2025-10-29T01:55:56Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Discord Instructions */ +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord Instructions ===&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite {{code|@beefbot:csclub.uwaterloo.ca}} and {{code|@discordbot:csclub.uwaterloo.ca}} to the channel&lt;br /&gt;
* Login to User {{code|beefbot}} (ask syscom for password) on our matrix instance (when we eventually disable password login, you will need to edit the nix config to re-enable it)&lt;br /&gt;
*  Open the DM with {{code|@discordbot:csclub.uwaterloo.ca  on beefbot&#039;s account, _inside_ the matrix channel, send, {{code|!discord bridge &amp;lt;channel ID&amp;gt;}} (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
*  Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot with {{code|!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...}} with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Template:Code&amp;diff=5449</id>
		<title>Template:Code</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Template:Code&amp;diff=5449"/>
		<updated>2025-10-29T01:55:11Z</updated>

		<summary type="html">&lt;p&gt;K95ma: copied template from https://en.wikipedia.org/w/index.php?title=Template:Code&amp;amp;action=history; see url for attribution&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#tag:syntaxhighlight|{{{code|{{{1}}}}}}|lang={{{lang|{{{2|text}}}}}}|class={{{class|}}}|style={{{style|}}}|inline=1}}&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5448</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5448"/>
		<updated>2025-10-29T01:53:31Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bridging ==&lt;br /&gt;
&lt;br /&gt;
We are currently running mautrix-discord. Bridge to IRC via heisenbridge may be added in the future.&lt;br /&gt;
&lt;br /&gt;
=== Discord Instructions ===&lt;br /&gt;
&lt;br /&gt;
* Create the Matrix channel to bridge to&lt;br /&gt;
* Invite @beefbot:csclub.uwaterloo.ca and @discordbot:csclub.uwaterloo.ca  to the channel&lt;br /&gt;
* Login to User `beefbot` (ask syscom for password) on our matrix instance (when we eventually disable password login, you will need to edit the nix config to re-enable it)&lt;br /&gt;
*  Open the DM with @discordbot:csclub.uwaterloo.ca  on beefbot&#039;s account, _inside_ the matrix channel, send, `!discord bridge &amp;lt;channel ID&amp;gt;` (the channel ID on Discord, the Discord bot must be able to see that channel)&lt;br /&gt;
*  Create a Discord Webhook URL for that channel on Discord&#039;s side, and then DM the discord bot with `!discord set-relay !26DmcJd3cQ...:csclub.uwaterloo.ca --url https://discord.com/...` with the first argument replaced by the actual room identifier and the second parameter the webhook URL.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5447</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5447"/>
		<updated>2025-10-26T21:18:23Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Matrix Installation */ -&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5446</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5446"/>
		<updated>2025-10-26T20:59:44Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so the config to setup both Synapse and PostgreSQL is hosted at https://git.csclub.uwaterloo.ca/k95ma/matrix-nixos/.&lt;br /&gt;
&lt;br /&gt;
The reverse proxy, Caddy is configured on citric-acid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5429</id>
		<title>NixOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=NixOS&amp;diff=5429"/>
		<updated>2025-09-29T04:23:38Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We&#039;re trying to explore different options for running services, and &#039;&#039;&#039;NixOS on Proxmox containers&#039;&#039;&#039; is one of them. Here&#039;s how it is supposed to work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Malleable&#039;&#039;&#039;: it should be relatively easy to modify an existing service config, update software version, and migrate one software to another, as everything are written in Nix configuration files.&lt;br /&gt;
* &#039;&#039;&#039;Recoverable&#039;&#039;&#039;: NixOS keeps old copies of the system, which can be reverted if we see any immediate issues.&lt;br /&gt;
* &#039;&#039;&#039;Discoverable&#039;&#039;&#039;: Services are located in one canonical, centralized location. This reduces the time needed to find the specific config for a specific software, and also makes it easy for someone to know what services are running.&lt;br /&gt;
* &#039;&#039;&#039;Replicable&#039;&#039;&#039;: As NixOS service configuration files are written in a human readable format, anyone wishing to use the &amp;quot;normal&amp;quot; way to configure their service should be able to understand how to setup their service in a similar way.&lt;br /&gt;
* &#039;&#039;&#039;Trackable&#039;&#039;&#039;: Easy to manage and track changes using Git, maybe even with CI.&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Proxmox VM ===&lt;br /&gt;
&lt;br /&gt;
If there isn&#039;t a template already, use https://hydra.nixos.org/job/nixos/release-25.05/nixos.proxmoxLXC.x86_64-linux (replace 25.05 with the latest release)&lt;br /&gt;
&lt;br /&gt;
Use &amp;quot;Create CT&amp;quot;, do not use the SSH config, and setup a root password. Then use the console on the web interface to login as root (press enter if you see a blank screen) and configure SSH from there.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5427</id>
		<title>Matrix</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Matrix&amp;diff=5427"/>
		<updated>2025-09-18T02:50:09Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.&lt;br /&gt;
&lt;br /&gt;
== Server Setup ==&lt;br /&gt;
&lt;br /&gt;
We are currently running Matrix on a Proxmox LXE container on &amp;lt;code&amp;gt;citric-acid&amp;lt;/code&amp;gt;. Ask Siracha for the credentials to access Proxmox and the VM.&lt;br /&gt;
&lt;br /&gt;
== Matrix Installation ==&lt;br /&gt;
&lt;br /&gt;
We are using NixOS, so use the following config (might be a bit messy) to setup both Synapse, Nginx, and PostgreSQL:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: We could have used &amp;lt;code&amp;gt;recommendedProxySettings = true&amp;lt;/code&amp;gt; which sets most of the &amp;lt;code&amp;gt;X-Forwarded-For&amp;lt;/code&amp;gt; headers correctly. However, this is a reverse proxy behind a reverse proxy (Nginx on citric acid -&amp;gt; Nginx on the container -&amp;gt; Synapse) so &amp;lt;code&amp;gt;X-Forwarded-Proto&amp;lt;/code&amp;gt; has to be always set to https. I&#039;m sure there is a better way to do this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ pkgs, lib, config, ... }:&lt;br /&gt;
let&lt;br /&gt;
  fqdn = &amp;quot;matrix.${config.networking.domain}&amp;quot;;&lt;br /&gt;
  clientConfig = {&lt;br /&gt;
    &amp;quot;m.homeserver&amp;quot;.base_url = &amp;quot;https://${fqdn}&amp;quot;;&lt;br /&gt;
    &amp;quot;m.identity_server&amp;quot; = {};&lt;br /&gt;
  };&lt;br /&gt;
  serverConfig.&amp;quot;m.server&amp;quot; = &amp;quot;${fqdn}:443&amp;quot;;&lt;br /&gt;
  mkWellKnown = data: &#039;&#039;&lt;br /&gt;
    add_header Content-Type application/json;&lt;br /&gt;
    add_header Access-Control-Allow-Origin *;&lt;br /&gt;
    return 200 &#039;${builtins.toJSON data}&#039;;&lt;br /&gt;
  &#039;&#039;;&lt;br /&gt;
  extraCfg = pkgs.writeText &amp;quot;synapse-extra-config.yaml&amp;quot; &#039;&#039;&lt;br /&gt;
  &#039;&#039;;&lt;br /&gt;
in {&lt;br /&gt;
  networking.firewall = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    allowedTCPPorts = [ 80 8008 ];&lt;br /&gt;
  };&lt;br /&gt;
  networking.domain = &amp;quot;csclub.uwaterloo.ca&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  services.postgresql = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    initialScript = pkgs.writeText &amp;quot;synapse-init.sql&amp;quot; &#039;&#039;&lt;br /&gt;
      CREATE ROLE &amp;quot;matrix-synapse&amp;quot; WITH LOGIN PASSWORD &#039;synapse&#039;;&lt;br /&gt;
      CREATE DATABASE &amp;quot;matrix-synapse&amp;quot; WITH OWNER &amp;quot;matrix-synapse&amp;quot;&lt;br /&gt;
        TEMPLATE template0&lt;br /&gt;
        LC_COLLATE = &amp;quot;C&amp;quot;&lt;br /&gt;
        LC_CTYPE = &amp;quot;C&amp;quot;;&lt;br /&gt;
    &#039;&#039;;&lt;br /&gt;
    dataDir = &amp;quot;/data/postgresql&amp;quot;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  services.nginx = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    # recommendedProxySettings = true;&lt;br /&gt;
    virtualHosts = {&lt;br /&gt;
      &amp;quot;csclub.uwaterloo.ca&amp;quot; = {&lt;br /&gt;
        locations.&amp;quot;/&amp;quot;.extraConfig = &#039;&#039;&lt;br /&gt;
          return 404;&lt;br /&gt;
        &#039;&#039;;&lt;br /&gt;
        locations.&amp;quot;= /.well-known/matrix/server&amp;quot;.extraConfig = mkWellKnown serverConfig;&lt;br /&gt;
        locations.&amp;quot;= /.well-known/matrix/client&amp;quot;.extraConfig = mkWellKnown clientConfig;&lt;br /&gt;
      };&lt;br /&gt;
      &amp;quot;${fqdn}&amp;quot; = {&lt;br /&gt;
        locations.&amp;quot;/&amp;quot;.extraConfig = &#039;&#039;&lt;br /&gt;
          return 404;&lt;br /&gt;
        &#039;&#039;;&lt;br /&gt;
        locations.&amp;quot;/_matrix&amp;quot;.proxyPass = &amp;quot;http://[::1]:8008&amp;quot;;&lt;br /&gt;
        locations.&amp;quot;/_matrix&amp;quot;.extraConfig = &#039;&#039;&lt;br /&gt;
    proxy_set_header        Host $host;&lt;br /&gt;
    proxy_set_header        X-Real-IP $remote_addr;&lt;br /&gt;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;
    proxy_set_header        X-Forwarded-Proto https;&lt;br /&gt;
    proxy_set_header        X-Forwarded-Host $host;&lt;br /&gt;
    proxy_set_header        X-Forwarded-Server $host;&lt;br /&gt;
        &#039;&#039;;&lt;br /&gt;
        locations.&amp;quot;/_synapse/client&amp;quot;.proxyPass = &amp;quot;http://[::1]:8008&amp;quot;;&lt;br /&gt;
        locations.&amp;quot;/_synapse/client&amp;quot;.extraConfig = &#039;&#039;&lt;br /&gt;
    proxy_set_header        Host $host;&lt;br /&gt;
    proxy_set_header        X-Real-IP $remote_addr;&lt;br /&gt;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;
    proxy_set_header        X-Forwarded-Proto https;&lt;br /&gt;
    proxy_set_header        X-Forwarded-Host $host;&lt;br /&gt;
    proxy_set_header        X-Forwarded-Server $host;&lt;br /&gt;
        &#039;&#039;;&lt;br /&gt;
      };&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  services.matrix-synapse = {&lt;br /&gt;
    enable = true;&lt;br /&gt;
    extraConfigFiles = [ extraCfg ];&lt;br /&gt;
    dataDir = &amp;quot;/data/matrix-synapse&amp;quot;;&lt;br /&gt;
    settings = {&lt;br /&gt;
      server_name = config.networking.domain;&lt;br /&gt;
      public_baseurl = &amp;quot;https://matrix.csclub.uwaterloo.ca/&amp;quot;;&lt;br /&gt;
      listeners = [&lt;br /&gt;
        {&lt;br /&gt;
          port = 8008;&lt;br /&gt;
          bind_addresses = [ &amp;quot;::1&amp;quot; ];&lt;br /&gt;
          type = &amp;quot;http&amp;quot;;&lt;br /&gt;
          tls = false;&lt;br /&gt;
          x_forwarded = true;&lt;br /&gt;
          resources = [&lt;br /&gt;
            {&lt;br /&gt;
                names = [ &amp;quot;client&amp;quot; ]; # no federation&lt;br /&gt;
                compress = true;&lt;br /&gt;
            }&lt;br /&gt;
          ];&lt;br /&gt;
        }&lt;br /&gt;
      ];&lt;br /&gt;
&lt;br /&gt;
      oidc_providers = [&lt;br /&gt;
        {&lt;br /&gt;
           idp_id = &amp;quot;keycloak&amp;quot;;&lt;br /&gt;
           idp_name = &amp;quot;CSC&amp;quot;;&lt;br /&gt;
           issuer = &amp;quot;https://keycloak.csclub.uwaterloo.ca/realms/csc&amp;quot;;&lt;br /&gt;
           client_id = &amp;quot;synapse&amp;quot;;&lt;br /&gt;
           client_secret = &amp;quot;xxxx&amp;quot;; # fill the client secret from keycloak here&lt;br /&gt;
           scopes = [ &amp;quot;openid&amp;quot; &amp;quot;profile&amp;quot; ];&lt;br /&gt;
           user_mapping_provider.config = {&lt;br /&gt;
                localpart_template = &amp;quot;{{ user.preferred_username }}&amp;quot;;&lt;br /&gt;
                display_name_template = &amp;quot;{{ user.name }}&amp;quot;;&lt;br /&gt;
           };&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
      ];&lt;br /&gt;
      registration_shared_secret = &amp;quot;xxxxx&amp;quot;;&lt;br /&gt;
      enable_registration = true;&lt;br /&gt;
      enable_registration_captcha = false;&lt;br /&gt;
      registration_requires_token = true;&lt;br /&gt;
    };&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Go to https://app.cinny.in/login/matrix.csclub.uwaterloo.ca, and click &amp;quot;Continue with CSC&amp;quot;.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Proxmox&amp;diff=5426</id>
		<title>Proxmox</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Proxmox&amp;diff=5426"/>
		<updated>2025-09-16T02:22:47Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Proxmox Vitural Environment (as of 2025-09-15) lives on the citric-acid machine and can be accessed via https://citric-acid.csclub.uwaterloo.ca:8006.&lt;br /&gt;
&lt;br /&gt;
== Setting up Proxmox ==&lt;br /&gt;
To setup proxmox, from `Server View`, open the `Datacenter` page. Then go to `Permissions -&amp;gt; Realms`.&lt;br /&gt;
&lt;br /&gt;
Then just make sure pam is setup lol&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
There are two ways to do networking: network bridge and NAT. Network bridge will put the container/virtual machine on the CSC network (basically side-by-side to proxmox itself), while NAT will encapsulate the container/VM inside a private subnet that is only visible to proxmox host itself.&lt;br /&gt;
&lt;br /&gt;
For services that only exposes HTTP/HTTPS, NAT is more desirable since multiple services can share a host nginx instance, only requiring the host IP to have 80/443 port opened to the Internet, thus saving some IP address in our pool and save some trips to the IST for firewall exemption. But for services that requires custom ports to be opened (for example, BigBlueButton requires a range of UDP ports to be exposed for relaying video streams), using the network bridge and giving the container/VM its own public IP might be easier.&lt;br /&gt;
&lt;br /&gt;
Currently, &amp;lt;code&amp;gt;vmbr0&amp;lt;/code&amp;gt; is used for bridged network and &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; is used for NAT (see [https://pve.proxmox.com/wiki/Network_Configuration#sysadmin_network_masquerading Proxmox&#039;s wiki on NAT networking] for setup instruction). &amp;lt;code&amp;gt;vmbr0&amp;lt;/code&amp;gt; uses the CSC DHCP server, so you can use DHCP there, but &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; requires manual IP assignment.&lt;br /&gt;
&lt;br /&gt;
Note that only using &amp;lt;code&amp;gt;vmbr1&amp;lt;/code&amp;gt; requires you to use SSH ProxyJump via citric-acid to access the inner container, as it wouldn&#039;t have a public IP.&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Keycloak&amp;diff=5425</id>
		<title>Keycloak</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Keycloak&amp;diff=5425"/>
		<updated>2025-09-16T01:20:31Z</updated>

		<summary type="html">&lt;p&gt;K95ma: fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are using [https://www.keycloak.org/ Keycloak] for web SSO (Single Sign-On). Clients may use Keycloak for authenticating users via SAML or OIDC (OpenID Connect).&lt;br /&gt;
&lt;br /&gt;
* Admin login: https://keycloak.csclub.uwaterloo.ca/admin&lt;br /&gt;
* Regular user login: https://keycloak.csclub.uwaterloo.ca/realms/csc/account&lt;br /&gt;
* OIDC Auto Discovery URL: https://keycloak.csclub.uwaterloo.ca/realms/csc/.well-known/openid-configuration&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
OK so before we get started, there&#039;s this really useful feature in Keycloak called &amp;quot;Conditional user attribute&amp;quot; which allows you to create a flow which branches based on attributes a user may have. For some reason, this is enabled in the test suite for Keycloak, but is not available from the main application. So we&#039;re going to compile and inject it ourselves.&lt;br /&gt;
&lt;br /&gt;
Clone https://git.csclub.uwaterloo.ca/public/keycloak-spi and run &amp;lt;code&amp;gt;mvn clean package&amp;lt;/code&amp;gt;. This will create a JAR file called csc-keycloak-spi.jar in the target directory; upload this to somewhere where it can be easily downloaded, e.g. your www directory.&lt;br /&gt;
&lt;br /&gt;
== Database setup ==&lt;br /&gt;
Go to biloba or chamomile, run &amp;lt;code&amp;gt;mysql&amp;lt;/code&amp;gt;, and run the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER &#039;keycloak&#039; IDENTIFIED BY &#039;replace_this_password&#039;;    &lt;br /&gt;
CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;    &lt;br /&gt;
GRANT ALL PRIVILEGES ON keycloak.* TO &#039;keycloak&#039;;    &lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kubernetes setup ==&lt;br /&gt;
We are running Keycloak on Kubernetes. This introduces some complications because it gets reverse proxied twice, and we also can&#039;t (or at least shouldn&#039;t) modify the filesystem of the Pod where it&#039;s running, since that Pod can get destroyed at any time. We still need to load that JAR file we just created, though, so we&#039;re going to place it into a PersistentVolume instead. We&#039;re going to do this by first creating a PersistentVolumeClaim, then claiming it in a temporary Pod which we&#039;ll use for shell access:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF | kubectl apply -f    &lt;br /&gt;
apiVersion: v1    &lt;br /&gt;
kind: PersistentVolumeClaim    &lt;br /&gt;
metadata:    &lt;br /&gt;
  namespace: syscom    &lt;br /&gt;
  name: keycloak-spi-pvc    &lt;br /&gt;
spec:    &lt;br /&gt;
  storageClassName: cloudstack-storage    &lt;br /&gt;
  accessModes:    &lt;br /&gt;
    - ReadWriteOnce    &lt;br /&gt;
  resources:    &lt;br /&gt;
    requests:    &lt;br /&gt;
      storage: 5Mi    &lt;br /&gt;
---    &lt;br /&gt;
apiVersion: v1    &lt;br /&gt;
kind: Pod    &lt;br /&gt;
metadata:    &lt;br /&gt;
  namespace: syscom    &lt;br /&gt;
  name: temp-pod    &lt;br /&gt;
spec:    &lt;br /&gt;
  containers:    &lt;br /&gt;
    - name: temp    &lt;br /&gt;
      image: alpine    &lt;br /&gt;
      volumeMounts:    &lt;br /&gt;
        - mountPath: &amp;quot;/data&amp;quot;    &lt;br /&gt;
          name: keycloak-spi-pv    &lt;br /&gt;
      stdin: true    &lt;br /&gt;
      stdinOnce: true    &lt;br /&gt;
      tty: true    &lt;br /&gt;
  volumes:    &lt;br /&gt;
    - name: keycloak-spi-pv    &lt;br /&gt;
      persistentVolumeClaim:    &lt;br /&gt;
        claimName: keycloak-spi-pvc&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run &amp;lt;code&amp;gt;kubectl -n syscom get pods&amp;lt;/code&amp;gt; a few times to check if the pod is ready; once it is, attach to it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n syscom exec -it temp-pod -- sh&lt;br /&gt;
cd /data&lt;br /&gt;
mkdir keycloak-spi&lt;br /&gt;
chmod a+w keycloak-spi&lt;br /&gt;
cd keycloak-spi&lt;br /&gt;
wget https://csclub.uwaterloo.ca/~merenber/csc-keycloak-spi.jar&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now delete the pod since we don&#039;t need it anymore:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n syscom delete pod temp-pod&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Create some secrets (use the MySQL password which you chose earlier):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n syscom create secret generic keycloak-secret \&lt;br /&gt;
  --from-literal=DB_USER=some_user \&lt;br /&gt;
  --from-literal=DB_PASSWORD=some_password \&lt;br /&gt;
  --from-literal=KEYCLOAK_USER=some_user \&lt;br /&gt;
  --from-literal=KEYCLOAK_PASSWORD=some_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now apply the main manifest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl apply -f https://git.csclub.uwaterloo.ca/cloud/manifests/raw/branch/master/keycloak.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DNS setup ==&lt;br /&gt;
From Infoblox, make keycloak.csclub.uwaterloo.ca a CNAME for rr-public-cloud.csclub.uwaterloo.ca; that record points to biloba and chamomile, which know how to reverse proxy requests to Kubernetes.&lt;br /&gt;
&lt;br /&gt;
== NGINX setup ==&lt;br /&gt;
Pretty standard stuff:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server {&lt;br /&gt;
  listen 80;&lt;br /&gt;
  listen [::]:80;&lt;br /&gt;
  server_name keycloak.csclub.uwaterloo.ca;&lt;br /&gt;
  return 301 https://$host$request_uri;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
server {&lt;br /&gt;
  listen 443 ssl http2;&lt;br /&gt;
  listen [::]:443 ssl http2;&lt;br /&gt;
  server_name keycloak.csclub.uwaterloo.ca;&lt;br /&gt;
  ssl_certificate /etc/ssl/private/csclub.uwaterloo.ca.chain;&lt;br /&gt;
  ssl_certificate_key /etc/ssl/private/csclub.uwaterloo.ca.key;&lt;br /&gt;
  &lt;br /&gt;
  location / {&lt;br /&gt;
    proxy_pass http://k8s;&lt;br /&gt;
  }&lt;br /&gt;
  include proxy_params;&lt;br /&gt;
&lt;br /&gt;
  access_log /var/log/nginx/keycloak-access.log;&lt;br /&gt;
  error_log /var/log/nginx/keycloak-error.log;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also make sure you have the following snippet in /etc/nginx/proxy_params:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Increase buffer size&lt;br /&gt;
# See https://ma.ttias.be/nginx-proxy-upstream-sent-big-header-reading-response-header-upstream/&lt;br /&gt;
proxy_buffer_size 128k;&lt;br /&gt;
proxy_buffers 4 256k;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Don&#039;t forget to enable the site and reload NGINX on both chamomile and biloba.&lt;br /&gt;
&lt;br /&gt;
== Web UI setup ==&lt;br /&gt;
If all went well, you should now be able to visit https://keycloak.csclub.uwaterloo.ca from your browser.&lt;br /&gt;
Create a new realm called &#039;csc&#039;. Set the Display Name to &#039;Computer Science Club&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Realm settings ===&lt;br /&gt;
From the web UI, go to &#039;Realm Settings&#039;, click the Login tab, and disable &#039;Login with email&#039;.&lt;br /&gt;
&lt;br /&gt;
Now click on the &#039;Tokens&#039; tab. Set &#039;SSO Session Idle&#039; and &#039;SSO Session Max&#039; to 120 days each. You can optionally do this for the Master realm as well.&lt;br /&gt;
&lt;br /&gt;
Now click on the &#039;Email&#039; tab.&lt;br /&gt;
&lt;br /&gt;
* Set &#039;Host&#039; to &#039;mail.csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Set &#039;From Display Name&#039; to &#039;Keycloak&#039;.&lt;br /&gt;
* Set &#039;From&#039; to &#039;no-reply@csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Set &#039;Reply To Display Name&#039; to &#039;Systems Committee&#039;.&lt;br /&gt;
* Set &#039;Reply To&#039; to &#039;syscom@csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Set &#039;Envelope From&#039; to &#039;keycloak@csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Enable StartTLS.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Settings ===&lt;br /&gt;
Click on &#039;Authentication&#039; from the panel on the left-hand side.&lt;br /&gt;
&lt;br /&gt;
==== Flows ====&lt;br /&gt;
Click on the &#039;Flows&#039; tab and select the &#039;Browser&#039; flow from the dropdown. Create a copy called &#039;CSC Browser&#039; and make it look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Cookie (Alternative)&lt;br /&gt;
CSC Browser Forms (Alternative)&lt;br /&gt;
    Username Password Form (Required)&lt;br /&gt;
    CSC Membership Check (Conditional)&lt;br /&gt;
        Condition - User Attribute (Required)&lt;br /&gt;
        Deny Access (Required)&lt;br /&gt;
    OTP Form (Required)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The condition should be whether a user has the attribute &#039;shadowExpire&#039; set to &#039;1&#039;. Set the error message in &#039;Deny Access&#039; to something reasonable (this gets displayed to users).&lt;br /&gt;
&lt;br /&gt;
Screenshot:&lt;br /&gt;
[[File:Keycloak_CSC_Browser_Flow.png]]&lt;br /&gt;
&lt;br /&gt;
Select the &#039;First Broker Login&#039; flow and create a copy called &#039;CSC First Broker Login&#039;. This will be invoked when a user signs in with an Identity Provider, and the IdP user ID is not linked to a Keycloak user. Make the flow look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Review Profile (Disabled)&lt;br /&gt;
User Creation or Linking (Required)&lt;br /&gt;
    Detect Existing Broker User (Required)&lt;br /&gt;
    Automatically Set Existing User (Required)&lt;br /&gt;
CSC Membership Check (Conditional)&lt;br /&gt;
    Condition - User Attribute (Required)&lt;br /&gt;
    Deny Access (Required)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, create a new flow called &#039;CSC Browser - IdP post-login&#039;. This will be invoked when a user signs in with an IdP, and the IdP user ID has already been linked to a Keycloak user. Make it look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CSC Membership Check - IdP Post-login (Conditional)&lt;br /&gt;
    Condition - User Attribute (Membership expired - IdP post-login) (Required)&lt;br /&gt;
    Deny Access (Denied because membership expired - IdP post-login) (Required)&lt;br /&gt;
Allow Access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that the last step needs to be &#039;Allow Access&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Bindings ====&lt;br /&gt;
Click on the &#039;Bindings&#039; tab and set &#039;Browser Flow&#039; to &#039;CSC Browser&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Required Actions ====&lt;br /&gt;
Click on the &#039;Required Actions&#039; tab and &amp;lt;b&amp;gt;disable&amp;lt;/b&amp;gt; the following:&lt;br /&gt;
&lt;br /&gt;
* Update Password&lt;br /&gt;
* Update Profile&lt;br /&gt;
* Delete Account&lt;br /&gt;
&lt;br /&gt;
=== User Federation ===&lt;br /&gt;
Click on &#039;User Federation&#039; from the left-hand panel and select &#039;ldap&#039;. Configure it as follows:&lt;br /&gt;
&lt;br /&gt;
* Edit Mode: READ_ONLY&lt;br /&gt;
* Vendor: Other&lt;br /&gt;
* Username LDAP attribute: uid&lt;br /&gt;
* RDN LDAP attribute: uid&lt;br /&gt;
* UUID LDAP attribute: entryUUID&lt;br /&gt;
* User Object Classes: member&lt;br /&gt;
* Connection URL: ldaps://ldap1.csclub.uwaterloo.ca ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
* Users DN: ou=People,dc=csclub,dc=uwaterloo,dc=ca&lt;br /&gt;
* Custom User LDAP Filter: (objectClass=member)&lt;br /&gt;
* Search Scope: One Level&lt;br /&gt;
* Bind Type: none&lt;br /&gt;
&lt;br /&gt;
Under Sync Settings, enable Changed Users Full Sync. Set the Changed Users Sync Period to something reasonable (should be at least once a day).&lt;br /&gt;
&lt;br /&gt;
Click on Mappers, click &#039;email&#039;, and set the LDAP Attribute to &#039;mailLocalAddress&#039;. Also set the LDAP Attribute for &#039;First Name&#039; to &#039;givenName&#039;.&lt;br /&gt;
&lt;br /&gt;
Create a new mapper of type &#039;user-attribute-ldap-mapper&#039;. Set &#039;User Model Attribute&#039; and &#039;LDAP Attribute&#039; to &#039;shadowExpire&#039;. Enable &#039;Always Read Value From LDAP&#039;.&lt;br /&gt;
&lt;br /&gt;
Now click the &#039;Synchronize all users&#039; button from the main LDAP configuration page. &amp;lt;b&amp;gt;This will take a few minutes so be patient&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Identity Providers ===&lt;br /&gt;
We are going to use [[ADFS]] for identity brokering. The idea is to allow members to login using their CSC credentials &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; their UW credentials.&lt;br /&gt;
&lt;br /&gt;
==== SAML Passthrough ====&lt;br /&gt;
I created a monstrosity called [https://git.csclub.uwaterloo.ca/merenber/saml-passthrough saml-passthrough]. The idea is to protect a SAML IdP &amp;lt;i&amp;gt;behind another SAML IdP&amp;lt;/i&amp;gt; (ADFS). So basically SAML-inside-SAML.&lt;br /&gt;
&lt;br /&gt;
The reason why we need this is because we can&#039;t change the AssertionConsumerService endpoint URL which we originally submitted to IST (if we really wanted to, we could submit another form, but that requires assistance from a faculty member, and it&#039;s just a big PiTA). This also allows us to &amp;lt;i&amp;gt;multiplex&amp;lt;/i&amp;gt; ADFS information to multiple Keycloak realms, if necessary.&lt;br /&gt;
&lt;br /&gt;
Anywho, the instructions for setting it up are in the README (it&#039;s just a FastCGI application). It should be running on caffeine right now under /srv/saml-passthrough. It&#039;s configured to download SP metadata from Keycloak at startup, so if you update the SP certificate in Keycloak, make sure to restart the saml-passthrough service.&lt;br /&gt;
&lt;br /&gt;
Now, back to the Keycloak UI. Click &#039;Identity Providers&#039; from the left-hand side, and add a SAML provider. Set the following:&lt;br /&gt;
&lt;br /&gt;
* Alias: adfs&lt;br /&gt;
* Display Name: University of Waterloo (ADFS)&lt;br /&gt;
* First Login Flow: CSC First Login Flow&lt;br /&gt;
* Post Login Flow: CSC Browser - IdP post-login&lt;br /&gt;
* Sync Mode: legacy&lt;br /&gt;
* Service Provider Entity ID: https://keycloak.csclub.uwaterloo.ca/auth/realms/csc&lt;br /&gt;
* Single Sign-On Service URL: https://csclub.uwaterloo.ca/keycloak/saml/sso&lt;br /&gt;
* Principal Type: Attribute [Friendly Name]&lt;br /&gt;
* Principal Attribute: uid&lt;br /&gt;
* HTTP-POST Binding Response: ON&lt;br /&gt;
* Want AuthnRequests Signed: ON&lt;br /&gt;
* Want Assertions Signed: ON&lt;br /&gt;
* Validate Signature: ON&lt;br /&gt;
* Validating X509 certificates: download the content of https://csclub.uwaterloo.ca/keycloak/saml/metadata and copy and paste the value inside the &amp;lt;code&amp;gt;&amp;lt;X509Certificate&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
That X509 certificate will expire in &amp;lt;b&amp;gt;January 2032&amp;lt;/b&amp;gt;; before then, make sure you do the following:&lt;br /&gt;
&lt;br /&gt;
* create a new keypair in /srv/saml-passthrough on caffeine&lt;br /&gt;
* restart the saml-passthrough service&lt;br /&gt;
* update the &#039;Validating X509 certificates&#039; field in Keycloak&lt;br /&gt;
&lt;br /&gt;
Keycloak&#039;s SP certificate (which can be viewed from Realm Settings -&amp;gt; Keys -&amp;gt; Providers -&amp;gt; rsa-generated) will expire in &amp;lt;b&amp;gt;December 2031&amp;lt;/b&amp;gt;; before then, make sure you upload a new keypair (just choose &#039;rsa-generated&#039; from the &#039;Add keystore&#039; dropdown), then restart the saml-passthrough service on caffeine.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Here&#039;s a test OIDC application which you can use to verify that everything is working: https://www.keycloak.org/app/#url=https://keycloak.csclub.uwaterloo.ca/&amp;amp;realm=csc&amp;amp;client=test&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Keycloak&amp;diff=5424</id>
		<title>Keycloak</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Keycloak&amp;diff=5424"/>
		<updated>2025-09-16T01:05:24Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Testing */ fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are using [https://www.keycloak.org/ Keycloak] for web SSO (Single Sign-On). Clients may use Keycloak for authenticating users via SAML or OIDC (OpenID Connect).&lt;br /&gt;
&lt;br /&gt;
* Admin login: https://keycloak.csclub.uwaterloo.ca/auth/admin&lt;br /&gt;
* Regular user login: https://keycloak.csclub.uwaterloo.ca/auth/realms/csc/account&lt;br /&gt;
* OIDC Auto Discovery URL: https://keycloak.csclub.uwaterloo.ca/auth/realms/csc/.well-known/openid-configuration&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
OK so before we get started, there&#039;s this really useful feature in Keycloak called &amp;quot;Conditional user attribute&amp;quot; which allows you to create a flow which branches based on attributes a user may have. For some reason, this is enabled in the test suite for Keycloak, but is not available from the main application. So we&#039;re going to compile and inject it ourselves.&lt;br /&gt;
&lt;br /&gt;
Clone https://git.csclub.uwaterloo.ca/public/keycloak-spi and run &amp;lt;code&amp;gt;mvn clean package&amp;lt;/code&amp;gt;. This will create a JAR file called csc-keycloak-spi.jar in the target directory; upload this to somewhere where it can be easily downloaded, e.g. your www directory.&lt;br /&gt;
&lt;br /&gt;
== Database setup ==&lt;br /&gt;
Go to biloba or chamomile, run &amp;lt;code&amp;gt;mysql&amp;lt;/code&amp;gt;, and run the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER &#039;keycloak&#039; IDENTIFIED BY &#039;replace_this_password&#039;;    &lt;br /&gt;
CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;    &lt;br /&gt;
GRANT ALL PRIVILEGES ON keycloak.* TO &#039;keycloak&#039;;    &lt;br /&gt;
FLUSH PRIVILEGES;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kubernetes setup ==&lt;br /&gt;
We are running Keycloak on Kubernetes. This introduces some complications because it gets reverse proxied twice, and we also can&#039;t (or at least shouldn&#039;t) modify the filesystem of the Pod where it&#039;s running, since that Pod can get destroyed at any time. We still need to load that JAR file we just created, though, so we&#039;re going to place it into a PersistentVolume instead. We&#039;re going to do this by first creating a PersistentVolumeClaim, then claiming it in a temporary Pod which we&#039;ll use for shell access:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat &amp;lt;&amp;lt;EOF | kubectl apply -f    &lt;br /&gt;
apiVersion: v1    &lt;br /&gt;
kind: PersistentVolumeClaim    &lt;br /&gt;
metadata:    &lt;br /&gt;
  namespace: syscom    &lt;br /&gt;
  name: keycloak-spi-pvc    &lt;br /&gt;
spec:    &lt;br /&gt;
  storageClassName: cloudstack-storage    &lt;br /&gt;
  accessModes:    &lt;br /&gt;
    - ReadWriteOnce    &lt;br /&gt;
  resources:    &lt;br /&gt;
    requests:    &lt;br /&gt;
      storage: 5Mi    &lt;br /&gt;
---    &lt;br /&gt;
apiVersion: v1    &lt;br /&gt;
kind: Pod    &lt;br /&gt;
metadata:    &lt;br /&gt;
  namespace: syscom    &lt;br /&gt;
  name: temp-pod    &lt;br /&gt;
spec:    &lt;br /&gt;
  containers:    &lt;br /&gt;
    - name: temp    &lt;br /&gt;
      image: alpine    &lt;br /&gt;
      volumeMounts:    &lt;br /&gt;
        - mountPath: &amp;quot;/data&amp;quot;    &lt;br /&gt;
          name: keycloak-spi-pv    &lt;br /&gt;
      stdin: true    &lt;br /&gt;
      stdinOnce: true    &lt;br /&gt;
      tty: true    &lt;br /&gt;
  volumes:    &lt;br /&gt;
    - name: keycloak-spi-pv    &lt;br /&gt;
      persistentVolumeClaim:    &lt;br /&gt;
        claimName: keycloak-spi-pvc&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run &amp;lt;code&amp;gt;kubectl -n syscom get pods&amp;lt;/code&amp;gt; a few times to check if the pod is ready; once it is, attach to it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n syscom exec -it temp-pod -- sh&lt;br /&gt;
cd /data&lt;br /&gt;
mkdir keycloak-spi&lt;br /&gt;
chmod a+w keycloak-spi&lt;br /&gt;
cd keycloak-spi&lt;br /&gt;
wget https://csclub.uwaterloo.ca/~merenber/csc-keycloak-spi.jar&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now delete the pod since we don&#039;t need it anymore:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n syscom delete pod temp-pod&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Create some secrets (use the MySQL password which you chose earlier):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n syscom create secret generic keycloak-secret \&lt;br /&gt;
  --from-literal=DB_USER=some_user \&lt;br /&gt;
  --from-literal=DB_PASSWORD=some_password \&lt;br /&gt;
  --from-literal=KEYCLOAK_USER=some_user \&lt;br /&gt;
  --from-literal=KEYCLOAK_PASSWORD=some_password&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now apply the main manifest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl apply -f https://git.csclub.uwaterloo.ca/cloud/manifests/raw/branch/master/keycloak.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DNS setup ==&lt;br /&gt;
From Infoblox, make keycloak.csclub.uwaterloo.ca a CNAME for rr-public-cloud.csclub.uwaterloo.ca; that record points to biloba and chamomile, which know how to reverse proxy requests to Kubernetes.&lt;br /&gt;
&lt;br /&gt;
== NGINX setup ==&lt;br /&gt;
Pretty standard stuff:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server {&lt;br /&gt;
  listen 80;&lt;br /&gt;
  listen [::]:80;&lt;br /&gt;
  server_name keycloak.csclub.uwaterloo.ca;&lt;br /&gt;
  return 301 https://$host$request_uri;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
server {&lt;br /&gt;
  listen 443 ssl http2;&lt;br /&gt;
  listen [::]:443 ssl http2;&lt;br /&gt;
  server_name keycloak.csclub.uwaterloo.ca;&lt;br /&gt;
  ssl_certificate /etc/ssl/private/csclub.uwaterloo.ca.chain;&lt;br /&gt;
  ssl_certificate_key /etc/ssl/private/csclub.uwaterloo.ca.key;&lt;br /&gt;
  &lt;br /&gt;
  location / {&lt;br /&gt;
    proxy_pass http://k8s;&lt;br /&gt;
  }&lt;br /&gt;
  include proxy_params;&lt;br /&gt;
&lt;br /&gt;
  access_log /var/log/nginx/keycloak-access.log;&lt;br /&gt;
  error_log /var/log/nginx/keycloak-error.log;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also make sure you have the following snippet in /etc/nginx/proxy_params:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Increase buffer size&lt;br /&gt;
# See https://ma.ttias.be/nginx-proxy-upstream-sent-big-header-reading-response-header-upstream/&lt;br /&gt;
proxy_buffer_size 128k;&lt;br /&gt;
proxy_buffers 4 256k;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Don&#039;t forget to enable the site and reload NGINX on both chamomile and biloba.&lt;br /&gt;
&lt;br /&gt;
== Web UI setup ==&lt;br /&gt;
If all went well, you should now be able to visit https://keycloak.csclub.uwaterloo.ca from your browser.&lt;br /&gt;
Create a new realm called &#039;csc&#039;. Set the Display Name to &#039;Computer Science Club&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Realm settings ===&lt;br /&gt;
From the web UI, go to &#039;Realm Settings&#039;, click the Login tab, and disable &#039;Login with email&#039;.&lt;br /&gt;
&lt;br /&gt;
Now click on the &#039;Tokens&#039; tab. Set &#039;SSO Session Idle&#039; and &#039;SSO Session Max&#039; to 120 days each. You can optionally do this for the Master realm as well.&lt;br /&gt;
&lt;br /&gt;
Now click on the &#039;Email&#039; tab.&lt;br /&gt;
&lt;br /&gt;
* Set &#039;Host&#039; to &#039;mail.csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Set &#039;From Display Name&#039; to &#039;Keycloak&#039;.&lt;br /&gt;
* Set &#039;From&#039; to &#039;no-reply@csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Set &#039;Reply To Display Name&#039; to &#039;Systems Committee&#039;.&lt;br /&gt;
* Set &#039;Reply To&#039; to &#039;syscom@csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Set &#039;Envelope From&#039; to &#039;keycloak@csclub.uwaterloo.ca&#039;.&lt;br /&gt;
* Enable StartTLS.&lt;br /&gt;
&lt;br /&gt;
=== Authentication Settings ===&lt;br /&gt;
Click on &#039;Authentication&#039; from the panel on the left-hand side.&lt;br /&gt;
&lt;br /&gt;
==== Flows ====&lt;br /&gt;
Click on the &#039;Flows&#039; tab and select the &#039;Browser&#039; flow from the dropdown. Create a copy called &#039;CSC Browser&#039; and make it look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Cookie (Alternative)&lt;br /&gt;
CSC Browser Forms (Alternative)&lt;br /&gt;
    Username Password Form (Required)&lt;br /&gt;
    CSC Membership Check (Conditional)&lt;br /&gt;
        Condition - User Attribute (Required)&lt;br /&gt;
        Deny Access (Required)&lt;br /&gt;
    OTP Form (Required)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The condition should be whether a user has the attribute &#039;shadowExpire&#039; set to &#039;1&#039;. Set the error message in &#039;Deny Access&#039; to something reasonable (this gets displayed to users).&lt;br /&gt;
&lt;br /&gt;
Screenshot:&lt;br /&gt;
[[File:Keycloak_CSC_Browser_Flow.png]]&lt;br /&gt;
&lt;br /&gt;
Select the &#039;First Broker Login&#039; flow and create a copy called &#039;CSC First Broker Login&#039;. This will be invoked when a user signs in with an Identity Provider, and the IdP user ID is not linked to a Keycloak user. Make the flow look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Review Profile (Disabled)&lt;br /&gt;
User Creation or Linking (Required)&lt;br /&gt;
    Detect Existing Broker User (Required)&lt;br /&gt;
    Automatically Set Existing User (Required)&lt;br /&gt;
CSC Membership Check (Conditional)&lt;br /&gt;
    Condition - User Attribute (Required)&lt;br /&gt;
    Deny Access (Required)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, create a new flow called &#039;CSC Browser - IdP post-login&#039;. This will be invoked when a user signs in with an IdP, and the IdP user ID has already been linked to a Keycloak user. Make it look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CSC Membership Check - IdP Post-login (Conditional)&lt;br /&gt;
    Condition - User Attribute (Membership expired - IdP post-login) (Required)&lt;br /&gt;
    Deny Access (Denied because membership expired - IdP post-login) (Required)&lt;br /&gt;
Allow Access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that the last step needs to be &#039;Allow Access&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Bindings ====&lt;br /&gt;
Click on the &#039;Bindings&#039; tab and set &#039;Browser Flow&#039; to &#039;CSC Browser&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Required Actions ====&lt;br /&gt;
Click on the &#039;Required Actions&#039; tab and &amp;lt;b&amp;gt;disable&amp;lt;/b&amp;gt; the following:&lt;br /&gt;
&lt;br /&gt;
* Update Password&lt;br /&gt;
* Update Profile&lt;br /&gt;
* Delete Account&lt;br /&gt;
&lt;br /&gt;
=== User Federation ===&lt;br /&gt;
Click on &#039;User Federation&#039; from the left-hand panel and select &#039;ldap&#039;. Configure it as follows:&lt;br /&gt;
&lt;br /&gt;
* Edit Mode: READ_ONLY&lt;br /&gt;
* Vendor: Other&lt;br /&gt;
* Username LDAP attribute: uid&lt;br /&gt;
* RDN LDAP attribute: uid&lt;br /&gt;
* UUID LDAP attribute: entryUUID&lt;br /&gt;
* User Object Classes: member&lt;br /&gt;
* Connection URL: ldaps://ldap1.csclub.uwaterloo.ca ldaps://ldap2.csclub.uwaterloo.ca&lt;br /&gt;
* Users DN: ou=People,dc=csclub,dc=uwaterloo,dc=ca&lt;br /&gt;
* Custom User LDAP Filter: (objectClass=member)&lt;br /&gt;
* Search Scope: One Level&lt;br /&gt;
* Bind Type: none&lt;br /&gt;
&lt;br /&gt;
Under Sync Settings, enable Changed Users Full Sync. Set the Changed Users Sync Period to something reasonable (should be at least once a day).&lt;br /&gt;
&lt;br /&gt;
Click on Mappers, click &#039;email&#039;, and set the LDAP Attribute to &#039;mailLocalAddress&#039;. Also set the LDAP Attribute for &#039;First Name&#039; to &#039;givenName&#039;.&lt;br /&gt;
&lt;br /&gt;
Create a new mapper of type &#039;user-attribute-ldap-mapper&#039;. Set &#039;User Model Attribute&#039; and &#039;LDAP Attribute&#039; to &#039;shadowExpire&#039;. Enable &#039;Always Read Value From LDAP&#039;.&lt;br /&gt;
&lt;br /&gt;
Now click the &#039;Synchronize all users&#039; button from the main LDAP configuration page. &amp;lt;b&amp;gt;This will take a few minutes so be patient&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Identity Providers ===&lt;br /&gt;
We are going to use [[ADFS]] for identity brokering. The idea is to allow members to login using their CSC credentials &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; their UW credentials.&lt;br /&gt;
&lt;br /&gt;
==== SAML Passthrough ====&lt;br /&gt;
I created a monstrosity called [https://git.csclub.uwaterloo.ca/merenber/saml-passthrough saml-passthrough]. The idea is to protect a SAML IdP &amp;lt;i&amp;gt;behind another SAML IdP&amp;lt;/i&amp;gt; (ADFS). So basically SAML-inside-SAML.&lt;br /&gt;
&lt;br /&gt;
The reason why we need this is because we can&#039;t change the AssertionConsumerService endpoint URL which we originally submitted to IST (if we really wanted to, we could submit another form, but that requires assistance from a faculty member, and it&#039;s just a big PiTA). This also allows us to &amp;lt;i&amp;gt;multiplex&amp;lt;/i&amp;gt; ADFS information to multiple Keycloak realms, if necessary.&lt;br /&gt;
&lt;br /&gt;
Anywho, the instructions for setting it up are in the README (it&#039;s just a FastCGI application). It should be running on caffeine right now under /srv/saml-passthrough. It&#039;s configured to download SP metadata from Keycloak at startup, so if you update the SP certificate in Keycloak, make sure to restart the saml-passthrough service.&lt;br /&gt;
&lt;br /&gt;
Now, back to the Keycloak UI. Click &#039;Identity Providers&#039; from the left-hand side, and add a SAML provider. Set the following:&lt;br /&gt;
&lt;br /&gt;
* Alias: adfs&lt;br /&gt;
* Display Name: University of Waterloo (ADFS)&lt;br /&gt;
* First Login Flow: CSC First Login Flow&lt;br /&gt;
* Post Login Flow: CSC Browser - IdP post-login&lt;br /&gt;
* Sync Mode: legacy&lt;br /&gt;
* Service Provider Entity ID: https://keycloak.csclub.uwaterloo.ca/auth/realms/csc&lt;br /&gt;
* Single Sign-On Service URL: https://csclub.uwaterloo.ca/keycloak/saml/sso&lt;br /&gt;
* Principal Type: Attribute [Friendly Name]&lt;br /&gt;
* Principal Attribute: uid&lt;br /&gt;
* HTTP-POST Binding Response: ON&lt;br /&gt;
* Want AuthnRequests Signed: ON&lt;br /&gt;
* Want Assertions Signed: ON&lt;br /&gt;
* Validate Signature: ON&lt;br /&gt;
* Validating X509 certificates: download the content of https://csclub.uwaterloo.ca/keycloak/saml/metadata and copy and paste the value inside the &amp;lt;code&amp;gt;&amp;lt;X509Certificate&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
That X509 certificate will expire in &amp;lt;b&amp;gt;January 2032&amp;lt;/b&amp;gt;; before then, make sure you do the following:&lt;br /&gt;
&lt;br /&gt;
* create a new keypair in /srv/saml-passthrough on caffeine&lt;br /&gt;
* restart the saml-passthrough service&lt;br /&gt;
* update the &#039;Validating X509 certificates&#039; field in Keycloak&lt;br /&gt;
&lt;br /&gt;
Keycloak&#039;s SP certificate (which can be viewed from Realm Settings -&amp;gt; Keys -&amp;gt; Providers -&amp;gt; rsa-generated) will expire in &amp;lt;b&amp;gt;December 2031&amp;lt;/b&amp;gt;; before then, make sure you upload a new keypair (just choose &#039;rsa-generated&#039; from the &#039;Add keystore&#039; dropdown), then restart the saml-passthrough service on caffeine.&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Here&#039;s a test OIDC application which you can use to verify that everything is working: https://www.keycloak.org/app/#url=https://keycloak.csclub.uwaterloo.ca/&amp;amp;realm=csc&amp;amp;client=test&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=User:K95ma&amp;diff=5421</id>
		<title>User:K95ma</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=User:K95ma&amp;diff=5421"/>
		<updated>2025-09-13T01:54:11Z</updated>

		<summary type="html">&lt;p&gt;K95ma: Created page with &amp;quot;Termcom guy&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Termcom guy&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=LDAP&amp;diff=5420</id>
		<title>LDAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=LDAP&amp;diff=5420"/>
		<updated>2025-09-10T00:58:05Z</updated>

		<summary type="html">&lt;p&gt;K95ma: /* Querying LDAP */ fix command&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We use [http://www.openldap.org/ OpenLDAP] for directory services. Our primary LDAP server is [[Machine_List#auth1|auth1]] and our secondary LDAP server is [[Machine_List#auth2|auth2]].&lt;br /&gt;
&lt;br /&gt;
=== ehashman&#039;s Guide to Setting up OpenLDAP on Debian ===&lt;br /&gt;
&lt;br /&gt;
Welcome to my nightmare.&lt;br /&gt;
&lt;br /&gt;
==== What is LDAP? ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;LDAP:&#039;&#039;&#039; Lightweight Directory Access Protocol&lt;br /&gt;
&lt;br /&gt;
An open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over an Internet Protocol (IP) network. — [https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol Wikipedia: LDAP]&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
In this case, &amp;amp;quot;directory&amp;amp;quot; refers to the user directory, like on an old-school Rolodex. Many groups use LDAP to maintain their user directory, including the University (the &amp;amp;quot;WatIAM&amp;amp;quot; identity management system), the Computer Science Club, and even the UW Amateur Radio Club.&lt;br /&gt;
&lt;br /&gt;
This is a guide documenting how to set up LDAP on a Debian Linux system.&lt;br /&gt;
&lt;br /&gt;
==== First steps ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Ensure that openldap is installed on the machine:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# apt-get install slapd ldap-utils&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Debian will do a lot of magic and set up a skeleton LDAP server and get it running. We need to configure that further.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Let&#039;s set up logging before we forget. Create the following files in &amp;lt;code&amp;gt;/var/log&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# mkdir /var/log/ldap&lt;br /&gt;
# touch /var/log/ldap.log&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Set ownership correctly:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# chown openldap:openldap /var/log/ldap&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Set up rsyslog to dump the LDAP logs into &amp;lt;code&amp;gt;/var/log/ldap.log&amp;lt;/code&amp;gt; by adding the following lines:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# vim /etc/rsyslog.conf&lt;br /&gt;
...&lt;br /&gt;
# Grab ldap logs, don&#039;t duplicate in syslog&lt;br /&gt;
local4.*                        /var/log/ldap.log&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Set up log rotation for these by creating the file [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/logrotate.d.ldap &amp;lt;code&amp;gt;/etc/logrotate.d/ldap&amp;lt;/code&amp;gt;] with the following contents:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;/var/log/ldap/*log {&lt;br /&gt;
    weekly&lt;br /&gt;
    missingok&lt;br /&gt;
    rotate 1000&lt;br /&gt;
    compress&lt;br /&gt;
    delaycompress&lt;br /&gt;
    notifempty&lt;br /&gt;
    create 0640 openldap adm&lt;br /&gt;
    postrotate&lt;br /&gt;
        if [ -f /var/run/slapd/slapd.pid ]; then&lt;br /&gt;
            /etc/init.d/slapd restart &amp;amp;gt;/dev/null 2&amp;amp;gt;&amp;amp;amp;1&lt;br /&gt;
        fi&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/ldap.log {&lt;br /&gt;
    weekly&lt;br /&gt;
    missingok&lt;br /&gt;
    rotate 24&lt;br /&gt;
    compress&lt;br /&gt;
    delaycompress&lt;br /&gt;
    notifempty&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;As of OpenLDAP 2.4, it doesn&#039;t actually create a config file for us. Apparently, this is a &amp;amp;quot;feature&amp;amp;quot;: LDAP maintainers think we should want to set this up via dynamic queries. We don&#039;t, so the first thing we need is our [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/slapd.conf &amp;lt;code&amp;gt;slapd.conf&amp;lt;/code&amp;gt;] file.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Building &amp;lt;code&amp;gt;slapd.conf&amp;lt;/code&amp;gt; from scratch =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Get a copy to work with:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# scp uid@auth1.csclub.uwaterloo.ca:/etc/ldap/slapd.conf /etc/ldap/  ## you need CSC root for this&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You&#039;ll want to comment out the TLS lines, and anything referring to Kerberos and access for now. You&#039;ll also want to comment out lines specifically referring to syscom and office staff.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you remove the reference to &amp;lt;code&amp;gt;nonMemberTerm&amp;lt;/code&amp;gt; as an index, as we&#039;re going to remove this field.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;You&#039;ll also need to generate a root password for the LDAP to bootstrap auth, like so:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# slappasswd&lt;br /&gt;
New password: &lt;br /&gt;
Re-enter new password:&lt;br /&gt;
{SSHA}longhash&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Add this line below &amp;lt;code&amp;gt;rootdn&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;slapd.conf&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;rootpw          {SSHA}longhash&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now we want to edit all instances of &amp;amp;quot;csclub&amp;amp;quot; to be &amp;amp;quot;wics&amp;amp;quot; instead, e.g.:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;suffix     &amp;amp;quot;dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
rootdn     &amp;amp;quot;cn=root,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Next, we need to grab all the relevant schemas:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;scp -r uid@auth1.csclub.uwaterloo.ca:/etc/ldap/schema/ /tmp/schemas&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use the include directives to help you find the ones you need. I noticed we were missing &amp;lt;code&amp;gt;sudo.schema&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;csc.schema&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;rfc2307bis.schema&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open up the [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/csc.schema &amp;lt;code&amp;gt;csc.schema&amp;lt;/code&amp;gt;] for editing; we&#039;re not using it verbatim. Remove the attributes &amp;lt;code&amp;gt;studentid&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;nonMemberTerm&amp;lt;/code&amp;gt; and the objectclass &amp;lt;code&amp;gt;club&amp;lt;/code&amp;gt;. Also make sure you change the OID so we don&#039;t clash with the CSC. Because we didn&#039;t want to go through the process of requesting a [http://pen.iana.org/pen/PenApplication.page PEN number], we chose arbitrarily to use 26338, which belongs to IWICS Inc.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;We also need to can the auto-generated config files, so do that:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# rm -rf /etc/openldap/slapd.d/*&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Also nuke the auto-generated database:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# rm /var/lib/ldap/__db.*&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Configure the database:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# cp /usr/share/slapd/DB_CONFIG /var/lib/ldap/&lt;br /&gt;
# chown openldap:openldap /var/lib/ldap/DB_CONFIG &amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now we can generate the new configuration files:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;And ensure that the permissions are all set correctly, lest this break something:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# chown -R openldap:openldap /etc/ldap/slapd.d&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;If at this point you get a nasty error, such as&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;5657d4db hdb_db_open: database &amp;amp;quot;dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;: db_open(/var/lib/ldap/id2entry.bdb) failed: No such file or directory (2).&lt;br /&gt;
5657d4db backend_startup_one (type=hdb, suffix=&amp;amp;quot;dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;): bi_db_open failed! (2)&lt;br /&gt;
slap_startup failed (test would succeed using the -u switch)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Just try restarting slapd, and see if that fixes the problem:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# service slapd stop&lt;br /&gt;
# service slapd start&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Congratulations! Your LDAP service is now configured and running.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Getting TLS Up and Running ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now that we have our LDAP service, we&#039;ll want to be able to serve encrypted traffic. This is especially important for any remote access, since binding to LDAP (i.e. sending it a password for auth) occurs over plaintext, and we don&#039;t want to leak our admin password.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Our first step is to copy our SSL certificates into the correct places. Public ones go into &amp;lt;code&amp;gt;/etc/ssl/certs/&amp;lt;/code&amp;gt; and private ones go into &amp;lt;code&amp;gt;/etc/ssl/private/&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Since the LDAP daemon needs to be able to read our private cert, we need to grant LDAP access to the private folder:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# chgrp openldap /etc/ssl/private &lt;br /&gt;
# chmod g+x /etc/ssl/private&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Next, uncomment the TLS-related settings in &amp;lt;code&amp;gt;slapd.conf&amp;lt;/code&amp;gt;. These are &amp;lt;code&amp;gt;TLSCertificateFile&amp;lt;/code&amp;gt; (the public cert), &amp;lt;code&amp;gt;TLSCertificateKeyFile&amp;lt;/code&amp;gt; (the private key), &amp;lt;code&amp;gt;TLSCACertificateFile&amp;lt;/code&amp;gt; (the intermediate CA cert), and &amp;lt;code&amp;gt;TLSVerifyClient&amp;lt;/code&amp;gt; (set to &amp;amp;quot;allow&amp;amp;quot;).&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# enable TLS connections&lt;br /&gt;
TLSCertificateFile      /etc/ssl/certs/wics-wildcard.crt&lt;br /&gt;
TLSCertificateKeyFile   /etc/ssl/private/wics-wildcard.key&lt;br /&gt;
&lt;br /&gt;
# enable TLS client authentication&lt;br /&gt;
TLSCACertificateFile    /etc/ssl/certs/GlobalSign_Intermediate_Root_SHA256_G2.pem&lt;br /&gt;
TLSVerifyClient         allow&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Update all your LDAP settings:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# rm -rf /etc/openldap/slapd.d/*&lt;br /&gt;
# slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/&lt;br /&gt;
# chown -R openldap:openldap /etc/ldap/slapd.d&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;And last, ensure that LDAP will actually serve &amp;lt;code&amp;gt;ldaps://&amp;lt;/code&amp;gt; by modifying the init script variables in &amp;lt;code&amp;gt;/etc/default/&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# vim /etc/default/slapd&lt;br /&gt;
...&lt;br /&gt;
SLAPD_SERVICES=&amp;amp;quot;ldap:/// ldapi:/// ldaps:///&amp;amp;quot;&lt;br /&gt;
...&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now you can restart the LDAP server:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# service slapd restart&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;And assuming this is successful, test to ensure LDAP is serving on port 636 for &amp;lt;code&amp;gt;ldaps://&amp;lt;/code&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# netstat -ntaup&lt;br /&gt;
Active Internet connections (servers and established)&lt;br /&gt;
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name&lt;br /&gt;
tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN      22847/slapd     &lt;br /&gt;
tcp        0      0 0.0.0.0:636             0.0.0.0:*               LISTEN      22847/slapd &amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Populating the Database ====&lt;br /&gt;
&lt;br /&gt;
Now you&#039;ll need to start adding objects to the database. While we&#039;ll want to mostly do this programmatically, there are a few entries we&#039;ll need to bootstrap.&lt;br /&gt;
&lt;br /&gt;
===== Root Entries =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Start by creating a file [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/tree.ldif &amp;lt;code&amp;gt;tree.ldif&amp;lt;/code&amp;gt;] to create a few necessary &amp;amp;quot;roots&amp;amp;quot; in our LDAP tree, with the contents:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;dn: dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: dcObject&lt;br /&gt;
objectClass: organization&lt;br /&gt;
o: Women in Computer Science&lt;br /&gt;
dc: wics&lt;br /&gt;
&lt;br /&gt;
dn: ou=People,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: organizationalUnit&lt;br /&gt;
ou: People&lt;br /&gt;
&lt;br /&gt;
dn: ou=Group,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: organizationalUnit&lt;br /&gt;
ou: Group&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now attempt an LDAP add, using the password you set earlier:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# ldapadd -cxWD cn=root,dc=wics,dc=uwaterloo,dc=ca -f tree.ldif&lt;br /&gt;
Enter LDAP Password:&lt;br /&gt;
adding new entry &amp;amp;quot;dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding new entry &amp;amp;quot;ou=People,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding new entry &amp;amp;quot;ou=Group,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Test that everything turned out okay, by performing a query of the entire database:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# ldapsearch -x -h localhost&lt;br /&gt;
# extended LDIF&lt;br /&gt;
#&lt;br /&gt;
# LDAPv3&lt;br /&gt;
# base &amp;amp;lt;dc=wics,dc=uwaterloo,dc=ca&amp;amp;gt; (default) with scope subtree&lt;br /&gt;
# filter: (objectclass=*)&lt;br /&gt;
# requesting: ALL&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
# wics.uwaterloo.ca&lt;br /&gt;
dn: dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: dcObject&lt;br /&gt;
objectClass: organization&lt;br /&gt;
o: Women in Computer Science&lt;br /&gt;
dc: wics&lt;br /&gt;
&lt;br /&gt;
# People, wics.uwaterloo.ca&lt;br /&gt;
dn: ou=People,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: organizationalUnit&lt;br /&gt;
ou: People&lt;br /&gt;
&lt;br /&gt;
# Group, wics.uwaterloo.ca&lt;br /&gt;
dn: ou=Group,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: organizationalUnit&lt;br /&gt;
ou: Group&lt;br /&gt;
&lt;br /&gt;
# search result&lt;br /&gt;
search: 2&lt;br /&gt;
result: 0 Success&lt;br /&gt;
&lt;br /&gt;
# numResponses: 4&lt;br /&gt;
# numEntries: 3&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Users and Groups =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Next, add users to track the current GID and UID. This will save us from querying the entire database every time we make a new user or group. Create this file, [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/nextxid.ldif &amp;lt;code&amp;gt;nextxid.ldif&amp;lt;/code&amp;gt;]:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;dn: uid=nextuid,ou=People,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
cn: nextuid&lt;br /&gt;
objectClass: account&lt;br /&gt;
objectClass: posixAccount&lt;br /&gt;
objectClass: top&lt;br /&gt;
uidNumber: 20000&lt;br /&gt;
gidNumber: 20000&lt;br /&gt;
homeDirectory: /dev/null&lt;br /&gt;
&lt;br /&gt;
dn: cn=nextgid,ou=Group,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: group&lt;br /&gt;
objectClass: posixGroup&lt;br /&gt;
objectClass: top&lt;br /&gt;
gidNumber: 10000&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;You&#039;ll see here that our first GID is 10000 and our first UID is 20000.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now add them, like you did with the roots of the tree:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# ldapadd -cxWD cn=root,dc=wics,dc=uwaterloo,dc=ca -f nextxid.ldif&lt;br /&gt;
Enter LDAP Password:&lt;br /&gt;
adding new entry &amp;amp;quot;uid=nextuid,ou=People,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding new entry &amp;amp;quot;cn=nextgid,ou=Group,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Special &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt; Entries =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;We also need to add a sudoers OU with a defaults object for default sudo settings. We also need entries for syscom, such that members of the syscom group can use sudo on all hosts, and for termcom, whose members can use sudo on only the office terminals. Call this one [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/sudoers.ldif &amp;lt;code&amp;gt;sudoers.ldif&amp;lt;/code&amp;gt;]:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;dn: ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: organizationalUnit&lt;br /&gt;
ou: SUDOers&lt;br /&gt;
&lt;br /&gt;
dn: cn=defaults,ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: top&lt;br /&gt;
objectClass: sudoRole&lt;br /&gt;
cn: defaults&lt;br /&gt;
sudoOption: !lecture&lt;br /&gt;
sudoOption: env_reset&lt;br /&gt;
sudoOption: listpw=never&lt;br /&gt;
sudoOption: mailto=&amp;amp;quot;wics-sys@lists.uwaterloo.ca&amp;amp;quot;&lt;br /&gt;
sudoOption: shell_noargs&lt;br /&gt;
&lt;br /&gt;
dn: cn=%syscom,ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: top&lt;br /&gt;
objectClass: sudoRole&lt;br /&gt;
cn: %syscom&lt;br /&gt;
sudoUser: %syscom&lt;br /&gt;
sudoHost: ALL&lt;br /&gt;
sudoCommand: ALL&lt;br /&gt;
sudoRunAsUser: ALL&lt;br /&gt;
&lt;br /&gt;
dn: cn=%termcom,ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&lt;br /&gt;
objectClass: top&lt;br /&gt;
objectClass: sudoRole&lt;br /&gt;
cn: %termcom&lt;br /&gt;
sudoUser: %termcom&lt;br /&gt;
sudoHost: honk&lt;br /&gt;
sudoHost: hiss&lt;br /&gt;
sudoHost: gosling&lt;br /&gt;
sudoCommand: ALL&lt;br /&gt;
sudoRunAsUser: ALL&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Now add them:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# ldapadd -cxWD cn=root,dc=wics,dc=uwaterloo,dc=ca -f sudoers.ldif&lt;br /&gt;
Enter LDAP Password:&lt;br /&gt;
adding new entry &amp;amp;quot;ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding new entry &amp;amp;quot;cn=defaults,ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding new entry &amp;amp;quot;cn=%syscom,ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&lt;br /&gt;
&lt;br /&gt;
adding new entry &amp;amp;quot;cn=%termcom,ou=SUDOers,dc=wics,dc=uwaterloo,dc=ca&amp;amp;quot;&amp;lt;/pre&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;Last, add some special local groups via [https://git.uwaterloo.ca/wics/documentation/blob/master/ldap/local-groups.ldif &amp;lt;code&amp;gt;local-groups.ldif&amp;lt;/code&amp;gt;]:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# ldapadd -cxWD cn=root,dc=wics,dc=uwaterloo,dc=ca -f local-groups.ldif&amp;lt;/pre&amp;gt;&lt;br /&gt;
The local groups are special because they usually are present on all systems, but we want to be able to add users to them at the LDAP level. For instance, the audio group controls access to sound equipment, and the adm group controls log read access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;p&amp;gt;That&#039;s all the entries we have to add manually! Now we can use software for the rest. See [[weo|&amp;lt;code&amp;gt;ceo&amp;lt;/code&amp;gt;]] for more details.&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Querying LDAP ===&lt;br /&gt;
&lt;br /&gt;
There are many tools available for issuing LDAP queries. Queries should be issued to &amp;lt;tt&amp;gt;ldap1.csclub.uwaterloo.ca&amp;lt;/tt&amp;gt;. The search base you almost certainly want is &amp;lt;tt&amp;gt;dc=csclub,dc=uwaterloo,dc=ca&amp;lt;/tt&amp;gt;. Read access is available without authentication; [[Kerberos]] is used to authenticate commands which require it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 ldapsearch -x -H ldap://ldap1.csclub.uwaterloo.ca -b dc=csclub,dc=uwaterloo,dc=ca uid=ctdalek&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;-x&amp;lt;/tt&amp;gt; option causes &amp;lt;tt&amp;gt;ldapsearch&amp;lt;/tt&amp;gt; to switch to simple authentication rather than trying to authenticate via SASL (which will fail if you do not have a Kerberos ticket).&lt;br /&gt;
&lt;br /&gt;
The University LDAP server (uwldap.uwaterloo.ca) can also be queried like this. Again, use &amp;quot;simple authentication&amp;quot; as read access is available (from on campus) without authentication. SASL authentication will fail without additional parameters.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 ldapsearch -x -H ldap://uwldap.uwaterloo.ca -b dc=uwaterloo,dc=ca &amp;quot;cn=Prabhakar Ragde&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Replication ===&lt;br /&gt;
&lt;br /&gt;
While &amp;lt;tt&amp;gt;ldap1.csclub.uwaterloo.ca&amp;lt;/tt&amp;gt; ([[Machine_List#auth1|auth1]]) is the LDAP master, an up-to-date replica is available on &amp;lt;tt&amp;gt;ldap2.csclub.uwaterloo.ca&amp;lt;/tt&amp;gt; ([[Machine_List#auth2|auth2]]).&lt;br /&gt;
&lt;br /&gt;
In order to replicate changes from the master, the slave maintains an authenticated connection to the master which provides it with full read access to all changes.&lt;br /&gt;
&lt;br /&gt;
Specifically, &amp;lt;tt&amp;gt;/etc/systemd/system/k5start-slapd.service&amp;lt;/tt&amp;gt; maintains an active Kerberos ticket for &amp;lt;tt&amp;gt;ldap/auth2.csclub.uwaterloo.ca@CSCLUB.UWATERLOO.CA&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;/var/run/slapd/krb5cc&amp;lt;/tt&amp;gt;. This is then used to authenticate the slave to the server, who maps this principal to &amp;lt;tt&amp;gt;cn=ldap-slave,dc=csclub,dc=uwaterloo,dc=ca&amp;lt;/tt&amp;gt;, which in turn has full read privileges.&lt;br /&gt;
&lt;br /&gt;
In the event of master failure, all hosts should fail LDAP reads seamlessly over to the slave.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Modifying LDAP entry ===&lt;br /&gt;
&lt;br /&gt;
Editing entries can be easily done with &amp;lt;code&amp;gt;ldapvi&amp;lt;/code&amp;gt;. First search for the entry using &amp;lt;code&amp;gt;ldapsearch&amp;lt;/code&amp;gt; like above, and change &amp;lt;code&amp;gt;ldapsearch -x&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;ldapvi -Y GSSAPI&amp;lt;/code&amp;gt; to make your edits.&lt;br /&gt;
&lt;br /&gt;
Note that if your &amp;lt;tt&amp;gt;EDITOR&amp;lt;/tt&amp;gt; enviroment is set to something not avaliable it will give out errors like&lt;br /&gt;
&lt;br /&gt;
 error (misc.c line 180): No such file or directory&lt;br /&gt;
 editor died&lt;br /&gt;
 error (ldapvi.c line 83): No such file or directory&lt;br /&gt;
&lt;br /&gt;
This can be fixed by something like&lt;br /&gt;
&lt;br /&gt;
 EDITOR=vi ldapvi ******&lt;br /&gt;
&lt;br /&gt;
==== Changing a user&#039;s username ====&lt;br /&gt;
&lt;br /&gt;
Only a member of the Systems Committee can change a user&#039;s username. &#039;&#039;&#039;At all times, a user&#039;s username must match the user&#039;s username in WatIAM.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
All changes to an account MUST be done in person so that identity can be confirmed. If a member cannot attend in person, then an alternate method of identity verification may be chosen by the Systems Administrator.&lt;br /&gt;
&lt;br /&gt;
# Edit entries in LDAP (&amp;lt;code&amp;gt;ldapvi -Y GSSAPI&amp;lt;/code&amp;gt;)&lt;br /&gt;
#* Find and replace the user&#039;s old username with the new one (&amp;lt;code&amp;gt;%s/$OLD/$NEW/g&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Change the user&#039;s Kerberos principal (on auth1 using &amp;lt;code&amp;gt;kadmin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;renprinc $OLD $NEW&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Move the user&#039;s home directory (on phosphoric-acid, &amp;lt;code&amp;gt;mv /users/$OLD /users/$NEW&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Modify the user&#039;s ~/.forward file if their old username is in it.&lt;br /&gt;
# Change the user&#039;s csc-general (and csc-industry, if subscribed) email address for &amp;lt;code&amp;gt;$OLD@csclub.uwaterloo.ca&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;$NEW@csclub.uwaterloo.ca&amp;lt;/code&amp;gt;&lt;br /&gt;
#* https://mailman.csclub.uwaterloo.ca/admin/csc-general&lt;br /&gt;
# If the user has vhosts on caffeine, update them to point to their new username&lt;br /&gt;
&lt;br /&gt;
If the user&#039;s account has been around for a while, and they request it, forward email from their old username to their new one.&lt;br /&gt;
&lt;br /&gt;
# Edit &amp;lt;code&amp;gt;/etc/aliases&amp;lt;/code&amp;gt; on mail. &amp;lt;code&amp;gt;$OLD: $NEW&amp;lt;/code&amp;gt;&lt;br /&gt;
# Run &amp;lt;code&amp;gt;newaliases&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=MediaWiki&amp;diff=5419</id>
		<title>MediaWiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=MediaWiki&amp;diff=5419"/>
		<updated>2025-09-10T00:38:29Z</updated>

		<summary type="html">&lt;p&gt;K95ma: f&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;CSC&#039;s MediaWiki instance is located at &amp;lt;code&amp;gt;/var/lib/mediawiki&amp;lt;/code&amp;gt; on [[Machine List#caffeine|caffeine]].&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=MediaWiki&amp;diff=5418</id>
		<title>MediaWiki</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=MediaWiki&amp;diff=5418"/>
		<updated>2025-09-10T00:37:57Z</updated>

		<summary type="html">&lt;p&gt;K95ma: +&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;CSC&#039;s MediaWiki instance is located at {{code|/var/lib/mediawiki}} on [[Machine List#caffeine|caffeine]].&lt;/div&gt;</summary>
		<author><name>K95ma</name></author>
	</entry>
</feed>