[Tutorial] Ubuntu 22.04 Security Hardening for DeFi and Web3 Startups

As the world of decentralized finance (DeFi) and Web3 continues to expand, the importance of robust security measures for these platforms cannot be overstated. DeFi and Web3 startups, which often involve millions of dollars in transactions and rely on the immutability of blockchain technology, are particularly susceptible to substantial losses due to irreversible transactions in the event of security breaches. Thus, it is crucial for these startups to ensure their server infrastructure is well-protected and hosted within secure data centers.

Selecting the right data center is a critical component of safeguarding DeFi and Web3 platforms, as a compromised server could lead to devastating consequences. Ensuring the security of the server and the sensitive data it holds is essential to maintaining the integrity of the decentralized ecosystem and protecting users’ digital assets.

This article provides some basic tips for hardening an Ubuntu server in a shared hosting environment. The tips include updating the server, configuring SSH, creating a new user, disabling root login, securing the shadow, group, and password files, disabling Grub recovery, and more.

By implementing these security measures, website owners can improve the security of their website and data, and reduce the risk of unauthorized access. These measures can also help prevent brute-force attacks, unauthorized data access, and data theft.

Before we start, please note that this tutorial is for educational purposes only. It is not a comprehensive guide to secure your Linux server but can be used as a starting point.

Prerequisites

This tutorial assumes that you have:

  • A Linux server running an Ubuntu 20.04 distro or higher.
  • Root access to your server.
  • A basic understanding of the linux commands.

Find and Replace

Before you find and replace, first copy this script to a code editor.

# Find and Replace:

# <NEW SSH PORT>
# <New User>
# <Server IP Address>
# <My Certificate>.pub

# ----

sudo apt update
sudo apt upgrade

sudo nano /etc/ssh/sshd_config

# change port to <NEW SSH PORT>

sudo systemctl restart sshd


# Create user <New User>

sudo adduser <New User> 
sudo usermod -aG sudo <New User>

# Verify
sudo grep '^sudo' /etc/group


sudo nano /etc/ssh/sshd_config

# Change PermitRootLogin -> no

sudo systemctl restart sshd

sudo reboot

# On your local machine
# rm ~/.ssh/known_hosts
# ssh-keygen -R <Server IP Address>

ssh-copy-id -i ./<My Certificate>.pub -p <NEW SSH PORT> <New User>@<Server IP Address>

# Verify

ssh -p <NEW SSH PORT> <New User>@<Server IP Address>

# ---------

sudo nano /etc/ssh/sshd_config

# Change PasswordAuthentication -> no

sudo systemctl restart sshd

# ---------

sudo visudo

# Add <New User>  ALL=(ALL) NOPASSWD:ALL


# Disable Grub Recovery
sudo nano /etc/default/grub

# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
sudo update-grub

# check other sources too
sudo nano /etc/default/grub.d/?.cfg



# cd /etc/grub.d/
# sudo cp 00_header 00_header.bak
# grub-mkpasswd-pbkdf2
# copy the password starting from grub
# sudo nano 00_header

# ----

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow <NEW SSH PORT>
sudo ufw allow 80 # only if you host a webserver
sudo ufw allow 443 # only if you host a webserver
sudo ufw enable

# ----

sudo nano /etc/passwd

# change root:x:0:0:root:/root:/bin/bash --> root:x:0:0:root:/root:/usr/sbin/nologin


# ----

sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades

# ---

sudo nano /etc/sysctl.conf

net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.all.accept_source_route=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.default.log_martians=1
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_max_syn_backlog=2048
net.ipv4.tcp_synack_retries=2
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.default.accept_ra=0

sudo sysctl -p

# ---

sudo nano /etc/pam.d/su

# Add or update:

```
auth       required   pam_wheel.so group=wheel
```

sudo nano /etc/group

# add

```
wheel:x:0:root:
```

sudo usermod -aG wheel <New User>


# ---

sudo nano /etc/modprobe.d/blacklist.conf

# add the following lines

blacklist usb-storage
blacklist uas

sudo update-initramfs -u

# ---

sudo nano /etc/fstab

add

tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec,mode=1777 0 0
tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec,mode=1777 0 0


# ---

sudo chmod 600 /etc/shadow
sudo chmod 600 /etc/gshadow
sudo chmod 644 /etc/passwd
sudo chmod 644 /etc/group



# --- Disable root login

sudo passwd -l root

sudo reboot

The first step is to replace the following placeholders with actual values in the Bash script:

  • <NEW SSH PORT>: Replace it with a new SSH port number (e.g., 2211).
  • <New User>: Replace it with a new username (e.g., Alice).
  • <Server IP Address>: Replace it with your server’s IP address.
  • <My Certificate>.pub: Replace it with the filename of your certificate’s public key (e.g., my_certificate.pub).

Disclaimer

This guide is intended to provide helpful tips for securing a Linux server. However, it is not a foolproof solution and does not guarantee security. It is important to understand that security is an ongoing process and requires vigilance and continuous effort.

Furthermore, while the steps outlined in this guide can help improve the security of your server, it is ultimately your responsibility to keep up-to-date with the latest security best practices, monitor your server for potential vulnerabilities, and take appropriate actions to address any issues that arise.

Therefore, we recommend that you continue to educate yourself on server security best practices, regularly monitor your server for any vulnerabilities or suspicious activity, and take appropriate actions to address any issues that arise to keep your server secure.

Setting up a Linux server can be a daunting task, especially when it comes to securing it. In this guide, we will go through a series of steps to help you secure your Ubuntu installation. The guide assumes that you are using Ubuntu 20.04 LTS or later, but the steps should be similar for other distributions.

Let’s begin!

Updating the Server

The first step is to update your server to ensure that you have the latest security patches installed.

sudo apt update
sudo apt upgrade

Changing SSH Port

By default, SSH listens on port 22, which is a well-known port and is often targeted by hackers. Changing the SSH port will make it harder for attackers to find your SSH service.

sudo nano /etc/ssh/sshd_config

Change the port to the new SSH port you chose in the previous step. Look for the line # Port 22 and change it to Port <NEW SSH PORT>. Save and close the file.

sudo systemctl restart sshd

This will restart the SSH service, and it will now listen on the new port.

Creating a New User

Creating a new user will give you another layer of security. This user will have limited privileges, and you can use it for your daily tasks.

sudo adduser <New User>
sudo usermod -aG sudo <New User>

This will create a new user with the username you chose in the previous step and add it to the sudo group to give it administrative privileges.

Verify that the new user has sudo privileges:

sudo grep '^sudo' /etc/group

Disabling Root Login

By disabling the root login, you will make it harder for attackers to gain access to your server. They will need to know the username and password of a user with sudo privileges.

sudo nano /etc/ssh/sshd_config

Look for the line PermitRootLogin and change it to no. Save and close the file.

sudo systemctl restart sshd

This will restart the SSH service with the new configuration.

Setting up SSH Key Authentication

SSH key authentication is a more secure way of logging into your server than using a password. SSH keys are difficult to brute force, and you don’t have to share your password with anyone.

ssh-copy-id -i ./<My Certificate>.pub -p <NEW SSH PORT> <New User>@<Server IP Address>

Verify that you can log in to the server using the new user and SSH key:

ssh -p <NEW SSH PORT> <New User>@<Server IP Address>

Disabling Password Authentication

Disabling password authentication will make it harder for attackers to brute force their way into your server. They will need to have access to an SSH key to log in.

sudo nano /etc/ssh/sshd_config

Look for the line PasswordAuthentication and change it to no. Save and close the file.

sudo systemctl restart sshd

This will restart the SSH service with the new configuration.

Disabling Grub Recovery

Disabling the GRUB (Grand Unified Bootloader) recovery mode can help prevent attackers from inside your data center because it limits the ability of an attacker to gain access and control over a system.

The GRUB recovery mode provides an alternate method for accessing a system’s boot loader, allowing users to recover from errors or perform maintenance tasks. However, this mode can also be exploited by attackers who have physical access to the system, allowing them to bypass security controls and gain access to sensitive data or modify the system’s configuration.

By disabling the GRUB recovery mode, you remove this potential avenue of attack, making it more difficult for attackers to gain unauthorized access to your systems. This can help reduce the risk of data breaches and other security incidents, particularly those that originate from within your own data center.

