How to Configure Apache VirtualHost for Dual HTTP and HTTPS Port Serving (80 & 443)


2 views

When configuring Apache to serve both HTTP (port 80) and HTTPS (port 443) under the same VirtualHost, we encounter a fundamental protocol conflict. The SSL Engine directives (SSLEngine on, certificate paths) cause errors when processing plain HTTP requests. Here's why this happens:

# This causes port 80 to fail
SSLEngine on
SSLCertificateFile /path/to/cert.crt
SSLCertificateKeyFile /path/to/key.key

The correct approach involves creating separate VirtualHost blocks for each protocol while maintaining the same DocumentRoot and other configurations:


    ServerName mysite.co.uk
    DocumentRoot /var/www/mysite/public
    # Other HTTP-only configurations
    
    # Redirect specific paths to HTTPS
    
        Redirect permanent https://mysite.co.uk/secure-area
    



    ServerName mysite.co.uk
    DocumentRoot /var/www/mysite/public
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/apache2/crts/mysite.crt
    SSLCertificateKeyFile /etc/apache2/crts/mysite.key
    SSLCertificateChainFile /etc/apache2/crts/DigiCertCA.crt
    
    # HTTPS-only configurations

For a site that needs partial SSL, consider these implementation patterns:

# Option 1: Directory-based SSL

    SSLEngine on
    # ... SSL config ...
    
    
        SSLRequireSSL
    


# Option 2: Environment variable detection
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/secure-area
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

When implementing dual-port serving, remember these optimization tips:

  • Use KeepAlive carefully - different timeouts for HTTP/HTTPS
  • Configure separate logging for each protocol
  • Consider HTTP/2 for HTTPS connections
# HTTP/2 configuration example
Protocols h2 http/1.1
H2Direct on

Watch for these frequent problems:

  1. Certificate path permissions (Apache user needs read access)
  2. Port conflicts (verify nothing else is using 80/443)
  3. Mixed content warnings (ensure assets load properly)
# Diagnostic commands
sudo apachectl configtest
sudo netstat -tulnp | grep ':443'
sudo tail -f /var/log/apache2/error.log

When configuring Apache to handle both HTTP and HTTPS traffic on standard ports (80/443) within the same VirtualHost, developers often encounter SSL engine conflicts. The fundamental issue arises because SSL directives automatically configure the host for HTTPS-only operation, breaking HTTP access.

The proper approach requires creating separate VirtualHost declarations while maintaining configuration DRY principles:

# Base configuration for both protocols
Define SHARED_CONFIG {
    ServerAdmin webmaster@localhost
    ServerName mysite.co.uk
    DocumentRoot /var/www/mysite/public
    
    
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    
    
    ErrorLog /var/log/apache2/error.log
    CustomLog /var/log/apache2/access.log combined
}

# HTTP VirtualHost

    Use SHARED_CONFIG
    # Non-SSL specific directives


# HTTPS VirtualHost

    Use SHARED_CONFIG
    SSLEngine on
    SSLCertificateFile /etc/apache2/crts/mysite.crt
    SSLCertificateKeyFile /etc/apache2/crts/mysite.key
    SSLCertificateChainFile /etc/apache2/crts/DigiCertCA.crt
    
    # Modern SSL configuration
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5

For complex scenarios requiring protocol-specific logic:

# Conditional content based on protocol
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^/secure-path(.*) https://%{HTTP_HOST}/secure-path$1 [R=301,L]

RewriteCond %{HTTPS} on
RewriteRule ^/non-secure-path(.*) http://%{HTTP_HOST}/non-secure-path$1 [R=301,L]

When serving mixed content:

  • Enable HTTP/2 for HTTPS connections: Protocols h2 http/1.1
  • Implement HSTS carefully: Header always set Strict-Transport-Security "max-age=63072000"
  • Use separate log files for protocol analysis
# Verify configuration
apachectl configtest

# Check listening ports
ss -tulnp | grep apache

# Debug SSL handshake
openssl s_client -connect mysite.co.uk:443 -servername mysite.co.uk -status