When setting up Apache VirtualHosts, a common requirement is to serve the same domain on multiple ports while maintaining proper hostname resolution. The key issue arises when additional ports inadvertently catch requests for unintended subdomains.
Here's the correct way to declare multiple ports for the same domain while preventing wildcard matching:
# Base SSL Configuration (Port 443)
Listen 443
NameVirtualHost *:443
<VirtualHost *:443>
ServerName domain.localhost
ServerAlias www.domain.localhost
DocumentRoot "/path/to/ssl/root"
# SSL Specific Settings
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
<Directory "/path/to/ssl/root">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# Non-SSL Configuration (Port 80)
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>
ServerName domain.localhost
ServerAlias www.domain.localhost
DocumentRoot "/path/to/non-ssl/root"
# Explicitly reject unintended subdomains
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.)?domain\.localhost$ [NC]
RewriteRule ^ - [F]
<Directory "/path/to/non-ssl/root">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Three key elements ensure proper isolation:
1. Separate Listen directives for each port
2. Explicit ServerName and ServerAlias declarations
3. Rewrite rules to block unintended subdomains
For non-standard ports (e.g., 8080), the configuration requires additional attention:
Listen 8080
<VirtualHost *:8080>
ServerName domain.localhost:8080
DocumentRoot "/path/to/custom/port/root"
# Prevent subdomain inheritance
UseCanonicalName On
<Directory "/path/to/custom/port/root">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
If subdomains still get caught:
# Check what Apache actually sees:
curl -I http://subdomain.domain.localhost
tail -f /var/log/apache2/error_log
# Verify virtual host matching:
apachectl -S
When working with Apache HTTP Server, you might need to serve the same website content on multiple ports. This is common for scenarios where you want both HTTP (port 80) and HTTPS (port 443) access, or when testing different configurations.
Here's how to properly configure multiple ports for the same VirtualHost:
# Listen directives for both ports
Listen 80
Listen 443
# Name-based virtual hosts for both ports
NameVirtualHost *:80
NameVirtualHost *:443
# HTTP configuration
ServerName domain.localhost
DocumentRoot "/path/to/your/site"
# Other HTTP-specific directives
# HTTPS configuration
ServerName domain.localhost
DocumentRoot "/path/to/your/site"
SSLEngine on
# SSL-specific directives
The issue you encountered with subdomains being caught by the port 80 VirtualHost occurs because Apache uses the first matching VirtualHost as a default. To prevent this:
# Add a default catch-all VirtualHost first
ServerName default.catch.all
DocumentRoot "/var/www/default"
# Then your specific VirtualHost
ServerName domain.localhost
DocumentRoot "/path/to/your/site"
# Other directives
For more complex scenarios where you need different behavior per port:
ServerName domain.localhost
DocumentRoot "/path/to/http/version"
# HTTP-specific rewrites or redirects
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
ServerName domain.localhost
DocumentRoot "/path/to/https/version"
# HTTPS-specific configuration
SSLEngine on
SSLCertificateFile "/path/to/cert.pem"
SSLCertificateKeyFile "/path/to/key.pem"
After configuration, always test with:
apachectl configtest
sudo apachectl restart
Use curl to verify both ports respond correctly:
curl -I http://domain.localhost
curl -Ik https://domain.localhost