December 5, 2025 18 min read Proxies, Networking, DevOps

Understanding Proxies and Reverse Proxies: A Complete Guide

Imagine you want to send a letter to someone, but you don't want them to know your home address. What do you do? You might ask a friend to send it on your behalf. In the computer world, proxies work similarly — they're middlemen that help you communicate safely and efficiently.

What is a Forward Proxy?

The Simple Explanation

A forward proxy (often just called a "proxy") is a server that sits between you and the internet. When you want to visit a website or download something, your request first goes to the proxy server, which then fetches what you want and brings it back to you.

Think of it like this: you're in a restaurant, and instead of going to the kitchen yourself, you tell the waiter what you want. The waiter goes to the kitchen, gets your food, and brings it to you. The kitchen staff never sees you directly — they only see the waiter.

Your Computer Request Forward Proxy Fetch Internet Response Data

The Real-World Problem It Solves

Consider a very common situation in companies:

The naive options are:

Both are bad for DMZ or production workloads.

The better solution is a forward proxy:

Your Private Server → Forward Proxy → Internet → Target Site
  1. You make a request (e.g., to download a package from pypi.org).
  2. The request is sent to your company's proxy server.
  3. The proxy (which has controlled internet access) calls pypi.org.
  4. The website sees the proxy's IP, not your private server.
  5. The proxy returns the response back to your server.

More Benefits of Forward Proxy

1. Privacy and Anonymity

Websites only see the proxy's IP address, not the real client. It's like wearing a mask on the internet.

2. Access Control

3. Content Filtering

Schools and enterprises use forward proxies to block inappropriate or risky content. Every request passes through the proxy, which can decide whether to allow or deny it.

4. Faster Access (Caching)

Forward proxies can cache responses:

5. Bypass Geographic Restrictions

If the proxy is in another country, sites see the proxy's location, not yours. This is how some users access geo-restricted content (subject to legal and policy constraints).

Setting Up Squid Forward Proxy (Step-by-Step)

Installation

Ubuntu/Debian:

sudo apt update
sudo apt install squid -y

RHEL/CentOS/Fedora:

sudo yum install squid -y
# or
sudo dnf install squid -y

Basic Squid Configuration

Edit the Squid configuration file:

sudo nano /etc/squid/squid.conf

Basic configuration example:

# Squid listening port
http_port 3128

# Define your internal network (adjust to your subnet)
acl localnet src 192.168.1.0/24
acl localnet src 10.0.0.0/8

# Safe ports (standard HTTP/HTTPS)
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 443         # https
acl Safe_ports port 21          # ftp
acl CONNECT method CONNECT

# Deny requests to unsafe ports
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

# Allow localhost and local network
http_access allow localhost
http_access allow localnet

# Deny all other access
http_access deny all

# Cache settings
cache_dir ufs /var/spool/squid 10000 16 256
cache_mem 256 MB
maximum_object_size 50 MB

# Logging
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log

Advanced Squid Configuration with Authentication

# Enable basic authentication
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic children 5
auth_param basic realm Squid Proxy Authentication
auth_param basic credentialsttl 2 hours

# Define authenticated users ACL
acl authenticated_users proxy_auth REQUIRED

# Allow authenticated users
http_access allow authenticated_users
http_access deny all

Create password file:

sudo apt install apache2-utils  # Ubuntu/Debian
sudo yum install httpd-tools     # RHEL/CentOS

# Create user
sudo htpasswd -c /etc/squid/passwords username
sudo chown proxy:proxy /etc/squid/passwords
sudo chmod 640 /etc/squid/passwords

Domain Whitelisting Configuration

# Whitelist specific domains only
acl allowed_domains dstdomain .github.com .pypi.org .npmjs.com .docker.io
acl localnet src 192.168.1.0/24

http_access allow localnet allowed_domains
http_access deny all

Start and Enable Squid

# Check configuration syntax
sudo squid -k parse

# Start Squid
sudo systemctl start squid
sudo systemctl enable squid

# Check status
sudo systemctl status squid

# View logs
sudo tail -f /var/log/squid/access.log

Firewall Configuration

# UFW (Ubuntu)
sudo ufw allow 3128/tcp

# Firewalld (RHEL/CentOS)
sudo firewall-cmd --permanent --add-port=3128/tcp
sudo firewall-cmd --reload

Configuring Linux Clients to Use Proxy

Temporary (Current Session Only)

export HTTP_PROXY="http://proxy.company.com:3128"
export HTTPS_PROXY="http://proxy.company.com:3128"
export NO_PROXY="localhost,127.0.0.1,.company.internal,192.168.1.0/24"

