When attempting to configure Apache to serve both HTTP and HTTPS traffic on the same port (in this case 20100), you'll encounter a fundamental protocol mismatch. The error message clearly indicates the issue:
Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.
This happens because Apache can't simultaneously listen for both encrypted (HTTPS) and unencrypted (HTTP) traffic on the same port without proper configuration.
For modern Apache versions (2.2.12+), you can use SNI (Server Name Indication) to handle this scenario:
NameVirtualHost *:20100
Listen 20100
<VirtualHost *:20100>
ServerName example.com
SSLStrictSNIVHostCheck off
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
# Redirect HTTP to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
Another method involves configuring mod_ssl to handle both protocols:
<VirtualHost *:20100>
ServerName example.com
# SSL Configuration
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
# HTTP to HTTPS redirection
RewriteEngine On
RewriteCond %{SERVER_PORT} =20100
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R=301,L]
</VirtualHost>
After making changes, always test your configuration:
apachectl configtest
service apache2 restart
Then verify with curl:
curl -v http://example.com:20100
curl -vk https://example.com:20100
When implementing this configuration:
- Ensure you have proper SSL certificates (consider Let's Encrypt for free certificates)
- Enable HSTS headers for additional security
- Disable weak cipher suites
- Monitor for mixed content warnings
# Example HSTS header
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
When attempting to run both HTTP and HTTPS services on the same port in Apache, you'll encounter a fundamental protocol mismatch. The standard configuration results in the familiar error:
Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.
Modern web servers can distinguish between protocols using Application-Layer Protocol Negotiation (ALPN) or Server Name Indication (SNI). For our solution, we'll leverage Apache's mod_ssl
and mod_rewrite
modules to create a seamless redirection system.
First, ensure your Apache configuration has these modules loaded:
LoadModule ssl_module modules/mod_ssl.so
LoadModule rewrite_module modules/mod_rewrite.so
Here's the complete virtual host configuration for port 20100:
<VirtualHost *:20100>
ServerName yourdomain.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
SSLCertificateChainFile /path/to/chain.pem
# Protocol detection and redirection
RewriteEngine On
RewriteCond %{SERVER_PORT} ^20100$
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Document root and other directives
DocumentRoot /var/www/html
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
The critical component is the rewrite rule that detects non-SSL requests on port 20100. The %{HTTPS}
variable checks the protocol while %{SERVER_PORT}
verifies the port number.
For servers where mod_rewrite isn't available, you can use ErrorDocument handling:
<VirtualHost *:20100>
ErrorDocument 400 "https://%{SERVER_NAME}%{REQUEST_URI}"
SSLEngine on
# ... rest of SSL configuration
</VirtualHost>
After implementation, test with these curl commands:
curl -I http://yourdomain.com:20100
curl -Ik https://yourdomain.com:20100
You should see a 301 redirect for HTTP requests and a 200 OK for HTTPS requests.
Running both protocols on the same port means every HTTP request first hits the SSL engine before redirection. For high-traffic sites, consider:
- Implementing HSTS (HTTP Strict Transport Security)
- Using a load balancer for SSL termination
- Setting proper cache headers for redirects
If you encounter problems, check:
- Firewall rules allowing traffic on port 20100
- Certificate paths and permissions
- Apache error logs for specific failure messages
- Browser cache clearing for redirect testing