It’s important to note that disabling the GRUB recovery mode is just one of many security measures that should be taken to secure a data center. Other best practices include implementing strong access controls, regular security assessments, and ongoing monitoring of system logs and network traffic.

sudo nano /etc/default/grub

Uncomment the line #GRUB_DISABLE_RECOVERY=“true” to disable the recovery mode. Save and close the file.

sudo update-grub

This will update the GRUB bootloader configuration.

Check if there are any other configuration files in /etc/default/grub.d/ that may need to be updated.

Setting up Uncomplicated Firewall (UFW)

The Uncomplicated Firewall (UFW) is a front-end for iptables that makes it easier to manage your server’s firewall.

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow <NEW SSH PORT>
sudo ufw allow 80 # only if you host a webserver
sudo ufw allow 443 # only if you host a webserver
sudo ufw enable

The first command installs UFW on your server. The second and third commands set the default incoming and outgoing policies to deny and allow, respectively. The fourth command allows SSH traffic. The fifth command allows traffic on the new SSH port you chose earlier. The last two commands allow traffic on ports 80 and 443 if you are hosting a web server.

Changing the Root Shell

Changing the root shell from /bin/bash to /usr/sbin/nologin is an additional security measure. It prevents anyone from logging in as the root user and executing commands.

sudo nano /etc/passwd

Find the line that starts with root: and change the last part from /bin/bash to /usr/sbin/nologin. The line should look like this:

root:x:0:0:root:/root:/usr/sbin/nologin

Save and close the file.

Setting Up Unattended Upgrades

Setting up unattended upgrades is a useful step to keep your server secure by automatically installing the latest security updates.

sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades

The first command installs the unattended-upgrades package, and the second command launches a configuration wizard.

In the configuration wizard, select Yes to enable automatic updates and Ok to confirm.

Configuring the Kernel Parameters

Configuring the kernel parameters will improve your server’s security by enabling additional protections.

sudo nano /etc/sysctl.conf

Add the following lines to the end of the file:

net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.all.accept_source_route=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.default.log_martians=1
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_max_syn_backlog=2048
net.ipv4.tcp_synack_retries=2
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.default.accept_ra=0

Note

The above settings are related to the behavior of the network stack in a Linux system and are specified in the /etc/sysctl.conf file.

  1. net.ipv4.conf.all.rp_filter=1 - This setting enables reverse path filtering for incoming packets on all network interfaces. Reverse path filtering is a security feature that helps prevent source address spoofing and certain types of denial-of-service attacks.

  2. net.ipv4.conf.all.accept_source_route=0 - This setting disables the acceptance of packets with source routes. Source routing allows the sender of a packet to specify the path that the packet should take through the network, which can be a security risk.

  3. net.ipv4.icmp_echo_ignore_broadcasts=1 - This setting disables the response to ICMP echo requests (ping) that are sent to the broadcast address of a network. This can help prevent certain types of denial-of-service attacks.

  4. net.ipv4.icmp_ignore_bogus_error_responses=1 - This setting ignores certain types of ICMP error messages that may be sent in response to packets that do not conform to the expected network protocol. This can help prevent certain types of denial-of-service attacks.

  5. net.ipv4.conf.all.log_martians=1 - This setting enables logging of packets with impossible addresses (called “martians”) that are received on all network interfaces.

  6. net.ipv4.conf.default.log_martians=1 - This setting enables logging of packets with impossible addresses (called “martians”) that are received on the default network interface.

  7. net.ipv4.tcp_syncookies=1 - This setting enables the use of TCP SYN cookies, which are a type of defense against SYN flood attacks. SYN flood attacks are a type of denial-of-service attack that attempt to overwhelm a system by sending a large number of TCP SYN packets.

  8. net.ipv4.tcp_max_syn_backlog=2048 - This setting determines the maximum number of TCP SYN packets that can be queued up for a connection that has not yet been established.

  9. net.ipv4.tcp_synack_retries=2 - This setting determines the number of times a system will attempt to retransmit a TCP SYN-ACK packet before giving up on establishing a connection.

  10. net.ipv6.conf.all.accept_ra=0 - This setting disables the acceptance of Router Advertisement (RA) messages on all IPv6-enabled network interfaces. RA messages are used by routers to advertise their presence and configuration information to hosts on a network.

  11. net.ipv6.conf.default.accept_ra=0 - This setting disables the acceptance of Router Advertisement (RA) messages on the default IPv6-enabled network interface.

