Redirect HTTPS 443 Port to multiple sites on other servers - apache

The scenario is this: On side "A" where I stay I can only use 443 for HTTPS from the browser, no other port is enabled for HTTPS requests. In the side "B" I have multiple HTTPS sites in different LAN servers behind one IP address to Internet.
Is a possible way to do something to access the multiple HTTPS Sites from the side "A"?. If I do port forwarding on the side B like: from side A :443 to side B : it works but only for one of the HTTPS sites.
I looked in to installing an Apache Server with SNI (server name indication) to do www.sideb.server1.com:443 and www.sideb.server2.com:443 to the only IP Address on side B and different servers, but don't know if I can "transfer" the traffic from that server to another one. Redirects, I assume, do not work because the client on side A cannot access other ports from side B.

It should be possible to let apache or ngnix work a a reverse proxy and forward the data to the right host based on the server name the clients sends using SNI. But, in this case all the certificates need to be located at side A, so that the reverse proxy can terminate the SSL connection with the correct certificate. And, client certificates will not work.
In theory there is another option: one could write a kind of proxy, which just looks at the initial SSL Client Hello (e.g the first packet sent from the client), extracts the clear-text server name extension and then forwards the whole connection to the right host. In this case you don't need to have the final certificates at the proxy side because you don't terminate the connection and client certificates will also work. Maybe someone has coded this already.

Related

Let's encrypt certificate with NO SNI

I have a site where i have ssl created by letsencrypt, but there is a problem with no sni ssl. Is it confugired ok?
https://www.ssllabs.com/ssltest/analyze.html?d=watcheds.com
Site looks good https://watcheds.com .
I
Your site is almost certainly hosted on a virtual host with many other sites on the same IP address. As such, HTTPS won't work without SNI because the server can't know which virtual host the client wants to connect to. The raw data in a TCP connection only has the IP address and port. The HTTP data is all in the packet content, which is encrypted in HTTPS.
SNI access works via HTTPS because the desired site is passed unencrypted and in the clear, allowing the server to properly route the incoming connection without access to your site's private SSL keys. Without SNI, the server would need to decrypt the incoming HTTPS request before knowing where to route it, and this would require the server to have access to your site's private keys.
And if the server were hosting many virtual hosts, without something like SNI it wouldn't know which set of private keys to use...

How to ensure a secure connection using a reverse proxy to an external server?

Guess this is the only post ever where I start with: "My SSL connection works but I don't know why".
I have a setup where the domain name and wildcard certificate lie on server A, and I want to use a subdomain of that domain to proxy requests to server B on another machine somewhere on the internet. Server B is currently only reachable via an IP, so I actually did not expect this to work, because SSL-certificates are based on domain names.
My setup is as follows (example):
Server A domain: www.production.io
Server A Subdomain: cus1.production.io
Server B IP: 65.23.523.12
Apache config for http of cus1.production.io:
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
Redirect / https://cus1.production.io/
Apache config for https of cus1.production.io:
ProxyPass / http://65.23.523.12/
ProxyPassReverse / http://65.23.523.12/
Calling cus1.production.io shows the application on 65.23.523.12 but with a secured connection (green lock) in the browser though the webserver on Server B does not offer https connections nor does it provide an SSL certificate.
Although the connection between a client and the "proxying" Server A is secure, the data transferred to the actual application is not. So this is actually a fraud.
Question: How do I make sure a secure connection will be applied between Server A and Server B?
It's not really "fraud", it's just that the SSL/TLS connection is ensured between the browser and Server A. The browser has nothing to do with Server B: Server A is the client to Server B.
If you can, set up SSL/TLS on Server B. Even if it's only accessible with an IP address, you could create your internal CA or a self-signed certificate. (That certificate should have this IP address in a SAN entry of IP address type.)
Then, you can use mod_ssl's SSLProxy* options to configure how Apache Httpd (on Server A) behaves as a client to server B (i.e. when it's a reverse proxy).
Typically, you'll need to set SSLProxyCACertificateFile (to point to your internal CA cert or that self-signed cert) and use SSLProxyCheckPeerName.
In short, it's up to you to make sure.
What you've just described is a common way of configuring SSL setups, where you have one set of servers that handle the secure connection to the browser, then they proxy the requests to another server, often just with http. This is known as ssl termination.
Usually this connection is done within a secure network, the servers hosting the certificates can be accessed from the internet, but the servers they forward to are not, so they don't proxy back across the internet. However, there is nothing in theory to prevent this if your servers aren't configured properly.

Using HTTPS with a dynamic ip

My situation:
I want to run a webserver on a device in an unknown network. Requests on port 80 or 443 will be forwarded to this device from the global ip.
The device regularly posts its IP address to a server on the web and it is saved on this server.
Is it possible to access this device via https without much trouble?
The problem of course is, that the ip can change and a SSL certificate needs to have a hostname.
Edit: The device doesn't have a domain assigned to it that I could use for a certificate. Is it maybe possible to use a domain I own and reroute that to the dynamic ip without changing the header?
As far as I understand it that would make using https possible
The common wisdom of SSL certificates being associated with one IP address is misleading. An SSL certificate is issued for the domain name, not the IP address. The issue with IP addresses stems from the details of the HTTPS protocol, and namely just the issue of name resolution. An HTTP server can host many different sites for many different domains, all on the same port and IP address. It knows which site is being requested based on an HTTP header.
Now, with HTTPS, the server first needs to negotiate a secure SSL connection before any HTTP headers are exchanged. The issue therefore is that it can't know which certificate for which domain it's supposed to use to negotiate a secure connection, because it hasn't yet had a chance to talk to the client about the domain it'd like to visit.
There are actually mechanisms for name negotiation before encryption in later versions of the HTTPS protocol, but the practical problem is that older clients do not support it yet (stare at IE6).
So the practical solution is to reserve one IP address and/or port for each HTTPS site, because then there's no issue of multiple name resolutions. One IP/port is reserved for one specific HTTPS site and in extension for one SSL certificate.
Which means, as long as your server is only serving one HTTPS domain, its IP address can change as often as it wants; there's no issue there.
There is no problem with dynamic IP. In SSL certificate you store a static hostname (domain.com), no IP address.

Is it possible to have a forward proxy with ssl encryption between the proxy and the user?

First of all I want to make clear that i am not talking about accessing content which is on origin servers that deliver using https which can be done using the module mod_proxy_connect.
What I want is a secured connection between the client and the proxy, also when the origin that is requested actually is served by an unsecured standard http server.
I am using apache 2.2 and also would like to make this possible with apache if that works.
I sniffed some requests using wireshark and noted the following:
A usual http of the url http://example.com/file looksl ike this:
on a connection to the origin server:
GET /file HTTP 1.1
Host: example.com
Note that the host information is stripped from the actual request and the host header is supplied instead (which can be handled server side in named virtual hosts).
When the request goes through a proxy server it looks slightly different:
on a connection to the proxy server:
GET http://example.com/file HTTP 1.1
Host: example.com
Note that the request line now actually contains the full url including protocol and hostname.
The host header is probably redundant, bus if I read the RFC correctly it is required by HTTP 1.1.
So I think about setting up an apache webserver listening on port 443, enable a virtualhost with ssl engine and certificates up and do not bind it to any hostname.
I think that should get apache to talk ssl, but however the certificates common name will not match the host specfied in the connect line to the proxys server ip adress.
Is what I want to to even possible with current standards and if so how can I do it?
Yes of course, that's what HTTPS proxy is.
Client connects to proxy over SSL, sends commands to proxy in text.
It is also possible to use HTTP CONNECT to establish HTTPS connection "inside" the SSL connection to HTTPS proxy, though not all clients support this:
HTTPS connection over HTTPS proxy
client proxy server
ssl \-------/ ssl
connect---------200 OK
ssl \---------------------------/ ssl
data-------------------------------data
/---------------------------\
/-------\
HTTP connection over HTTPS proxy
client proxy server
ssl \-------/ ssl
GET http://server/ ->
GET /
Host: server ->
<---------OK, data
<--------------OK, data
/-------\

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.