Prerequisites - Updated September 2024

  • Ubuntu Server LTS 24.04.x (server install, basic - no GUI or other options), 16GB RAM, 120GB HDD
  • Latest postgreSQL 18, Adoptium JDK 25
  • Latest Tomcat 11

Basics:

  • sudo apt update && sudo apt upgrade -y
  • sudo apt install zip unzip
  • sudo touch /etc/cloud/cloud-init.disabled
  • sudo apt purge cloud-init -y
  • sudo rm -Rf /etc/cloud
  • sudo systemctl disable --now unattended-upgrades
  • sudo apt remove unattended-upgrades
  • sudo apt install yamllint
  • sudo apt install whois
  • sudo timedatectl set-timezone UTC
  • sudo timedatectl set-ntp on
  • sudo apt update && sudo apt upgrade -y
  • sudo apt autoremove

Basic Security

Ubunutu firewall basic configuration, handy commands:

  • sudo ufw enable | disable
  • sudo ufw status numbered ( see rules )
  • sudo ufw delete X ( delete a rule by number )
  • sudo ufw reload ( after rule changes )
sudo ufw allow from [trusted IP] to any port 22 ( if sshd is on non-standard port use that port )
sudo ufw allow from any to any port 80
sudo ufw allow from any to any port 443

Use fail2ban to protect against brute force/dictionary ssh attacks and mal-formed http requests. - tutorial

sudo apt install fail2ban

Basic sshd refinements. (we recommend using ssh keys tutorial)

sudo nano /etc/ssh/sshd_config

Protocol 2
Port XXX ( change port, config ufw to allow the selected port )
ListenAddress x.x.x.x ( if multiple IP, bind to one IP )
LogLevel VERBOSE
AllowUsers user_1 user_2 ( list logins that are allowed to ssh )
LoginGraceTime 30
PermitRootLogin no
MaxAuthTries 3
HostbasedAuthentication no
IgnoreRhosts yes
PermitEmptyPasswords no
AllowTcpForwarding no
X11Forwarding no
ClientAliveInterval 300
ClientAliveCountMax 0
MaxStartups 2

sudo systemctl restart ssh

PostgreSQL

Installation Instructions: https://www.postgresql.org/download/linux/ubuntu/

Create the file repository configuration:

sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh

Update the package lists:

sudo apt-get update

sudo apt-get -y install postgresql-18
Tune postgresql: https://pgtune.leopard.in.ua/

File to edit when tuning PG:

sudo nano /etc/postgresql/18/main/postgresql.conf

Set password for user "postgres"

sudo -u postgres psql postgres
\password postgres ( enter desired password when prompted )
\q (to exit the posgreSQL command interface )

Edit pg_hba.conf to force password confirmation for postgres commands
Look for --- "Database administrative login by Unix domain socket", replace "peer" with "md5"

sudo nano /etc/postgresql/18/main/pg_hba.conf

Restart PG for changes to take effect:

sudo pg_ctlcluster 18 main restart

See Replication page to setup db replication between the registry and the rdap server.

https://cocca.org.nz/srs/replication.html


Java 25

Install Java JDK 25 LTS

sudo mkdir /usr/lib/jvm
cd /usr/lib/jvm
Direct from Adoptium https://adoptium.net
sudo wget --inet4-only https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.3%2B9/OpenJDK25U-jdk_x64_linux_hotspot_25.0.3_9.tar.gz --no-check-certificate
Extract download
sudo tar -xvzf OpenJDK25U-jdk_x64_linux_hotspot_25.0.3_9.tar.gz

Append the following command to open the environment variables file.

sudo nano /etc/environment
JAVA_HOME="/usr/lib/jvm/jdk-25+36"

Run from command line.

sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk-25.0.3+9/bin/java" 0
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk-25.0.3+9/bin/javac" 0
sudo update-alternatives --set java /usr/lib/jvm/jdk-25.0.3+9/bin/java
sudo update-alternatives --set javac /usr/lib/jvm/jdk-25.0.3+9/bin/javac

Check Version

java -version
sudo update-alternatives --config java
sudo update-alternatives --display java


Tomcat 11

