DEV Community

Udara Dananjaya
Udara Dananjaya

Posted on

Setting Up a Secure Web Server Proxy

In secure environments, ensuring traffic is routed safely while maintaining HTTPS-only connections is critical. This guide outlines how to configure a web server to act as an intermediary, enabling secure public access to SSH and SCP services on an internal server.

Server Roles and Tools

  • Web Server: Acts as the gateway for public users. Runs both nginx and httpd for HTTPS handling and reverse proxy configurations.
  • Internal Server: Provides SSH access and also runs nginx and httpd for HTTPS services.

Flow Overview

  1. Public User [HTTPS] ➔ Accesses the web server.
  2. Web Server [HTTPS] ➔ Proxies traffic securely to the internal server.
  3. Internal Server [SSH via localhost] ➔ Enables SSH and SCP access through the web server.

1. Configuring HTTPS on the Internal Server

1.1 Generate a Self-Signed SSL Certificate

If your internal server does not have an SSL certificate:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/internal_server.key -out /etc/ssl/certs/internal_server.crt
Enter fullscreen mode Exit fullscreen mode
  • Place the certificate and key in secure directories like /etc/ssl/.

1.2 Configure Apache (httpd) for HTTPS

Edit the Apache configuration file:

sudo nano /etc/httpd/conf.d/ssl.conf
Enter fullscreen mode Exit fullscreen mode

Add or modify the following:

<VirtualHost *:443>
    ServerName internal-server-ip
    DocumentRoot /var/www/html

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/internal_server.crt
    SSLCertificateKeyFile /etc/ssl/private/internal_server.key

    <Directory /var/www/html>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

Restart the httpd service:

sudo systemctl restart httpd
Enter fullscreen mode Exit fullscreen mode

1.3 Configure Nginx (Optional)

If using nginx on the internal server instead of Apache, configure it as follows:

server {
    listen 443 ssl;
    server_name internal-server-ip;

    ssl_certificate /etc/ssl/certs/internal_server.crt;
    ssl_certificate_key /etc/ssl/private/internal_server.key;

    location / {
        proxy_pass http://localhost:application_port;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Enter fullscreen mode Exit fullscreen mode

Restart the nginx service:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

1.4 Restrict Access to the Internal Server

Use a firewall to allow only the web server to access the internal server:

sudo ufw allow from web-server-ip to any port 443
sudo ufw allow from web-server-ip to any port 22
sudo ufw enable
Enter fullscreen mode Exit fullscreen mode

2. Configuring the Web Server as a Reverse Proxy

2.1 Install and Configure HTTPS

If nginx is not installed:

sudo apt update
sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode

Generate or install an SSL certificate for the web server:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/web_server.key -out /etc/ssl/certs/web_server.crt
Enter fullscreen mode Exit fullscreen mode

2.2 Set Up the Reverse Proxy

Edit the Nginx configuration file:

sudo nano /etc/nginx/sites-available/reverse_proxy
Enter fullscreen mode Exit fullscreen mode

Add the following:

server {
    listen 443 ssl;
    server_name web-server-ip;

    ssl_certificate /etc/ssl/certs/web_server.crt;
    ssl_certificate_key /etc/ssl/private/web_server.key;

    location / {
        proxy_pass https://internal-server-ip;
        proxy_ssl_verify off; # Optional for self-signed certs
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable the configuration:

sudo ln -s /etc/nginx/sites-available/reverse_proxy /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

3. Enabling SSH Access via the Web Server

3.1 Set Up an SSH Tunnel

On the internal server, establish a reverse SSH tunnel to the web server:

ssh -R 2222:localhost:22 user@web-server-ip
Enter fullscreen mode Exit fullscreen mode
  • This forwards port 2222 on the web server to port 22 on the internal server.

3.2 Automate the Tunnel

To make the tunnel persistent, add the following to the internal server's SSH config (~/.ssh/config):

Host web-server
    HostName web-server-ip
    User user
    ServerAliveInterval 60
    RemoteForward 2222 localhost:22
Enter fullscreen mode Exit fullscreen mode

3.3 Access the Internal Server via the Web Server

From a public machine, SSH into the internal server through the web server:

ssh -p 2222 user@web-server-ip
Enter fullscreen mode Exit fullscreen mode

3.4 Transfer Files to the Internal Server Using SCP

To securely copy files to the internal server via the web server:

scp -P 2222 your_file user@web-server-ip:/path/on/internal-server
Enter fullscreen mode Exit fullscreen mode

4. Accessing the Internal Server from Public Internet

To securely access the internal server from the public internet, always connect to the web server first via HTTPS. The web server proxies traffic to the internal server. For SSH and file transfer:

  1. Establish a tunnel as described in Step 3.1.
  2. Use the web server’s public-facing IP address and the specified port to access the internal server through SSH or SCP.

Security Best Practices

  1. Restrict Access:

    • Use firewalls to limit traffic between servers.
    • Allow only trusted IPs to access the web server’s HTTPS port.
  2. Use Strong SSL/TLS Configurations:

    • Configure Nginx and Apache to use strong ciphers and protocols:
     ssl_protocols TLSv1.2 TLSv1.3;
     ssl_ciphers HIGH:!aNULL:!MD5;
    
  3. Enable Logging:

    • Monitor logs on both servers to detect suspicious activity:
      • Apache: /var/log/httpd/access_log
      • Nginx: /var/log/nginx/access.log

Top comments (0)