By default, Apache serves content for any request that reaches the server, whether it comes via IP address or domain name. This happens because the default virtual host typically handles all requests that don't match specific hostnames in other virtual hosts.
Allowing access via IP address can lead to several issues:
- Potential security risks from automated scanners
- Duplicate content SEO problems
- Branding and user experience issues
- Possible confusion in analytics data
There are two primary methods to restrict IP-based access in Apache:
Method 1: Using the Default Virtual Host
Create or modify your default virtual host configuration (usually 000-default.conf) to block all IP-based access:
<VirtualHost *:80> ServerName default <Location /> Require all denied </Location> </VirtualHost>
Method 2: Using Name-Based Virtual Hosts
For a more sophisticated approach where you want to serve different content for IP access versus domain access:
<VirtualHost your.server.ip.address:80> ServerName your.server.ip.address DocumentRoot /var/www/blocked ErrorDocument 403 "Access via IP address is not allowed" <Directory "/var/www/blocked"> Require all denied </Directory> </VirtualHost> <VirtualHost *:80> ServerName yourdomain.com ServerAlias www.yourdomain.com DocumentRoot /var/www/yourdomain # Rest of your normal configuration </VirtualHost>
For more granular control, you can use mod_rewrite:
<VirtualHost *:80> RewriteEngine On RewriteCond %{HTTP_HOST} ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ RewriteRule ^(.*)$ - [F,L] # Your regular configuration </VirtualHost>
After making changes, always test:
sudo apachectl configtest sudo systemctl restart apache2
Then verify by trying to access your server via IP address - you should receive a 403 Forbidden error.
For SSL/TLS sites, you'll need to duplicate these configurations for port 443:
<VirtualHost *:443> ServerName default SSLEngine on # Your SSL certificates here <Location /> Require all denied </Location> </VirtualHost>
- Remember to configure both IPv4 and IPv6 addresses if your server supports both
- Be cautious with load balancers or reverse proxies that might use IP addresses
- Some applications might need specific adjustments for health checks
Many Apache administrators want to prevent direct IP access to their web servers for security and branding reasons. When users access sites via IP address, it can:
- Bypass SSL certificate validation
- Expose server information unnecessarily
- Cause confusion with name-based virtual hosts
Here are two effective approaches to block IP access in Apache:
1. Using Virtual Host Configuration
This is the most straightforward method. Edit your Apache configuration file (typically in /etc/httpd/conf/httpd.conf or /etc/apache2/sites-available/):
<VirtualHost *:80>
ServerName yourserverip
<Location />
Require all denied
</Location>
</VirtualHost>
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
DocumentRoot /var/www/html
# Your regular configuration here
</VirtualHost>
2. Using .htaccess File
For directory-level control, create or modify your .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^yourdomain\.com$ [NC]
RewriteCond %{HTTP_HOST} !^www\.yourdomain\.com$ [NC]
RewriteRule ^(.*)$ - [F,L]
For more robust control, consider this combined approach:
<VirtualHost *:80>
ServerName 192.168.1.1 # Replace with your server IP
Redirect 403 /
ErrorDocument 403 "Access via IP address is not allowed"
<Directory />
Order deny,allow
Deny from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example
# Normal configuration continues...
</VirtualHost>
After making changes, always:
- Test configuration syntax:
apachectl configtest
- Restart Apache:
systemctl restart httpd
- Verify by accessing both IP and domain
Problem: SSL/TLS certificate warnings when accessing via IP
Solution: Implement the same blocking for port 443 (HTTPS)
<VirtualHost *:443>
ServerName yourserverip
SSLEngine on
# Your SSL cert paths
<Location />
Require all denied
</Location>
</VirtualHost>