When configuring an Apache reverse proxy with multiple VirtualHosts, implementing granular IP-based access control for specific domains while maintaining open access for others presents unique challenges. The key issue arises from the interaction between global Proxy directives and VirtualHost-specific configurations.
Many administrators try these common but ineffective approaches:
<VirtualHost *:80>
Servername newsite.com
<Location http://newsite.com>
Order Deny,Allow
Deny from all
Allow from x.x.x.x
</Location>
<IfModule rewrite_module>
RewriteRule ^/$ http://newsite.internal.com [proxy]
</IfModule>
</VirtualHost>
This fails because Location blocks match against the local path, not the proxied URL. Similarly, placing directives in the wrong context won't achieve the desired IP restriction.
The correct implementation combines VirtualHost definitions with proper Proxy directive placement:
<VirtualHost *:80>
ServerName newsite.com
# First restrict access
<Proxy *>
Order deny,allow
Deny from all
Allow from x.x.x.x
Allow from y.y.y.y/24
</Proxy>
# Then define the proxy rules
ProxyPass / http://newsite.internal.com/
ProxyPassReverse / http://newsite.internal.com/
</VirtualHost>
# Default open access for other sites
<VirtualHost *:80>
ServerName othersite.com
ProxyPass / http://othersite.internal.com/
ProxyPassReverse / http://othersite.internal.com/
</VirtualHost>
For newer Apache versions, the modern syntax provides better control:
<VirtualHost *:80>
ServerName newsite.com
<Location />
Require ip x.x.x.x
Require ip y.y.y.y/24
</Location>
ProxyPass / http://newsite.internal.com/
ProxyPassReverse / http://newsite.internal.com/
</VirtualHost>
- Always place restrictive VirtualHosts before permissive ones in your config
- Test with 'apachectl configtest' before reloading
- Consider combining with mod_remoteip when behind additional proxies
- For complex rules, use SetEnvIf to create custom access conditions
If access controls still don't work:
- Check Apache's error log for configuration warnings
- Verify module loading order (mod_access_compat before mod_authz_host)
- Test with curl -v to see request headers and response codes
- Use 'apachectl -M' to confirm required modules are loaded
When working with Apache reverse proxy configurations, we often need to implement granular access control for specific proxied sites while maintaining open access for others. The challenge arises when trying to restrict access to one particular domain (newsite.com) while keeping other proxied sites publicly accessible.
The primary issue stems from the interaction between different proxy directives in Apache's configuration hierarchy. When you have both specific and wildcard proxy directives, Apache processes them in a particular order that might override your intended restrictions.
# Problematic configuration example
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Proxy http://newsite.com/>
Order deny,allow
Deny from all
Allow from x.x.x.x
</Proxy>
For IP-based access control to work effectively with reverse proxying, you need to:
- Place the specific proxy directives before the wildcard ones
- Use the VirtualHost context for site-specific restrictions
- Combine Proxy and Location directives appropriately
Here's a properly structured configuration that achieves the desired access control:
<VirtualHost *:80>
ServerName newsite.com
# First, set up the IP restrictions
<Location />
Order deny,allow
Deny from all
Allow from 192.168.1.100
Allow from 10.0.0.0/24
</Location>
# Then configure the reverse proxy
ProxyPass / http://newsite.internal.com/
ProxyPassReverse / http://newsite.internal.com/
# Additional proxy settings if needed
ProxyPreserveHost On
</VirtualHost>
# General proxy settings for other sites
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
If you prefer using Proxy blocks, you can structure it this way:
<VirtualHost *:80>
ServerName newsite.com
<Proxy http://newsite.internal.com/*>
Order deny,allow
Deny from all
Allow from x.x.x.x
</Proxy>
ProxyPass / http://newsite.internal.com/
ProxyPassReverse / http://newsite.internal.com/
</VirtualHost>
- Always place more specific rules before general ones
- Test configurations with "apachectl configtest" before applying
- Consider using Require instead of Order/Deny/Allow if using Apache 2.4+
- For complex scenarios, combine with mod_rewrite conditions