Disabling su Switching

Creating a new user group is an extra security measure. It allows you to restrict access to specific files or directories to a group of users.

sudo nano /etc/pam.d/su

Add the following line at the end of the file:

auth       required   pam_wheel.so group=wheel

Save and close the file.

sudo nano /etc/group

Add the following line at the end of the file:

wheel:x:0:root:

Save and close the file.

sudo usermod -aG wheel <New User>

This command adds the new user to the wheel group.

Editing /etc/pam.d/su is helpful to improve the security of your server. By default, any user with sudo privileges can switch to another user, including the root user, without a password. This default behavior is insecure because it allows users with elevated privileges to easily gain access to other accounts without any additional authentication.

Adding the auth required pam_wheel.so group=wheel line to the su file changes this default behavior by requiring users to be members of the wheel group to use the su command. This means that only users who are explicitly authorized by being members of the wheel group can switch to another user without providing a password.

This extra layer of security helps to limit the number of users who have access to elevated privileges, which can help prevent unauthorized access to your server. Additionally, if an attacker gains access to a user account with sudo privileges, they will not be able to switch to the root user without first being a member of the wheel group.

Disabling USB Storage

Datacenters often house multiple servers in a shared space, making it difficult to monitor physical access to individual servers. Disabling USB storage can help prevent unauthorized access to the server through USB devices, even if an attacker gains physical access to the server.

Also, datacenters may be located in high-risk areas or may be targeted by attackers due to the sensitive data they host. Disabling USB storage can help to mitigate the risk of data theft or manipulation through unauthorized physical access.

By default, Linux systems automatically detect and mount USB storage devices, making them accessible to any user with physical access to the server. This default behavior is insecure because it allows anyone with a USB storage device to potentially access, modify or copy data from your server, even if they don’t have authorized access to it.

Disabling USB storage on the server helps to prevent unauthorized access by limiting physical access to your server. By adding the following lines to /etc/modprobe.d/blacklist.conf:

blacklist usb-storage
blacklist uas

you prevent the kernel from loading the USB storage and USB attached SCSI (UAS) drivers, effectively disabling USB storage on the server.

This step is an additional security measure that helps to protect your server from unauthorized access, especially if it is located in a datacenter or if physical security is not guaranteed.

Adding Additional Mount Options

Adding additional mount options will ensure that the /tmp and /var/tmp directories are mounted as tmpfs. This will prevent attackers from using these directories to execute malicious code.

sudo nano /etc/fstab

Add the following lines to the end of the file:

tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec,mode=1777 0 0
tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec,mode=1777 0 0

The above script configures the /tmp and /var/tmp directories to use a temporary file system (tmpfs) instead of being mounted as a permanent file system.

tmpfs is a temporary file system that uses RAM to store files and data. When the server reboots, the contents of tmpfs are lost, and the file system is recreated with a clean slate. This feature helps to prevent sensitive data from being left behind on the server after it shuts down.

The options nosuid, nodev, and noexec are added for security reasons. nosuid and nodev options prevent the execution of setuid and device files in the /tmp and /var/tmp directories. The noexec option prevents the execution of any binaries stored in these directories. These options can help prevent malicious code execution in the /tmp and /var/tmp directories.

The mode=1777 option sets the file permissions on the directories to drwxrwxrwt. This means that anyone can create or delete files in the directories, but only the owner of a file can modify or delete it. This is a common setting for the /tmp and /var/tmp directories, as it allows any user to write temporary files while preventing unauthorized access to them.

Securing the Shadow, Group, and Password Files

The next step is to secure the shadow, group, and password files by changing their permissions.

Securing the shadow, group, and password files on a server is helpful for servers hosted in a datacenter because it helps to prevent unauthorized access to sensitive user data.

