Apache HTTPS reverse proxy with SNI without key on the proxy - apache

example1.com and example2.com resolve to host0. host0 runs an Apache reverse proxy with two VirtualHosts. It delegates requests for example1.com to host1 and for example2.com to host2.
Using http in all places, that clearly can be made to work.
Using https, I could stick the keys for example1.com and example2.com on host0, and then have host0 talk http or https to host1 and host2. Given SNI, that should work, too.
My question: can it be made to work without the example1.com or example2.com keys on host0? I'd like to avoid that host0 is in a position to perform a man-in-the-middle attack.
If I understand SNI correctly, the key material is only exchanged after the client has communicated the desired virtual host to host0. This should be (?) sufficient information for Apache to essentially forward the connection to host1 or host2, without looking at the content of the transmission at all. That does not require key material at all.

Do you really need Apache reverse proxy, or you need the problem solved? I had the same problem and I resolved it with HAProxy in tcp mode as described here http://blog.haproxy.com/2012/04/13/enhanced-ssl-load-balancing-with-server-name-indication-sni-tls-extension/ instead of Apache reverse proxy.

If you don't mind using Nginx or HAProxy instead of Apache, you'll find good answers at the following question at ServerFault:
Can a Reverse Proxy use SNI with SSL pass through?

Related

does icecast force ssl if enabled?

In the documentation for icecast 2.4.2 I see the following about ssl.
ssl If set to 1 will enable HTTPS on this listen-socket. Icecast must
have been compiled against openSSL to be able to do so.
However this wording is unclear to me whether or not the ssl is forced for this port or not? I am wondering this because we are running into an issue where safari is forcing ssl redirect and we want to keep the server listening on both ssl and non-ssl on the same port ( if thats possible )
Another thing is that it says it must be compiled against openSSL but we are installing it from apt in xenial. Does this mean its default to ssl?
Thanks~!
However this wording is unclear to me whether or not the ssl is forced for this port or not?
On that particular socket, it is. A server bound to that socket cannot support HTTPS and non-HTTPS at the same time. Usually, you'll use port 80 for HTTP and port 443 for HTTPS.
Note that you can have multiple sockets bound to Icecast, simply by putting in multiple <listen-socket> sections. It's common to serve both HTTP and HTTPS this way.
I am wondering this because we are running into an issue where safari is forcing ssl redirect
Your server configuration is irrelevant here. Icecast will not redirect HTTP requests to HTTPS. It's possible that you hit the stream on HTTPS once and that Safari cached this. It's also possible that you turned on HSTS or something for your domain. You would have to debug this with a tool like Fiddler.
and we want to keep the server listening on both ssl and non-ssl on the same port
You say "keep the server listening"... that's not possible. If it appears you're set up this way today, that's not accurate.
In a sense it does. Icecast if you are using it as its own server will not resolve the enabled ssl port unless its https://.
You also cannot use the same port for both ssl and non-ssl.
Finally the xenial ubuntu package also is not compiled for ssl.

Configure WampServer3 to work with AWS Certificate Manager, Application Load Balancer over port 443

Question:
Is it possible to use WampServer3 (Apache, PHP, MySQL) to work with my Application Load Balancer over port 443? If so how?
Issue:
Currently my application load balancer is connected to my instance and I have 2 listeners, Port 80 and Port 443. The listener on port 443 has an SSL Certificate attached to it that was generated by the AWS Certificate Manager.
My target group that is listening on port 80 is healthy and working properly.
My target group that is listening on port 443 is unhealthy and timing out.
I know that port 443 is failing due to the Apache settings but I am not sure how I am supposed to enable the port in Apache.
Based on everything that I have read, Apache requires you to have the physical file and key for the SSL in order for it to allow requests through port 443. I have tried to follow the instructions without those two things but WampServer3 will not restart without them.
I feel like there has to be a way to get this to work but I have hit a wall. Perhaps I am not searching for the right thing, or I am missing an additional module that needs to be used.
TLDR: Because the SSL that is generated by the AWS Certificate Manager cannot be physically downloaded, how can I get it to work with Apache on Windows 10 without having the file or key?
EDIT
So to my understanding I need to not only put the Rewrite code below in my <VirtualHost>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
I also need to put X-Forwarded-Proto: https at the top of my healthcheck.php page before the <html> tag? I'll keep reading about this since I don't fully understand it.
You have a listener on both 80 and 443 on your load balancer. The listener on 443 has the ACM cert.
You also say that you have one target group for each listener - one on 80 which is health, and one on 443 which is not.
The simple answer is to use one target group for both listeners. That way the connection to your end user is secure if they come in on 443, and only internal traffic between your ALB and instances uses HTTP. That way the health check will succeed, and your users will be able to use the site.
But that's not what most people really want - they want end-to-end security, and more than likely they want to redirect from port 80 to 443.
To force everyone to use 443, you will need a redirect rule in your apache config that checks to see if the incoming connection was secure. Because SSL is terminated on the ALB, you will need to check one of the X-Forwarded header values (See this) and redirect if say X-Forward-Port is 80.
To ensure that end-to-end traffic is secure, you can configure you listeners to listen on port 443 instead of port 80. You can use self-signed certificates for this, and I believe that some versions of Linux come with default certs. The ALB will not do certificate validation.
Edit:
In a comment, there was a question on where to put the rewrite code:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
If you have a single entry then this should work. If you have separate entries for port 80 and 443 AND you're using self-signed certs with different listeners, then you would need to put it in the port 80 virtual host entry.
I ended up not using the AWS Certificate Manager at all due to the hurdles that one has to overcome in order to get it to work.
Instead I found a great resource that provides SSL Certificates for free - LetsEncrypt. I would highly recommend this solution for everyone due to the ease of use. Plus they seem to be backed by many reputable companies.

