Debug School

rakesh kumar
rakesh kumar

Posted on • Edited on

How to redirect and manage incoming traffic using proxy in virtual host

Key Functions of a Proxy

When to Use a Reverse Proxy

Request Forwarding

Difference between Difference Between ProxyPass and ProxyPassReverse

How to redirect HTTP traffic to HTTPS and then forwards secure HTTPS requests to the Traccar service running on port 8082

How to redirects HTTP to HTTPS and proxies requests to different front-end services (React, Vue, Angular) while using a shared backend API

Troubleshoot

A proxy is an intermediary server that sits between a client (such as a browser or a user device) and a destination server (such as a web server or API). The proxy receives requests from the client, forwards them to the destination server, and then returns the server's response to the client.

Key Functions of a Proxy

Request Forwarding: A proxy server forwards the client’s request to the destination server.

Response Handling: After the destination server processes the request, the proxy server forwards the response back to the client.

Interception and Control: It can inspect, filter, modify, or cache the requests and responses, giving it the ability to modify content, log requests, or block malicious traffic.

When to Use a Reverse Proxy

A reverse proxy can be used in various scenarios:

Load Balancing: Distribute incoming traffic across multiple backend servers.

Security: Protect backend servers by hiding their identity from the client.

Caching: Cache content to reduce the load on backend servers and improve performance.

SSL Termination: Handle SSL/TLS encryption/decryption on behalf of the backend servers.

API Gateway: Aggregate and route API requests from clients to different microservices.

Content Filtering: Inspect incoming and outgoing requests to enforce security policies.

Request Forwarding

Run the following commands to enable the modules:

sudo a2enmod proxy
sudo a2enmod proxy_http
Enter fullscreen mode Exit fullscreen mode

Redirect Traffic Based on IP Address to Different Ports


# /etc/httpd/conf/httpd.conf or /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName example.com

    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

This configuration forwards all incoming requests to the backend server running on localhost:3000 (e.g., Node.js server).

For example, let’s say you have multiple services running on the same server:

Service 1: Running on port 8081 (e.g., a web application)
Enter fullscreen mode Exit fullscreen mode
Service 2: Running on port 8082 (e.g., a REST API)
Enter fullscreen mode Exit fullscreen mode

You can configure Apache to redirect traffic to these different services based on the requested URL or conditions.

Define the Reverse Proxy Settings

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    # Enable mod_rewrite for URL rewriting (if necessary)
    RewriteEngine On

    # Reverse Proxy for Service 1 (on port 8081)
    ProxyPass "/service1" "http://localhost:8081"
    ProxyPassReverse "/service1" "http://localhost:8081"

    # Reverse Proxy for Service 2 (on port 8082)
    ProxyPass "/service2" "http://localhost:8082"
    ProxyPassReverse "/service2" "http://localhost:8082"

    # Log Settings
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
Enter fullscreen mode Exit fullscreen mode
curl http://example.com/service1
Enter fullscreen mode Exit fullscreen mode

Redirecting Traffic to Another Server's IP Address Using Apache Reverse Proxy

<VirtualHost *:80>
    ServerName yourdomain.com

    # Document root for your website (can be different)
    DocumentRoot /var/www/html

    # Enable mod_rewrite (optional, if needed)
    RewriteEngine On

    # Proxy pass for service1, redirecting to another server's IP address
    ProxyPass "/service1" "http://192.168.1.100:8080"
    ProxyPassReverse "/service1" "http://192.168.1.100:8080"

    # Custom log settings
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode



<VirtualHost *:80>
    ServerName yourdomain.com

    # Service 1 (forward to backend server 1)
    ProxyPass "/service1" "http://192.168.1.100:8080"
    ProxyPassReverse "/service1" "http://192.168.1.100:8080"

    # Service 2 (forward to backend server 2)
    ProxyPass "/service2" "http://192.168.1.101:8080"
    ProxyPassReverse "/service2" "http://192.168.1.101:8080"

    # Log settings
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

redirect to domain name
If you want to set up Apache as a reverse proxy to redirect traffic to different domains instead of specific IP addresses, you can modify the ProxyPass and ProxyPassReverse directives to forward the requests to different domains that are hosted on different servers.

