Sign In
Sign In

How to Install Mattermost on Ubuntu

How to Install Mattermost on Ubuntu
Hostman Team
Technical writer
Servers
14.11.2024
Reading time: 8 min

Mattermost is a messaging and collaboration platform that can be installed on self-hosted servers or in the cloud. It serves as an alternative to messengers like Slack and Rocket.Chat.

In this guide, we will review the Free plan, which includes unlimited message history and group calls (for more details on pricing plans, see the official website). Mattermost clients are available for mobile (iOS, Android) and desktop (Windows, Linux, Mac), and there’s also a browser-based version.

Only the Self-Hosted Mattermost version is available under the Free plan; 

We will go through the installation on Ubuntu. Other installation methods (including a Docker image) are available in the official docs.

Technical Requirements

For 1,000 users, a minimum configuration of 1 CPU, 2 GB RAM, and PostgreSQL v11+ or MySQL 8.0.12+ is required.

We will use the following resources:

  • For PostgreSQL 16: We'll provision a DBaaS with 1 CPU, 1 GB RAM, and 20 GB of disk space.
  • For Mattermost: We'll provision a server running Ubuntu with 2 CPUs, 2 GB RAM, and 60 GB of disk space.

We will also need to restrict access to the database. We will do it by setting up a private network in Hostman.

Environment Setup

Creating a Private Network

To restrict database access, we can use Firewall, but in this setup, all services will be within the same network

Important: Services must be located in the same region to operate within a single network.

Image4

Database

We'll provision the database as a service with the following configuration: 1 CPU, 1 GB RAM, and 20 GB of disk space, hosted in Poland.

Image3

While creating the database, in the Network section, select the No external IP option and the network created in the previous step.

Image17

The default database is default_db, and the user is gen_user.

Server for Mattermost

Next, we need to set up a server for Mattermost and Nginx. This server will run Ubuntu 22.04 and will be hosted in Poland.

Image13

For the configuration, we need at least 2 CPUs, 2 GB RAM, and 50 GB of disk space, so we will choose a close enough plan:

Image6

You can also select the exact parameters (2 CPUs, 2 GB RAM, 50 GB) by using the Custom tab, but it will be more expensive.

As with the PostgreSQL setup, select the previously created network in the Network step.

Image9

Create the server.

Domain

We will also need a domain to obtain a TLS certificate. In this guide, we will use example.com.

You can add your domain in the Domains → Add domain section in the Hostman control panel. 

Image1

Ensure the domain is linked to the server. You can verify this in the Network section. If the domain is not listed next to the IP address, it can be added manually through the Set Up Reverse Zone option.

Image11

Installing Mattermost

Now that the environment is ready, we can proceed with installing Mattermost. To begin, we’ll connect to the repository at deb.packages.mattermost.com/repo-setup.sh:

curl -o- https://deb.packages.mattermost.com/repo-setup.sh | sudo bash -s mattermost

Here, the mattermost argument is passed to sudo bash -s mattermost to add only the Mattermost repository. If no argument is provided, the script’s default all argument will add repositories for Mattermost, Nginx, PostgreSQL, and Certbot.

Installing the Service

The Mattermost service will install to /opt/mattermost, with a mattermost user and group created automatically:

sudo apt update
sudo apt install mattermost -y

After installation, create a config.json file with the necessary permissions, based on the config.defaults.json file. Read and write access should be granted only to the owner (in this case, the mattermost user):

sudo install -C -m 600 -o mattermost -g mattermost /opt/mattermost/config/config.defaults.json /opt/mattermost/config/config.json

Configuring Mattermost

Open config.json to fill in key parameters:

sudo nano /opt/mattermost/config/config.json

Set the following:

  • SiteURL: Enter the created domain with the https protocol in the ServiceSettings block, which will be linked with an SSL certificate later.

"ServiceSettings": {
    "SiteURL": "https://example.com",
    "WebsocketURL": ""
}
  • DriverName: Ensure this is set to postgres in the SqlSettings block.

  • DataSource: Provide the username, password, host, and database name in the connection link in the SqlSettings block.

Image16

Other configurations are optional for the initial launch and can be modified later in the Mattermost administrative console.

Starting Mattermost

Start the Mattermost service:

sudo systemctl start mattermost

To verify that Mattermost started successfully:

sudo systemctl status mattermost.service

Image15

And verify it is accessible on port 8065.

Image5

If the site doesn’t open, check the firewall settings. You can also verify local access to port 8065 directly from the server:

curl -v localhost:8065

Enabling Auto-Start

Finally, enable Mattermost to start automatically on boot:

sudo systemctl enable mattermost.service

With these steps, Mattermost should be up and running and ready for further configuration and usage.

Setting Up Nginx as a Reverse Proxy for Mattermost

We will set up Nginx as a reverse proxy to prevent direct access on port 8065, which will be closed later via firewall.

Install Nginx:

sudo apt install nginx

Create the Nginx Configuration File:

sudo nano /etc/nginx/sites-available/mattermost

Nginx Configuration for Mattermost:

Add the following configuration, replacing example.com with your actual domain name. This configuration proxies both HTTP and WebSocket protocols.

upstream backend {
  server 127.0.0.1:8065;
  keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
  listen 80;
  server_name example.com;

  location ~ /api/v[0-9]+/(users/)?websocket$ {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    client_max_body_size 50M;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Frame-Options SAMEORIGIN;
    proxy_buffers 256 16k;
    proxy_buffer_size 16k;
    client_body_timeout 60;
    send_timeout 300;
    lingering_timeout 5;
    proxy_connect_timeout 90;
    proxy_send_timeout 300;
    proxy_read_timeout 90s;
    proxy_pass http://backend;
  }

  location / {
    client_max_body_size 50M;
    proxy_set_header Connection "";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Frame-Options SAMEORIGIN;
    proxy_buffers 256 16k;
    proxy_buffer_size 16k;
    proxy_read_timeout 600s;
    proxy_cache mattermost_cache;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 2;
    proxy_cache_use_stale timeout;
    proxy_cache_lock on;
    proxy_http_version 1.1;
    proxy_pass http://backend;
  }
}

Create a symbolic link to enable the Mattermost configuration:

sudo ln -s /etc/nginx/sites-available/mattermost /etc/nginx/sites-enabled/mattermost

Remove the default configuration:

sudo rm -f /etc/nginx/sites-enabled/default

Restart the Nginx service to apply the changes:

sudo service nginx restart

Setting Up SSL with Let’s Encrypt:

Use Certbot to obtain an SSL certificate for your domain. Certbot will automatically configure Nginx for HTTPS.

sudo apt install python3-certbot-nginx && certbot

Certbot will prompt you to enter your email and domain name and then add the certificate to your domain.

After installing the certificate, Certbot will update the Nginx configuration file to include:

  • A listen directive for handling requests on port 443 (HTTPS)
  • SSL keys and configuration directives
  • A redirect from HTTP to HTTPS

With this setup complete, Mattermost should be accessible over HTTPS on your domain. Nginx will handle HTTP to HTTPS redirection, and secure connections will be established using the SSL certificate from Let’s Encrypt.

Setting Up Firewall

Now, go to your Mattermost server page in the Hostman control panel. Open the Network tab to add firewall rules.

Image2

We will allow incoming TCP requests to ports 22 for SSH access, and 80 and 443 for TCP

To collect metrics on the server dashboard, port 10050 also needs to be open; the list of IP addresses that require access to this port can be found in /etc/zabbix/zabbix_agentd.conf.

Image14

First Launch

Now you can Mattermost at https://your_domain/.

Image8

You can create an account and workspace directly in the browser.

Image7

After installation and on the first login, you may encounter an issue with WebSocket connectivity.

Image10

To solve it, check the configuration. You can do it in the System Console.

Image12

Out-of-the-box features include calls, playbooks, a plugin marketplace, and GitLab authentication. Additionally, Mattermost offers excellent documentation.

Conclusion

In this guide, we deployed the free self-hosted version of Mattermost on Hostman servers with a dedicated database accessible only from the internal network. Keep in mind that we allocated the server resources for a general scenario, so you may need additional resources. It’s advisable not to skip load testing! As a next step, I recommend connecting an S3 storage, also available on Hostman.

Servers
14.11.2024
Reading time: 8 min

Similar

Servers

Server Hardening

Server hardening is the process of improving security by reducing vulnerabilities and protecting against potential threats. There are several types of hardening: Physical: A method of protection based on the use of physical means, such as access control systems (ACS), video surveillance, safes, motion detectors, and protective enclosures. Hardware: Protection implemented at the hardware level. This includes trusted platform modules (TPM), hardware security modules (HSM, such as Yubikey), and biometric scanners (such as Apple Touch ID or Face ID). Hardware protection measures also include firmware integrity control mechanisms and hardware firewalls. Software: A type of hardening that utilizes software tools and security policies. This involves access restriction, encryption, data integrity control, monitoring anomalous activity, and other measures to secure digital information. We provide these examples of physical and hardware hardening to give a full understanding of security mechanisms for different domains. In this article, we will focus on software protection aspects, as Hostman has already ensured hardware and physical security. Most attacks are financially motivated, as they require high competence and significant time investments. Therefore, it is important to clearly understand what you are protecting and what losses may arise from an attack. Perhaps you need continuous high availability for a public resource, such as a package mirror or container images, and you plan to protect your resource for this purpose. There can be many variations. First, you need to create a threat model, which will consist of the following points: Value: Personal and public data, logs, equipment, infrastructure. Possible Threats: Infrastructure compromise, extortion, system outages. Potential Attackers: Hacktivists, insider threats, competitors, hackers. Attack Methods: Physical access, malicious devices, software hacks, phishing/vishing, supply chain attacks. Protection Measures: Periodic software updates, encryption, access control, monitoring, hardening—what we will focus on in this article. Creating a threat model is a non-trivial but crucial task because it defines the overall “flow” for cybersecurity efforts. After you create the threat model, you might need to perform revisions and clarifications depending on changes in business processes or other related parameters. While creating the threat model, you can use STRIDE, a methodology for categorizing threats (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege), and DREAD, a risk assessment model (Damage, Reproducibility, Exploitability, Affected Users, Discoverability). For a more formalized approach, you can also refer to ISO/IEC 27005 or NIST 800-30 standards. There will always be risks that can threaten both large companies and individual users who recently ordered a server to host a simple web application. The losses and criticality may vary, but from a technical perspective, the most common threats are: DoS/DDoS: Denial of service or infrastructure failure, resulting in financial and/or reputational losses. Supply Chain Attack: For example, infecting an artifact repository, such as a Container Registry: JFrog Artifactory, Sonatype Nexus. Full System Compromise: Includes establishing footholds and horizontal movement within the infrastructure. Using your server as a launchpad for complex technological attacks on other resources. If this leads to serious consequences, you will likely spend many hours in court and incur significant financial costs. Gaining advantages by modifying system resources, bypassing authentication, or altering the logic of the entire application. This can lead to reputational and/or financial losses. Some of these attacks can be cut off early or significantly complicated for potential attackers if the server is properly configured. Hardening is not a one-time procedure; it is an ongoing process that requires continuous monitoring and adaptation to new threats. The main goal of this article is to equip readers with server hardening techniques. However, in the context of this article, we will discuss a more relevant and practical example—server protection. After ordering a server, we would normally perform the initial setup. This is typically done by system administrators or DevOps specialists. In larger organizations, other technical experts (SecOps, NetOps, or simply Ops) may get involved, but in smaller setups, the same person who writes the code usually handles these tasks. This is when the most interesting misconfigurations can arise. Some people configure manually: creating users, groups, setting network configurations, installing the required software; others write and reuse playbooks—automated scripts. In this article, we will go over the following server hardening checklist: Countering port scanning Configuring the Nginx web server Protecting remote connections via SSH Setting up Port Knocking Configuring Linux kernel parameters Hardening container environments If you later require automation, you can easily write your own playbook, as you will already know whether specific security configurations are necessary. Countering Port Scanning Various types of attackers, from botnet networks to APT (Advanced Persistent Threat) groups, use port scanners and other device discovery systems (such as shodan.io, search.censys.io, zoomeye.ai, etc.) that are available on the internet to search for interesting hosts for further exploitation and extortion. One popular network scanner is Nmap. It allows determining "live" hosts in a network and the services running on them through a variety of scanning methods. Nmap also includes the Nmap Script Engine, which offers both out-of-the-box functionality and the possibility to add custom scripts. To scan resources using Nmap, an attacker would execute a command like: nmap -sC -sV -p- -vv --min-rate 10000 $IP Where: $IP is the IP address or range of IP addresses to scan. -sC enables the script engine. -sV detects service versions. -vv (from "double verbose") enables detailed output. --min-rate 10000 is a parameter defining how many requests are sent in one go. In this case, an aggressive mode (10,000 units) is selected. Additionally, the rate modes can be adjusted separately with the flag -T (Aggressive, Insane, Normal, Paranoid, Polite, Sneaky). Example of a scan result is shown below. From this information, we can see that three services are running: SSH on port 22 Web service on port 80 Web service on port 8080 The tool also provides software versions and more detailed information, including HTTP status codes, port status (in this case, "open"), and TTL values, which help to determine if the service is in a container or if there is additional routing that changes the TTL. Thus, an attacker can use a port scanner or search engine results to find your resource and attempt to attack based on the gathered information. To prevent this, we need to break the attacker's pattern and confuse them. Specifically, we can make it so that they cannot identify which port is open and what service is running on it. This can be achieved by opening all ports: 2^16 - 1 = 65535. By "opening," we mean configuring incoming connections so that all connection attempts to TCP ports are redirected to port 4444, on which the portspoof utility dynamically responds with random signatures of various services from the Nmap fingerprint database. To implement this, install the portspoof utility. Clone the appropriate repository with the source code and build it: git clone https://github.com/drk1wi/portspoof.gitcd portspoof./configure && make && sudo make install Note that you may need to install dependencies for building the utility: sudo apt install gcc g++ make Grant execution rights and run the automatic configuration script with the specified network interface. This script will configure the firewall correctly and set up portspoof to work with signatures that mask ports under other services. sudo chmod +x $HOME/portspoof/system_files/init.d/portspoof.shsudo $HOME/portspoof/system_files/init.d/portspoof.sh start $NETWORK_INTERFACE Where $NETWORK_INTERFACE is your network interface (in our case, eth0). To stop the utility, run the command: sudo $HOME/portspoof/system_files/init.d/portspoof.sh stop eth0 Repeating the scan using Nmap or any other similar program, which works based on banner checking of running services, will now look like this: Image source: drk1wi.github.io There is another trick that, while less effective as it does not create believable service banners, allows you to avoid additional utilities like portspoof. First, configure the firewall so that after the configuration, you can still access the server via SSH (port 22) and not disrupt the operation of existing legitimate services. sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j RETURN Then, initiate the process of redirecting all TCP traffic to port 5555: sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -m conntrack --ctstate NEW -j REDIRECT --to-ports 5555 Now, create a process that generates pseudo-random noise on port 5555 using NetCat: nc -lp 5555 < /dev/urandom These techniques significantly slow down the scan because the scanner will require much more time to analyze each of the 65,535 "services." Now, the primary task of securing the server is complete! Configuring the Nginx Web Server Nmap alone is not sufficient for a comprehensive analysis of a web application. In addition to alternatives like naabu from Project Discovery and rustscan, there are advanced active reconnaissance tools. These not only perform standard port scanning but specialize in subdomain enumeration, directory brute-forcing, HTTP parameter testing (such as dirbuster, gobuster, ffuf), and identifying and exploiting vulnerabilities in popular CMS platforms (wpscan, joomscan) and specific attacks (sqlmap for SQL injections, tplmap for SSTI). These scanners work by searching for endpoints of an application, utilizing techniques like brute-forcing, searching through HTML pages, or connected JavaScript files. During their operation, millions of iterations occur comparing the response with the expected output to identify potential vulnerabilities and expose the service to exploitation. To protect web applications from such scanners, we suggest configuring the web server. In this example, we’ll configure Nginx, as it is one of the most popular web servers. In most configurations, Nginx proxies and exposes an application running on the server or within a cluster. This setup allows for rich configuration options. To enhance security, we can add HTTP Security Headers and the lightweight and powerful ChaCha20 encryption protocol for devices that lack hardware encryption support (such as mobile phones). Additionally, rate limiting may be necessary to prevent DoS and DDoS attacks. HTTP headers like Server and X-Powered-By reveal information about the web server and technologies used, which can help an attacker determine potential attack vectors.We need to remove these headers. To do this, install the Nginx extras collection: sudo apt install nginx-extras Then, configure the Nginx settings in /etc/nginx/nginx.conf: server_tokens off;more_clear_headers Server;more_clear_headers 'X-Powered-By'; Also, add headers to mitigate Cross-Site Scripting (XSS) attack surface: add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;add_header X-XSS-Protection "1; mode=block"; And protect against Clickjacking: add_header X-Frame-Options "SAMEORIGIN"; You can slow down automated attacks by setting request rate limits from a single IP address. Do this only if you are confident it won't impact service availability or functionality. A sample configuration might look like this: http { limit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s; server { location /api/ { limit_req zone=req_zone burst=20 nodelay; } } } This configuration limits requests to 10 per second from a single IP, with a burst buffer of 20 requests. To protect traffic from MITM (Man-in-the-Middle) attacks and ensure high performance, enable TLS 1.3 and configure strong ciphers: ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; ssl_prefer_server_ciphers on; You can also implement additional web application protection using a WAF (Web Application Firewall). Some free solutions include: BunkerWeb — Lightweight, popular, and effective WAF. ModSecurity — A powerful Nginx module with flexible rules. To perform basic configuration of ModSecurity, you can install it like this: sudo apt install libnginx-mod-security2 Then, enable ModSecurity in the Nginx configuration: server { modsecurity on; modsecurity_rules_file /etc/nginx/modsecurity.conf; } Use Security Headers to analyze HTTP headers and identify possible configuration errors. When configuring any infrastructure components, it's important to follow best practices. For instance, to create secure Nginx configurations, you can use an online generator, which allows you to easily generate optimal base settings for Nginx, including ciphers, OCSP Stapling, logging, and other parameters. Protecting Remote Connections via SSH If your server is still secured only by a password, this is a quite insecure configuration. Even complex passwords can eventually be compromised, especially when outdated or vulnerable versions of SSH are in use, allowing brute force attacks without restrictions, such as in CVE-2020-1616. Below is a table showing how long it might take to crack a password based on its complexity Image source: security.org It’s recommended to disable password authentication and set up authentication using private and public keys. Generate a SSH key pair (public and private keys) on your workstation: ssh-keygen -t ed25519 -C $EMAIL Where $EMAIL is your email address, and -t ed25519 specifies the key type based on elliptic curve cryptography (using the Curve25519 curve). This provides high performance, compact key sizes (256 bits), and resistance to side-channel attacks. Copy the public key to the server. Read your public key from the workstation and save it to the authorized_keys file on the server, located at $HOME/.ssh/authorized_keys (where $HOME is the home directory of the user on the server you are connecting to). You can manually add the key or use the ssh-copy-id utility, which will prompt for the password. ssh-copy-id user@$IP Alternatively, you can add the key directly through your Hostman panel. Go to the Cloud servers → SSH Keys section and click Add SSH key.   Enter your key and give it a name. Once added, you can upload this key to a specific virtual machine or add it directly during server creation in the 6. Authorization section. To further secure SSH connections, adjust the SSH server configuration file at /etc/ssh/sshd_config by applying the following settings: PermitRootLogin no — Prevents login as the root user. PermitEmptyPasswords no — Disallows the use of empty passwords. X11Forwarding no — Disables forwarding of graphical applications. AllowUsers $USERS — Defines a list of users allowed to log in via SSH. Separate usernames with spaces. PasswordAuthentication no — Disables password authentication. PubkeyAuthentication yes — Enables public and private key authentication. HostbasedAuthentication no — Disables host-based authentication. PermitUserEnvironment no — Disallows changing environment variables to limit exploitation through variables like LD_PRELOAD. After adjusting the configuration file, restart the OpenSSH daemon: systemctl restart sshd Finally, after making these changes, you can conduct a security audit using a service like ssh-audit or this website designed for SSH security checks. This will help ensure your configuration is secure and appropriately hardened. Configuring Port Knocking SSH is a relatively secure protocol, as it was developed by the OpenBSD team, which prides itself on creating an OS focused on security and data integrity. However, even in such widely used and serious software, software vulnerabilities occasionally surface. Some of these vulnerabilities allow attackers to perform user enumeration. Although these issues are typically patched promptly, it doesn't eliminate the fact that recent critical vulnerabilities, like regreSSHion, have allowed for Remote Code Execution (RCE). Although this particular exploit requires special conditions, it highlights the importance of protecting your server's data. One way to further secure SSH is to hide the SSH port from unnecessary visibility. Changing the SSH port seems pointless because, after the first scan by an attacker, they will quickly detect the new port. A more effective strategy is to use Port Knocking, a method of security where a "key" (port knocking sequence) is used to open the port for a short period, allowing authentication. Install knockd using your package manager: sudo apt install knockd -y Configure knockd by editing the /etc/knockd.conf file to set the port knocking sequence and the corresponding actions. For example: [options] UseSyslog [openSSH] sequence = 7000,8000,9000 seq_timeout = 5 command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 9000,8000,7000 seq_timeout = 5 command = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn sequence: The port sequence that needs to be "knocked" (accessed) in the correct order. seq_timeout: The maximum time allowed to send the sequence (in seconds). command: The command to be executed once the sequence is received correctly. It typically opens or closes the SSH port (or another service). %IP%: The client IP address that sent the sequence (the one "knocking"). tcpflags: The SYN flag is used to filter out other types of packets. Start and enable knockd to run at boot: sudo systemctl enable --now knockd Use knock or nmap to send the correct port knocking sequence: Example command with nmap: nmap -Pn --max-retries 0 -p 7000,8000,9000 $IP Example command with knock: knock $IP 7000 8000 9000 Where $IP is the IP address of the server you're trying to connect to. If everything is configured correctly, once the correct sequence of port knocks is received, the SSH port (port 22) will temporarily open. At this point, you can proceed with the standard SSH authentication process. This technique isn't limited to just SSH; you can configure port knocking for other services if needed (e.g., HTTP, FTP, or any custom service). Port knocking adds an extra layer of security by obscuring the SSH service from the general public and only allowing access to authorized clients who know the correct sequence. Configuring Linux Kernel Parameters In today's insecure world, one of the common types of attack is Living off the Land (LOTL). This is when legitimate tools and resources are used to exploit and escalate privileges on the compromised system. One such tool that attackers frequently leverage is the ability to view kernel system events and message buffers. This technique is even used by advanced persistent threats (APTs). It is important to secure your Linux kernel configurations to mitigate the risk of such exploits. Below are some recommended settings that can enhance the security of your system. To enable ASLR (Address Space Layout Randomization), set these parameters: kernel.randomize_va_space = 2: Randomizes the memory spaces for applications to prevent attackers from knowing where specific processes will run.. kernel.kptr_restrict = 2: Restricts user-space applications from obtaining kernel pointer information. Also, disable system request (SysRq) functionality: kernel.sysrq = 0 And restrict access to kernel message buffer (dmesg): kernel.dmesg_restrict = 1 With this configuration, an attacker will not know a program's memory address and won't be able to infiltrate any important process for exploitation purposes. They will also be unable to view the kernel message buffer (dmesg) or send debugging requests (sysrq), which will further complicate their interaction with the system. Hardening Container Environments In modern architectures, container environments are an essential part of the infrastructure, offering significant advantages for developers, DevOps engineers, and system administrators. However, securing these environments is crucial to protect against potential threats and ensure the integrity of your systems. To protect container environments, it's essential to adopt secure development practices and integrate DevSecOps alongside existing DevOps methodologies. This also includes forming resilient patterns and building strong security behaviors from an information security perspective. Use minimal images, such as Google Distroless, and Software Composition Analysis (SCA) tools to check the security of your images. You can use the following methods to analyze the security of an image. Docker Scout and Docker SBOM for generating a list of artifacts that make up an image. Install Docker Scout and Docker SBOM as plugins for Docker.  Create a directory for Docker plugins (if it doesn't exist): mkdir -pv $HOME/.docker/cli-plugins Install Docker Scout: curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s -- Install Docker SBOM: curl -sSfL https://raw.githubusercontent.com/docker/sbom-cli-plugin/main/install.sh | sh -s -- To check for vulnerabilities in an image using Docker Scout: docker scout cves gradle To generate an SBOM using Docker SBOM (which internally uses Syft): docker sbom $IMAGE_NAME $IMAGE_NAME is the name of the container image you wish to analyze. To save the SBOM in JSON format for further analysis: docker sbom alpine:latest --format syft-json --output sbom.txt sbom.txt will be the file containing the generated SBOM. Container Scanning with Trivy Trivy is a powerful security scanner for container images. It helps identify vulnerabilities and misconfigurations. Install Trivy using the following script: curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.59.1 Run a security scan for a container image: trivy image $IMAGE_NAME $IMAGE_NAME is the name of the image you want to analyze. For detailed output in JSON format, use: trivy -q image --ignore-unfixed --format json --list-all-pkgs $IMAGE_NAME Even with the minimal practices listed in this section, you can ensure a fairly decent level of container security. Conclusion Using the techniques outlined in the article, you can significantly complicate or even prevent a hack by increasing entropy. However, it is important to keep in mind that entropy should be balanced with system usability to avoid creating unnecessary difficulties for legitimate users.
19 March 2025 · 18 min to read
Linux

