Apache always loads the same vhost - apache

I have the following vhosts. However the vhosts always seem to resolve to app.home when using https, the only way to make it load cloud.home is by removing app.home from the vhosts. Whichs leads me to believe that it ignores the ServerName setting.
app.home.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName app.home
ProxyPreserveHost On
ProxyRequests off
ProxyPass /api/websocket ws://localhost:8123/api/websocket disablereuse=on keepalive=on
ProxyPassReverse /api/websocket ws://localhost:8123/api/websocket disablereuse=on
ProxyPass / http://localhost:8123/ disablereuse=on keepalive=on
ProxyPassReverse / http://localhost:8123/ disablereuse=on#`
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:8123/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:8123/$1 [P,L]
SSLCertificateFile /etc/letsencrypt/live/app.home/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.home/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
cloud.home.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName cloud.home
DocumentRoot "/var/www/cloud"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/cloud/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/cloud.home.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/cloud.home.access.log combined
SSLCertificateFile /etc/letsencrypt/live/cloud.home/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cloud.home/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Apache receives an encrypted connection on port 443. It then negotiates the certificate with the client's browser. But at this point, it has not read the requested domain yet. It must negotiate the certificate first to decrypt the payload.
So Apache will always use the first VirtualHost it finds that matches port 443. It gets the certificate from this one.
To fix that, you have to:
setup a second IP for your second domain. So Apache will be configured to say domain1 == IP1, domain2 == IP2.
Use a different port for the second domain, like :444. But this is not convenient since it is not the default.
Use SNI. Do some research on this, too long for an explication here.

Related

Set up an apache reverse proxy with SSL certs and multiple domains

I need help configuring Apache to act as a reverse proxy with https and multiple domains, such that www.myfirstdomain.com and www.myseconddomain.com both point to x.x.x.x and than the server will selectively forward to, let's say, x.x.x.x:2400 (myfirstdomain.com, http), x.x.x.x:2401 (myfirstdomain.com, https), x.x.x.x:2600 (myseconddomain.com, http) and x.x.x.x:2601 (mysecondomain.com, https).
I tried many options but in the end I got stuck because I issued more than 5 certs (renews) per week and also I couldn't make it work.
myfirstdomain.com and www.myfirstdomain.com (http and https) were configured as follows:
/etc/apache2/sites-available/000-default.conf :
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:2400/
ProxyPassReverse / http://127.0.0.1:2400/
</VirtualHost>
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:2401/
ProxyPassReverse / http://127.0.0.1:2401/
</VirtualHost>
<VirtualHost *:2400>
ServerName myfirstdomain.com
ServerAlias www.myfirstdomain.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/myfirstdomain/public
<Directory /var/www/html/myfirstdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =myfirstdomain.com
RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
RewriteCond %{SERVER_NAME} =www.myfirstdomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:2401>
ServerName myfirstdomain.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/myfirstdomain/public
<Directory /var/www/html/myfirstdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =myfirstdomain.com
RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Then I generated the certs with certbot --apache for both www and non-www and I had this file:
/etc/apache2/sites-available/000-default-le-ssl.conf:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:2401/
ProxyPassReverse / http://127.0.0.1:2401/
</VirtualHost>
<VirtualHost *:2401>
ServerName myfirstdomain.com
ServerAlias www.myfirstdomain.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/myfirstdomain/public
<Directory /var/www/html/myfirstdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
# Some rewrite rules in this file were disabled on your HTTPS site,
# because they have the potential to create redirection loops.
# RewriteCond %{SERVER_NAME} =myfirstdomain.com
# RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
# RewriteCond %{SERVER_NAME} =www.myfirstdomain.com
# RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
SSLCertificateFile /etc/letsencrypt/live/www.myfirstdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.myfirstdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
I also tried to regenerate the HTTPS certificates but it won't work. How do I do it?
First of all, remember that Apache listens on a range of ports, for instance 80 and 443.
Virtualhosts use the same ports (80 and 443) and Apache selects the correct folder using the domain name you use.
For example, myfirstdomain.com could display /var/www/html/myfirstdomain/public, but
if apache listens on port 80, it never match the rule for *:2400.
I haven't tryed this, but you could put ProxyPass and ProxyPassReverse in each virtual hosts and leave the port to :80 or :443.
When you call myfirstdomain.com:80, the rule on apache match and it executing proxing to another server.
See this answer.
LetsEncrypt create an ACME challenge (a file with a random string) that could be reachable from the internet. The Certification Server search this file, if exists the certificate is released; if not, it throw an error.
I don't remember the correct pathof the file, but you must verify:
can you reach "myfistdomain.com" from the internet?
an external server can reach "myfistdomain.com" ? (check dns name and port forwarding of your router
can you open the ACME challenge file?
can the server open the ACME challenge file?
On some Plesk installations acme files cannot be reacheable because Plesk adds some automatic rules.

Apache Reverse Proxy For Specific Subdomain

I'm have a an Apache HTTP server that has a reverse proxy to a tomcat server. However, I only want the reverse proxy to happen when the client uses the subdomain www. This is because I want to use other subdomains to point to other applications, such as email.
e.g. www.example.com will go display the apache tomcat webapp.
The way to do this, I presume, is to configure my DNS so that every subdomain I use will point to my server. Right now, in addition to www, that is server.example.com and posfixadmin.example.com. However, the issue is that all my subdomains end up pointing to tomcat.
So when I try to visit postfixadmin.example.com/setup.php to set up postfixadmin through its web setup, it ends up taking me to my tomcat webapp's 404.
Here is my virtualhost configuration:
<VirtualHost www.example.com:80>
ServerName http://www.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
<VirtualHost server.example.com:80>
ServerName server.example.com
DocumentRoot /var/www/html/
RewriteEngine on
RewriteCond %{SERVER_NAME} =server.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} {END,NE,R=permanent}
</VirtualHost>
<VirtualHost postfixadmin.example.com:80>
ServerName postfixadmin.example.com
DocumentRoot /var/www/postfixadmin/public
ErrorLog /var/log/httpd/postfixadmin_error.log
CustomLog /var/log/httpd/postfixadmin_access.log combined
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/postfixadmin/public>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
EDIT
It looks like the proxy conf file doesn't do anything (??). I decided to experiment around and change the first virtualhost servername to the following:
<VirtualHost *:80>
ServerName abcd.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
Then, I restarted and reloaded Apache...But for some reason, going to www.example.com STILL took me to the tomcat webapp! Does anyone know what drives this?
As to the DNS: I have set specific CNAME entries for each subdomain including www; all of them point back to the public IP of my server that houses my example.com domain (using # in my case - possible with most DNS, I think). There may be some different strategies on this, but I believe you're on the correct path based on what you've suggested in the question.
As to Apache configuration:
I believe that the http protocol does not need to be specified in the ServerName directive and that, generally, the domain need not appear inside the <VirtualHost>...</VirtualHost> tags.
I should mention that I am relatively unfamiliar with Tomcat but am assuming it is listening at 8080 on the localhost, in which case this should help.
I'm not 100% certain that that is all that is snarling you, but try trimming that ServerName back and doing like so, including the change to the VirtualHost open tag:
<VirtualHost *:80>
ServerName www.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
Your second <VirtualHost> probably requires similar changes, though it also seems that you are directing it to serve requests from the web/network which are coming in on port 8080 -- which I don't believe is your intent.
I think what you want is to also listen on port 80 from the web/network, but to follow these directives if addressed to server.example.com like so:
<VirtualHost *:80>
ServerName server.example.com
DocumentRoot /var/www/html/
RewriteEngine on
RewriteCond %{SERVER_NAME} =server.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} {END,NE,R=permanent}
</VirtualHost>
And finally, similar change to the opening <VirtualHost> tag on the final one:
<VirtualHost *:80>
ServerName postfixadmin.example.com
DocumentRoot /var/www/postfixadmin/public
ErrorLog /var/log/httpd/postfixadmin_error.log
CustomLog /var/log/httpd/postfixadmin_access.log combined
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/postfixadmin/public>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
Altogether, this seems more like what you're looking for:
<VirtualHost *:80>
ServerName www.example.com
ProxyPass / http://localhost:8080
ProxyPassReverse / http://localhost:8080
</Virtualhost>
<VirtualHost *:80>
ServerName server.example.com
DocumentRoot /var/www/html/
RewriteEngine on
RewriteCond %{SERVER_NAME} =server.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} {END,NE,R=permanent}
</VirtualHost>
<VirtualHost *:80>
ServerName postfixadmin.example.com
DocumentRoot /var/www/postfixadmin/public
ErrorLog /var/log/httpd/postfixadmin_error.log
CustomLog /var/log/httpd/postfixadmin_access.log combined
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/postfixadmin/public>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
I got it!
It turns out that the problem was in the ssl configuration file - the :443 ports were overlapping.
Thanks for the help!