By default, these files are accessible by the root user and users with sudo privileges. This default behavior is insecure because it allows anyone with access to the server to potentially view, modify or copy sensitive user data.

Securing these files involves setting appropriate file permissions to prevent unauthorized access. The following steps can be taken to secure these files:

sudo chmod 600 /etc/shadow
sudo chmod 600 /etc/gshadow
sudo chmod 644 /etc/passwd
sudo chmod 644 /etc/group

The above commands set the permissions on the /etc/shadow and /etc/gshadow files to rw-------, which means that only the root user can read or write to these files. Similarly, the permissions on the /etc/passwd and /etc/group files are set to rw-r--r--, which means that the root user can read and write, and all other users can only read.

By securing these files, you can prevent unauthorized access to sensitive user data, such as hashed passwords and group membership information. This can be especially important in a datacenter or VM environment where multiple users may have access to the server or where sensitive data is being stored.

Disabling the Root Login

Disabling the root login is an essential security measure for Linux servers. By default, the root user has unlimited access to the server, and if an attacker gains access to the root account, they can potentially take complete control of the server.

Disabling the root login means that the root account cannot be used to log in directly to the server. Instead, users with sudo privileges must first log in with their own accounts and then use the sudo command to run administrative commands. This adds an extra layer of security to the server by requiring additional authentication to gain access to elevated privileges.

Disabling the root login also helps to prevent brute-force attacks on the root account. Attackers often attempt to gain access to a server by repeatedly guessing the root password. By disabling the root login, you can effectively block these types of attacks.

Bonus #1: Full Disk Encryption

Full disk encryption serves as a vital layer of protection for your data, ensuring that unauthorized access is minimized, and the integrity of your data remains uncompromised.

One of the risks associated with running your server in a data center is the potential for a data center employee to be bribed or otherwise coerced into installing malware on your server. This could lead to serious consequences, such as data breaches, unauthorized access to sensitive information, or even system-wide compromises. In some cases, the attacker might leverage the compromised server to launch attacks on other systems or networks.

To mitigate this risk, it is crucial to employ security measures such as full disk encryption on your servers. Ubuntu 20.04 or higher provides robust support for full disk encryption, utilizing the LUKS (Linux Unified Key Setup) standard. This ensures that your data is encrypted at rest, rendering it unreadable to anyone without the correct decryption key. This helps to protect your data, even in the event that an attacker gains physical access to your server.

However, it is important to note that full disk encryption is not a one-size-fits-all solution. In addition to employing encryption, you should also take the following steps to safeguard your servers in a data center:

  1. Choose a reputable data center provider: A reputable provider should have a proven track record of security and compliance, along with stringent physical security measures in place.
  2. Implement strong access controls: Limit the number of individuals who have access to your servers, both physically and remotely. Implement strong authentication methods, such as multi-factor authentication, to protect against unauthorized access.
  3. Regularly monitor and audit your environment: Keep a close eye on your servers for any signs of suspicious activity. Regularly audit your environment to ensure that security measures are in place and functioning correctly.
  4. Establish a comprehensive incident response plan: In the event of a security breach or other incident, a well-defined response plan will help you to quickly contain the damage and recover your systems.

Bonus #2: Perform Due Diligence on Your Data Center

Before entrusting your servers to a data center, it’s important to thoroughly research its reputation and track record. Conduct an online search to look for user reviews, testimonials, and any complaints or security incidents involving the data center. Additionally, consider the following points when evaluating a data center:

  1. Certifications and compliance: Verify if the data center holds relevant industry certifications, such as ISO/IEC 27001, SOC 2, or PCI DSS, which demonstrate their commitment to maintaining high standards of security and privacy.
  2. Physical security measures: Inquire about the data center’s physical security, including access controls, surveillance systems, and intrusion detection mechanisms. Ensure that they have robust measures in place to prevent unauthorized access.
  3. Redundancy and disaster recovery: Check whether the data center has redundant power and network infrastructure, as well as a comprehensive disaster recovery plan in case of unforeseen events.

By performing due diligence on the data center itself, you can gain a better understanding of the facility’s security posture and make an informed decision about whether it meets your requirements for safeguarding your servers.

4 Likes