In this case, you'll replace the IP addresses in the ProxyPass and ProxyPassReverse directives with the domain names of the backend servers


<VirtualHost *:80>
    ServerName yourdomain.com

    # Service 1 (forward to backend server 1 with domain)
    ProxyPass "/service1" "http://backend1.example.com"
    ProxyPassReverse "/service1" "http://backend1.example.com"

    # Service 2 (forward to backend server 2 with domain)
    ProxyPass "/service2" "http://backend2.example.com"
    ProxyPassReverse "/service2" "http://backend2.example.com"

    # Log settings
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

You have:

configuration of multiple front end sharing same backend on same server

Multiple React frontend projects (one for each service, e.g. /users, /orders)

A single Laravel backend API

An Apache reverse proxy to route frontend and API requests

<VirtualHost *:80>
    ServerName api.example.com

    # React frontends
    ProxyPass /users http://localhost:3001/
    ProxyPassReverse /users http://localhost:3001/

    ProxyPass /orders http://localhost:3002/
    ProxyPassReverse /orders http://localhost:3002/

    # Backend API
    ProxyPass /api http://localhost:8000/api
    ProxyPassReverse /api http://localhost:8000/api

    ProxyPass /sanctum http://localhost:8000/sanctum
    ProxyPassReverse /sanctum http://localhost:8000/sanctum
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

Load Balancing

A reverse proxy can distribute incoming requests to different backend servers to ensure no single server is overwhelmed, improving the system’s scalability and availability.

Example:
Apache as a reverse proxy with load balancing:

# /etc/httpd/conf/httpd.conf or /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName example.com

    # Enable Load Balancing using mod_proxy
    <Proxy "balancer://mycluster">
        BalancerMember http://192.168.1.1:8080
        BalancerMember http://192.168.1.2:8080
        ProxySet lbmethod=byrequests
    </Proxy>

    # Forward requests to the load balancer
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

In this example, Apache forwards all incoming traffic to two backend servers (192.168.1.1:8080 and 192.168.1.2:8080) and balances the load between them.

API Gateway in Microservices Architecture with Load Balancer


<VirtualHost *:80>
    ServerName api.example.com

    # Load balancing for user authentication service
    <Proxy "balancer://auth-service">
        BalancerMember http://192.168.1.1:8081
        BalancerMember http://192.168.1.2:8081
        ProxySet lbmethod=byrequests
    </Proxy>

    # Load balancing for payment processing service
    <Proxy "balancer://payment-service">
        BalancerMember http://192.168.1.1:8082
        BalancerMember http://192.168.1.2:8082
        ProxySet lbmethod=byrequests
    </Proxy>

    # Load balancing for order management service
    <Proxy "balancer://order-service">
        BalancerMember http://192.168.1.1:8083
        BalancerMember http://192.168.1.2:8083
        ProxySet lbmethod=byrequests
    </Proxy>

    # Load balancing for inventory service
    <Proxy "balancer://inventory-service">
        BalancerMember http://192.168.1.1:8084
        BalancerMember http://192.168.1.2:8084
        ProxySet lbmethod=byrequests
    </Proxy>

    # Route requests based on URL path
    ProxyPass "/auth" balancer://auth-service/
    ProxyPassReverse "/auth" balancer://auth-service/

    ProxyPass "/pay" balancer://payment-service/
    ProxyPassReverse "/pay" balancer://payment-service/

    ProxyPass "/order" balancer://order-service/
    ProxyPassReverse "/order" balancer://order-service/

    ProxyPass "/inventory" balancer://inventory-service/
    ProxyPassReverse "/inventory" balancer://inventory-service/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

Security/Access Control

A reverse proxy can help protect backend servers by hiding them behind the proxy. It can also enforce security policies such as IP filtering or rate limiting.

Example:
Restrict access to the backend server to specific IP addresses:

# /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName example.com

    # Restrict access to the backend server
    <Location />
        Order Deny,Allow
        Deny from all
        Allow from 192.168.1.100
        Allow from 192.168.1.101
    </Location>

    # Proxy to the backend server
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

In this case, only IP addresses 192.168.1.100 and 192.168.1.101 are allowed to access the backend server at localhost:8080.