Multiple domains and SSL : all domains use my SSL certificate but I don't want?

I have a wildcard SSL certificate on my apache server. It works perfectly with my domain, but the mistake is that it works with all the domains on my apache server ! And I don't want it, when I go on https://www.mywebsitewithouthttps.com, firefox tell me that the page is not secure because the certificate is for www.mydomainwithhttps.com. If I add an exception for this SSL error on my browser, it is not "mywebsitewithouthttps.com" that is display but "mydomainwithhttps.com" (on this URL : https://www.mywebsitewithouthttps.com) !
I don't want my certificate to work for all the other domains ! It's a big problem because Google is crawling and indexing all my other domains on HTTPS with the content of mydomainwithhttps.com :-(
This my virtualhost for SSL :
NameVirtualHost *:443
<VirtualHost *:443>
ServerName www.mydomainwithhttps.com
DocumentRoot "/home/mydomainwithhttps/www"
suPHP_Engine On
suPHP_AddHandler x-httpd-php
suPHP_UserGroup mydomainwithhttps users
AddHandler x-httpd-php .php
SSLEngine on
SSLCertificateFile /certificates/ssl_certificate.crt
SSLCertificateKeyFile /certificates/www.mydomainwithhttps.com.key
SSLCACertificateFile /certificates/IntermediateCA.crt
</VirtualHost>
If you make a HTTPS request the client will establish a TCP connection to the relevant IP and port (usually 443) at the server. If the connection succeeded it will start the TLS handshake and during the TLS handshake it will get the certificate for validation.
If you have multiple servers at the same IP address and port they all share the same TCP listener. Since the TCP connection attempt has no information about the targets server name but only has the targets IP address and port the listener will accept all connection attempts, even if the (yet unknown) target hostname has no HTTPS configured.
Modern clients then send the target hostname inside the TLS handshake and only then the server knows what the client wants. If it has HTTPS configured for the requested name the server can send the appropriate certificate. If HTTPS is not configured for this name the server will either send a default certificate or close the connection (maybe send a TLS alert when closing).
In summary this leaves you with the following options:
Use a different IP address for HTTPS sites and non-HTTPS sites. This way the TCP connection will already fail because the server is not listening for connections on this IP:port.
Configure your server to return an error when the client requests a hostname for which no HTTPS is configured. This way the client will probably get some strange error message about HTTPS problem in the browser. I'm not sure but maybe you can setup Apache this way when using the SSLStrictSNIVHostCheck on option. If this option does not help then apache might not support this kind of setup.
Configure your server to use a default certificate (usually the first configured certificate) whenever the name does not match or the client does not support SNI. The client will get a certificate mismatch warning in the browser. This is the setup you currently have.
Setup HTTPS properly for all domains either by having separate certificates or by including them all into a single certificate.
Thus to make sure that the bots don't assume that your site can do HTTPS you need to go with option 1 or 2. Please note also that in all of these cases you expect the bots to support SNI, which not all do. Therefore for best compatibility you would need to use a separate IP address for each HTTPS site.
You can configure the multi domain with SSL and with different certificate on both UBUNTU and RHEL by following multi donain with ssl
The problem is that Apache will try to find config for https://www.mywebsitewithouthttps.com/ and when it doesn't, it will default back to the first https config (the one for mydomainwithhttps).
This will show a cert error but, as you've experienced, if you click through, you see the wrong site.
I cannot however understand Google crawling and indexing the site. I would have thought it would have stopped when it saw the cert error? I'd be very surprised if that is not the case but if it's not you can put a rewrite rule on for those hostname a to redirect back to http.
There's only 2 ways around this:
Get certs for the other domains so you can connect via https. You can still redirect back to http if you really want.
Separate out the servers with https to a different server (or a different IP on the same server and set up Apache config to listen on port 443 on https IP address only).
That's just the way Apache (and most - if not all - other webservers) work.

Using Apache and mod_proxy in a forward proxy to convert http requests to https

I've used both Apache and nginx as a reverse proxy performing HTTPS termination (listening on port 443) and forwarding the unencrypted HTTP traffic to Tomcat on port 8080 before.
However, what I need to do now is do the opposite. I have some client applications running on localhost that are (for simplicity) just talking plain HTTP. I want to be able to tell these client apps to use a forward proxy (on localhost) that will convert them to HTTPS and use a client-side certificate for the communication to the origin. Ie, the client will think it is communicating plain HTTP on port 80, but the traffic will actually leave the host as HTTPS on port 443.
Does anyone know how to configure mod_proxy to do this (or even if it is possible)?
At a further stage, I may need to configure the proxy to use different client certificates based on headers set by the client and also have mod_proxy use RFC 5077 (quick session resumption).
It doesn't have to be Apache (so if nginx or squid can do the function I'm happy with that) as long as it's not a resource hog. We already have Apache running as a reverse proxy anyway so it would be handy if Apache can do it.

HTTPS block domain

When having multiple domain names point to the same server. But you only have a certificate for one of these domains, is it possible to block the other domains in Apache. But only when HTTPS is used not when HTTP is used.
I tried using a NameVirtualHost setup for 443 port. But when the domain is not found Apache simply defaults to the first virtual host. I would like it to refuse the connection. In this way when connecting directly through HTTPS on one of the not supported domains the connection is refused rather then having the browser display warning screen because of a wrong identity.
Any thoughts?
Not possible.
This is a chicken and egg problem - to verify an https connection the browser connects and tries to validate the certificate/common name and the given URL. The first handshake / connection to port 443 has to be encrypted.
The only way to handle this problem would be to setup dedicated IPs for all domains - or for at least the domain using HTTPS.
It's far from ideal, but another option would be to use a non-standard for your HTTPS site and not have the server listening on port 443.