Install latest tomcat 11.x.x ( https://tomcat.apache.org/download-11.cgi )

For security purposes, Tomcat should run under a separate, unprivileged user. Run the following command to create a user called tomcat:

sudo useradd -m -d /opt/tomcat -U -s /bin/false tomcat

To install Tomcat, you’ll need the latest Core Linux build for Tomcat 10

cd /tmp
wget https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.23/bin/apache-tomcat-11.0.23.tar.gz --no-check-certificate
sudo tar xzvf apache-tomcat-11.0.23.tar.gz -C /opt/tomcat --strip-components=1

Since you have already created a user, you can now grant tomcat ownership over the extracted installation by running:

sudo chown -R tomcat:tomcat /opt/tomcat/
sudo chmod -R u+x /opt/tomcat/bin

The systemd service that you will now create will keep Tomcat quietly running in the background. The systemd service will also restart Tomcat automatically in case of an error or failure.

sudo nano /etc/systemd/system/tomcat.service

Paste the content bellow in the new tomcat.service file.

[Unit]
Description=Tomcat
After=network.target

[Service]
Type=forking
AmbientCapabilities=CAP_NET_BIND_SERVICE

User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/jdk-25.0.3+9"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom"
Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms1024M -Xmx2048M -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/bin/startup.sh - updated
ExecStop=/opt/tomcat/bin/shutdown.sh - updated

RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

Run systemctl daemon-reload to reload units.

After installing tomcat, download the latest CoCCA RDAP ROOT.war and copy it to /opt/tomcat/webapps/.

sudo systemctl stop tomcat
cd /opt/tomcat/webapps/
rm -fr ROOT
rm -fr docs
rm -fr examples
rm -fr manager
rm -fr host-manager

cd /opt/tomcat/conf/
mv server.xml server.back
mv context.xml context.back
wget https://cocca.org.nz/srs/server.xml
wget https://cocca.org.nz/srs/context.xml

Download the default CoCCA tomcat config files (server.xml & context.xml).

Edit the server.xml and context.xml file for db name, username, password port etc.

sudo nano /opt/tomcat/conf/context.xml
sudo nano /opt/tomcat/conf/server.xml

RDAP Server Only

Create a folder for the CoCCA rdap.properties config file.
mkdir /opt/tomcat/rdap/
cd /opt/tomcat/rdap/

Redis Cache 8

RDAP Server Only

To install Redis, either follow the instruction here https://redis.io/docs/latest/operate/oss_and_stack/install/archive/install-redis/install-redis-on-linux or run the following commands one by one.

sudo apt-get install lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
sudo systemctl enable redis-server
sudo systemctl start redis-server

After install, run this command to verify the installation:

redis-cli --scan --pattern 'WHOIS_DOMAIN_CACHE::*' | wc -l

You should see 0. The above command shows how many domain records are currently cached in Redis.

Edit /opt/tomcat/rdap/rdap.properties add the following properties:

    redis.whois.ttl-minutes=1440
    # DataLoader behaviour
    whois.dataloader.enabled=true
    whois.dataloader.page-size=500
    # Reload interval in ms (default 15 minutes); must be less than redis.whois.ttl-minutes
    whois.dataloader.interval-ms=900000

During bootstrap, the system will populate Redis cache by querying data in Registry database.
You can run this command to see how many domains cached so far:
redis-cli --scan --pattern 'WHOIS_DOMAIN_CACHE::*' | wc -l

The system works by fetching all domain records from Registry database and load into Redis, and then refresh the full dataset every 15 mins by default.

Both API and port 43 query uses cached data by default. Full dataset refresh happens in backend, both API and port 43 continue to work during refresh.

letsencrypt

If you want to get started with a free https certificate to match your host name, we suggest https://letsencrypt.org

If using nginx as a reverse proxy it is not nessesary to use a jks. The SSL .pem certs can be in refferences in the nginx config file. In the recomended setup Tomcat listens on port 127.0.0.1:8080, the TLS is configured in nginx.

Using nginx as a reversr proxy is the recommnded configuration.

sudo apt install certbot
sudo apt install python3-certbot-nginx

Stop nginx webserver temporarily.

sudo systemctl stop nginx

Request a new certificate

sudo certbot certonly --standalone

Make note of the path and .pem files created by letsencrypt to add to the nginx config file.
Certificate is saved at:
/etc/letsencrypt/live/temp.coccaregistry.org/fullchain.pem
Key is saved at:
/etc/letsencrypt/live/temp.coccaregistry.org/privkey.pem

Enable letsencrypt Auto-Renew, in root's crontab.

sudo crontab -u root -e
17 11 28 * * /usr/bin/certbot --quiet renew --nginx

NGINX proxy

OPTIONAL - For better security and caching install nginx reverse proxy.

sudo apt update
sudo apt install nginx
sudo apt install -y libnginx-mod-stream

Download the two (2) default CoCCA nginx config files (rdap.nic.tld & nginx.conf).

sudo wget https://cocca.org.nz/srs/rdap.nic.tld --no-check-certificate
sudo wget https://cocca.org.nz/srs/nginx.conf --no-check-certificate

Copy the downloaded rdap.nic.tld to /etc/nginx/sites-available/rdap.nic.tld

Edit rdap.nic.tld and update the placholder host names, and pem file locations for SSL

Overwrite the default /etc/nginx/nginx.conf with the downloaded nginx.conf

Next, enable this configuration file by creating a link from it to the sites-enabled directory that Nginx reads at startup:

sudo ln -s /etc/nginx/sites-available/rdap.nic.tld /etc/nginx/sites-enabled/

NGINX uses the default linked configuration file. Creating a reverse proxy requires creating and linking a custom file. To avoid any potential conflicts, use the following command:

sudo unlink /etc/nginx/sites-enabled/default

Test the Configuration

sudo nginx -t

To configure NGINX to launch on reboot automatically, enable the service with:

sudo systemctl enable nginx

Create a Non-Root User

sudo useradd -m -d /opt/nginxuser -U -s /bin/false nginxuser

Grant nginxuser Necessary Permissions

sudo chown -R nginxuser:nginxuser /var/log/nginx
sudo chown -R nginxuser:nginxuser /var/lib/nginx

Now, Open the Nginx configuration file in a text editor.

sudo nano /etc/nginx/nginx.conf

Within the configuration file, locate the user directive (top of the conf file), and set it to the non-root user you created.

  • user nginxuser;
  • worker_connections 1024;
  • After the "http {" and before "Basic Settings"add the following 4 lines
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    proxy_cache_path /var/cache/nginx keys_zone=static_cache:10m inactive=60m;
    proxy_cache_key "$scheme$request_method$host$request_uri";
  • uncomment server_tokens off;

Save and exit, with nano you can do this by hitting CTRL+O then CTRL+X.

Test the Configuration

sudo nginx -t
sudo systemctl restart tomcat
sudo systemctl restart nginx

Check the process using the following command to ensure that Nginx is running with the non-root user.

ps aux | grep nginx

SRS TC Notes

SRS Server Only

Tomcat is not running as the root user, so in order for the CoCCA SRS to write zone files, backups, escrow files and reload bind, certain folder permissions must be set. Adjust commands below to suit your install & file locations.

sudo chown -R root:tomcat /var/lib/bind/*
sudo chmod -R 775 /var/lib/bind/*
usermod -aG bind tomcat
chgrp bind /etc/bind/rndc.key
chmod 640 /etc/bind/rndc.key
systemctl restart tomcat
sudo -u tomcat rndc status # verify the permission change see if tomcat can run rndc command
chown -R tomcat:tomcat /opt/zones/
chown -R tomcat:tomcat /opt/backups/
chown -R tomcat:tomcat /opt/escrow/

You can config SRS to use the EPP certs generated by Let's Encrypt as well. The following steps will help you set up the necessary directories and scripts to copy the certificates to the appropriate location for Tomcat.

Create a directory for the EPP certificates and set the appropriate ownership:
mkdir /opt/tomcat/srs/epp-certs
sudo chown -R tomcat:tomcat /opt/tomcat/

Because the files in /etc/letsencrypt/live are symlinks, you will need to create a script that copies the actual certificate files to the Tomcat directory. Create a new script file:
sudo nano /etc/letsencrypt/renewal-hooks/deploy/copy-epp-cert.sh
with the following content:

#!/bin/sh
set -e
SRC=/etc/letsencrypt/live/
DEST=/opt/tomcat/srs/epp-certs
install -d -o tomcat -g tomcat -m 750 "$DEST"
install -o tomcat -g tomcat -m 640 "$SRC/privkey.pem" "$DEST/privkey.pem"
install -o tomcat -g tomcat -m 640 "$SRC/fullchain.pem" "$DEST/fullchain.pem"

The above script will run every time the certificate is renewed, copying the new certificate files to the Tomcat directory. Make sure to replace with your actual EPP domain name.

After that, go to https://coccaregistry.org/configuration/epp_edit.jsp and select "Use Let's Encrypt Certificate" as the EPP Server Certificate option. Put /opt/tomcat/srs/epp-certs in the EPP Server Certificate Path field. Save the changes to take effect.

WHOIS p43

RDAP Server Only

OPTIONAL - By default CoCCA runs a whois server on port 4300 of the RDAP server. If you want to run a port 43 service you need to setup port forwarding in UFW.

Step 1
sudo nano /etc/ufw/sysctl.conf
IPv4 - uncomment net/ipv4/ip_forward=1.
IPv6 - uncomment
net/ipv6/conf/all/forwarding=1
net/ipv6/conf/default/forwarding=1
Save and Exit
Step 2
For IPv4 - sudo nano /etc/ufw/before.rules
For IPv6 - sudo nano /etc/ufw/before6.rules

Add a NAT table after the table that starts with *filter and ends with COMMIT, at bottom of the file.

# Start port 43 WHOIS NAT
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 43 -j REDIRECT --to-port 4300
COMMIT
# End port 43 WHOIS NAT

Save and Exit
sudo ufw allow 43/tcp
sudo ufw allow 4300/tcp
sudo systemctl restart ufw