SSL Termination

A reverse proxy can handle SSL/TLS encryption on behalf of backend servers, allowing the backend servers to focus on processing requests. This is called SSL Termination.

Example:
Enable SSL termination on Apache:

# /etc/apache2/sites-available/default-ssl.conf
<VirtualHost *:443>
    ServerName example.com

    # Enable SSL
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example_com.crt
    SSLCertificateKeyFile /etc/ssl/private/example_com.key

    # Proxy requests to backend server
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

This configuration terminates SSL at the proxy server, so the backend server communicates over HTTP (not HTTPS). It reduces the overhead of managing SSL certificates on multiple backend servers.

Caching

Reverse proxies can cache responses from backend servers, which reduces the load on the backend and improves the speed of content delivery.

Example:
Enable caching in Apache using mod_cache:

# /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName example.com

    # Enable caching
    CacheEnable disk /
    CacheRoot /var/cache/apache2

    # Proxy to backend server
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/

    # Set caching duration
    CacheDefaultExpire 600
    CacheMaxExpire 86400
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

This caches the responses for 10 minutes (CacheDefaultExpire 600), reducing the backend server load and speeding up content delivery for subsequent requests.

API Gateway (Microservices Architecture)

In a microservices architecture, a reverse proxy can act as an API gateway that routes client requests to appropriate microservices.

Example:
A reverse proxy to route API requests to different services:

# /etc/apache2/sites-available/api-gateway.conf
<VirtualHost *:80>
    ServerName api.example.com

    # Route to user service
    ProxyPass /users http://user-service:3000/
    ProxyPassReverse /users http://user-service:3000/

    # Route to order service
    ProxyPass /orders http://order-service:4000/
    ProxyPassReverse /orders http://order-service:4000/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

In this example, the reverse proxy routes requests to different microservices (/users to the user-service and /orders to the order-service).

Difference between Difference Between ProxyPass and ProxyPassReverse

ProxyPass and ProxyPassReverse are both crucial directives used when setting up Apache as a reverse proxy, but they serve distinct purposes:

ProxyPass: Forwards requests from clients to a backend server. It tells Apache how and where to send inbound web requests.

ProxyPassReverse: Rewrites HTTP response headers (specifically Location and Content-Location) from the backend so that redirects and links sent back to the client point to the proxy server, not the backend’s internal address.

In essence:

ProxyPass controls request forwarding (client → Apache → backend).

ProxyPassReverse controls response header rewriting (backend → Apache adjusts URLs → client), making the user experience seamless and masking backend technology and URLs.

Unique Examples
Basic Reverse Proxying a Web Application

ProxyPass /app http://localhost:8080/
ProxyPassReverse /app http://localhost:8080/
Enter fullscreen mode Exit fullscreen mode

ProxyPass: Forwards all requests from /app to your local application.

