Trying to get Apache 2.4.33 on an AWS EC2 instance to terminate an SSL certificate correctly, it doesn't seem to populate the HTTPS environment variable to PHP, and .htaccess rewrite rules don't work at all.
This is my setup:
/etc/httpd/conf/httpd.conf:
<Directory "/var/www/">
Options -Indexed +FollowSymLinks -MultiViews
AllowOverride all
Require all granted
</Directory>
/etc/httpd/conf.d/ssl.conf:
Listen 443 https
<VirtualHost _default_:443>
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/cert.crt
SSLCertificateKeyFile /etc/pki/tls/private/private.key
SSLCertificateChainFile /etc/pki/tls/certs/chain.ca-bundle
</VirtualHost>
/etc/httpd/conf.d/vhosts.conf:
<VirtualHost *:80 *:443>
DocumentRoot /var/www/example.com
ServerName example.com
ServerAlias www.example.com
UseCanonicalPhysicalPort on
</VirtualHost>
/var/www/example.com/.htaccess:
RewriteEngine on
#if ELB http
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
#if server http
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
#if www.
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
Edit: .htaccess has -rw-rw-r-- permissions.
And this is what PHP reports:
for http://example.com (which for some reason is not enforced, despite .htaccess):
$_SERVER['HTTPS'] = NULL
$_SERVER['SERVER_PORT'] = '80'
for https://example.com:
$_SERVER['HTTPS'] = NULL
$_SERVER['SERVER_PORT'] = '443'
The only reason the port is correct is due to UseCanonicalPhysicalPort, but why is the HTTPS variable always null, and why doesn't .htaccess do anything?
Edit:
Per Patrick's comment, I've split the ports into one exclusive VirtualHost for each port, and removed the UseCanonicalPhysicalPort directive. This seems to have solved the first issue, and PHP now correctly displays both the $_SERVER['HTTPS'] and SERVER_PORT variables.
The second issue remains though: .htaccess rewrite rules are still not working.
Thanks for any insight!
Related
I have read quite a few postings on configuring SSL on Xampp/Windows/Apache/VirtualHost and think I have done it right, but when I enter in the virtualhost url (q.localhost), I always get to the default localhost Xampp info page, which reads: 'http://q.localhost/xampp/' in the url bar.
Below are what I have in my various files that I think are relevant:
Apache httpd.conf:
LoadModule ssl_module modules/mod_ssl.so
Apache httpd-vhosts.conf:
<Directory C:/vhost>
AllowOverride All
Require all granted
</Directory>
#this is the default address of XAMPP
<VirtualHost *:80>
DocumentRoot "C:/XAMPP/htdocs/"
ServerName localhost
</VirtualHost>
#this is the first vhost address in XAMPP
<VirtualHost *:443>
DocumentRoot "C:/XAMPP/htdocs/data/anycompany"
ServerName q.localhost
<Directory "C:/XAMPP/htdocs/data/anycompany">
AllowOverride All
Order Deny,Allow
Allow from all
</Directory>
SSLEngine On
SSLCertificateFile "C:/xampp/apache/conf/ssl.crt/server.crt"
SSLCertificateKeyFile "C:/xampp/apache/conf/ssl.key/server.key"
</VirtualHost>
###### THIS WORKS, BUT COMMENTED OUT REPLACED BY THE ABOVE ########
#this is the first vhost address in XAMPP
#<VirtualHost *:80>
# DocumentRoot "C:/XAMPP/htdocs/data/anycompany"
# ServerName q.localhost
#</VirtualHost>
Windows Hosts file:
127.0.0.1 localhost
127.0.0.1 q.localhost
127.0.0.1 test.localhost
Apache httpd-ssl.conf:
DocumentRoot "C:/xampp/htdocs/data/anycompany"
ServerName q.localhost:443
ServerAdmin admin#localhost.com
Apache version 1.8.3 being used.
Doesn't seem to have any error message in the apache error log.
SOLVED:
Seems like the configuration above was correct, but I didn't realize one thing, and I had to include some further configuration to make it work. Explained below:
Typing "q.localhost" in URL window failed, and redirected to the Xampp default page. Had to include https:// before the url, so typing in "https://q.localhost" brought up the correct page. However, clicking on the various other links on the website also failed, as it required, but did not have the "https://..." in front of the link.
To correct the above problem, I referred to this article. which suggested adding redirects to configuration file: \xampp\apache\conf\extra\httpd-xampp.conf. I added what he suggested to enable automatic redirects without having to always type in "https://..."
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect /xampp folder to https
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} xampp
RewriteRule ^(.*) https://%{SERVER_NAME}$1 [R,L]
# Redirect /phpMyAdmin folder to https
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} phpmyadmin
RewriteRule ^(.*) https://%{SERVER_NAME}$1 [R,L]
# Redirect /security folder to https
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} security
RewriteRule ^(.*) https://%{SERVER_NAME}$1 [R,L]
# Redirect /webalizer folder to https
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} webalizer
RewriteRule ^(.*) https://%{SERVER_NAME}$1 [R,L]
# Redirect /folder_name folder to https
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} folder_name
RewriteRule ^(.*) https://%{SERVER_NAME}$1 [R,L]
</IfModule>
This is essentially the same question as htaccess force https and redirect www to non-www, but no other subdomains (i.e., I want to configure Apache to redirect all non-HTTPS and/or "www" URLs to HTTPS non-www URLs), but I want to configure Apache via a Virtual Host rather than an .htaccess file (since I read that avoiding .htaccess has some benefits).
I was able to get the following answer to work when using an .htaccess file: https://stackoverflow.com/a/34333450/1468130 But it did not work when I tried transferring that answer's configuration to my Virtual Hosts configuration; "https://www.domain.com" never redirected to "https://domain.com".
I read up on the differences between .htaccess and Virtual Host .conf files, and found this http://tltech.com/info/rewriterule-in-htaccess-vs-httpd-conf/ and this: https://www.digitalocean.com/community/questions/can-you-use-virtual-host-config-conf-to-redirect-www-domain-to-non-www?answer=15129 which seemed to hint that I could just wrap the configuration in a <Directory> block and it would work. Unfortunately, it doesn't ("https://www.domain.com" is still never redirected to "https://domain.com"), so I'm wondering if the Internet knew what I was doing wrong:
<VirtualHost *:80>
ServerName domain.com
ServerAlias www.domain.com
ServerAdmin admin#domain.com
DocumentRoot /var/www/domain.com/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/domain.com/>
RewriteEngine On
# match any URL with www and rewrite it to https without the www
RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
# match urls that are non https (without the www)
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(www\.)(.*) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</Directory>
</VirtualHost>
I've also tried configuring <VirtualHost *:443> as Dusan Bajic suggested in the comments, but that has no effect either; https://www.domain.com still won't redirect to https://domain.com:
<VirtualHost *:443>
ServerName domain.com
ServerAlias www.domain.com
ServerAdmin admin#domain.com
DocumentRoot /var/www/domain.com/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/domain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/domain.com/chain.pem
<Directory /var/www/domain.com/>
RewriteEngine On
# match any URL with www and rewrite it to https without the www
RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
</Directory>
</VirtualHost>
Also per the comments, I have tried the above *:443 configuration paired with a *:80 configuration with the <Directory> block changed to only redirect HTTP to HTTPS. But when I do that, "www" never gets removed.
<Directory /var/www/paradoxmayhem.com/>
RewriteEngine On
RewriteCond %{SERVER_NAME} =www.paradoxmayhem.com [OR]
RewriteCond %{SERVER_NAME} =paradoxmayhem.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</Directory>
Got it! Apparently, when I used letsencrypt (certbot) to configure SSL, it automatically created another virtual host file (at /etc/apache2/sites-enabled/domain.com-le-ssl.conf), which has its own definition for the domain.com *:443 Virtual Host, and seems to have taken precedence over any of the *:443 configuration I tried to set up before. I added the following code to the -le-ssl.conf file, and now my redirects finally work in all the cases I desired, using 100% Apache Virtual Host configuration:
<Directory /var/www/domain.com/>
RewriteEngine On
# match any URL with www and rewrite it to https without the www
RewriteCond %{HTTP_HOST} ^(www\.)(.*) [NC]
RewriteRule (.*) https://%2%{REQUEST_URI} [L,R=301]
</Directory>
This question already has answers here:
http to https through .htaccess
(17 answers)
Closed 6 years ago.
How to tell if http://ttt.com or http://www.ttt.com is used by the user, redirect it to https://www.ttt.com ?
httpd.conf:
<VirtualHost *:80>
ServerName www.ttt.com
ServerAlias ttt.com
DocumentRoot /home/www/html/ttt/public
<Directory /home/www/html/ttt/public>
#Options ExecCGI
#AddDefaultCharset utf-8
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
.htaccess :
RewriteEngine On
############################################
## always send 404 on missing files in these folders
#RewriteCond %{REQUEST_URI} !^/(files)/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Try the following Code at the main directory .htaccess file :
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R]
You can do it from the httpd.conf with the following:
<VirtualHost *:80>
ServerName www.ttt.com
Redirect "/" "https://www.ttt.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.ttt.com
...
...
</VirtualHost>
Or from the .htaccess file:
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Here you go: https://wiki.apache.org/httpd/RedirectSSL
Redirect Request to SSL
Let's say you want http://www.example.com/secure/ to always be sent
over SSL (I presume here that both the normal and the SSL vhost have
the same content). You could do this by linking to the correct page
from within your HTML pages... but there will always be some user who
will sneak by it that way.
Using virtual hosts (using redirect)
When using SSL, you will frequently have at least two virtual hosts:
one on port 80 to serve ordinary requests, and one on port 443 to
serve SSL. If you wish to redirect users from the non-secure site to
the SSL site, you can use an ordinary Redirect directive inside the
non-secure VirtualHost:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName mysite.example.com
DocumentRoot /usr/local/apache2/htdocs
Redirect permanent /secure https://mysite.example.com/secure
</VirtualHost>
<VirtualHost _default_:443>
ServerName mysite.example.com
DocumentRoot /usr/local/apache2/htdocs
SSLEngine On
# etc...
</VirtualHost>
When redirecting everything you don't even need a DocumentRoot:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent / https://secure.example.com/
</VirtualHost>
<VirtualHost _default_:443>
ServerName secure.example.com
DocumentRoot /usr/local/apache2/htdocs
SSLEngine On
# etc...
</VirtualHost>
Note: redirect can also be used inside .htaccess files or to address
particular URLs, as in:
Example:
Redirect permanent /login https://mysite.example.com/login
Using mod_rewrite
While the solution is recommended because it is simpler
and safer, you can also use mod_rewrite to get the same effect as
described here: RewriteHTTPToHTTPS
From https://httpd.apache.org/docs/trunk/mod/mod_alias.html#redirect:
# Redirect to a URL on a different host Redirect "/service" "http://foo2.example.com/service"
# Redirect to a URL on the same host Redirect "/one" "/two"
If the client requests http://example.com/service/foo.txt, it will be
told to access http://foo2.example.com/service/foo.txt instead. This
includes requests with GET parameters, such as
http://example.com/service/foo.pl?q=23&a=42, it will be redirected to
http://foo2.example.com/service/foo.pl?q=23&a=42. Note that POSTs will
be discarded. Only complete path segments are matched, so the above
example would not match a request for
http://example.com/servicefoo.txt. For more complex matching using the
expression syntax, omit the URL-path argument as described below.
Alternatively, for matching using regular expressions, see the
RedirectMatch directive.
If you want both the www.example.com/* and the example.com/* to be redirected you could make two VirtualHost with different ServerName or you can use the Rewrite plugin.
I have a server with two subdomains, so I set up redirection for both of my subdomains specially because I want to force that the two subdomains are accessed only by https instead of http. My ideal scenario would be that I have those redirection untouched and be able to access phpMyAdmin locally (for security reasons obviously) but the problem now is that when I type the following in my browser:
127.0.0.1/phpmyadmin or localhost/phpmyadmin it takes me to https://example1.com/webservice/myrestfile-REST.php?appconfig=example
Is there any way to solve this problem?
This is the configuration that I currently have with the redirection:
<VirtualHost *:80>
ServerName example1.com
ServerAlias API.com
ErrorLog /var/www/html/error.log
CustomLog /var/www/html/requests.log combined
DocumentRoot /var/www/html
RewriteEngine On
LogLevel alert rewrite:trace6
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^ https://example1.com/webservice/myrestfile-REST.php?appconfig=example [R,L]
Redirect permanent / https://example1.com
# RewriteRule ^(.*)$ /webservice/myrestfile-REST.php?appconfig=example [QSA,L]
</VirtualHost>
<VirtualHost *:443>
ServerName example1.com
DocumentRoot /var/www/html
RewriteEngine On
RewriteRule ^(.*)$ /webservice/myrestfile-REST.php?appconfig=example [QSA,L]
SSLEngine On
SSLCertificateFile /etc/httpd/ssl/40d5d69ae6a53.crt
SSLCertificateKeyFile /etc/httpd/ssl/sitekey.key
SSLCertificateChainFile /etc/httpd/ssl/gd_bundle-g2-g1.crt
</VirtualHost>
It looks like you have apache set to listen on any ip <VirtualHost *:80> which would include the loopback address 127.0.0.1. See if you can just use the condition to ignore those.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/phpmyadmin$ [NC]
RewriteCond %{HTTP_HOST} !^127\.0\.0\.1 [OR]
RewriteCond %{HTTP_HOST} !^localhost [NC]
RewriteRule ^(.*)$ /webservice/myrestfile-REST.php?appconfig=example [QSA,L]
See how that works and let me know.
I want to make sure all my traffic is on ssl even if they type http. But I also want it to pass the folders so mod_rewrite will still work. I tried this poor example but it does not work. Basicly I if they type http://mydomain.com/apage it will redirect to https://mydomain.com/apage
Server: Apache2, LAMP stack.
.htaccess
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^(/) https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,L]
I am open to tweaking a virtual host files for Apache but I have not seen it done like that before. This is my first adventure into ssl hosting.
Just replacing http with https
RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
I suggest not using mod_rewrite or htaccess if you have access to httpd.conf.
If you want to force all users to use https (a good idea) you can add something like this to httpd.conf:
<VirtualHost 1.2.3.4:80>
ServerName SSL.EXAMPLE.COM
CustomLog /var/log/httpd/EXAMPLE.access_log combined
ErrorLog /var/log/httpd/EXAMPLE.error_log
Redirect / https://ssl.example.com/
</VirtualHost>
<VirtualHost 1.2.3.4:443>
ServerName ssl.example.com
DocumentRoot /var/www/html
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM
.
.
.
</VirtualHost>
<Directory /var/www/html>
#If all else fails, this will ensure nothing can get in without being encrypted.
SSLRequireSSL
</Directory>