Apache rewrite before mod_jk (remove www) - apache

Here's the context:
I am working with Centos 7, apache 2.4.6 and tomcat 8.0.
I have a classical php website that is stored in /var/www folder.
I have a JEE website that is stored in tomcat webapps folder.
I have a wildcard ssl certificate (signed).
Here's what I want:
I want ALL accesses to my server to be redirected to correct website, with https, and without www.
Here are the use cases:
URL 'example.com' ==> redirected to https OK
URL 'www.example.com' ==> redirected https + remove www OK
URL 'https://www.example.com' ==> keep https + remove www OK
URL 'test.example.com' ==> redirected to https OK
URL 'www.test.example.com' ==> redirected https + remove www OK
URL 'https://www.test.example.com' ==> KO not redirected - browser displays a page saying that website is badly configured and connection not secured (because the wildcard ssl does not cover 2 levels)
This last point is what I'm trying to fix.
Here's my configuration:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect / https://example.com/
</VirtualHost>
<VirtualHost *:80>
ServerName test.example.com
ServerAlias www.test.example.com
Redirect / https://test.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/public/example
SSLEngine on
SSLCertificateFile xxx
SSLCertificateKeyFile xxx
SSLCertificateChainFile xxx
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
</VirtualHost>
<VirtualHost *:443>
ServerName test.example.com
ServerAlias www.test.example.com
SSLEngine on
SSLCertificateFile xxx
SSLCertificateKeyFile xxx
SSLCertificateChainFile xxx
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
JkMount / worker_test
JkMount /* worker_test
</VirtualHost>
So, it seems that I'm almost there, but what am I doing wrong ?

As far as I know, you cannot configure more than one https virtual host for each IP, that's it, name based virtual hosting is limited to only one SSL virtual host.
This info is from https://wiki.apache.org/httpd/NameBasedSSLVHosts
As a rule, it is impossible to host more than one SSL virtual host on the same IP address and port. This is because Apache needs to know the name of the host in order to choose the correct certificate to setup the encryption layer. But the name of the host being requested is contained only in the HTTP request headers, which are part of the encrypted content. It is therefore not available until after the encryption is already negotiated. This means that the correct certificate cannot be selected, and clients will receive certificate mismatch warnings and be vulnerable to man-in-the-middle attacks.
In reality, Apache will allow you to configure name-based SSL virtual hosts, but it will always use the configuration from the first-listed virtual host (on the selected IP address and port) to setup the encryption layer. In certain specific circumstances, it is acceptable to use a single SSL configuration for several virtual hosts. In particular, this will work if the SSL certificate applies to all the virtual hosts. For example, this will work if:
All the VirtualHosts are within the same domain, eg: one.example.com and two.example.com.
You have a wildcard SSL certificate for that domain (one where the Common Name begins with an asterix: i.e *.example.com)
I´ve heard about using SNI to achieve this kind of configurations, but I have never tested: SSL with Virtual Hosts Using SNI

Related

How to redirect http://example.com to https://example.com in apache2.conf using VirtualHost

I am trying to redirect http URLs to https and also www URLs to non-www.
I am using the latest version of Apache 2 http server running in a Raspberry Pi 3 model B+.
I would like to use VirtualHosts in apache2.conf, because I read in many places that this approach is to be prefered instead of using .htaccess
I get 3 redirects to work OK:
http://www.example.com goes to https://example.com
https://example.com goes to https://example.com
https://www.example.com goes to https://example.com
But
http://example.com goes to http://example.com
In other words, the non-www unsafe (http) site does not get redirected
to the safe (https) site... and I do not get to load my SSL certificate.
I got the www sites redirected to the non-www using a CNAME.
The http gets to the https using the Redirect directive.
This is the relevant part of my apache2.conf file:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
Protocols h2 http/1.1
ErrorLog logs/error_log
SSLEngine on
SSLCertificateFile /etc/ssl/example.com.crt
SSLCertificateKeyFile /etc/ssl/example_com_key.txt
SSLCertificateChainFile /etc/ssl/example.com.ca-bundle
SSLUseStapling on
</VirtualHost>
SSLStaplingCache shmcb:/tmp/stapling_cache(128000)
This will redirect all of your www websites to non-www and secure them if you have completed the CERTBOT for each domain conf file. Put this in /etc/apache2/apache2.conf inside the Directory /www section:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
There is no need to CERTBOT a www domain after this code is inserted. Just do the domain.com choice. You do not need htaccess files. They can be restricted by the AllowOverride None selection.
Remember to restart apache.

VirtualHost causing ERR_TOO_MANY_REDIRECTS after installing LetsEncrypt certificates

Edit: I took the redirect lines out of the VirtualHosts for the two domains that aren't working. After rebooting Apache, both the HTTP and HTTPS version of both sites work as intended, but its not automatically redirecting anymore (obviously). But those same exact redirect rules are working fine for sidmandesign.com
I am migrating my webserver from an IIS server to a LAMP stack using Ubuntu. I used certbot to install three SSL certificates for my three domains. Certbot added a -le-ssl.conf file to the virtualhosts directory, so in there I now have (all in /etc/apache2/sites-enabled/ directory with the proper include inside apache.conf):
sidmandesign.conf:
<VirtualHost *:80>
ServerName www.sidmandesign.com
ServerAlias sidmandesign.com
DocumentRoot "/var/www/html/Sidman Designs/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =sidmandesign.com [OR]
RewriteCond %{SERVER_NAME} =www.sidmandesign.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
sidmandesign-le-ssl.conf:
<VirtualHost *:443>
ServerName www.sidmandesign.com
ServerAlias sidmandesign.com
DocumentRoot "/var/www/html/Sidman Designs"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/sidmandesign.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sidmandesign.com/privkey.pem
</VirtualHost>
augustinebuilders.conf:
<VirtualHost *:80>
ServerName www.augustinebuilders.com
ServerAlias augustinebuilders.com
DocumentRoot "/var/www/html/augustine/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =augustinebuilders.com [OR]
RewriteCond %{SERVER_NAME} =www.augustinebuilders.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
augustinebuilders-le-ssl.conf:
<VirtualHost *:443>
ServerName www.augustinebuilders.com
ServerAlias augustinebuilders.com
DocumentRoot "/var/www/html/augustine"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/augustinebuilders.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/augustinebuilders.com/privkey.pem
</VirtualHost>
salvagedserendipity.conf:
<VirtualHost *:80>
ServerName www.salvagedserendipity.com
ServerAlias salvagedserendipity.com
DocumentRoot "/var/www/html/salvagedserendipity/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =salvagedserendipity.com [OR]
RewriteCond %{SERVER_NAME} =www.salvagedserendipity.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
salvagedserendipity-le-ssl.conf:
<VirtualHost *:443>
ServerName www.salvagedserendipity.com
ServerAlias salvagedserendipity.com
DocumentRoot "/var/www/html/salvagedserendipity"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/salvagedserendipity.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/salvagedserendipity.com/privkey.pem
</VirtualHost>
Sidmandesign.com works just fine, it redirects to HTTPS and I can see everything. However when I try the other two sites, they redirect to HTTPS but I get a ERR_TOO_MANY_REDIRECTS in Chrome and a generic cannot display this page in Edge/IE.
Any ideas why one domain would work but the other two don't when configs appear identical?
Your RewriteCond syntax
In your *:80 VirtualHost, remove your RedirectCond and RewriteRule directives and add (well, adjust for your domains!):
Redirect permanent / https://www.example.com
No need to verify if the domain names match, Apache will only use the configuration in that VirtualHost if the domain matches ServerName or ServerAlias directives values anyway.
Another point, RewriteCond does not need the = sign (for future reference):
RewriteCond %{SERVER_NAME} ^www.example.com$
Remove DocumentRoot in VirtualHost *:80
Since you never server any content for the *:80 VirtualHost, you should remove DocumentRoot directives.
Multiple SSL VirtualHosts problem
For port 80, no problem you can have many VirtualHosts defined. Apache will look at the requested domain and use the matching configuration.
But for SSL, that does not work. Apache cannot read the requested domain until after the SSL certificates negotiation is done with the browser. So what does it do? It uses the first *:443 VirtualHost it finds.
Ways around this are:
1 SSL domain == 1 IP == 1 VirtualHost set for that IP only (i.e. not *:443). The problem here is you might not have access to more than one address.
1 SSL domain == 1 port == 1 VirtualHost set for that port (i.e. *:443, *:444, ...). The problem here is that port 443 is the default for https sites, so other sites need to be explicitly requested for in the browser, which is counter intuitive for clients. If you have network infrastructure in front of your Apache, you could change the port there. https://www.example.com is sent to apache:443, https://www.example2.com is sent to apache:444, and so forth. But this needs to be done before the traffic gets to Apache.
Use SNI in Apache (https://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI).
In your case
The request http://<SOMEDOMAIN>, on port 80 is sent to the proper VirtualHost.
This VH redirects it to https://<SOMEDOMAIN>, on port 443. Well it should.
The first VH is always used, so certificate /etc/letsencrypt/live/sidmandesign.com/fullchain.pem is the one send to the client's browser. You can validate this by looking at the browser console and inspecting the certificate.
The browser thus sees a certificate for one domain, which does not match the requested one (well besides the first domain).
Lastly
For the "ERR_TOO_MANY_REDIRECTS in Chrome", look at the console (F12, Network tab, check Preserve logs). You will see every redirection Chrome got. This way you will see what is looping. My guess is that the '=' sign is messing things up.

How to force redirect http to https on a apache reverse proxy server?

I have an apache reverse proxy server with http and https services. I want to redirect http to https forcible. What should i configure the config file?
Recommended and also safer way is using VirtualHost:
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
or
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent /login https://www.example.com/login
</VirtualHost>
The other way is using mod_rewrite:
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
As I said, Apache recommends using VirtualHost config.
Examples taken from:
https://wiki.apache.org/httpd/RedirectSSL
https://wiki.apache.org/httpd/RewriteHTTPToHTTPS

TURN Server use https connection for the admin session

I have installed TURN server. And APACHE is also installed there. SSL Certificates are also installed. The site is running fine where I am typing https://www.domain.com or https://domain.com
But if I type only www.domain.com or domain.com it is saying "TURN Server
use https connection for the admin session".
All I want, if someone types the URL without HTTPS, it will redirect it to HTTPS URL.
It is a server where TURN Server is also installed ( Repeating it again )
I think this link can help.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The Apache doc recommend this:
<VirtualHost *:80>
ServerName www.example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>

Redirecting HTTP to HTTPS with Apache

I have an issue using mod_rewrite to force redirection of HTTP requests to HTTPS using Apache 2.2.22 on Ubuntu Server 12.04.
My /etc/apache2/sites-available/default file is as follows:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
</VirtualHost>
The HTTPS host is defined in default-ssl in the same directory.
Visiting the server's local IP address, the redirect appears to work fine. However, accessing it via the FQDN, it doesn't. Using the FQDN, the site is available at port 5443, which is mapped in the firewall to 443 on the server, so perhaps that has something to do with the problem. I cannot just use port 443 directly, as it is in use on this IP address by another server.
To further clarify, the following are valid links:
https://website:5443
https://192.168.200.80:443
The redirect works here:
http://192.168.200.80
But the following gives a 400 Bad Request, and this is where the redirect is needed:
http://website:5443/
"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 is totally possible. The following redirects all http to the https url.
<VirtualHost *:80>
ServerName mydomainname.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
make sure you load the rewrite module mod_rewrite and enable it.
Your problem here is the initial HTTP request: This won't work as the server won't understand it receiving the request on port 443 (as the response code suggests).
If no port is given, the protocol http defaults to port 80, https to port 443.
This is also the reason why your local redirect works. I bet, if you access the page through http://website/ (with proper port forwarding of port 80), it will work as well. Also note that your VirtualHost is only defined for port 80 anyway, so it won't be valid for requests sent to website:5443 (or website:443).
In general, you'd need a server accepting both HTTP and HTTPS requests on a single port. Not sure any popular server actually supports something like that, because (I think) it essentially violates the specs.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
if u want to redirect your site from http:// anything.example.com to https: //anything.example.com ... Just create a dedicated hosting .conf file as /etc/httpd/conf.d/dedicated.conf and other conf file as virtual.conf ... entries for dedicated.conf are as follows....
this is dedicated server hosting conf file for redirecting it to https...
<virtualhost *:80>
servername host.example.com
documentroot /var/www/html
rewriteengine on
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
sslcertificatefile /etc/pki/tls/certs/name.crt
sslcertificatekeyfile /etc/pki/tls/private/name.key
</virtualhost>
<directory /var/www/html>
allowoverride all
require all granted
</directory>
Alternatively as mentioned in comment below, we can use redirect also:
<virtualhost *:80>
servername host.example.com
documentroot /var/www/html
RedirectMatch / https://host.example.com:ANY_PORT/ #if there is specific port
sslcertificatefile /etc/pki/tls/certs/name.crt
sslcertificatekeyfile /etc/pki/tls/private/name.key
</virtualhost>
<directory /var/www/html>
allowoverride all
require all granted
</directory>