Apache2, vhosts and SSL - apache

My setup:
site1.com | Port 80
site2.com | Port 80
panel.site1.com | Rewrites port 80 traffic to 443
This works until someone tries https:// site[x].com and the server redirects them to my panel. I need this panel to be open to the ~100 people who will use it, but I don't want the wrong people stumbling across it.
I've tried adding:
<VirtualHost *:443>
ServerAdmin me#email
ServerName site1.com
ServerAlias www.site1.com
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
to the vhost of site1.com, but it still returns the control panel. I believe this is because the certs are checked before Apache vhost rules are applied, but I'm not really sure. Is there a fix for this or is it simply the limitations of Apache2+SSL?

Apache document states that.
If no matching ServerName or ServerAlias is found in the set of
virtual hosts containing the most specific matching IP address and
port combination, then the first listed virtual host that matches that
will be used.
And so looks like you have kept the <VirtualHost> section of panel.site1.com on top of all other virtual host section. Because of this, requests for https://site[x].com will land in it, and so the issue is not related to SSL.
Update:
You can try below configuration and it should work.
<VirtualHost *:80>
ServerName www.site1.com
ServerAlias site1.com
DocumentRoot /var/www/site1
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^panel.site1.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
</VirtualHost>
<VirtualHost *:80>
ServerName www.site2.com
ServerAlias site2.com
DocumentRoot /var/www/site2
</VirtualHost>
<VirtualHost *:443>
ServerName panel.site1.com
DocumentRoot /var/www/panel
SSLEngine on
SSLOptions +StrictRequire
SSLCertificateFile /opt/apache1/conf/server.crt
SSLCertificateKeyFile /opt/apache1/conf/server.key
</VirtualHost>
How this works
When request are for http://site1.com the first VirtualHost
section will be selected.
When request are for http://site2.com the second VirtualHost section will be selected.
If a request arrives for http://site[x].com then first VirtualHost section will be selected.
If a request arrives for http://panel.site1.com the request will be redirected to https://panel.site1.com and the third VirtualHost section will be selected.

Related

Lets Encrypt and Too many redirects

I'm using PufferPanel to manage my game servers and I have run into a problem with the SSL certificate step. I'm using Lets Encrypt to generate a certificate and with that comes system files verification to make sure it is authentic. I can't get the .well-known to work as Pufferhost must have something within its JS which redirects anything to a 404 page. I found some resources online and came up with the configuration below. Unfortunately, it does not work. It shows a chrome error saying that I am performing too many redirects, how can I fix this. I really appreciate any help you can provide.
##################################################################################################
# PANEL VIRTUAL HOST #
##################################################################################################
<VirtualHost *:80 *:8080 *:443>
ServerName panel.example.com
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,QSA]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule .* ws://localhost:8080%{REQUEST_URI} [P]
</VirtualHost>
The vhost listen to Port 8080 and then redirect to Port 8080, that should be the loop.
I would suggest to use individual vhosts for each Port.
One for Port 80 HTTP and one for Port 443 HTTPS. Port 8080 needs no vhost because you redirect to it.
Then you can use the Vhost with Port 80 with a DocumentRoot where Lets-encrypt can store the .well-known/acme-challenge/.
<VirtualHost *:80>
DocumentRoot "/var/www/html"
ServerName www.example.com
</VirtualHost>
<VirtualHost *:443>
DocumentRoot "/var/www/html"
ServerName www.example.com
ProxyPreserveHost On
ProxyPass "/" "http://localhost:8080/"
ProxyPassReverse "/" "http://localhost:8080/"
</VirtualHost>
When you have the Lets Encrypt Certificate you can add an redirect from Port 80 to Port 443 to force HTTPS. Then you need to add the SSL-Certificate to the Port 443 vhost config.
<VirtualHost *:80>
DocumentRoot "/var/www/html"
ServerName www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
DocumentRoot "/var/www/html"
ServerName www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
ProxyPreserveHost On
ProxyPass "/" "http://localhost:8080/"
ProxyPassReverse "/" "http://localhost:8080/"
</VirtualHost>
Depending on your OS the SSLCertificateFile/SSLCertificateKeyFile-Path is at an other location.

Apache2 multiple domains to use same document root

Trying to get multiple domains (potentially dozens) to use the same document root as I want laravel to take care of all the routing.
Sites will be custom domain names ie. johnwilson.com, davidsmith.com, lisabrown.com and laravel will display a templated page. I do not want the URL rewritten in the address bar to the user.
I can't get apache2 to respect my virtual host configuration though, especially using SSL.
The configuration is a LAMP stack on Ubuntu. I have two other runrelated sites already running successfully on this server, using two seperate document roots. These are proxied through cloudfare.
These "templated" pages I'm just going to use lets encrypt for though.
I've tried:
2 seperate virtual hosts.
<VirtualHost *:443>
ServerName johnsmith.com.au
DocumentRoot /var/www/microsites/public
# letsencrypt certificate details here
</VirtualHost>
<VirtualHost *:443>
ServerName lisabrown.com.au
DocumentRoot /var/www/microsites/public
# letsencrypt certificate details here
</VirtualHost>
In this case johnsmith.com.au works, but lisabrown.com.au just redirects to johnsmith.com.au. completely rewriting the url in the address bar.
I've tried using ServerAlias aswell but this leads me to various errors, 404, SSL_INSECURE.
What's the correct way to do this? TIA
Using the following conf files (one per domain) I got it to work as expected. (and deleting the letsencrypt auto generated domain-le-ssl.conf file)
<VirtualHost *:80>
ServerName domain.com.au
ServerAlias www.domain.com.au
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.domain.com.au [OR]
RewriteCond %{SERVER_NAME} =domain.com.au
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName domain.com.au
ServerAdmin admin#domain.com.au
DocumentRoot /var/www/microsites/public
ErrorLog ${APACHE_LOG_DIR}/microsites/domain.error.log
CustomLog ${APACHE_LOG_DIR}/microsites/domain.access.log combined
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/domain.com.au/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.com.au/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

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.