ProxyPassReverse: Ensures backend redirects (e.g., Location: http://localhost:8080/login) are rewritten to /app/login for the user.

Proxying with a Remote Backend Server


ProxyPass / http://192.168.1.100:8081/
ProxyPassReverse / http://192.168.1.100:8081/
Enter fullscreen mode Exit fullscreen mode

Users visiting your proxy see your domain, not the backend’s private IP.

Backend redirects like Location: http://192.168.1.100:8081/foo appear as your domain’s equivalent URL to the client.

Path Mapping Between Proxy and Backend

ProxyPass /service http://my-backend:9000/api/
ProxyPassReverse /service http://my-backend:9000/api/
Enter fullscreen mode Exit fullscreen mode

URLs like /service/users are actually served from /api/users on the backend.

If backend responds with a redirect to http://my-backend:9000/api/login, ProxyPassReverse rewrites it to /service/login.

Proxy for a Jenkins Instance with Path Translation

ProxyPass /jenkins http://localhost:8081/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8081/jenkins
Enter fullscreen mode Exit fullscreen mode

All /jenkins requests are handled by your Jenkins server on a different port.

Jenkins redirects (such as for login) will keep the frontend path /jenkins visible to the user instead of exposing the backend host or port.

Using ProxyPassReverse for Cookie Domains

ProxyPass /mail http://mail.internal:8888/
ProxyPassReverse /mail http://mail.internal:8888/
ProxyPassReverseCookieDomain mail.internal yourdomain.com
Enter fullscreen mode Exit fullscreen mode

reverse-proxy
load-balancer-vs-reverse-proxy-vs-forward-proxy-vs-api-gateway

HTTP traffic is redirected to HTTPS and then forwards secure HTTPS requests to the Traccar service running on port 8082

read for proxy

proxy-in-virtual-host

/opt/lampp/etc/extra/httpd-vhosts.conf

<VirtualHost *:80>
    ServerName traccar.motoshare.in
    Redirect permanent / https://traccar.motoshare.in/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

/opt/lampp/etc/extra/httpd-ssl.conf

<VirtualHost *:443>
    ServerName traccar.motoshare.in
    SSLEngine On
    SSLCertificateFile "/opt/lampp/etc/certs/traccar.motoshare.in/traccar.motoshare.in.cer"
    SSLCertificateKeyFile "/opt/lampp/etc/certs/traccar.motoshare.in/traccar.motoshare.in.key"
    SSLCACertificateFile "/opt/lampp/etc/certs/traccar.motoshare.in/fullchain.cer"

    ProxyPreserveHost On
    ProxyPass / http://localhost:8082/
    ProxyPassReverse / http://localhost:8082/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

How to redirects HTTP to HTTPS and proxies requests to different front-end services (React, Vue, Angular) while using a shared backend API


<VirtualHost *:80>
    ServerName myapp.mydomain.com

    # Redirect HTTP to HTTPS
    Redirect permanent / https://myapp.mydomain.com/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode
<VirtualHost *:443>
    ServerName myapp.mydomain.com

    # SSL Configuration
    SSLEngine On
    SSLCertificateFile "/etc/ssl/certs/myapp.mydomain.com.crt"
    SSLCertificateKeyFile "/etc/ssl/private/myapp.mydomain.com.key"
    SSLCACertificateFile "/etc/ssl/certs/myapp.mydomain.com.chain.pem"

    # Proxying React service running on port 3000
    ProxyPass /react http://localhost:3000/
    ProxyPassReverse /react http://localhost:3000/

    # Proxying Vue service running on port 8081
    ProxyPass /vue http://localhost:8081/
    ProxyPassReverse /vue http://localhost:8081/

    # Proxying Angular service running on port 4200
    ProxyPass /angular http://localhost:4200/
    ProxyPassReverse /angular http://localhost:4200/

    # Laravel Backend API (assuming it's running on port 8000)
    ProxyPass /api http://localhost:8000/api
    ProxyPassReverse /api http://localhost:8000/api

    # Optional: Serve static content or assets for React/Vue/Angular if necessary
    Alias /react/static /var/www/myapp/react/static
    Alias /vue/static /var/www/myapp/vue/static
    Alias /angular/static /var/www/myapp/angular/static

    <Directory "/var/www/myapp/react/static">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    <Directory "/var/www/myapp/vue/static">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    <Directory "/var/www/myapp/angular/static">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

--------OR---------------------------------

<VirtualHost *:443>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com

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

    # Ensure these modules are loaded
    ProxyPreserveHost On

    # Proxy /react to React app (port 3000)
    ProxyPass /react http://localhost:3000/
    ProxyPassReverse /react http://localhost:3000/

    # Proxy /vue to Vue app (port 4000)
    ProxyPass /vue http://localhost:4000/
    ProxyPassReverse /vue http://localhost:4000/

    # Proxy /angular to Angular app (port 5000)
    ProxyPass /angular http://localhost:5000/
    ProxyPassReverse /angular http://localhost:5000/

    # Proxy /api to backend API (port 8000) - shared for all
    ProxyPass /api http://localhost:8000/api
    ProxyPassReverse /api http://localhost:8000/api

    # Optional: Static root to one of the frontends
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

Troubleshoot

custom-error-handling-and-indexing-in-apache-http-server

sudo tail -f /opt/lampp/logs/access_log
tail -f storage/logs/laravel.log
tail -f /opt/traccar/logs/tracker-server.log
Enter fullscreen mode Exit fullscreen mode

Top comments (0)