Skip to content

Instantly share code, notes, and snippets.

@bartosjiri
Last active August 9, 2021 17:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bartosjiri/f7e2e6a6c8890be7f5992470ac4c9350 to your computer and use it in GitHub Desktop.
Save bartosjiri/f7e2e6a6c8890be7f5992470ac4c9350 to your computer and use it in GitHub Desktop.
Secure Nginx server guide

Secure Nginx server guide

This gist will guide you through the setup of a basic Nginx web server using Debian-based Linux distribution.

It is primarily focused on securing the access to the server via various protocols and limiting user permissions.

Launch the server

  1. Launch a server with Ubuntu 19.04 or other Debian-based distribution.
  2. Log in using SSH with the server IP:
    ssh root@SERVER-IP
    
  3. Install software updates:
    apt-get update && apt-get upgrade
    
  4. Set the timezone:
    dpkg-reconfigure tzdata
    
  5. Set swap partition size:
    • For swap file: link
    • For swap partition: follow instructions of your server provider

Secure the access

Add limited user account

Create a primary administrative user to discontinue future operations through root user.

  1. Create the user, replacing YOUR-USERNAME with your desired username. You will be asked to provide a password for the user as well:
    adduser YOUR-USERNAME
    
  2. Add the user to the sudo group so you'll have administrative privileges:
    adduser YOUR-USERNAME sudo
    

Harden SSH Access

Switch from the default password authentication used for connecting to the server via SSH to a cryptographic key-pair.

  1. If you haven't created an RSA key-pair yet, follow this guide.
  2. Upload the public key to the server:
    • Linux:
      ssh-copy-id YOUR-USERNAME@SERVER-IP
      
    • macOS:
      scp ~/.ssh/id_rsa.pub YOUR-USERNAME@SERVER-IP:~/.ssh/authorized_keys
      
    • Windows: guide
  3. Disallow root logins over SSH and default passowrd authentication in /etc/ssh/sshd_config:
    PermitRootLogin no
    PasswordAuthentication no
    
  4. Listen on only preferred protocols in /etc/ssh/sshd_config file:
    • To listen only on IPv4:
      AddressFamily inet
      
    • To listen only on IPv6:
      AddressFamily inet6
      
  5. Restart the SSH service to load the new configuration:
    systemctl restart sshd
    
  6. Logout and relog with the created YOUR-USERNAME:
    ssh YOUR-USERNAME@SERVER-IP
    

Configure firewall

Define rules for the UFW firewall included in Ubuntu.

  1. Setup default traffic rules:
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw allow "OpenSSH"
    sudo ufw enable
    

Add protocol protection

Setup Fail2Ban to secure access via SSH and HTTP.

  1. Install Fail2ban:

    sudo apt-get install fail2ban
    
  2. Create a custom settings file:

    sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
    
  3. Point banning action to UFW firewall in /etc/fail2ban/jail.local file:

    #banaction = iptables-multiport
    #banaction_allports = iptables-allports
    banaction = ufw
    
  4. (Optional) Set custom ban duration and number of retries with watched period in /etc/fail2ban/jail.local file:

    bantime = 60m
    findtime = 10m
    maxretry = 5
    
  5. Enable specific protocols in /etc/fail2ban/jail.local file:

    • SSH
      [sshd]
      enabled = true
      port = ssh
      logpath = %(sshd_log)s
      backend = %(ssh_backend)s
      
    • HTTP
      [nginx-http-auth]
      enabled = true
      port = http, https
      logpath = /var/log/nginx/error.log
      
  6. (Optional) Whitelist your own IP address in /etc/fail2ban/jail.local file:

    [DEFAULT]
    ignoreip = 127.0.0.1/8, YOUR-IP
    
  7. (Optional) Change file modification backend

    This is a solution for fail2ban error No file(s) found for glob <path>. Also make sure that the listed file actually exists:

    backend = systemd
    
  8. (Optional) Restart Fail2ban:

    sudo fail2ban-client restart
    

    (Since we haven't installed Nginx in this guide yet, it will fail - it is included to keep fail2ban setup instructions complete)

Setup SFTP access

SFTP provides encrypted file transfer through SSH. MySecureShell utility is used to extend the default options of users and permissions management.

  1. Install MySecureShell:

    sudo apt-get install mysecureshell
    
  2. Setup global and user-specific configuration:

    sudo nano /etc/ssh/sftp_config
    

    To learn more about all available options, visit the official documentation.

  3. Restart MySecureShell to apply changes and verify the configuration:

    sudo systemctl restart mysecureshell
    sudo sftp-verif
    
  4. To manage users you can use one of sftp-user commands from this guide.

    For client-based user management, you can also try my custom configuration.

Setup Nginx

Install and launch the Nginx webserver for current setup.

  1. Install Nginx:

    sudo apt-get install nginx
    
  2. Start Nginx:

    sudo service nginx start
    
  3. Check if Nginx is running:

    sudo service nginx status
    
    • If the status prints out nginx.service: Failed to read PID from file /run/nginx.pid: Invalid argument, run the following:
      sudo mkdir /etc/systemd/system/nginx.service.d
      sudo sh -c 'printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf'
      sudo systemctl daemon-reload
      sudo systemctl restart nginx 
      
  4. Restart Fail2ban:

    sudo fail2ban-client restart
    
  5. Add firewall rules for Nginx:

    sudo ufw allow "Nginx Full"
    sudo ufw reload
    
  6. Check if you can access the default Nginx page at SERVER-IP in your browser.

  7. Further Nginx configurations can be done following this guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment