Skip to main content

Proxy

This page explains proxy concepts and provides practical examples you can use for deployment and troubleshooting. It focuses on common proxy types (forward, reverse), implementation examples (Squid, Nginx, Apache, HAProxy), and related concepts (transparent proxy, SOCKS, Layer 7).


Overview

A proxy is an intermediary that forwards requests between clients and other servers. Common goals when introducing a proxy include:

  • Security (authentication, access control)
  • Performance (caching, compression)
  • Routing and load distribution
  • Observability and filtering

Choose a proxy type and tool based on your requirements: application-aware routing (Nginx, HAProxy), caching and web proxying (Squid), or TCP-level balancing (HAProxy).

Types of Proxies

Forward Proxy

A forward proxy sits between clients and the internet. Clients must be configured (explicitly or transparently) to use it.

When to use:

  • Content filtering and web access control
  • Outbound caching and bandwidth savings
  • Enforcing corporate browsing policies

How it looks:

Client → Forward Proxy → Internet → Destination Server

Example: using curl with a forward proxy

# Simple request via a forward proxy
curl -x http://proxy.example.com:3128 https://example.com

# With basic auth
curl -x http://user:pass@proxy.example.com:3128 https://example.com

Squid (forward proxy) — basic config

Install (Debian/Ubuntu):

sudo apt update && sudo apt install -y squid
sudo systemctl enable --now squid

Minimal /etc/squid/squid.conf snippets:

# Listen on port 3128
http_port 3128

# Allow local networks
acl localnet src 10.0.0.0/8
acl localnet src 172.16.0.0/12
acl localnet src 192.168.0.0/16

http_access allow localnet
http_access allow localhost
http_access deny all

# Caching (tune to your environment)
cache_dir ufs /var/spool/squid 1000 16 256
cache_mem 256 MB

Add authentication when needed (basic_ncsa_auth + htpasswd) and tune ACLs for business hours or blocked domains.

Reverse Proxy

Reverse proxies accept client connections and forward them to backend servers. They are transparent to clients and commonly provide:

  • Load balancing
  • TLS termination
  • Caching and compression
  • URL-based routing (API gateways)

Client → Reverse Proxy → Backend Servers

Common reverse proxy choices: Nginx, HAProxy, Apache, Envoy.

Nginx — simple reverse proxy + TLS

Install:

sudo apt install -y nginx
sudo systemctl enable --now nginx

Example site configuration (simplified):

server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com;

ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;

