How to Configure Multiple Ports for the Same VirtualHost in Apache (SSL & Non-SSL Examples)


2 views

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