Prerequisites - Updated Dec 18th 2023

  • Ubuntu Server LTS 22.04.3 (server install, basic - no GUI or other options), 16GB RAM, 200GB HDD
  • Latest postgreSQL 16, JDK 21
  • Latest Tomcat 10.1.x

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
  • apt-get install gnupg
  • sudo apt-get -y install yamllint
  • sudo apt install ufw
  • sudo apt install nano
  • 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 sshd

PostgreSQL

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

Create the file repository configuration:

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

Import the repository signing key:

wget --no-check-certificate -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

Update the package lists:

sudo apt-get update

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

File to edit when tuning PG:

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

Starting (or stopping) postgres: ( stop | start | restart )

sudo pg_ctlcluster 16 main restart

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/16/main/pg_hba.conf

Restart PG for changes to take effect:

sudo pg_ctlcluster 16 main restart


Java 21

Install Java JDK 21

sudo mkdir /usr/lib/jvm
cd /usr/lib/jvm
Direct from Adoptium https://adoptium.net
sudo wget --inet4-only https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2%2B13/OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz --no-check-certificate
Extract download
sudo tar -xvzf OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz

Append the following command to open the environment variables file.

sudo nano /etc/environment
JAVA_HOME="/usr/lib/jvm/jdk-21.0.2+13"

Run from command line.

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

Check Version

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


Tomcat 10.1

NOTE ! - Install 10.1.19 +

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-10/v10.1.19/bin/apache-tomcat-10.1.19.tar.gz --no-check-certificate
sudo tar xzvf apache-tomcat-10.1.19.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

User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/jdk-21.0.2+13"
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=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"

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

RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload

After installing tomcat, download the latest CoCCA RDAP ROOT.war.

sudo systemctl stop tomcat
cd /opt/tomcat/webapps/
rm -fr ROOT
rm -fr docs
rm -fr examples
sudo wget --inet4-only https://updates.coccaregistry.org/rdap/ROOT.war --no-check-certificate

Rename server.xml and context.xml files to server.bak and context.bak in /opt/tomcat/conf/

Download the default CoCCA tomcat config files.

cd /opt/tomcat/conf/
rm -fr server.xml
rm -fr context.xml
sudo wget --inet4-only https://updates.coccaregistry.org/rdap/server.xml --no-check-certificate
sudo wget --inet4-only https://updates.coccaregistry.org/rdap/context.xml --no-check-certificate

Edit the context.xml file for db name, username, password

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

Create a folder for the CoCCA rdap config file.

mkdir /opt/tomcat/rdap/
cd /opt/tomcat/rdap/
sudo wget --inet4-only https://updates.coccaregistry.org/rdap/rdap.properties --no-check-certificate

letsencrypt

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

sudo apt install certbot

Stop tomcat webserver temporarily.

sudo systemctl stop tomcat

Request a new certificate

mkdir /opt/tomcat/jks
cd /opt/tomcat/jks/
sudo certbot certonly --standalone

Create p12 (one long string/command)

openssl pkcs12 -export -name sslcertificate -in /etc/letsencrypt/live/registry.example.tld/fullchain.pem -inkey /etc/letsencrypt/live/registry.example.tld/privkey.pem -out registry.example.tld.p12

Create Java keystore and import p12 (one long string/command):

/usr/lib/jvm/jdk-21.0.2+13/bin/keytool -importkeystore -destkeystore registry.example.tld.jks -srckeystore registry.example.tld.p12 -srcstoretype pkcs12 -alias sslcertificate

Edit tomcat server.xml config file to enable https certificate:

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

Add jks file name and password for the custom jks created above.

Restart tomcat to see CoCCA rdap https clinet.

sudo systemctl restart tomcat


Secure Tomcat

Running Tomcat on Privileged Port 443

Tomcat listens on port 8080 for HTTP and 8443 for HTTPS. If you want Tomcat to listen on the standard HTTP (80) and HTTPS (443) ports, some aditional config is required. Ports below 1024 are considered privileged ports on Linux and only available to processes running as root.

sudo apt install authbind

Assuming a user tomcat was created as per the tutorial

sudo touch /etc/authbind/byport/443
sudo chmod 500 /etc/authbind/byport/443
sudo chown tomcat /etc/authbind/byport/443

Modify /opt/tomcat/conf/server.xml and configure tomcat to listen to port 443 (Connector port="443")

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

Edit the tomcat systemd file.

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

Add prefix "/usr/bin/authbind --deep" to the Start and Stop commands


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

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

systemctl daemon-reload
sudo systemctl restart tomcat
ps auxwww | grep -v grep | grep tomcat

When ready for production, disable tomcat manager by un-commenting (enable) valve restrictions in the two files bellow.

sudo nano /opt/tomcat/webapps/manager/META-INF/context.xml
sudo nano /opt/tomcat/webapps/host-manager/META-INF/context.xml

Start on reboot

sudo systemctl enable tomcat