Redirect address with folder structure to https? - apache

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>

Related

Apache not reporting HTTPS server variable to PHP

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!

virtual host force https and redirect www to non-www, but no other subdomains

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>

Apache - how to make http requests into https only? [duplicate]

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.

Web application behind reverse proxy - how do I handle SSL?

I have a public Apache server which needs to proxy to an internal Apache server (for SVN access). What I'd like to have is:
User ---[HTTPS]---> Web Server ---[HTTP]---> SVN Server
I'm not too familiar with SSL handling, so I'd like some opinions on this approach. Is this an ok model; should I be using SSL everywhere, etc.
My approach works for the most part, but fails when rewriting redirects back to HTTPS. If a user goes to
https://acme.web.mcx/svn (no trailing '/')
they are redirected by the SVN server to
http://acme.web.mcx/svn/ (almost there!)
Here's my config for the Web Server (Proxying server):
<VirtualHost *:443>
ServerAdmin me#admin.com
ServerAlias *.web.mcx www.web.mcx web.mcx
DocumentRoot /server/web/app/webroot
ErrorLog logs/web-error_log
CustomLog logs/web-access_log common
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.web\.mcx$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^.]+)\.web\.mcx$ [NC]
RewriteRule ^/svn(.*) http://db.mcx/svn$1 [P]
ProxyPassReverse /svn http://db.mcx/svn
ProxyPreserveHost on
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/server.crt
SSLCertificateKeyFile /etc/httpd/ssl/server.key
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyVia On
<Location /svn/>
<Limit OPTIONS PROPFIND GET REPORT MKACTIVITY PROPPATCH PUT CHECKOUT MKCOL MOVE COPY DELETE LOCK UNLOCK MERGE>
Order Deny,Allow
Allow from all
Satisfy Any
</Limit>
</Location>
I keep answering my own questions :)
Here's my 'works until it breaks' solution: I changed my VirtualHost setting to always redirect http:// requests for /svn* to https. The client will be redirected twice sometimes (if they don't use the trailing slash), but that's ok with me. Redirect one: SVN server redirects client to the proper path with a slash (although forgets about https), redirect two: Web server redirects client back to https.
<VirtualHost *:80>
ServerAdmin me#admin.com
ServerAlias *.web.mcx www.web.mcx web.mcx
DocumentRoot /server/web/app/webroot
ErrorLog logs/web-error_log
CustomLog logs/web-access_log common
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.web\.mcx$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^.]+)\.web\.mcx$ [NC]
RewriteCond %{REQUEST_URI} svn.*
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
ProxyRequests Off
</VirtualHost>

Apache Rewrite: Always use HTTPS (how to add an exception)

On mydomain.com, I currently keep all of my apache conf files in:
/etc/httpd/conf.d/
In there I have a file called alwaysHttps.conf that contains:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I have a bunch of virtualhosts, and for one domain on the site: myotherdomain.com I would like to turn off the auto redirect. Is it possible to setup an exception to the redirect to https, rather than having to get rid of the global alwaysHttps.conf?
<VirtualHost *:80>
DocumentRoot /home/webadmin/myotherdomain.com/html
ServerName myotherdomain.com
CustomLog "/home/webadmin/myotherdomain.com/access_log" "combined"
ErrorLog "/home/webadmin/myotherdomain.com/error_log"
<Directory /home/webadmin/myotherdomain.com/html>
Options Includes FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !myotherdomain\.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [QSA]
Fantastic!
In my http.conf I have:
NameVirtualHost *:80
NameVirtualHost *:443
Listen 8033
The reason for the listen on 8033 was because I am using OpenVPN's feature to dual use port 80. Once I changed my
<VirtualHost *:80> to
<VirtualHost *:8033>
everything worked.
The curious thing though is why all of my other virtual domains and *.conf files work even though they have
<VirtualHost *:80>
and not
<VirtualHost *:8033>.
Any idea why that would be the case?