Welcome! Log In Create A New Profile

Advanced

Problems with SNI config

Posted by Jeremy Utley 
Jeremy Utley
Problems with SNI config
April 13, 2017 06:40PM
Hello all!

I'm trying to convert an Apache reverse proxy setup over to using HAProxy,
but am running into issues with SNI. I followed
http://stuff-things.net/2016/11/30/haproxy-sni/ to set this up, but it's
not working, and I have not yet been able to figure out why.

HAProxy version: 1.5.4-3 installed from the EPEL repo on Centos 6 (Policy
here forbids self-compiled versions, so we are limited to only what's
available to us in EPEL)

I've narrowed down the problem to my frontend definition - if I simplify
the front-end to not do SNI, it works fine to either backend. If I add a
default_backend definition, it goes to the default backend no matter which
hostname I provide. Without the default_backend in the frontend
configuration, I get a 503 error from the proxy. So something is
definately not right with my SNI configuration, but I certainly can not
find it!

Here is a sanitized version of my frontend definition in haproxy.cfg:

frontend https-8443
bind 192.168.1.1:8443 ssl crt /etc/haproxy/certs/
use_backend site1 if { hdr(host) -i site1.domain.com }
use_backend site2 if { hdr(host) -i site2.domain.com }


We will eventually have something like 20-30 different SSL sites in this
configuration, along with some IP-based ACLs as well, but I'm not to that
point as of yet. I am simply trying to get SNI working, to direct to a
different backend depending on the hostname requested (which, according to
my reading, should be perfectly doable with haproxy.

Anybody got any ideas of what I'm doing wrong?

Thanks for your time!

Jeremy Utley
Gibson, Brian (IMS)
RE: Problems with SNI config
April 13, 2017 06:50PM
I’ve not tried using ACLs in curly brackets like you are, but I can confirm that this configuration works for me

acl name1 hdr(host) -i www.example.orghttp://www.example.org
acl name2 hdr(host) -i www.example-other.orghttp://www.example-other.org

use_backend backend1 if name1
use_backend backend2 if name2

I use this code specifically to do what you’re trying to do, though I’m using the latest stable build. I’m pretty sure this code should work in 1.5 though as well.

Also if you can’t use self compiled stuff, can you use something like IUS? https://ius.io/

From: Jeremy Utley [mailto:[email protected]]
Sent: Thursday, April 13, 2017 12:29 PM
To: haproxy@formilux.org
Subject: Problems with SNI config

Hello all!

I'm trying to convert an Apache reverse proxy setup over to using HAProxy, but am running into issues with SNI. I followed http://stuff-things.net/2016/11/30/haproxy-sni/ to set this up, but it's not working, and I have not yet been able to figure out why.

HAProxy version: 1.5.4-3 installed from the EPEL repo on Centos 6 (Policy here forbids self-compiled versions, so we are limited to only what's available to us in EPEL)

I've narrowed down the problem to my frontend definition - if I simplify the front-end to not do SNI, it works fine to either backend. If I add a default_backend definition, it goes to the default backend no matter which hostname I provide. Without the default_backend in the frontend configuration, I get a 503 error from the proxy. So something is definately not right with my SNI configuration, but I certainly can not find it!

Here is a sanitized version of my frontend definition in haproxy.cfg:

frontend https-8443
bind 192.168.1.1:8443http://192.168.1.1:8443 ssl crt /etc/haproxy/certs/
use_backend site1 if { hdr(host) -i site1.domain.comhttp://site1.domain.com }
use_backend site2 if { hdr(host) -i site2.domain.comhttp://site2.domain.com }


We will eventually have something like 20-30 different SSL sites in this configuration, along with some IP-based ACLs as well, but I'm not to that point as of yet. I am simply trying to get SNI working, to direct to a different backend depending on the hostname requested (which, according to my reading, should be perfectly doable with haproxy.

Anybody got any ideas of what I'm doing wrong?

Thanks for your time!

Jeremy Utley

________________________________

Information in this e-mail may be confidential. It is intended only for the addressee(s) identified above. If you are not the addressee(s), or an employee or agent of the addressee(s), please note that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this e-mail in error, please notify the sender of the error.
Jeremy Utley
Re: Problems with SNI config
April 13, 2017 11:10PM
Thanks for the suggestion, Brian! First off, IUS *IS* actually on our
allowed list, so I upgraded to the IUS haproxy RPM v1.7.3 (Our local repo
copy does not have 1.7.4 sync'd into it yet - I didn't even realize haproxy
was in the IUS repo). I also converted my configuration to be like you
indicated, and I am unfortunately still having the same issue. Here is my
new front-end configuration (sanitized):

frontend https-8443
bind 192.168.1.1:8443 ssl crt /etc/haproxy/certs/
acl site01 hdr(host) -i site01.domain.com
acl site02 hdr(host) -i site02.domain.com
use_backend site01 if site01
use_backend site02 if site02

If I delete the two use_backend lines, and add a default_backend line, it
works properly.

For additional reference, here are the two backends and my defaults section
as well:

backend site01
balance roundrobin
server server01 192.168.1.2:80

backend site02
balance roundrobin
server server02 192.168.1.3:80

(In this implementation, we're using it more for the proxy functions than
we are the HA functions).

defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000


Also, looking at the log file, all I see is:

Apr 13 16:43:37 tc-vpn01 haproxy[8986]: 192.168.1.100:59689
[13/Apr/2017:16:43:37.874] https-8443~ https-8443/<NOSRV> -1/-1/-1/-1/0 503
212 - - SC-- 0/0/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"

Anyone with any ideas?

Thanks,

Jeremy

On Thu, Apr 13, 2017 at 11:41 AM, Gibson, Brian (IMS) <[email protected]>
wrote:

> I’ve not tried using ACLs in curly brackets like you are, but I can
> confirm that this configuration works for me
>
>
>
> acl name1 hdr(host) -i www.example.org
>
> acl name2 hdr(host) -i www.example-other.org
>
>
>
> use_backend backend1 if name1
>
> use_backend backend2 if name2
>
>
>
> I use this code specifically to do what you’re trying to do, though I’m
> using the latest stable build. I’m pretty sure this code should work in
> 1.5 though as well.
>
>
>
> Also if you can’t use self compiled stuff, can you use something like IUS?
> https://ius.io/
>
>
>
> *From:* Jeremy Utley [mailto:[email protected]]
> *Sent:* Thursday, April 13, 2017 12:29 PM
> *To:* haproxy@formilux.org
> *Subject:* Problems with SNI config
>
>
>
> Hello all!
>
>
>
> I'm trying to convert an Apache reverse proxy setup over to using HAProxy,
> but am running into issues with SNI. I followed
> http://stuff-things.net/2016/11/30/haproxy-sni/ to set this up, but it's
> not working, and I have not yet been able to figure out why.
>
>
>
> HAProxy version: 1.5.4-3 installed from the EPEL repo on Centos 6 (Policy
> here forbids self-compiled versions, so we are limited to only what's
> available to us in EPEL)
>
>
>
> I've narrowed down the problem to my frontend definition - if I simplify
> the front-end to not do SNI, it works fine to either backend. If I add a
> default_backend definition, it goes to the default backend no matter which
> hostname I provide. Without the default_backend in the frontend
> configuration, I get a 503 error from the proxy. So something is
> definately not right with my SNI configuration, but I certainly can not
> find it!
>
>
>
> Here is a sanitized version of my frontend definition in haproxy.cfg:
>
>
>
> frontend https-8443
>
> bind 192.168.1.1:8443 ssl crt /etc/haproxy/certs/
>
> use_backend site1 if { hdr(host) -i site1.domain.com }
>
> use_backend site2 if { hdr(host) -i site2.domain.com }
>
>
>
>
>
> We will eventually have something like 20-30 different SSL sites in this
> configuration, along with some IP-based ACLs as well, but I'm not to that
> point as of yet. I am simply trying to get SNI working, to direct to a
> different backend depending on the hostname requested (which, according to
> my reading, should be perfectly doable with haproxy.
>
>
>
> Anybody got any ideas of what I'm doing wrong?
>
>
>
> Thanks for your time!
>
>
>
> Jeremy Utley
>
> ------------------------------
>
> Information in this e-mail may be confidential. It is intended only for
> the addressee(s) identified above. If you are not the addressee(s), or an
> employee or agent of the addressee(s), please note that any dissemination,
> distribution, or copying of this communication is strictly prohibited. If
> you have received this e-mail in error, please notify the sender of the
> error.
>
Lukas Tribus
Re: Problems with SNI config
April 13, 2017 11:40PM
Hello Jeremy,

you are not using SNI, you are using the Host header to pick the backend.

You are also using a non-standard port, so the browser will append the
port to the Host header [1].


If 8443 is the port the browser connects to, your ACL's must look like this:
acl site01 hdr(host) -i site01.domain.com:8443
acl site02 hdr(host) -i site02.domain.com:8443


Regards,
Lukas


[1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23
Willy Tarreau
Re: Problems with SNI config
April 14, 2017 11:30AM
Hi Lukas,

On Thu, Apr 13, 2017 at 11:28:16PM +0200, Lukas Tribus wrote:
> [1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23

Just a quick hint, we really need to get used to replace the outdated
rfc2616 links with the more recent 723x ones, this one is much more
complete :

https://tools.ietf.org/html/rfc7230#section-5.4

(and what you said remains otherwise correct :-))

Willy
Lukas Tribus
[PATCH] doc: update RFC references
April 28, 2017 03:30PM
---
A few doc and code comment updates bumping RFC references to the new
ones.
---
doc/configuration.txt | 12 ++++++------
include/common/defaults.h | 2 +-
include/proto/proto_http.h | 2 +-
include/types/proto_http.h | 4 ++--
src/haproxy.c | 4 ++--
src/proto_http.c | 6 +++---
6 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index bfce6b1..06a1a2a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -268,7 +268,7 @@ about the way they could be written, but it is important not to accuse an
application of being buggy if it does unusual, valid things.

Important note:
- As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks
+ As suggested by RFC7231, HAProxy normalizes headers by replacing line breaks
in the middle of headers by LWS in order to join multi-line headers. This
is necessary for proper analysis and helps less capable HTTP parsers to work
correctly and not to be fooled by such complex constructs.
@@ -318,7 +318,7 @@ The status code is always 3-digit. The first digit indicates a general status :
- 4xx = error caused by the client (eg: 401, 403, 404)
- 5xx = error caused by the server (eg: 500, 502, 503)

-Please refer to RFC2616 for the detailed meaning of all such codes. The
+Please refer to RFC7231 for the detailed meaning of all such codes. The
"reason" field is just a hint, but is not parsed by clients. Anything can be
found there, but it's a common practice to respect the well-established
messages. It can be composed of one or multiple words, such as "OK", "Found",
@@ -2319,7 +2319,7 @@ balance url_param <param> [check_post]
- Expect: 100-continue is not supported, load balancing will fall back to
Round Robin.

- - Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk.
+ - Transfer-Encoding (RFC7230 3.3.1) is only supported in the first chunk.
If the entire parameter value is not present in the first chunk, the
selection of server is undefined (actually, defined by how little
actually appeared in the first chunk).
@@ -5648,7 +5648,7 @@ no option http-server-close
latency on the client side (slow network) and the fastest session reuse on
the server side to save server resources, similarly to "option forceclose".
It also permits non-keepalive capable servers to be served in keep-alive mode
- to the clients if they conform to the requirements of RFC2616. Please note
+ to the clients if they conform to the requirements of RFC7230. Please note
that some servers do not always conform to those requirements when they see
"Connection: close" in the request. The effect will be that keep-alive will
never be used. A workaround consists in enabling "option
@@ -5715,7 +5715,7 @@ no option http-use-proxy-header
yes | yes | yes | no
Arguments : none

- While RFC2616 explicitly states that HTTP/1.1 agents must use the
+ While RFC7230 explicitly states that HTTP/1.1 agents must use the
Connection header to indicate their wish of persistent or non-persistent
connections, both browsers and proxies ignore this header for proxied
connections and make use of the undocumented, non-standard Proxy-Connection
@@ -14598,7 +14598,7 @@ req.hdr([<name>[,<occ>]]) : string
with -1 being the last one. A typical use is with the X-Forwarded-For header
once converted to IP, associated with an IP stick-table. The function
considers any comma as a delimiter for distinct values. If full-line headers
- are desired instead, use req.fhdr(). Please carefully check RFC2616 to know
+ are desired instead, use req.fhdr(). Please carefully check RFC7231 to know
how certain headers are supposed to be parsed. Also, some of them are case
insensitive (eg: Connection).

diff --git a/include/common/defaults.h b/include/common/defaults.h
index 1618ab4..81dc3b1 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -136,7 +136,7 @@
#endif

// cookie delimitor in "prefix" mode. This character is inserted between the
-// persistence cookie and the original value. The '~' is allowed by RFC2965,
+// persistence cookie and the original value. The '~' is allowed by RFC6265,
// and should not be too common in server names.
#ifndef COOKIE_DELIM
#define COOKIE_DELIM '~'
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 9409df3..14c0ce6 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -30,7 +30,7 @@

/*
* some macros used for the request parsing.
- * from RFC2616:
+ * from RFC7230:
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
* SEP = one of the 17 defined separators or SP or HT
* LWS = CR, LF, SP or HT
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 9987c33..1d378ac 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -171,7 +171,7 @@ enum ht_state {
*/
HTTP_MSG_BODY = 27, // parsing body at end of headers
HTTP_MSG_100_SENT = 28, // parsing body after a 100-Continue was sent
- HTTP_MSG_CHUNK_SIZE = 29, // parsing the chunk size (RFC2616 #3.6.1)
+ HTTP_MSG_CHUNK_SIZE = 29, // parsing the chunk size (RFC7230 #4.1)
HTTP_MSG_DATA = 30, // skipping data chunk / content-length data
HTTP_MSG_CHUNK_CRLF = 31, // skipping CRLF after data chunk
HTTP_MSG_TRAILERS = 32, // trailers (post-data entity headers)
@@ -274,7 +274,7 @@ enum {
STAT_STATUS_SIZE
};

-/* This is an HTTP message, as described in RFC2616. It can be either a request
+/* This is an HTTP message, as described in RFC7230. It can be either a request
* message or a response message.
*
* The values there are a little bit obscure, because their meaning can change
diff --git a/src/haproxy.c b/src/haproxy.c
index 02f90a8..261b213 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -7,8 +7,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Please refer to RFC2068 or RFC2616 for informations about HTTP protocol, and
- * RFC2965 for informations about cookies usage. More generally, the IETF HTTP
+ * Please refer to RFC7230 - RFC7235 informations about HTTP protocol, and
+ * RFC6265 for informations about cookies usage. More generally, the IETF HTTP
* Working Group's web site should be consulted for protocol related changes :
*
* http://ftp.ics.uci.edu/pub/ietf/http/
diff --git a/src/proto_http.c b/src/proto_http.c
index 579473b..53bfd8b 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -850,8 +850,8 @@ int http_find_next_header(char *sol, struct hdr_idx *idx, struct hdr_ctx *ctx)
return 0;
}

-/* Find the end of the header value contained between <s> and <e>. See RFC2616,
- * par 2.2 for more information. Note that it requires a valid header to return
+/* Find the end of the header value contained between <s> and <e>. See RFC7230,
+ * par 3.2 for more information. Note that it requires a valid header to return
* a valid result. This works for headers defined as comma-separated lists..
*/
char *find_hdr_value_end(char *s, const char *e)
@@ -1119,7 +1119,7 @@ char *http_get_path(struct http_txn *txn)
if (ptr >= end)
return NULL;

- /* RFC2616, par. 5.1.2 :
+ /* RFC7230, par. 2.7 :
* Request-URI = "*" | absuri | abspath | authority
*/

--
2.7.4
Willy Tarreau
Re: [PATCH] doc: update RFC references
April 28, 2017 07:10PM
On Fri, Apr 28, 2017 at 01:24:30PM +0000, Lukas Tribus wrote:
> ---
> A few doc and code comment updates bumping RFC references to the new
> ones.

Merged, thank you Lukas!
Willy
Sorry, only registered users may post in this forum.

Click here to login