In this scenario, we have two Apache servers sharing a single public IP address:
- Server 1: 192.168.1.101 (handles example.com)
- Server 2: 192.168.1.102 (should handle beta.example.com exclusively)
Here's how to configure the reverse proxy on Server 1 to properly route only the beta subdomain:
<VirtualHost *:80>
ServerName example.com
# Your regular configuration for example.com
DocumentRoot /var/www/example.com
</VirtualHost>
<VirtualHost *:80>
ServerName beta.example.com
ServerAlias beta.example.com
ProxyPreserveHost On
ProxyPass / http://192.168.1.102/
ProxyPassReverse / http://192.168.1.102/
# Logging configuration
ErrorLog ${APACHE_LOG_DIR}/beta-error.log
CustomLog ${APACHE_LOG_DIR}/beta-access.log combined
</VirtualHost>
To ensure ONLY beta.example.com traffic gets proxied to Server 2, we'll add additional security measures:
<VirtualHost *:80>
ServerName beta.example.com
<Location />
Order allow,deny
Allow from all
# Prevent direct IP access
Deny from 192.168.1.102
</Location>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://192.168.1.102/
ProxyPassReverse / http://192.168.1.102/
</VirtualHost>
For HTTPS support with Let's Encrypt:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName beta.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/beta.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/beta.example.com/privkey.pem
ProxyPreserveHost On
ProxyPass / http://192.168.1.102/
ProxyPassReverse / http://192.168.1.102/
</VirtualHost>
</IfModule>
After making these changes:
- Run
sudo apache2ctl configtestto check for syntax errors - Reload Apache:
sudo systemctl reload apache2 - Test with:
curl -v http://beta.example.comcurl -v http://example.com(should NOT proxy)
Here's a common scenario many sysadmins face when working with multiple servers behind a single public IP:
Public IP (example.com) ├── Server 1 (192.168.1.101) - Handles main domain traffic └── Server 2 (192.168.1.102) - Should only handle beta subdomain
The key is to set up proper VirtualHost blocks with conditional proxying. Here's how to implement this on Server 1:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html/main
# Other main domain configurations
</VirtualHost>
<VirtualHost *:80>
ServerName beta.example.com
ProxyPreserveHost On
ProxyPass / http://192.168.1.102/
ProxyPassReverse / http://192.168.1.102/
# Optional: Add security restrictions
<Location "/">
Require all granted
</Location>
</VirtualHost>
For more complex scenarios where you need additional conditions, consider using mod_rewrite:
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
RewriteEngine On
RewriteCond %{HTTP_HOST} ^beta\.example\.com$ [NC]
RewriteRule ^(.*)$ http://192.168.1.102/$1 [P,L]
DocumentRoot /var/www/html/main
</VirtualHost>
When implementing reverse proxies, always consider these security measures:
- Configure proper ServerName and ServerAlias to prevent host header attacks
- Consider implementing SSL/TLS for all proxied connections
- Set appropriate timeouts: ProxyTimeout 300
- Restrict proxy to only necessary paths
If things don't work as expected, check these aspects:
# Verify Apache modules are loaded apachectl -M | grep -E 'proxy|rewrite' # Check syntax before restarting apachectl configtest # Examine access logs tail -f /var/log/apache2/access.log
Here's a complete configuration with SSL and optimized settings:
<VirtualHost *:443>
ServerName beta.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://192.168.1.102/ connectiontimeout=5 timeout=300
ProxyPassReverse / http://192.168.1.102/
<Proxy *>
Require all granted
</Proxy>
ErrorLog ${APACHE_LOG_DIR}/beta-error.log
CustomLog ${APACHE_LOG_DIR}/beta-access.log combined
</VirtualHost>