Apache Virtual Hosts Non-www not working

I'm setting up a Virtual Hosts file on my CentOS 7 box and I'm having trouble getting my domain to resolve correctly.
Here's what my current /etc/httpd/conf.d/vhost.conf file looks like
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster#domain.com
ServerName www.domain.com
ServerAlias domain.com
DocumentRoot /var/www/html/domain.com/public_html/
ErrorLog /var/log/httpd/error.log
CustomLog /var/log/httpd/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.domain.com [OR]
RewriteCond %{SERVER_NAME} =domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
It seems the the correct redirects are happening. For exmaple:
domain.com redirects to https: //www.domain.com
www works fine
BUT
https: //domain.com doesn't work
http ://domain.com doesn't work
In fact, if I remove the redirects I have set, domain.com ins't working at all, so it looks like the ServerAlias is broken?
I'm wondering if I need another redirect or is there some other step I'm missing?
Also, don't mind the spaces between http and the domain name. StackOverflow made me format it that way.
As presented, no request to anything https will ever work. Normal, you only have a VirtualHost on port 80. You do have a Listen directive for that port right?
For your redirections. It says: if you ask for http://www.example.com or http://example.com, redirect to https://<WHAT THE USER ASKED FOR>. In essence you are forcing your users to use https all the time, no problem there. But you do not have a VirtualHost on port 443, hence no response.
So:
Listen *:80
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
ErrorLog /var/log/httpd/80_error.log
CustomLog /var/log/httpd/80_access.log combined
RewriteEngine on
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
Listen *:443
<VirtualHost *:443>
ServerName www.example.com
# in case users do directly to https
ServerAlias example.com
DocumentRoot /var/www/html/domain.com/public_html/
DocumentIndex index.html
ErrorLog /var/log/httpd/443_error.log
CustomLog /var/log/httpd/443_access.log combined
# SSL CONFIGURATIONS, TODO!
</VirtualHost>
In your *:443 VH, you will have to configure certificates and SSL.
Your certificates will have to be valid for both www.example.com and example.com to avoid browser complaints.
Careful there might be an ssl.conf included file under conf.d that defines some of this. Make sure you only set it once to avoid confusion.
No need to define DocumentRoot in *:80 VH since it only redirects and does not respond content to client.
Have fun!
I solved the issue. I had my local hosts file configured to point to an old out of date IP address……
domain.com *bad ip address*
I'm so embarrassed. I must have set that up months ago and forgot.

apache redirect HTTPS to canonical HTTPS

I want all access to my website to be forced to HTTPS (https://support.google.com/webmasters/answer/6073543?hl=en).
I also want to force canonical www URL access (https://www.yes-www.org/why-use-www/)
I am attempting to do so according to Apache recommendations using the Redirect directive https://wiki.apache.org/httpd/RedirectSSL and https://httpd.apache.org/docs/2.4/rewrite/remapping.html#canonicalhost
I have a valid lets-encrypt certificate which has both www and the naked domain.
I have configured *:80 and *:443 VirtualHost redirects. /etc/httpd/conf.d/www.example.com.conf:
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
Redirect permanent / https://www.example.com
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
SSLCACertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
Redirect permanent / https://www.example.com
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
SSLCACertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
DocumentRoot "/var/www/html/www.example.com"
</VirtualHost>
<Directory "/var/www/html/www.example.com">
Order allow,deny
Allow from all
</Directory>
All works well if I specify base URL (example.com, www.example.com, https://example.com, etc). However, if I specify a page on the naked HTTPS request the redirect eats the root slash (https://example.com/index.html becomes https://www.example.comindex.html).
I do it with the following for all non-ssl to ssl -
<VirtualHost *:80>
ServerName example.org
ServerAlias www.example.org
RewriteEngine on
RewriteRule ^/(.*)$ https://www.example.org/$1 [R,L]
</VirtualHost>
Slighly different should do the same for https://example.org only redirecting to www.example.org
<VirtualHost your.ip.add.ress:443>
ServerName example.org
RewriteEngine on
RewriteRule ^/(.*)$ https://www.example.org/$1 [R,L]
*snip*
Normal SSL certificate/key stuff goes here
*snip*
</VirtualHost>
RedirectMatch appears to solve the problem similar to the Rewrite suggested by ivanivan. Changing Redirect line in *:443 VHost section to the following seems to fix the issue:
RedirectMatch permanent ^/?(.*) https://www.example.com/$1
I still don't understand why simple Redirect doesn't work with HTTPS.
As an aside, https://salferrarello.com/chrome-clear-redirect-cache/ was useful disabling Redirect caching in Chrome during testing.