# Some tools use lowercase
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export no_proxy="$NO_PROXY"

Verify:

echo $HTTP_PROXY
echo $HTTPS_PROXY
echo $NO_PROXY

System-Wide (All Users)

Edit /etc/environment:

HTTP_PROXY="http://proxy-server.com:3128"
HTTPS_PROXY="http://proxy-server.com:3128"
NO_PROXY="localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16"
http_proxy="http://proxy-server.com:3128"
https_proxy="http://proxy-server.com:3128"
no_proxy="localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16"

User-Level (Shell Profile)

Add to ~/.bashrc or ~/.zshrc:

export HTTP_PROXY="http://proxy-server.com:3128"
export HTTPS_PROXY="http://proxy-server.com:3128"
export NO_PROXY="localhost,127.0.0.1,.internal"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export no_proxy="$NO_PROXY"

Application-Specific Proxy Settings

APT (Debian/Ubuntu)

sudo nano /etc/apt/apt.conf.d/proxy.conf

Acquire::http::Proxy "http://proxy-server.com:3128";
Acquire::https::Proxy "http://proxy-server.com:3128";

YUM/DNF (RHEL/CentOS/Fedora)

sudo nano /etc/yum.conf

proxy=http://proxy-server.com:3128

Docker (systemd)

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

[Service]
Environment="HTTP_PROXY=http://proxy-server.com:3128"
Environment="HTTPS_PROXY=http://proxy-server.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.internal"

sudo systemctl daemon-reload
sudo systemctl restart docker

Git

git config --global http.proxy  http://proxy-server.com:3128
git config --global https.proxy http://proxy-server.com:3128

npm

npm config set proxy       http://proxy-server.com:3128
npm config set https-proxy http://proxy-server.com:3128

pip

pip install package_name --proxy http://proxy-server.com:3128

or ~/.pip/pip.conf:

[global]
proxy = http://proxy-server.com:3128

Proxy with Authentication

export HTTP_PROXY="http://username:password@proxy-server.com:3128"
export HTTPS_PROXY="http://username:password@proxy-server.com:3128"

Security note: avoid storing plain-text passwords in files; prefer secure secrets handling where possible.

Testing Your Proxy Configuration

curl -I http://google.com
wget http://google.com

# Explicitly using a proxy
curl -I -x http://proxy-server.com:3128 http://google.com

# Test with authentication
curl -I -x http://username:password@proxy-server.com:3128 http://google.com

Setting Up Proxy in Windows (High Level)

What is a Reverse Proxy?

The Simple Explanation

With a forward proxy, the proxy sits in front of clients. With a reverse proxy, it sits in front of your servers.

From the outside world, everyone talks to the reverse proxy (for example Nginx or HAProxy). The reverse proxy then decides which backend server will actually handle the request.

A good mental model: your servers are in a secure room, and the reverse proxy is the receptionist at the front desk. Visitors (clients) never walk past the desk without going through the receptionist first.

Client Request Reverse Proxy Server 1 Server 2 Server 3

A Real-World Scenario

Imagine you run an online store with multiple backend servers:

Without a reverse proxy:

With a reverse proxy in front:

Client → Reverse Proxy → [ Web Server 1, Web Server 2, API Server ]
  1. Client connects to https://yourshop.com.
  2. DNS points yourshop.com to the reverse proxy's IP.
  3. The reverse proxy receives the request and decides where to send it.
  4. It forwards the request to one of the backend servers.
  5. The backend responds to the reverse proxy, which returns the response to the client.

Key Things a Reverse Proxy Can Do

1. Hide and Protect Your Servers

2. Load Balancing

Distribute requests across multiple servers so one machine is not overloaded:

3. SSL Termination

You can terminate HTTPS at the reverse proxy:

4. Caching and Compression

5. Single Entry Point for Microservices

You can route different URL paths to different services behind the reverse proxy:

location /api/      { proxy_pass http://localhost:8000/; }
location /users/    { proxy_pass http://localhost:8001/; }
location /payments/ { proxy_pass http://localhost:8002/; }

Setting Up Nginx Reverse Proxy (Step-by-Step)

Installation

Ubuntu/Debian:

sudo apt update
sudo apt install nginx -y

RHEL/CentOS/Fedora:

sudo yum install nginx -y
# or
sudo dnf install nginx -y

Basic Reverse Proxy Configuration

Create a new site configuration:

sudo nano /etc/nginx/sites-available/reverse-proxy

Simple single backend configuration:

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        proxy_pass http://192.168.1.100:3000;
        proxy_set_header Host $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;
        
        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}