How to Use SSH Keys for Authentication

Many cloud applications are built on the popular SSH protocol—it is widely used for managing network infrastructure, transferring files, and executing remote commands. SSH stands for Secure Socket Shell, meaning it provides a shell (command-line interface) around the connection between multiple remote hosts, ensuring that the connection is secure (encrypted and authenticated). SSH connections are available on all popular operating systems, including Linux, Ubuntu, Windows, and Debian. The protocol establishes an encrypted communication channel within an unprotected network by using a pair of public and private keys. Keys: The Foundation of SSH SSH operates on a client-server model. This means the user has an SSH client (a terminal in Linux or a graphical application in Windows), while the server side runs a daemon, which accepts incoming connections from clients. In practice, an SSH channel enables remote terminal management of a server. In other words, after a successful connection, everything entered in the local console is executed directly on the remote server. The SSH protocol uses a pair of keys for encrypting and decrypting information: public key and private key. These keys are mathematically linked. The public key is shared openly, resides on the server, and is used to encrypt data. The private key is confidential, resides on the client, and is used to decrypt data. Of course, keys are not generated manually but with special tools—keygens. These utilities generate new keys using encryption algorithms fundamental to SSH technology. More About How SSH Works Exchange of Public Keys SSH relies on symmetric encryption, meaning two hosts wishing to communicate securely generate a unique session key derived from the public and private data of each host. For example, host A generates a public and private key pair. The public key is sent to host B. Host B does the same, sending its public key to host A. Using the Diffie-Hellman algorithm, host A can create a key by combining its private key with the public key of host B. Likewise, host B can create an identical key by combining its private key with the public key of host A. This results in both hosts independently generating the same symmetric encryption key, which is then used for secure communication. Hence, the term symmetric encryption. Message Verification To verify messages, hosts use a hash function that outputs a fixed-length string based on the following data: The symmetric encryption key The packet number The encrypted message text The result of hashing these elements is called an HMAC (Hash-based Message Authentication Code). The client generates an HMAC and sends it to the server. The server then creates its own HMAC using the same data and compares it to the client's HMAC. If they match, the verification is successful, ensuring that the message is authentic and hasn't been tampered with. Host Authentication Establishing a secure connection is only part of the process. The next step is authenticating the user connecting to the remote host, as the user may not have permission to execute commands. There are several authentication methods: Password Authentication: The user sends an encrypted password to the server. If the password is correct, the server allows the user to execute commands. Certificate-Based Authentication: The user initially provides the server with a password and the public part of a certificate. Once authenticated, the session continues without requiring repeated password entries for subsequent interactions. These methods ensure that only authorized users can access the remote system while maintaining secure communication. Encryption Algorithms A key factor in the robustness of SSH is that decrypting the symmetric key is only possible with the private key, not the public key, even though the symmetric key is derived from both. Achieving this property requires specific encryption algorithms. There are three primary classes of such algorithms: RSA, DSA, and algorithms based on elliptic curves, each with distinct characteristics: RSA: Developed in 1978, RSA is based on integer factorization. Since factoring large semiprime numbers (products of two large primes) is computationally difficult, the security of RSA depends on the size of the chosen factors. The key length ranges from 1024 to 16384 bits. DSA: DSA (Digital Signature Algorithm) is based on discrete logarithms and modular exponentiation. While similar to RSA, it uses a different mathematical approach to link public and private keys. DSA key length is limited to 1024 bits. ECDSA and EdDSA: These algorithms are based on elliptic curves, unlike DSA, which uses modular exponentiation. They assume that no efficient solution exists for the discrete logarithm problem on elliptic curves. Although the keys are shorter, they provide the same level of security. Key Generation Each operating system has its own utilities for quickly generating SSH keys. In Unix-like systems, the command to generate a key pair is: ssh-keygen -t rsa Here, the type of encryption algorithm is specified using the -t flag. Other supported types include: dsa ecdsa ed25519 You can also specify the key length with the -b flag. However, be cautious, as the security of the connection depends on the key length: ssh-keygen -b 2048 -t rsa After entering the command, the terminal will prompt you to specify a file path and name for storing the generated keys. You can accept the default path by pressing Enter, which will create standard file names: id_rsa (private key) and id_rsa.pub (public key). Thus, the public key will be stored in a file with a .pub extension, while the private key will be stored in a file without an extension. Next, the command will prompt you to enter a passphrase. While not mandatory (it is unrelated to the SSH protocol itself), using a passphrase is recommended to prevent unauthorized use of the key by a third-party user on the local Linux system. Note that if a passphrase is used, you must enter it each time you establish the connection. To change the passphrase later, you can use: ssh-keygen -p Or, you can specify all parameters at once with a single command: ssh-keygen -p old_password -N new_password -f path_to_files For Windows, there are two main approaches: Using ssh-keygen from OpenSSH: The OpenSSH client provides the same ssh-keygen command as Linux, following the same steps. Using PuTTY: PuTTY is a graphical application that allows users to generate public and private keys with the press of a button. Installing the Client and Server Components The primary tool for an SSH connection on Linux platforms (both client and server) is OpenSSH. While it is typically pre-installed on most operating systems, there may be situations (such as with Ubuntu) where manual installation is necessary. The general command for installing SSH, followed by entering the superuser password, is: sudo apt-get install ssh However, in some operating systems, SSH may be divided into separate components for the client and server. For the Client To check whether the SSH client is installed on your local machine, simply run the following command in the terminal: ssh If SSH is supported, the terminal will display a description of the command. If nothing appears, you’ll need to install the client manually: sudo apt-get install openssh-client You will be prompted to enter the superuser password during installation. Once completed, SSH connectivity will be available. For the Server Similarly, the server-side part of the OpenSSH toolkit is required on the remote host. To check if the SSH server is available on your remote host, try connecting locally via SSH: ssh localhost If the SSH daemon is running, you will see a message indicating a successful connection. If not, you’ll need to install the SSH server: sudo apt-get install openssh-server As with the client, the terminal will prompt you to enter the superuser password. After installation, you can check whether SSH is active by running: sudo service ssh status Once connected, you can modify SSH settings as needed by editing the configuration file: ./ssh/sshd_config For example, you might want to change the default port to a custom one. Don’t forget that after making changes to the configuration, you must manually restart the SSH service to apply the updates: sudo service ssh restart Copying an SSH Key to the Server On Hostman, you can easily add SSH keys to your servers using the control panel. Using a Special Copy Command After generating a public SSH key, it can be used as an authorized key on a server. This allows quick connections without the need to repeatedly enter a password. The most common way to copy the key is by using the ssh-copy-id command: ssh-copy-id -i ~/.ssh/id_rsa.pub name@server_address This command assumes you used the default paths and filenames during key generation. If not, simply replace ~/.ssh/id_rsa.pub with your custom path and filename. Replace name with the username on the remote server. Replace server_address with the host address. If the usernames on both the client and server are the same, you can shorten the command: ssh-copy-id -i ~/.ssh/id_rsa.pub server_address If you set a passphrase during the SSH key creation, the terminal will prompt you to enter it. Otherwise, the key will be copied immediately. In some cases, the server may be configured to use a non-standard port (the default is 22). If that’s the case, specify the port using the -p flag: ssh-copy-id -i ~/.ssh/id_rsa.pub -p 8129 name@server_address Semi-Manual Copying There are operating systems where the ssh-copy-id command may not be supported, even though SSH connections to the server are possible. In such cases, the copying process can be done manually using a series of commands: ssh name@server_address 'mkdir -pm 700 ~/.ssh; echo ' $(cat ~/.ssh/id_rsa.pub) ' >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys' This sequence of commands does the following: Creates a special .ssh directory on the server (if it doesn’t already exist) with the correct permissions (700) for reading and writing. Creates or appends to the authorized_keys file, which stores the public keys of all authorized users. The public key from the local file (id_rsa.pub) will be added to it. Sets appropriate permissions (600) on the authorized_keys file to ensure it can only be read and written by the owner. If the authorized_keys file already exists, it will simply be appended with the new key. Once this is done, future connections to the server can be made using the same SSH command, but now the authentication will use the public key added to authorized_keys: ssh name@server_address Manual Copying Some hosting platforms offer server management through alternative interfaces, such as a web-based control panel. In these cases, there is usually an option to manually add a public key to the server. The web interface might even simulate a terminal for interacting with the server. Regardless of the method, the remote host must contain a file named ~/.ssh/authorized_keys, which lists all authorized public keys. Simply copy the client’s public key (found in ~/.ssh/id_rsa.pub by default) into this file. If the key pair was generated using a graphical application (typically PuTTY on Windows), you should copy the public key directly from the application and add it to the existing content in authorized_keys. Connecting to a Server To connect to a remote server on a Linux operating system, enter the following command in the terminal: ssh name@server_address Alternatively, if the local username is identical to the remote username, you can shorten the command to: ssh server_address The system will then prompt you to enter the password. Type it and press Enter. Note that the terminal will not display the password as you type it. Just like with the ssh-copy-id command, you can explicitly specify the port when connecting to a remote server: ssh client@server_address -p 8129 Once connected, you will have control over the remote machine via the terminal; any command you enter will be executed on the server side. Conclusion Today, SSH is one of the most widely used protocols in development and system administration. Therefore, having a basic understanding of its operation is crucial. This article aimed to provide an overview of SSH connections, briefly explain the encryption algorithms (RSA, DSA, ECDSA, and EdDSA), and demonstrate how public and private key pairs can be used to establish secure connections with a personal server, ensuring that exchanged messages remain inaccessible to third parties. We covered the primary commands for UNIX-like operating systems that allow users to generate key pairs and grant clients SSH access by copying the public key to the server, enabling secure connections.
30 January 2025 · 10 min to read
Servers