Apache 2.4 redirect https to another port

I'm a rookie, but I've struggled with this for some time and I am definitely doing something wrong.
We use Apache 2.4 as the front of our internal web pages.
When I try to forward a request to a port other than 80, it goes crazy and is redirected several times
http://demos.company.com/demos.company.com/demos.company.com/demos.company.com/demos.company.com/demos.company.com/demos.company.com/[...]/demos.company.com/WebApplicationFail
httpd.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
<VirtualHost *:80>
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule ^(.*) %{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile "C:/Program Files/Apache24/conf/ssl/company.crt"
SSLCertificateKeyFile "C:/Program Files/Apache24/conf/ssl/company.key"
SSLCertificateChainFile "C:/Program Files/Apache24/conf/ssl/CA.pem"
# Proxy configuration
ProxyPreserveHost On
ProxyRequests Off
ServerName demos.company.com
ProxyPass /WebApplicationOK http://10.0.0.160/WebApplicationOK
ProxyPassReverse /WebApplicationOK http://10.0.0.160/WebApplicationOK
ProxyPass /WebApplicationFailRoute http://10.0.0.125:8000/WebApplicationFail
ProxyPassReverse /WebApplicationFailRoute http://10.0.0.125:8000/WebApplicationFail
</VirtualHost>
We need to maintain the redirection of every http request to https.
If possible, we need that the Internet address "https://demos.company.com/ThisContext" show the intranet web "http://10.0.0.125:8000/OtherContext".
Thanks in advance.
That's the problem with adding complex directives for trivial tasks.
You have a Virtualhost which uses port 80, why even check for SSL?, everything it will receive will not be SSL.
Also the rewrite directive is missing the scheme.
So just:
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [R,L]
If you don't need to use variables, for variable host names I would go even simpler:
Redirect / https://whateverhost.example.com/
Rule to success in httpd: Go always with the most simple option.
I've got it, it simple actually. You just only add those lines for redirection from below to your ssl.conf I guess
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName XXXX.ddns.net
# These are your SSL settings; your responsibility
SSLCertificateFile /etc/letsencrypt/live/XXXX.ddns.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/XXXX.ddns.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# Your document root; where the JavaScript application lives
DocumentRoot /var/www/html
<Directory /var/www/html/ >
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride None
Order Allow,Deny
Allow From All
</Directory>
# Reverse proxy settings for API (custom redirection https to specific port)
ProxyRequests Off
ProxyPreserveHost On
<Location /api >
ProxyPass http://127.0.0.1:3000/api
ProxyPassReverse http://127.0.0.1:3000/api
</Location>
</VirtualHost>

Apache2 conf file with SSL causes ERR_CONNECTION_REFUSED

I am trying to configure my SSL certificate on a Ubuntu 15.10 box. I have installed the certificate files and the private key in the required directory:
SSLCertificateFile /etc/apache2/ssl-certs/pts.crt
SSLCertificateKeyFile /etc/apache2/ssl-certs/msk.key
SSLCertificateChainFile /etc/apache2/ssl-certs/intermediate.crt
When I do sudo service apache2 restart I am then prompted to Enter passphrase for SSL/TLS keys for www.mydomain.com:443 (RSA): ******** and since this process reports back with no errors, I am assuming that I have at least installed the certificates and private key correctly, otherwise I would have expected an error at this stage.
My problem is that I receive ERR_CONNECTION_REFUSED when trying to load the site.
Here is my backup copy of the VirtualHost entry for the SSL site that I am using. Are there any obvious problems with this file?
I should also add that when I use this configuration, not only does the intended site fail to load, but it also causes all other sites for this apache2 box to fail to load also. Any ideas?
`<VirtualHost *:80>
ServerName mydomain.com
ServerAlias www.mydomain.com
ServerAdmin daniel#mydomain.com
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
<VirtualHost 172.30.30.21:443>
ServerName www.mydomain.com
ServerAlias mydomain.com
ServerAdmin me#mydomain.com
SSLEngine on
SSLProtocol all
SSLCertificateFile /etc/apache2/ssl-certs/pts.crt
SSLCertificateKeyFile /etc/apache2/ssl-certs/msk.key
SSLCertificateChainFile /etc/apache2/ssl-certs/intermediate.crt
DocumentRoot /home/apts/Dropbox/mydomain.com/
<Directory /home/apts/Dropbox/mydomain.com/>
<IfModule mod_rewrite.c>
<IfModule mod_ssl.c>
# <Location /squirrelmail>
RewriteEngine on
RewriteCond %{HTTPS} !^on$ [NC]
RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [L]
# </Location>
</IfModule>
</IfModule>
SSLOptions +StrictRequire
Options +FollowSymLinks -Indexes +MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM
SSLVerifyClient none
SSLProxyEngine off
</VirtualHost>`

How to forward https with php POST to a different domain via DNS?

I'm in the middle of updating a domain name which is currently using HTTPS and has an API that many users are connecting to daily.
What I need to do, is basically reroute all that traffic via DNS/the new server to the new domain name.
EG
Currently users are hitting: https://olddomain.com/api and we are now using https://newdomain.com/api so I need all calls from https://olddomain.com/api to be redirect, with php POST data intact to https://newdomain.com/api
CNAME doesn't seem to redirect it with post data, and it fails the API call. The CNAME is for olddomain.com pointing to newdomain.com, with apache2 mod rewrites which should take care of the redirects, if you navigate to olddomain.com it does forward to newdomain.com but the POST data does not go with it for some reason. The new server has both the old and new domain SSL certs, so that should be valid.
This is what my 000-default looks like in /etc/apache2/sites-enabled/000-default
<VirtualHost *:80>
ServerAdmin webmaster#localhost
ServerName newdomain.com
ServerAlias newdomain.com
RewriteEngine on
RewriteCond %{HTTP_HOST} ^olddomain.com
RewriteRule ^/(.*)$ https://newdomain.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^www.olddomain.com
RewriteRule ^/(.*)$ https://newdomain.com/$1 [L,R=301]
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride ALL
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride ALL
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName newdomain.com
SSLEngine on
SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
SSLCertificateFile /etc/apache2/ssl/certs/newdomain.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/private/newdomain.key
SSLCertificateChainFile /etc/apache2/ssl/ssl_bundle.crt
DocumentRoot /var/www/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName olddomain.com
ServerAlias www.olddomain.com
RewriteEngine on
RewriteCond %{HTTP_HOST} ^olddomain.com
RewriteRule ^/(.*)$ https://newdomain.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^www.olddomain.com
RewriteRule ^/(.*)$ https://newdomain.com/$1 [L,R=301]
SSLEngine on
SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
SSLCertificateFile /etc/apache2/ssl/certs/olddomain.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/private/olddomain.key
SSLCertificateChainFile /etc/apache2/ssl/ssl_bundle.crt
DocumentRoot /var/www/
</VirtualHost>
Did you try to use the HTTP status 307 (Temporary redirect) instead of 301? According to the W3C's HTTP/1.1 Status Codes Definitions, this method would allow you to preserve the original HTTP method (and therefore its associated body in case of a POST) of the redirected request, although the standards also mandates that the user agent asks confirmation from the user in case of a non-GET and non-HEAD.
eg., in you Apache configuration file, try to replace lines like:
RewriteRule ^/(.*)$ https://newdomain.com/$1 [L,R=301]
by:
RewriteRule ^/(.*)$ https://newdomain.com/$1 [L,R=307]
Note that some user agents have been reported not to be conforming to the standard regarding the HTTP 307 status (eg. not asking user confirmation), while some others do not understand it at all. So I suggest to test it carefully with the browsers you target if you choose to use this method and look for fallback mechanisms if needed.