location / {
proxy_pass http://backend_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

For load balancing, define an upstream block and use health checks or external monitoring to detect failures.

HAProxy — TCP/HTTP load balancing

Use HAProxy for high-performance, low-latency load balancing. Example haproxy.cfg snippet:

frontend http_front
bind *:80
mode http
default_backend web_servers

backend web_servers
mode http
balance roundrobin
option httpchk GET /health
server web1 10.0.1.10:8080 check
server web2 10.0.1.11:8080 check

Apache as Reverse Proxy

Enable proxy modules and configure a virtual host. Use ProxyPass/ProxyPassReverse for simple reverse proxy setups.

Transparent Proxy

A transparent proxy intercepts traffic without client-side configuration. Typically implemented with NAT/iptables rules that redirect traffic to a proxy process.

iptables example (redirect HTTP to Squid):

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Note: HTTPS interception requires SSL bumping and careful handling of certificates; use only with clear policy and legal review.

SOCKS Proxy (SOCKS5)

SOCKS proxies operate at the session layer and are protocol-agnostic. A common way to create a SOCKS5 proxy is with SSH:

# Create local SOCKS5 proxy on port 1080
ssh -D 1080 -N -f user@remote-host.example.com

# Use with curl (via a socks5 proxy)
curl --socks5 localhost:1080 https://example.com

Programmatically, use libraries such as PySocks or go-socks5 for application support.

Layer 7 (Application) Proxy

Layer 7 proxies understand HTTP semantics and can perform path-based routing, header rewriting, and response modification. They are ideal for API gateways and microservices routing.

Example: route /api/users to one service and /api/orders to another using Nginx location blocks.

Best Practices

  • Secure management endpoints: bind control/management interfaces to localhost and use auth.
  • Use TLS between clients and the reverse proxy, and consider mTLS to backends when required.
  • Keep security headers and rate limits in place at the edge (HSTS, X-Frame-Options, CSP).
  • Monitor latency and error rates (upstream_time, status codes) and expose metrics (Prometheus, HAProxy stats, Nginx VTS).
  • Tune timeouts and buffer sizes to match backend behavior (reduce proxy buffering for streaming endpoints).
  • Use a separate caching tier (Varnish or Nginx cache) when caching is critical.
  • Apply the principle of least privilege to ACLs and network segmentation.

Troubleshooting Checklist

  • Verify DNS resolution from the proxy host.
  • Check listening ports and firewall rules (ss/netstat, ufw/iptables).
  • Inspect access and error logs (Nginx: /var/log/nginx/, Squid: /var/log/squid/).
  • Reproduce requests locally with curl and verbose flags: curl -v --trace-ascii - --resolve example.com:443:IP https://example.com.
  • Confirm backend health endpoints and readiness probes.

Quick Recipes

  • Test a reverse proxy route:
curl -I https://example.com/some-path
  • Check cache status header (Nginx):
curl -I https://example.com/ | grep X-Cache-Status
  • Create a SOCKS5 tunnel and test:
ssh -D 1080 -N user@remote
curl --socks5 localhost:1080 https://api.example.com

Further reading and tools


If you'd like, I can: add a downloadable example configuration per proxy (ready-to-run), split this page into smaller per-tool pages, or add a troubleshooting playbook with commands and checks tailored to your environment. Tell me which you'd prefer next.

Example: route payments and auth API paths (nginx location blocks):

    # Payment service
location /api/payments {
proxy_pass http://payment-service:3002;
proxy_set_header Host $host;
}

# Authentication
location /api/auth {
proxy_pass http://auth-service:3003;
proxy_set_header Host $host;
}

Reverse Proxy Implementation Examples

Using Nginx

Installation:

# Ubuntu/Debian
sudo apt update
sudo apt install nginx

# CentOS/RHEL
sudo yum install nginx

# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx

Complete Configuration Example:

# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
use epoll;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

# Logging
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

# Performance settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 20M;

# Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;

# Backend servers
upstream app_servers {
least_conn;
server 10.0.1.10:8080 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 weight=1 max_fails=3 fail_timeout=30s;
}

# Reverse proxy server
server {
listen 80;
server_name example.com www.example.com;

# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com www.example.com;

# SSL configuration
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;

# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

# Static files
location /static/ {
alias /var/www/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}

# Proxy to backend
location / {
proxy_pass http://app_servers;

# Headers
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;
proxy_set_header X-Forwarded-Host $server_name;

# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Buffering
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;

# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}

Using Apache as Reverse Proxy

Installation and modules:

# Ubuntu/Debian
sudo apt install apache2
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo a2enmod ssl
sudo systemctl restart apache2

Configuration (/etc/apache2/sites-available/reverse-proxy.conf):

<VirtualHost *:80>
ServerName example.com

# Redirect to HTTPS
Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
ServerName example.com

# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key

# Security headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"

# Load balancer configuration
<Proxy balancer://mycluster>
BalancerMember http://10.0.1.10:8080 route=1
BalancerMember http://10.0.1.11:8080 route=2
BalancerMember http://10.0.1.12:8080 route=3
ProxySet lbmethod=byrequests
ProxySet stickysession=JSESSIONID
</Proxy>

# Reverse proxy
ProxyPreserveHost On
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/

# Logs
ErrorLog ${APACHE_LOG_DIR}/reverse-proxy-error.log
CustomLog ${APACHE_LOG_DIR}/reverse-proxy-access.log combined
</VirtualHost>

Using HAProxy

HAProxy is specifically designed for load balancing and reverse proxying:

# Installation
sudo apt install haproxy

Configuration (/etc/haproxy/haproxy.cfg):

global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon

# SSL/TLS settings
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

# Frontend - receives requests
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem

# Redirect HTTP to HTTPS
redirect scheme https if !{ ssl_fc }

# ACLs for routing
acl api_req path_beg /api
acl static_req path_beg /static

# Use backends based on ACLs
use_backend api_servers if api_req
use_backend static_servers if static_req
default_backend web_servers

# Backend - servers that fulfill requests
backend web_servers
balance roundrobin
option httpchk GET /health
http-check expect status 200

server web1 10.0.1.10:8080 check
server web2 10.0.1.11:8080 check
server web3 10.0.1.12:8080 check backup

backend api_servers
balance leastconn
option httpchk GET /api/health

server api1 10.0.2.10:8080 check
server api2 10.0.2.11:8080 check

backend static_servers
balance roundrobin

server static1 10.0.3.10:8080 check
server static2 10.0.3.11:8080 check

# Statistics page
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 30s
stats auth admin:password

1. Transparent Proxy

A transparent proxy intercepts network traffic without requiring client configuration. Clients are unaware they're using a proxy.

Use cases:

  • Content filtering in corporate networks
  • Traffic monitoring and analysis
  • Automatic caching

Implementation with iptables:

# Redirect HTTP traffic to proxy
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \
-j REDIRECT --to-port 3128

# Redirect HTTPS traffic
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 \
-j REDIRECT --to-port 3129

Squid transparent proxy configuration:

http_port 3128 transparent
https_port 3129 transparent ssl-bump cert=/etc/squid/ssl/squid.pem

# SSL bump configuration
ssl_bump server-first all
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/lib/ssl_db -M 4MB

2. SOCKS Proxy

SOCKS (Socket Secure) is a protocol that routes network packets between client and server through a proxy server.

Key features:

  • Works at a lower level (session layer)
  • Protocol-agnostic (works with any protocol)
  • No packet modification
  • Commonly used for SSH tunneling

Setting up SOCKS5 proxy with SSH:

# Create SOCKS proxy via SSH tunnel
ssh -D 1080 -N -f user@remote-server.com

# Use with applications
curl --socks5 localhost:1080 https://api.example.com

# Configure in browser
# Firefox: Settings → Network Settings → Manual proxy configuration
# SOCKS Host: localhost, Port: 1080, SOCKS v5

Python SOCKS proxy example:

import socks
import socket

# Configure SOCKS proxy
socks.set_default_proxy(socks.SOCKS5, "localhost", 1080)
socket.socket = socks.socksocket

# Now all socket connections use the proxy
import requests
response = requests.get('https://api.example.com')

3. Application Layer Proxy (Layer 7)

Operates at the application layer, understanding specific protocols:

HTTP/HTTPS Proxy:

# Nginx Layer 7 proxy with path-based routing
server {
listen 80;
server_name example.com;

location /app1 {
proxy_pass http://app1-backend:8080;
rewrite ^/app1(.*)$ $1 break;
}

location /app2 {
proxy_pass http://app2-backend:8080;
rewrite ^/app2(.*)$ $1 break;
}
}

4. TCP/UDP Proxy (Layer 4)

Operates at the transport layer, forwarding TCP/UDP packets:

Nginx Stream proxy for TCP:

stream {
upstream database {
server db1.example.com:5432;
server db2.example.com:5432;
}

server {
listen 5432;
proxy_pass database;
proxy_connect_timeout 1s;
}
}

HAProxy TCP proxy:

frontend mysql_front
bind *:3306
mode tcp
default_backend mysql_back

backend mysql_back
mode tcp
balance roundrobin
server mysql1 10.0.1.10:3306 check
server mysql2 10.0.1.11:3306 check

5. Content Delivery Network (CDN) as Proxy

CDNs act as geographically distributed reverse proxies:

Cloudflare configuration example:

# Origin server configuration
server {
listen 80;
server_name origin.example.com;

# Verify Cloudflare IPs
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 2400:cb00::/32;
real_ip_header CF-Connecting-IP;

location / {
root /var/www/html;
index index.html;
}
}

6. API Gateway

An API gateway is a specialized reverse proxy for microservices:

Kong API Gateway example:

# Add service
curl -i -X POST http://localhost:8001/services/ \
--data name=user-service \
--data url='http://user-service:8080'

# Add route
curl -i -X POST http://localhost:8001/services/user-service/routes \
--data 'paths[]=/users' \
--data 'methods[]=GET' \
--data 'methods[]=POST'

# Add rate limiting plugin
curl -i -X POST http://localhost:8001/services/user-service/plugins \
--data name=rate-limiting \
--data config.minute=100 \
--data config.policy=local

7. Service Mesh Proxy

Service mesh uses sidecar proxies for microservices communication:

Envoy proxy in Istio:

apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: my-app
spec:
ports:
- port: 8080
name: http
selector:
app: my-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:v1
ports:
- containerPort: 8080
# Istio automatically injects Envoy sidecar proxy

Best Practices

Security Best Practices

  1. Always use HTTPS for production
# Force HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
  1. Implement proper authentication
# Basic auth
location /admin {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://backend;
}
  1. Rate limiting
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_req zone=mylimit burst=20 nodelay;
  1. Hide proxy headers
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
add_header X-Frame-Options "SAMEORIGIN" always;

Performance Best Practices

  1. Enable caching
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m max_size=1g;
proxy_cache cache;
proxy_cache_valid 200 60m;
  1. Enable compression
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
  1. Connection pooling
upstream backend {
server backend:8080;
keepalive 32;
}

proxy_http_version 1.1;
proxy_set_header Connection "";
  1. Buffer configuration
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;

Monitoring and Logging

  1. Access logs
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';

access_log /var/log/nginx/access.log detailed;
  1. Health checks
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
  1. Metrics endpoint
# Nginx stub_status
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}

High Availability

  1. Multiple backend servers
upstream backend {
server backend1:8080 weight=3;
server backend2:8080 weight=2;
server backend3:8080 backup;
}
  1. Health monitoring
upstream backend {
server backend1:8080 max_fails=3 fail_timeout=30s;
server backend2:8080 max_fails=3 fail_timeout=30s;
}
  1. Session persistence
upstream backend {
ip_hash; # or: hash $cookie_sessionid;
server backend1:8080;
server backend2:8080;
}

Troubleshooting

Common Issues

1. Proxy not forwarding requests

Check proxy is running:

sudo systemctl status nginx
sudo netstat -tlnp | grep nginx

Verify configuration:

sudo nginx -t
sudo tail -f /var/log/nginx/error.log

2. SSL certificate errors

# Check certificate validity
openssl x509 -in /etc/nginx/ssl/cert.crt -text -noout

# Test SSL connection
openssl s_client -connect example.com:443 -servername example.com

3. Slow proxy response

# Check upstream response times
grep "upstream_response_time" /var/log/nginx/access.log | tail -20

# Monitor connections
watch -n 1 'netstat -an | grep ESTABLISHED | wc -l'

4. 502 Bad Gateway

Common causes:

  • Backend server down
  • Firewall blocking connections
  • Timeout too short
# Check backend connectivity
curl -v http://backend:8080

# Increase timeouts
proxy_connect_timeout 75s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;

Debugging Tools

# Check proxy headers
curl -v -H "Host: example.com" http://localhost/

# Test with specific proxy
curl -x http://proxy:8080 https://example.com

# Monitor traffic
sudo tcpdump -i any -nn port 80 or port 443

# Check DNS resolution
nslookup backend.example.com
dig backend.example.com

Conclusion

Proxies are essential components of modern infrastructure, providing:

  • Forward Proxy: Client-side intermediary for privacy, access control, and caching
  • Reverse Proxy: Server-side intermediary for load balancing, security, and performance
  • Specialized Proxies: SOCKS, transparent, API gateways, service mesh

Key takeaways:

  1. Choose the right proxy type for your use case
  2. Implement security best practices (HTTPS, authentication, rate limiting)
  3. Optimize for performance (caching, compression, connection pooling)
  4. Monitor and maintain (logging, health checks, metrics)
  5. Plan for high availability (multiple backends, health monitoring)

Additional Resources