Server Setup for Rocky Linux 9

Login with Root

ssh root@your_server_ip

Install Package Updates

dnf check-update
dnf upgrade

Setup Firewall (firewalld)

dnf install firewalld -y
systemctl start firewalld
systemctl status firewalld

Check Status and Add HTTP/HTTPS

firewall-cmd --permanent --list-all
firewall-cmd --get-services
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

Create User

wheel = sudo group

adduser your_user
passwd your_user
usermod -aG wheel your_user

Setup SSH for New User

On local machine:

ssh-keygen -b 4096 -f /home/your_user/.ssh/ssh_key_name
ssh-copy-id -i /home/your_user/.ssh/ssh_key_name your_user@your_server_ip

To automatically use key (and optional different port) when connecting:

nano ~/.ssh/config

And in there add entry:

Host your_server_ip
  IdentityFile ~/.ssh/ssh_key_name
  IdentitiesOnly yes
  Port your_ssh_port

Now to connect to server with user:

ssh your_user@your_server_ip

Common SSH Configuration

Disabling Password Authentication

sudo nano /etc/ssh/sshd_config
...
PasswordAuthentication no
...
sudo systemctl restart sshd

Changing SSH Port Number

Make sure to open the new SSH port in your firewall before you restart the SSH daemon with the new port setting, otherwise you will be locked out of your server.

sudo firewall-cmd --permanent --add-port=your_ssh_port/tcp
sudo nano /etc/ssh/sshd_config
...
# Port 22
Port your_ssh_port
...

If SELinux is installed (e.g. for CentOS or RockyLinux), add the ssh port to the SELinux port management too.

sudo dnf install policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp your_ssh_port
sudo systemctl restart sshd

After confirming you can login via SSH through the new port, you can remove the default SSH port from the open firewall ports.

sudo firewall-cmd --permanent --remove-service ssh

Disable Root Login

sudo nano /etc/ssh/sshd_config
...
PermitRootLogin no
...
sudo systemctl restart sshd

Setup Nginx

sudo dnf install nginx
sudo systemctl enable nginx
sudo systemctl start nginx
systemctl status nginx

Visiting the server IP in your browser should give you the Nginx test page.

http://your_server_ip

Setup Nginx Site

Add new directory to host the site from.

sudo mkdir -p /var/www/your_domain/web
sudo chown -R $USER:$USER /var/www/your_domain/web
nano /var/www/your_domain/web/index.html
<html>
  <head>
    <title>Welcome to your_domain</title>
  </head>
  <body>
    <h1>
      Success! Your Nginx server is successfully configured for
      <em>your_domain</em>.
    </h1>
    <p>This is a sample page.</p>
  </body>
</html>

Add configuration file for the new site.

sudo nano /etc/nginx/conf.d/your_domain.conf
server {
    server_name your_domain www.your_domain;

    listen 80;
    listen [::]:80;

    root /var/www/your_domain/web;
    index index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Check configuration syntax

sudo nginx -t
sudo systemctl restart nginx

To serve site from non-default directory, add new directory to SELinux security context.

sudo chcon -vR system_u:object_r:httpd_sys_content_t:s0 /var/www/your_domain/web/

Setup SSL for the new site

Install certbot via the EPEL repository.

sudo dnf install epel-release
sudo dnf install certbot python3-certbot-nginx

Generate certificates for the site.

sudo certbot --nginx -d your_domain -d www.your_domain certonly

Update the nginx configuration for the site.

sudo nano /etc/nginx/conf.d/your_domain.conf
server {
    server_name your_domain www.your_domain;

    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/your_domain/web;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}


server {
    server_name your_domain www.your_domain;

    listen 80;
    listen [::]:80;

    return 301 https://$host$request_uri;
}

To redirect all non-www requests to the www domain, use this server configuration instead.

server {
    server_name www.your_domain;

    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/letsencrypt/live/www.your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.your_domain/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/your_domain/web;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    server_name your_domain;

    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    return 301 https://www.$host$request_uri;
}

server {
    server_name your_domain www.your_domain;

    listen 80;
    listen [::]:80;

    return 301 https://www.$host$request_uri;
}

Note that this server configuration uses a different certificate for the non-www and www domain respectively. Alternatively, you can use the same certificate for both domains by defining the second domain as Subject Alternative Name.

Test the renewal process.

sudo certbot renew --dry-run

Usually the certbot installation comes with automated renewals directly configured. This can be confirmed by checking either the crontab or systemd timers for the certbot renew command.

For systemd timers:

sudo systemctl list-timers --all

In case the systemd timer is inactive, you can enable and start it manually with:

sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer
sudo systemctl status certbot-renew.timer

For crontab:

sudo crontab -e

TODO

This post is Tagged with  the following keywords: