1

I need to redirect HTTPS stream from HAProxy to Nginx without SSL termination and without loosing an info about the original client IP. Unfortunately I cannot change the configuration of default 443 site on Nginx because it's maintained by Synology NAS configuration.

I was thinking about new listen port on Nginx accepting proxy protocol from HAProxy and kind of internal redirection to the local 443 port without SSL decoding / encoding, but with passing the original client IP taken from HAProxy. Is that somehow possible?

Edit: The background is that I have tunneled OpenVPN and web services on the same external 443 port, so actually it looks as below:

router 443 TCP -> HAProxy -> SNI check -> stunnel -> OpenVPN | ------> SSL termination -> Nginx 443 HTTPS 

I use HAProxy because ngx_stream_ssl_preread_module is not available on Synology's builtin Nginx.

Edit: I think the situation and question can be more generic:

Nginx: port X accessed via proxy protocol with SSL/TLS port Y 

How to pass the stream from port X to Y with the information about the source client IP and without the SSL termination? Is listen directive with proxy_protocol on port Y the only possible option?

4
  • Can you explain what you're trying to accomplish? Your approach seems a bit too complicated. Commented Aug 8, 2017 at 18:15
  • I'm trying to find a way to avoid SSL termination on HAProxy and to pass an original client IP to Nginx server. I cannot use true transparent proxy because I don't fulfill requirements and I don't want to change the current configuration on Nginx 443 port, because it's managed by Synology DSM. Commented Aug 8, 2017 at 19:14
  • you're re-iterating what you're trying to do, but you're still omitting why does it actually have to be done that way. Why do you need HAProxy? Why do you need it to pass HTTPS connections to nginx on port 443 preserving client IP? What's the actual problem you're trying to solve? Commented Aug 8, 2017 at 19:44
  • I use HAProxy because I need somehow to decide what should I forward to stunnel server, and what should I forward to Nginx. I use SNI on stunnel client which is later intercepted from TCP stream by HAProxy. I need to preserve original client IP on Nginx for blacklisting / logging purposes. I need to use port 443 on Nginx because I have plenty of Synology services available there. Commented Aug 8, 2017 at 19:48

2 Answers 2

0

Yes, you can do the above with nginx.

A simple Google search reveals that the listen directive has a proxy_protocol parameter since 1.5.12, which, for security reasons, should probably be used in conjunction with the set_real_ip_from directive:

Note that this will invariably require minimal modification of the nginx configuration that's in your case maintained by the third-party tool that you mention; for obvious security reasons, it should not be possible to pass client-IP information without any such modification.


Additionally, note that you don't actually need HAProxy anymore — the new stream functionality within nginx already lets you operate on TCP and SSL streams, including, as of the most recent versions, the ability to discriminate unopened SSL streams based on SNI, the Server Name Indication — see ssl_preread and the corresponding $ssl_preread_server_name since 1.11.5.

10
  • I've tried to use Nginx for SNI detection, but my Synology Nginx build lacks ngx_stream_ssl_preread_module which is mandatory for ssl_preread to be available. I've seen that I can use proxy_protocol with listen directive, but as that part of Nginx configuration for 443 port is maintained by Synology setup it requires additional efforts to keep it not removed. That's why I was looking for an alternative. Commented Aug 8, 2017 at 20:25
  • @onlyoneme perhaps that's because it's not compiled by default; but there is no possible alternative given your requirements — it would be a security vulnerability for any software to suddenly start accepting client ip forging without an explicit configuration to such an effect. Commented Aug 8, 2017 at 20:32
  • set_real_ip_from can be defined in "http" location, and in fact it is in my case; the sections I do not want to touch are "server" ones related to the 443 port Commented Aug 8, 2017 at 20:42
  • Besides that HAProxy puts the client IP into X-Real-IP header and it's visible for Nginx and works without issue, but it requires SSL termination before. Commented Aug 8, 2017 at 20:54
  • So, you can edit parts of the conf, just not the whole conf? That's new — then what you could possibly do is shadow the autogenerated server with another server that would be defined earlier; you could ensure this way that the changes to the autogenerated server couldn't be overwritten; however, this would also remove the ability for the autogenerated changes to take effect. Commented Aug 8, 2017 at 20:58
0

One possible solution is to do SSL Bridging with HAProxy. This means that HAProxy will:
1. Decrypt the SSL connection.
2. Insert the X-Real-IP header.
3. Encrypt the connection again when talking to Nginx.

Decrypting the SSL connection needs HAProxy to be running on HTTP mode, but at the same time HAProxy should receive stunnel traffic coming to the same 443 port. So the solution I can think of is to first split both traffic via a dummy backend.

Of course this will come with extra perf cost, but it won't be noticeable if there is no really high load.

frontend ft_ssl bind *:443 mode tcp acl web_traffic req_ssl_sni -i <web-domain> acl stunnel_traffic req_ssl_sni -i <stunnel-domain> use_backend bk_ssl_dummy if web_traffic use_backend bk_ssl_stunnel if stunnel_traffic backend bk_ssl_stunnel mode tcp server stunnel1 <IP>:<PORT> check backend bk_ssl_dummy mode tcp server web_ssl_offload 127.0.0.1:8888 send-proxy-v2-ssl-cn check frontend ft_web_offload bind 127.0.0:8888 ssl crt <path-to-crt> accept-proxy mode http http-request set-header X-Real-IP %[src] default_backend bk_ssl_nginx backend bk_ssl_nginx mode http server nginx1 <sIP>:443 ssl check 

Connections are re-encrypted when routed to Nginx since we use the ssl param in the server line.

Configuring Nginx to use proxy-protocl will let you have a much more simple HAProxy conf, so this solution will only make sense if you only can't change Nginx conf.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.