How to Protect a Server from DDoS Attacks

A DDoS attack (Distributed Denial of Service) aims to overwhelm a network with excessive traffic, reducing its performance or causing a complete outage. This is reflected in the term "denial-of-service" (refusal of service). The frequency and intensity of DDoS attacks have been rising rapidly. A report by Cloudflare noted that in 2021, the number of attacks grew by one-third compared to 2020, with a peak in activity observed in December. The duration of a DDoS attack can vary. According to research by Securelist: 94.95% of attacks end within four hours. 3.27% last between 5 to 9 hours. 1.05% persist for 10 to 19 hours. Only 0.73% of all attacks extend beyond 20 hours. Effective Tools for Protecting a Server from DDoS Attacks If you don't want to rely on vendors' solutions, paid services, or proprietary software, you can use the following tools to defend against DDoS attacks: IPTables. A powerful firewall tool available in Linux systems that allows precise control over incoming and outgoing traffic. CSF (ConfigServer Security and Firewall). A robust security tool that simplifies managing firewall rules and provides additional protection mechanisms. Nginx Modules. Modules specifically designed for mitigating DDoS attacks, such as limiting the number of requests per IP or delaying excessive requests. Software Filters. Tools or scripts that analyze and filter traffic to block malicious or excessive requests, helping to maintain service availability. IPTables. Blocking Bots by IP Address The IPTables tool helps protect a server from basic DDoS attacks. Its primary function is to filter incoming traffic through special tables. The resource owner can add custom tables. Each table contains a set of rules that govern the tool's behavior in specific situations. By default, there are only two response options: ACCEPT (allow access) and REJECT (block access). In IPTables, it is possible to limit the number of connections.  If a single IP address exceeds the allowed number of connections, the tool will block access for that IP. You can extend the tool's functionality with additional criteria: Limit: Sets a limit on the number of packet connections within a chosen time period. Hashlimit: Works similarly to Limit, but applies to groups of hosts, subnets, and ports. Mark: Used to mark packets, limit traffic, and filter. Connlimit: Limits the number of simultaneous connections for a single IP address or subnet. IPRange: Defines a range of IP addresses that are not considered as a subnet by the tool. Additionally, IPTables can use criteria such as Owner, State, TOS, TTL, and Unclean Match to set personalized configurations, effectively protecting the resource from DDoS attacks. The ipset kernel module allows you to create a list of addresses that exceed the specified connection limit. The ipset timeout parameter sets a time limit for the created list, which is enough to ride out a DDoS attack. By default, IPTables settings return to their basic configuration after a system reboot. To save the settings, you can use additional utilities (such as iptables-save or iptables-persistent), but it is recommended to start with the default options to avoid saving incorrect settings that could block server access for everyone. ConfigServer Security and Firewall While IPTables is a convenient and effective tool, it can be quite complex to configure. You’ll need to learn how to manage it and write additional scripts, and if something goes wrong, your resource may end up being a "closed club" for just a few users. CSF (ConfigServer Security and Firewall) is a "turnkey" configurator, meaning you only need to set the correct parameters and not worry about the server's security. Installing the Server Firewall The preliminary installation steps involve downloading two additional components required to run CSF: the Perl interpreter and the libwww library. The next step is to install ConfigServer Security and Firewall itself. Since the tool is not available in the official repository, you'll need to download it directly from the provided link or by fetching the ready-made archive: cd /usr/srcwget https://download.configserver.com/csf.tgz After downloading, extract the archive and move it to the defender’s files folder. Then, run the installation process. Once installed successfully, you can proceed with configuring CSF. Configuring the Server Firewall By default, the settings in ConfigServer and Firewall are active for 5 minutes, after which any changes are reset. This test format is useful for conducting experiments and understanding errors in the applied configuration. To switch to live mode, change the Testing value to 0. Proper configuration of CSF ensures reliable protection against DDoS attacks. Here are some essential commands in CSF: Specify incoming ports: TCP_IN = "22,23,25,36,75,87" Specify outgoing ports: TCP_OUT = "22,23,25,36,75,87" Configure email notifications for SSH connections: LF_SSH_EMAIL_ALERT = "1" Add an IP address to the exception list (useful for server management teams): csf -a 192.168.0.7 Block a specific IP address from connecting to the server: csf -d 192.168.0.6 Nginx Modules How can you protect your server from DDoS attacks using simpler methods? Use Nginx modules like limit_conn and limit_req. The limit_conn module limits the maximum number of connections to the server, while the limit_req module limits the number of requests within a specified time frame. For example, if you want to limit the number of simultaneous connections to 30 and restrict the number of connections within a 3-second window, the configuration will look as follows: limit_conn_zone $binary_remote_addr zone=perip: 30m;limit_req_zone $binary_remote_addr zone=dynamic:30m rate=3r/s; This configuration allows only 3 requests per second. Any additional requests are queued. The burst parameter controls the queue size. For example, if the burst value is set to 7, the module will queue up to 7 requests when the request count exceeds 10, while any further requests will be rejected with an error. Software Filter Server protection against DDoS attacks can also be achieved using web applications. A traffic filter uses JavaScript, which is inaccessible to bots, effectively redirecting DDoS attacks to a placeholder page. The operation of the filter is simple. The configuration defines conditions for blocking bots, and when a visitor meets those conditions, they are redirected to a placeholder page instead of the requested page. The filter can also specify the reason for the redirection.
03 December 2024 · 6 min to read

Do you have questions,
comments, or concerns?

Our professionals are available to assist you at any moment,
whether you need help or are just unsure of where to start.
Email us
Hostman's Support