Discussion:
apache proxy pass rules in HAproxy
Imam Toufique
2018-10-23 07:04:14 UTC
Permalink
I am looking for some help on how to write the following apache
proxypass rules in HAproxy. Not to mention I am at a bit of loss with my
first try :-) . Here are my current proxypass rules:

ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub

<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>

As I am not well versed in the massive HAproxy configuration guide, if any
of you can give me a hand with this, I would very much appreciate it.

thanks
Imam Toufique
2018-10-24 00:33:05 UTC
Permalink
Not completely there yet, but I at least got the backend server login
screen to come up with the following:

frontend
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3

backend
backend web3_cluster
mode http
#http-request set-header Host bk.dom.com
balance roundrobin # roundrobin is rotate customers into backend server
server web1 10.1.100.156:8000/jhub check inter 2000 cookie w1
server web2 10.1.100.160:8000/jhub check inter 2000 cookie w1


I am running into a redirect loop , I cant login to the backend UI, i get
this error:

500 : Internal Server Error

Redirect loop detected.


Not sure why I am getting this error. the application is jupyterhub , it
runs OK with Apaches reverse proxy .
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try :-)
. Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just rewrites,
as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide, if
any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass haproxy and
adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-24 00:40:41 UTC
Permalink
Post by Imam Toufique
Not completely there yet, but I at least got the backend server login
frontend
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
backend web3_cluster
mode http
#http-request set-header Host bk.dom.com
balance roundrobin # roundrobin is rotate customers into backend server
server web1 10.1.100.156:8000/jhub check inter 2000 cookie w1
server web2 10.1.100.160:8000/jhub check inter 2000 cookie w1
I am running into a redirect loop , I cant login to the backend UI, i get
500 : Internal Server Error
Redirect loop detected.
Not sure why I am getting this error. the application is jupyterhub , it
runs OK with Apaches reverse proxy .
Try:

server web1 10.1.100.156:8000 <http://10.1.100.156:8000/jhub> check
inter 2000 cookie w1
server web2 10.1.100.160:8000 <http://10.1.100.160:8000/jhub> check
inter 2000 cookie w1
Imam Toufique
2018-10-24 01:15:53 UTC
Permalink
Ok, I will give that a try. thanks.
Post by Igor Cicimov
Post by Imam Toufique
Not completely there yet, but I at least got the backend server login
frontend
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
backend web3_cluster
mode http
#http-request set-header Host bk.dom.com
balance roundrobin # roundrobin is rotate customers into backend server
server web1 10.1.100.156:8000/jhub check inter 2000 cookie w1
server web2 10.1.100.160:8000/jhub check inter 2000 cookie w1
I am running into a redirect loop , I cant login to the backend UI, i get
500 : Internal Server Error
Redirect loop detected.
Not sure why I am getting this error. the application is jupyterhub , it
runs OK with Apaches reverse proxy .
server web1 10.1.100.156:8000 <http://10.1.100.156:8000/jhub> check
inter 2000 cookie w1
server web2 10.1.100.160:8000 <http://10.1.100.160:8000/jhub> check
inter 2000 cookie w1
--
Regards,
*Imam Toufique*
*213-700-5485*
Imam Toufique
2018-10-25 07:11:01 UTC
Permalink
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
current setup:

frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }

acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3

backend
server web1.oit.uci.edu 128.110.80.5:80 check

this works for the most part. But I am confused with a problem. when I get
to my application, my backend IP address shows up in the browser URL.

for example, I see this in my browser:

http://128.110.80.5/jhub/user/itoufiqu/tree?

whereas, I was expecting that it would show the original URL, such as:

http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )

While I am no expert in HA proxy world, I think this might due to the fact
that my backend does not have SSL and HAproxy frontend does have SSL. At
this point, I would avoid that IP address showing up in the browser. what
is the best way to accomplish this?

thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try :-)
. Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just rewrites,
as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide, if
any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass haproxy and
adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-25 07:31:12 UTC
Permalink
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem. when I
get to my application, my backend IP address shows up in the browser URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy with
ssl termination and that it's domain/url is https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do that
depends on the backend app you are using but most of them like apache2,
tomcat etc. have specific configs that you can find in their documentation.
For example if your backend is apache2 I bet you don't have the DomainName
set in the config in which case it defaults to the host ip address.
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to the fact
that my backend does not have SSL and HAproxy frontend does have SSL. At
this point, I would avoid that IP address showing up in the browser. what
is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try :-)
. Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just rewrites,
as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide, if
any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass haproxy
and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-25 08:20:52 UTC
Permalink
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem. when I
get to my application, my backend IP address shows up in the browser URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy with
ssl termination and that it's domain/url is https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do that
depends on the backend app you are using but most of them like apache2,
tomcat etc. have specific configs that you can find in their documentation.
For example if your backend is apache2 I bet you don't have the DomainName
set in the config in which case it defaults to the host ip address.
You can also try:

rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com <http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2
if { ssl_fc }

to fix the URL but note that this will not save you from hard coded url's
in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to the
fact that my backend does not have SSL and HAproxy frontend does have SSL.
At this point, I would avoid that IP address showing up in the browser.
what is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try
:-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide, if
any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass haproxy
and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps


p. +61 (0) 433 078 728
e. ***@encompasscorporation.com <http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
Imam Toufique
2018-10-26 22:37:34 UTC
Permalink
Hi,

I came up with the following config, things seem to be working now, for the
most part.

frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3

web3_cluster

backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none inter
2000 cookie w1

The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.

Now, the interesting thing I have noticed with the above setup -- when I
connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser points to the
backend node.

For example:

my proxy address: https://proxy.domain.com/jhub

after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?

...and everything works thereafter.

I tried the rewrite method that Igor has suggested before, that did not
make any difference. But what I noticed is, after I connect, no traffic go
through the proxy anymore, my client ( i.e. laptop) connects directly to
the backend server. Not sure if this good or bad though (?) , but, I am not
sure how to configure this so that I will go through a proxy but still be
connected in the backend via a private IP and I can ( still ) authenticate
via shibboleth.

So, when I change the 'web3_cluster' backend to :

server crsplabweb1 privateIP:80 inter 2000 cookie w1

and, I set backend apache to accept connection on port 80, then I break
shibboleth authentication.

Any inputs here?

thanks, guys!
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem. when I
get to my application, my backend IP address shows up in the browser URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy with
ssl termination and that it's domain/url is https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do that
depends on the backend app you are using but most of them like apache2,
tomcat etc. have specific configs that you can find in their documentation.
For example if your backend is apache2 I bet you don't have the DomainName
set in the config in which case it defaults to the host ip address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com <http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2
if { ssl_fc }
to fix the URL but note that this will not save you from hard coded url's
in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to the
fact that my backend does not have SSL and HAproxy frontend does have SSL.
At this point, I would avoid that IP address showing up in the browser.
what is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try
:-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide,
if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass haproxy
and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-27 03:33:56 UTC
Permalink
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now, for
the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none inter
2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup -- when I
connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser points to the
backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did not
make any difference. But what I noticed is, after I connect, no traffic go
through the proxy anymore, my client ( i.e. laptop) connects directly to
the backend server. Not sure if this good or bad though (?) , but, I am not
sure how to configure this so that I will go through a proxy but still be
connected in the backend via a private IP and I can ( still ) authenticate
via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I break
shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs so we
can see what is going on (please obfuscate any sensitive data). Also the
use of the "cookie w1" is not clear since you are not setting it in HAP and
is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem. when I
get to my application, my backend IP address shows up in the browser URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy with
ssl termination and that it's domain/url is https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do that
depends on the backend app you are using but most of them like apache2,
tomcat etc. have specific configs that you can find in their documentation.
For example if your backend is apache2 I bet you don't have the DomainName
set in the config in which case it defaults to the host ip address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com <http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2
if { ssl_fc }
to fix the URL but note that this will not save you from hard coded url's
in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to the
fact that my backend does not have SSL and HAproxy frontend does have SSL.
At this point, I would avoid that IP address showing up in the browser.
what is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try
:-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide,
if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass haproxy
and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps


p. +61 (0) 433 078 728
e. ***@encompasscorporation.com <http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
Imam Toufique
2018-10-27 05:44:12 UTC
Permalink
Hi Igor,

Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.

haproxy.cfg:
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon

defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check

frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }

acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2

acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3


backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2

backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just one
node, instead of making changes to 2 nodes at a time.

Here is my apache config:

in httpd.conf, only change I have made is ( the rest is a stock centos 7.5
httpd.conf ):
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------

in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth SP.
One of the issues I encountered is, If I did not have SSL , i was getting a
browser warning for not having SSL.

Here is my ssl.conf:

--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin

<VirtualHost _default_:443>

UseCanonicalName on
ServerName crsplabweb1.domain.com:443

ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn

SSLEngine on

SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c

<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>

<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>

<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>

BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------

Thanks
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now, for
the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none
inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup -- when I
connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser points to the
backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did not
make any difference. But what I noticed is, after I connect, no traffic go
through the proxy anymore, my client ( i.e. laptop) connects directly to
the backend server. Not sure if this good or bad though (?) , but, I am not
sure how to configure this so that I will go through a proxy but still be
connected in the backend via a private IP and I can ( still ) authenticate
via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I break
shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs so
we can see what is going on (please obfuscate any sensitive data). Also the
use of the "cookie w1" is not clear since you are not setting it in HAP
and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem. when
I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy
with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do that
depends on the backend app you are using but most of them like apache2,
tomcat etc. have specific configs that you can find in their documentation.
For example if your backend is apache2 I bet you don't have the DomainName
set in the config in which case it defaults to the host ip address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com <http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2
if { ssl_fc }
to fix the URL but note that this will not save you from hard coded
url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to the
fact that my backend does not have SSL and HAproxy frontend does have SSL.
At this point, I would avoid that IP address showing up in the browser.
what is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first try
:-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration guide,
if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
Imam Toufique
2018-10-27 17:06:50 UTC
Permalink
Hi Aleks,
Yes, I should have done last in my last email post. Sorry about that.

haproxy version:

[***@crsplabnet2 haproxy]# haproxy -vv
HA-Proxy version 1.8.14-52e4d43 2018/09/20
Copyright 2000-2018 Willy Tarreau <***@haproxy.org>

Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement
-fwrapv -fno-strict-overflow -Wno-unused-label
OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_SYSTEMD=1 USE_PCRE=1

Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT
IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.32 2012-11-30
Running on PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with zlib version : 1.2.7
Running on zlib version : 1.2.7
Compression algorithms supported : identity("identity"),
deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.

Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.

Available filters :
[SPOE] spoe
[COMP] compression
[TRACE] trace

-----------------------------
Shibboleth version ( running in both of my backend nodes, as HAproxy can't
interact with shib , to do authentication offload in HAProxy )

[***@web1 ~]# rpm -qa |grep hibb
shibboleth-3.0.2-1.1.x86_64

-------------------------------

Apache version ( running in both backend nodes ONLY ) :

[***@web1 ~]# rpm -qa |grep httpd
httpd-devel-2.4.6-80.el7.centos.x86_64
httpd-tools-2.4.6-80.el7.centos.x86_64
httpd-2.4.6-80.el7.centos.x86_64

-----------------------------------
Linux version in all systems:

Centos 7.5 , running stock kernel 3.10.0-862.el7.x86_64

here is a workflow and some background info:

background info:
A. the application that we are trying to use: jupyterhub --
https://github.com/jupyterhub
B. We have shibboleth IDP that all our internal sites do authentication
from.
C. This application Jupyterhub spawns its own ( internally built ) proxy
instance and binds that to port 8000, as you saw in the <Location> config
section in apache config above.
D. Jupyterhub can directly authenticate with shibboleth ( some additional
work is needed ), but since we are putting this behind HAProxy, running
Shibboleth SP in the backend node ( where the jupyterhub instance runs ) is
needed. therefore, I decided to wrap jupytrehub within apache as apache
has built-in support for shibboleth ( mod_shib , that gets installed with
shibboleth RPM ).

Here is what I was thinking expected workflow would be:



Client [ public IP ] connects ---> HAproxy [ public IP ] connects --->
backend node [ private IP:80 ]

Note: Shibboleth is running in the backend node with its public IP: 443, as
it loves to work with SSL and I needed an in-common SSL cert installed to
get the SP working correctly.



So, for example, in the browser, I go to:

-- proxy.example.com ( HAProxy system )
-- from the backend, shibboleth responds to me with a login screen.
-- I authenticate with username/password
-- Shibboleth hands my username as an attribute called "UserID". to
Apache, and I forward that "UserID" to jupyterhub. Apache pulls the
jupyterhub instance, presents to the user.

Here is what I expect:

Type:

URL in the browser: 'proxy.exmaple.com/jhub'


After authentication, the browse URL shown to connect directly to the
backend node, such as:

https://backendnode1.example.com/jhub/itoufiqu/tree?

whereas, I would expect it to keep the proxy URL to be:
https://proxy.exmaple.com/jhub/itoufiqu/tree?

Interesting thing is, this redirect to the backend machine, connects the
client directly to the backend machine over the public IP of the backend
machine. I think this is due to SSO being done by shibboleth. Since
Shibboleth fails authentication from within the internal LAN ( as the IDP
could not talk to the SP in the private network), I had to get a public
IP. In this process, HAProxy loses all accounting data to this session,
except the first connection attempt.

This setup could be good or bad, I am not sure. My initial thoughts were,
all traffic passes through HAProxy. In retrospect, HAProxy is not being
taxed at all, there is a direct connection between the client and the
backend node over a public IP ( of the backend node). But, what I don't
understand is, if a connection attempt is made through HAProxy, why would
it allow the connection to be handed off to the backend node directly (
client -> backend node )?

Thoughts?
Hi Imam.
haproxy -vv
apache httpd version
shibboleth version
Client -> haproxy -> apache httpd -> shibboleth ?
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I
Post by Imam Toufique
can keep this from being too cluttered.
--------------------------------------------------------------------------------------
Post by Imam Toufique
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
The 2 log entries are redundant, imho.
Post by Imam Toufique
mode http
Is set at default block. Please take a look at
https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/
Post by Imam Toufique
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
I personally would use here also set-header instead of add.
Post by Imam Toufique
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
This should be only the host name.
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.6-hdr
and
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.6-req.hdr
I would add a addition acl.
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu
acl path_web2 path_beg -i /webdav
Post by Imam Toufique
use_backend webdav_cluster if host_web2
an add it to the use_backend line
use_backend webdav_cluster if host_web2 path_web2
Post by Imam Toufique
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
I would add here the following line.
cookie SRV1 insert indirect nocache
Post by Imam Toufique
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
I would add here the following line.
cookie SRV2 insert indirect nocache
Post by Imam Toufique
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Post by Imam Toufique
Note: I have a single backend node, as it was easy to test with just one
node,
Post by Imam Toufique
instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos
7.5
Post by Imam Toufique
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000
Post by Imam Toufique
<http://127.0.0.1:8000> . Also, note that the backend is running
shibboleth
Post by Imam Toufique
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a
Post by Imam Toufique
browser warning for not having SSL.
Can you set up shibboleth in that manner that he answers with
proxy.domain.com?
As we don't know which version is in place I send you just as a hint here
some
links.
https://wiki.shibboleth.net/confluence/display/SHIB2/SPReverseProxy
http://shibboleth.1660669.n2.nabble.com/shibboleth-sp-behind-an-HAproxy-td5960149.html
https://duckduckgo.com/?q=shibboleth+behind+haproxy
--------------------------------------------------------------------------
Post by Imam Toufique
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
Maybe you can change this to proxy.domain.com and add a ServerAlias
ServerName proxy.domain.com
ServerAlias crsplabweb1 crsplabweb1.domain.com
https://httpd.apache.org/docs/2.4/mod/core.html#serveralias
Post by Imam Toufique
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
Post by Imam Toufique
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Post by Imam Toufique
Thanks
Regards
Aleks
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Hi Imam,
Hi,
I came up with the following config, things seem to be working
now, for
Post by Imam Toufique
the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify
none inter 2000 cookie w1
Post by Imam Toufique
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for
authentication. As I could not get shibboleth SP to work by
staying in
Post by Imam Toufique
my private network, I had to set up a public IP for the backend
node,
Post by Imam Toufique
get SSL certs - so shibboleth authentication could be done. I
am sure
Post by Imam Toufique
there is a better approach to this, but I don't know what it
is. I will
Post by Imam Toufique
be trying out SNAT to see if that will allow me to keep using my
private
Post by Imam Toufique
IP for the backend nodes. If any of you know how to do SNAT,
please
Post by Imam Toufique
chime in, it would be worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup
-- when I
Post by Imam Toufique
connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser
points to
Post by Imam Toufique
the backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that
did not
Post by Imam Toufique
make any difference. But what I noticed is, after I connect, no
traffic
Post by Imam Toufique
go through the proxy anymore, my client ( i.e. laptop) connects
directly
Post by Imam Toufique
to the backend server. Not sure if this good or bad though (?) ,
but, I
Post by Imam Toufique
am not sure how to configure this so that I will go through a
proxy but
Post by Imam Toufique
still be connected in the backend via a private IP and I can (
still )
Post by Imam Toufique
authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then
I break
Post by Imam Toufique
shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache
configs so we
Post by Imam Toufique
can see what is going on (please obfuscate any sensitive data). Also
the use
Post by Imam Toufique
of the "cookie w1" is not clear since you are not setting it in HAP
and is
Post by Imam Toufique
kinda redundant for single backend setup.
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov
On Thu, 25 Oct 2018 6:13 pm Imam Toufique <
so I almost got this to work, based on the situation
I am
Post by Imam Toufique
in. To elaborate just a bit, my setup involves a
shibboleth
Post by Imam Toufique
SP that I need to authenticate my application.
Since I
Post by Imam Toufique
can't set up the HA proxy node with shibboleth SP -
I had to
Post by Imam Toufique
wrap my application in the backend with apache so I
can pass
Post by Imam Toufique
REMOTE_USER to the application. the application I
have is -
Post by Imam Toufique
jupyterhub and it start with its own proxy. Long
story
Post by Imam Toufique
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port
%[dst_port]
Post by Imam Toufique
http-request add-header X-Forwarded-Proto https
if { ssl_fc }
Post by Imam Toufique
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu <http://web1.oit.uci.edu>
128.110.80.5:80 <http://128.110.80.5:80> check
this works for the most part. But I am confused
with a
Post by Imam Toufique
problem. when I get to my application, my backend IP
address
Post by Imam Toufique
shows up in the browser URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
whereas, I was expecting that it would show the
original
Post by Imam Toufique
http://crsplab2.domain.com/jhub/user/itoufiqu/tree
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>?
(
Post by Imam Toufique
where crsplab2.domain.com <
http://crsplab2.domain.com> is
Post by Imam Toufique
the URL to get HAproxy )
You need to tell your backend app that it runs behind
reverse
Post by Imam Toufique
proxy with ssl termination and that it's domain/url
is https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>.
How you do
Post by Imam Toufique
that depends on the backend app you are using but most
of them
Post by Imam Toufique
like apache2, tomcat etc. have specific configs that you
can
Post by Imam Toufique
find in their documentation. For example if your backend
is
Post by Imam Toufique
apache2 I bet you don't have the DomainName set in the
config in
Post by Imam Toufique
which case it defaults to the host ip address.
rspirep ^Location:\ http://(.*):80(.*) Location:\
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2
if {
Post by Imam Toufique
ssl_fc }
to fix the URL but note that this will not save you from
hard coded
Post by Imam Toufique
url's in the returned html pages the way apache does.
While I am no expert in HA proxy world, I think this
might
Post by Imam Toufique
due to the fact that my backend does not have SSL and
HAproxy frontend does have SSL. At this point, I
would
Post by Imam Toufique
avoid that IP address showing up in the browser.
what is
Post by Imam Toufique
the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic
Hi.
Post by Imam Toufique
I am looking for some help on how to write the
following apache proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of
loss with
Post by Imam Toufique
my first try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of
thinks
Post by Imam Toufique
not just rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
Post by Imam Toufique
ProxyPassMatch ws://
10.1.100.156:8000/jhub/$1/$2$3
Post by Imam Toufique
<http://10.1.100.156:8000/jhub/$1/$2$3>
Post by Imam Toufique
ProxyPassReverse
ws://10.1.100.156:8000/jhub/$1/$2$3
<http://10.1.100.156:8000/jhub/$1/$2$3>
Post by Imam Toufique
</LocationMatch>
As I am not well versed in the massive HAproxy
configuration guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would
very much
Post by Imam Toufique
appreciate it.
I'm also not "that" expert but I would try the
following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
Post by Imam Toufique
"/jhub/\1/\2\3"
# You will need to replace the first column
with the
Post by Imam Toufique
response from the
# backend response
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
Post by Imam Toufique
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
Post by Imam Toufique
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000
<http://10.1.100.156:8000> check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
Post by Imam Toufique
I would run haproxy in Debug mode and see how the
request pass haproxy and adopt
the config.
It would be nice when you show us the working
conf ;-)
Post by Imam Toufique
It would be nice to have a
http-request replace-uri <match-regex>
<replace-fmt>
Post by Imam Toufique
to replace the reqrep.
--
Regards,
*Imam Toufique*
*213-700-5485*
Imam Toufique
2018-10-28 17:17:48 UTC
Permalink
Hi Aleks,

Yes, I have looked at your previous email. Those 3 URLs you mentioned
below --
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep

i have done them already, otherwise, both of my SP's will not work. I had
this setup from day one.

As for your question on pointing shibboleth SP to proxy.example.com, I
don't think that is doable, as shibboleth SP needs to access the actual
resource ( i.e. jupyterhub instance in this case ), which is in the
backend node.

Are there any plans to support shibboleth with HAProxy? As you know,
apache/nginx has both support for it.

If my current setup is not acceptable by mgmt . , I will have to start
looking at nginx on how to do this. The current setup directly allows the
backend nodes to be accessible by users, which, I don't think is the best
thing.

--imam
Hi.
Thanks for the infos. Have you also seen the other answers in the previous
mail?
Regards
Aleks
------------------------------
*Gesendet:* 27. Oktober 2018 19:06:50 MESZ
*Betreff:* Re: apache proxy pass rules in HAproxy
Hi Aleks,
Yes, I should have done last in my last email post. Sorry about that.
HA-Proxy version 1.8.14-52e4d43 2018/09/20
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement
-fwrapv -fno-strict-overflow -Wno-unused-label
OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_SYSTEMD=1 USE_PCRE=1
maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
Built with transparent proxy support using: IP_TRANSPARENT
IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.32 2012-11-30
Running on PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with zlib version : 1.2.7
Running on zlib version : 1.2.7
Compression algorithms supported : identity("identity"),
deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
[SPOE] spoe
[COMP] compression
[TRACE] trace
-----------------------------
Shibboleth version ( running in both of my backend nodes, as HAproxy can't
interact with shib , to do authentication offload in HAProxy )
shibboleth-3.0.2-1.1.x86_64
-------------------------------
httpd-devel-2.4.6-80.el7.centos.x86_64
httpd-tools-2.4.6-80.el7.centos.x86_64
httpd-2.4.6-80.el7.centos.x86_64
-----------------------------------
Centos 7.5 , running stock kernel 3.10.0-862.el7.x86_64
A. the application that we are trying to use: jupyterhub --
https://github.com/jupyterhub
B. We have shibboleth IDP that all our internal sites do authentication
from.
C. This application Jupyterhub spawns its own ( internally built ) proxy
instance and binds that to port 8000, as you saw in the <Location> config
section in apache config above.
D. Jupyterhub can directly authenticate with shibboleth ( some additional
work is needed ), but since we are putting this behind HAProxy, running
Shibboleth SP in the backend node ( where the jupyterhub instance runs ) is
needed. therefore, I decided to wrap jupytrehub within apache as apache
has built-in support for shibboleth ( mod_shib , that gets installed with
shibboleth RPM ).
Client [ public IP ] connects ---> HAproxy [ public IP ] connects --->
backend node [ private IP:80 ]
Note: Shibboleth is running in the backend node with its public IP: 443,
as it loves to work with SSL and I needed an in-common SSL cert installed
to get the SP working correctly.
-- proxy.example.com ( HAProxy system )
-- from the backend, shibboleth responds to me with a login screen.
-- I authenticate with username/password
-- Shibboleth hands my username as an attribute called "UserID". to
Apache, and I forward that "UserID" to jupyterhub. Apache pulls the
jupyterhub instance, presents to the user.
URL in the browser: 'proxy.exmaple.com/jhub'
After authentication, the browse URL shown to connect directly to the
https://backendnode1.example.com/jhub/itoufiqu/tree?
https://proxy.exmaple.com/jhub/itoufiqu/tree?
Interesting thing is, this redirect to the backend machine, connects the
client directly to the backend machine over the public IP of the backend
machine. I think this is due to SSO being done by shibboleth. Since
Shibboleth fails authentication from within the internal LAN ( as the IDP
could not talk to the SP in the private network), I had to get a public
IP. In this process, HAProxy loses all accounting data to this session,
except the first connection attempt.
This setup could be good or bad, I am not sure. My initial thoughts were,
all traffic passes through HAProxy. In retrospect, HAProxy is not being
taxed at all, there is a direct connection between the client and the
backend node over a public IP ( of the backend node). But, what I don't
understand is, if a connection attempt is made through HAProxy, why would
it allow the connection to be handed off to the backend node directly (
client -> backend node )?
Thoughts?
Hi Imam.
haproxy -vv
apache httpd version
shibboleth version
Client -> haproxy -> apache httpd -> shibboleth ?
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I
Post by Imam Toufique
can keep this from being too cluttered.
--------------------------------------------------------------------------------------
Post by Imam Toufique
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
The 2 log entries are redundant, imho.
Post by Imam Toufique
mode http
Is set at default block. Please take a look at
https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/
Post by Imam Toufique
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
I personally would use here also set-header instead of add.
Post by Imam Toufique
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
This should be only the host name.
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.6-hdr
and
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.6-req.hdr
I would add a addition acl.
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu
acl path_web2 path_beg -i /webdav
Post by Imam Toufique
use_backend webdav_cluster if host_web2
an add it to the use_backend line
use_backend webdav_cluster if host_web2 path_web2
Post by Imam Toufique
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
I would add here the following line.
cookie SRV1 insert indirect nocache
Post by Imam Toufique
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
I would add here the following line.
cookie SRV2 insert indirect nocache
Post by Imam Toufique
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Post by Imam Toufique
Note: I have a single backend node, as it was easy to test with just
one node,
Post by Imam Toufique
instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos
7.5
Post by Imam Toufique
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000
Post by Imam Toufique
<http://127.0.0.1:8000> . Also, note that the backend is running
shibboleth
Post by Imam Toufique
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a
Post by Imam Toufique
browser warning for not having SSL.
Can you set up shibboleth in that manner that he answers with
proxy.domain.com?
As we don't know which version is in place I send you just as a hint here
some
links.
https://wiki.shibboleth.net/confluence/display/SHIB2/SPReverseProxy
http://shibboleth.1660669.n2.nabble.com/shibboleth-sp-behind-an-HAproxy-td5960149.html
https://duckduckgo.com/?q=shibboleth+behind+haproxy
--------------------------------------------------------------------------
Post by Imam Toufique
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
Maybe you can change this to proxy.domain.com and add a ServerAlias
ServerName proxy.domain.com
ServerAlias crsplabweb1 crsplabweb1.domain.com
https://httpd.apache.org/docs/2.4/mod/core.html#serveralias
Post by Imam Toufique
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
Post by Imam Toufique
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Post by Imam Toufique
Thanks
Regards
Aleks
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Hi Imam,
Hi,
I came up with the following config, things seem to be working
now, for
Post by Imam Toufique
the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify
none inter 2000 cookie w1
Post by Imam Toufique
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for
authentication. As I could not get shibboleth SP to work by
staying in
Post by Imam Toufique
my private network, I had to set up a public IP for the backend
node,
Post by Imam Toufique
get SSL certs - so shibboleth authentication could be done. I
am sure
Post by Imam Toufique
there is a better approach to this, but I don't know what it
is. I will
Post by Imam Toufique
be trying out SNAT to see if that will allow me to keep using
my private
Post by Imam Toufique
IP for the backend nodes. If any of you know how to do SNAT,
please
Post by Imam Toufique
chime in, it would be worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup
-- when I
Post by Imam Toufique
connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser
points to
Post by Imam Toufique
the backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that
did not
Post by Imam Toufique
make any difference. But what I noticed is, after I connect,
no traffic
Post by Imam Toufique
go through the proxy anymore, my client ( i.e. laptop) connects
directly
Post by Imam Toufique
to the backend server. Not sure if this good or bad though (?)
, but, I
Post by Imam Toufique
am not sure how to configure this so that I will go through a
proxy but
Post by Imam Toufique
still be connected in the backend via a private IP and I can (
still )
Post by Imam Toufique
authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then
I break
Post by Imam Toufique
shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache
configs so we
Post by Imam Toufique
can see what is going on (please obfuscate any sensitive data).
Also the use
Post by Imam Toufique
of the "cookie w1" is not clear since you are not setting it in HAP
and is
Post by Imam Toufique
kinda redundant for single backend setup.
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov
On Thu, 25 Oct 2018 6:13 pm Imam Toufique <
so I almost got this to work, based on the
situation I am
Post by Imam Toufique
in. To elaborate just a bit, my setup involves a
shibboleth
Post by Imam Toufique
SP that I need to authenticate my application.
Since I
Post by Imam Toufique
can't set up the HA proxy node with shibboleth SP -
I had to
Post by Imam Toufique
wrap my application in the backend with apache so I
can pass
Post by Imam Toufique
REMOTE_USER to the application. the application I
have is -
Post by Imam Toufique
jupyterhub and it start with its own proxy. Long
story
Post by Imam Toufique
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port
%[dst_port]
Post by Imam Toufique
http-request add-header X-Forwarded-Proto https
if { ssl_fc }
Post by Imam Toufique
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu <http://web1.oit.uci.edu>
128.110.80.5:80 <http://128.110.80.5:80> check
this works for the most part. But I am confused
with a
Post by Imam Toufique
problem. when I get to my application, my backend
IP address
Post by Imam Toufique
shows up in the browser URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
whereas, I was expecting that it would show the
original
Post by Imam Toufique
http://crsplab2.domain.com/jhub/user/itoufiqu/tree
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>?
(
Post by Imam Toufique
where crsplab2.domain.com <
http://crsplab2.domain.com> is
Post by Imam Toufique
the URL to get HAproxy )
You need to tell your backend app that it runs behind
reverse
Post by Imam Toufique
proxy with ssl termination and that it's domain/url
is https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>.
How you do
Post by Imam Toufique
that depends on the backend app you are using but most
of them
Post by Imam Toufique
like apache2, tomcat etc. have specific configs that
you can
Post by Imam Toufique
find in their documentation. For example if your
backend is
Post by Imam Toufique
apache2 I bet you don't have the DomainName set in the
config in
Post by Imam Toufique
which case it defaults to the host ip address.
rspirep ^Location:\ http://(.*):80(.*) Location:\
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2
if {
Post by Imam Toufique
ssl_fc }
to fix the URL but note that this will not save you from
hard coded
Post by Imam Toufique
url's in the returned html pages the way apache does.
While I am no expert in HA proxy world, I think
this might
Post by Imam Toufique
due to the fact that my backend does not have SSL
and
Post by Imam Toufique
HAproxy frontend does have SSL. At this point, I
would
Post by Imam Toufique
avoid that IP address showing up in the browser.
what is
Post by Imam Toufique
the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic
Hi.
Post by Imam Toufique
I am looking for some help on how to write the
following apache proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of
loss with
Post by Imam Toufique
my first try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse
http://10.1.100.156:8000/jhub
Post by Imam Toufique
Well ProxyPass and ProxyPassReverse do a lot of
thinks
Post by Imam Toufique
not just rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
Post by Imam Toufique
ProxyPassMatch ws://
10.1.100.156:8000/jhub/$1/$2$3
Post by Imam Toufique
<http://10.1.100.156:8000/jhub/$1/$2$3>
Post by Imam Toufique
ProxyPassReverse
ws://10.1.100.156:8000/jhub/$1/$2$3
<http://10.1.100.156:8000/jhub/$1/$2$3>
Post by Imam Toufique
</LocationMatch>
As I am not well versed in the massive HAproxy
configuration guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would
very much
Post by Imam Toufique
appreciate it.
I'm also not "that" expert but I would try the
following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
Post by Imam Toufique
"/jhub/\1/\2\3"
# You will need to replace the first column
with the
Post by Imam Toufique
response from the
# backend response
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
Post by Imam Toufique
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
Post by Imam Toufique
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000
<http://10.1.100.156:8000> check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
Post by Imam Toufique
I would run haproxy in Debug mode and see how
the
Post by Imam Toufique
request pass haproxy and adopt
the config.
It would be nice when you show us the working
conf ;-)
Post by Imam Toufique
It would be nice to have a
http-request replace-uri <match-regex>
<replace-fmt>
Post by Imam Toufique
to replace the reqrep.
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-29 00:21:43 UTC
Permalink
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just one
node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos 7.5
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth SP.
One of the issues I encountered is, If I did not have SSL , i was getting a
browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by HAP in
Apache thus you get http response instead ssl.

First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu and
crsplabweb1.domain.com certificates inside. More details on setting SSL
certificates in Haproxy can be found here:
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt

The config will then look something like this:

frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...

backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000

On the apache side remove the ssl settings (since now HAP will be
terminating SSL) and set a SSL redirect, something like this:

<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com

SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now, for
the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none
inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup -- when I
connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser points to the
backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did not
make any difference. But what I noticed is, after I connect, no traffic go
through the proxy anymore, my client ( i.e. laptop) connects directly to
the backend server. Not sure if this good or bad though (?) , but, I am not
sure how to configure this so that I will go through a proxy but still be
connected in the backend via a private IP and I can ( still ) authenticate
via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I break
shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs so
we can see what is going on (please obfuscate any sensitive data). Also the
use of the "cookie w1" is not clear since you are not setting it in HAP
and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem. when
I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy
with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do that
depends on the backend app you are using but most of them like apache2,
tomcat etc. have specific configs that you can find in their documentation.
For example if your backend is apache2 I bet you don't have the DomainName
set in the config in which case it defaults to the host ip address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard coded
url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to the
fact that my backend does not have SSL and HAproxy frontend does have SSL.
At this point, I would avoid that IP address showing up in the browser.
what is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first
try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps


p. +61 (0) 433 078 728
e. ***@encompasscorporation.com <http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
Imam Toufique
2018-10-29 02:30:05 UTC
Permalink
Hi Igor,

Thank you so much, I will definitely try your suggestions, but I am not
sure how it will help my situation. shibboleth SP looks for, let's
suppose, https://crsplabweb2.example.com/Shibboleth.sso - for it it's
single sign-on. for apache or nginx to talk to the SP, SP needs to run in
the same node ( as far as I know ). So, I am not sure how shibboleth will
be able to communicate with the HAP for its SSO calls.

--imam
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just one
node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth SP.
One of the issues I encountered is, If I did not have SSL , i was getting a
browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by HAP in
Apache thus you get http response instead ssl.
First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu and
crsplabweb1.domain.com certificates inside. More details on setting SSL
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...
backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000
On the apache side remove the ssl settings (since now HAP will be
<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now, for
the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none
inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup -- when
I connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser points to the
backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did not
make any difference. But what I noticed is, after I connect, no traffic go
through the proxy anymore, my client ( i.e. laptop) connects directly to
the backend server. Not sure if this good or bad though (?) , but, I am not
sure how to configure this so that I will go through a proxy but still be
connected in the backend via a private IP and I can ( still ) authenticate
via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I break
shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs so
we can see what is going on (please obfuscate any sensitive data). Also the
use of the "cookie w1" is not clear since you are not setting it in HAP
and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem.
when I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy
with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do
that depends on the backend app you are using but most of them like
apache2, tomcat etc. have specific configs that you can find in their
documentation. For example if your backend is apache2 I bet you don't have
the DomainName set in the config in which case it defaults to the host ip
address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard coded
url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to
the fact that my backend does not have SSL and HAproxy frontend does have
SSL. At this point, I would avoid that IP address showing up in the
browser. what is the best way to accomplish this?
thanks for your continues help!
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first
try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-29 03:07:34 UTC
Permalink
Well you need to point crsplabweb2.example.com to the haproxy IP that's the
whole point of it running behind a proxy. Or am I missing something?
Post by Imam Toufique
Hi Igor,
Thank you so much, I will definitely try your suggestions, but I am not
sure how it will help my situation. shibboleth SP looks for, let's
suppose, https://crsplabweb2.example.com/Shibboleth.sso - for it it's
single sign-on. for apache or nginx to talk to the SP, SP needs to run in
the same node ( as far as I know ). So, I am not sure how shibboleth will
be able to communicate with the HAP for its SSO calls.
--imam
On Sun, Oct 28, 2018 at 5:21 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just one
node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by HAP
in Apache thus you get http response instead ssl.
First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu
and crsplabweb1.domain.com certificates inside. More details on setting
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...
backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000
On the apache side remove the ssl settings (since now HAP will be
<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now,
for the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none
inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup -- when
I connect to HAProxy, let's say with https://proxy.domain.com , I
authenticate with shibboleth, and then the URL in the browser points to the
backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did
not make any difference. But what I noticed is, after I connect, no
traffic go through the proxy anymore, my client ( i.e. laptop) connects
directly to the backend server. Not sure if this good or bad though (?) ,
but, I am not sure how to configure this so that I will go through a
proxy but still be connected in the backend via a private IP and I can (
still ) authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I
break shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs
so we can see what is going on (please obfuscate any sensitive data). Also
the use of the "cookie w1" is not clear since you are not setting it
in HAP and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem.
when I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy
with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do
that depends on the backend app you are using but most of them like
apache2, tomcat etc. have specific configs that you can find in their
documentation. For example if your backend is apache2 I bet you don't have
the DomainName set in the config in which case it defaults to the host ip
address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard coded
url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to
the fact that my backend does not have SSL and HAproxy frontend does have
SSL. At this point, I would avoid that IP address showing up in the
browser. what is the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic <
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first
try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate
it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps


p. +61 (0) 433 078 728
e. ***@encompasscorporation.com <http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
Imam Toufique
2018-10-29 03:37:54 UTC
Permalink
" Well you need to point crsplabweb2.example.com to the haproxy IP that's
the whole point of it running behind a proxy. Or am I missing something? "

Well, I am not sure what you meant by that comment above.
Post by Igor Cicimov
Well you need to point crsplabweb2.example.com to the haproxy IP that's
the whole point of it running behind a proxy. Or am I missing something?
Post by Imam Toufique
Hi Igor,
Thank you so much, I will definitely try your suggestions, but I am not
sure how it will help my situation. shibboleth SP looks for, let's
suppose, https://crsplabweb2.example.com/Shibboleth.sso - for it it's
single sign-on. for apache or nginx to talk to the SP, SP needs to run in
the same node ( as far as I know ). So, I am not sure how shibboleth will
be able to communicate with the HAP for its SSO calls.
--imam
On Sun, Oct 28, 2018 at 5:21 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just
one node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by HAP
in Apache thus you get http response instead ssl.
First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu
and crsplabweb1.domain.com certificates inside. More details on setting
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...
backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000
On the apache side remove the ssl settings (since now HAP will be
<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now,
for the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none
inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup --
when I connect to HAProxy, let's say with https://proxy.domain.com
, I authenticate with shibboleth, and then the URL in the browser points to
the backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did
not make any difference. But what I noticed is, after I connect, no
traffic go through the proxy anymore, my client ( i.e. laptop) connects
directly to the backend server. Not sure if this good or bad though (?) ,
but, I am not sure how to configure this so that I will go through a
proxy but still be connected in the backend via a private IP and I can (
still ) authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I
break shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs
so we can see what is going on (please obfuscate any sensitive data). Also
the use of the "cookie w1" is not clear since you are not setting it
in HAP and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem.
when I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse proxy
with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do
that depends on the backend app you are using but most of them like
apache2, tomcat etc. have specific configs that you can find in their
documentation. For example if your backend is apache2 I bet you don't have
the DomainName set in the config in which case it defaults to the host ip
address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard coded
url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to
the fact that my backend does not have SSL and HAproxy frontend does have
SSL. At this point, I would avoid that IP address showing up in the
browser. what is the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic <
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following apache
proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my first
try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate
it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response from the
# backend response
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
Igor Cicimov
2018-10-29 04:21:15 UTC
Permalink
The DNS, point the DNS record for crsplabweb2.example.com to the public IP
of haproxy.
Post by Imam Toufique
" Well you need to point crsplabweb2.example.com to the haproxy IP that's
the whole point of it running behind a proxy. Or am I missing something? "
Well, I am not sure what you meant by that comment above.
On Sun, Oct 28, 2018 at 8:07 PM Igor Cicimov <
Post by Igor Cicimov
Well you need to point crsplabweb2.example.com to the haproxy IP that's
the whole point of it running behind a proxy. Or am I missing something?
Post by Imam Toufique
Hi Igor,
Thank you so much, I will definitely try your suggestions, but I am not
sure how it will help my situation. shibboleth SP looks for, let's
suppose, https://crsplabweb2.example.com/Shibboleth.sso - for it it's
single sign-on. for apache or nginx to talk to the SP, SP needs to run in
the same node ( as far as I know ). So, I am not sure how shibboleth will
be able to communicate with the HAP for its SSO calls.
--imam
On Sun, Oct 28, 2018 at 5:21 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just
one node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock centos
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by HAP
in Apache thus you get http response instead ssl.
First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu
and crsplabweb1.domain.com certificates inside. More details on
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...
backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000
On the apache side remove the ssl settings (since now HAP will be
<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now,
for the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify none
inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup --
when I connect to HAProxy, let's say with https://proxy.domain.com
, I authenticate with shibboleth, and then the URL in the browser points to
the backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did
not make any difference. But what I noticed is, after I connect, no
traffic go through the proxy anymore, my client ( i.e. laptop) connects
directly to the backend server. Not sure if this good or bad though (?) ,
but, I am not sure how to configure this so that I will go through a
proxy but still be connected in the backend via a private IP and I can (
still ) authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I
break shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache configs
so we can see what is going on (please obfuscate any sensitive data). Also
the use of the "cookie w1" is not clear since you are not setting it
in HAP and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in. To
elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem.
when I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse
proxy with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do
that depends on the backend app you are using but most of them like
apache2, tomcat etc. have specific configs that you can find in their
documentation. For example if your backend is apache2 I bet you don't have
the DomainName set in the config in which case it defaults to the host ip
address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard coded
url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due to
the fact that my backend does not have SSL and HAproxy frontend does have
SSL. At this point, I would avoid that IP address showing up in the
browser. what is the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic <
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following
apache proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my
first try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much appreciate
it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response
from the
# backend response
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
<http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps


p. +61 (0) 433 078 728
e. ***@encompasscorporation.com <http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
Imam Toufique
2018-10-29 05:04:07 UTC
Permalink
"The DNS, point the DNS record for crsplabweb2.example.com to the public IP
of haproxy. "

I must be missing something, pardon me. If I did that, then where do I run
and validate shibboleth requests? As far as I know, for shibboleth to
work, i need to run 'shibd' , i need to establish an entityID -- all that
is possible when I have either apache or nginx running that shibboleth
initiate / resolve a SAML request from/to.

Pardon me again... , how do we perform shibboleth authentication for the
backend nodes with your proposed setup? I am willing to try out anything,
I would like to keep using haproxy :-) , don't get me wrong. Perhaps I am
not getting the clear picture here.

--imam
Post by Igor Cicimov
The DNS, point the DNS record for crsplabweb2.example.com to the public
IP of haproxy.
Post by Imam Toufique
" Well you need to point crsplabweb2.example.com to the haproxy IP
that's the whole point of it running behind a proxy. Or am I missing
something? "
Well, I am not sure what you meant by that comment above.
On Sun, Oct 28, 2018 at 8:07 PM Igor Cicimov <
Post by Igor Cicimov
Well you need to point crsplabweb2.example.com to the haproxy IP that's
the whole point of it running behind a proxy. Or am I missing something?
Post by Imam Toufique
Hi Igor,
Thank you so much, I will definitely try your suggestions, but I am not
sure how it will help my situation. shibboleth SP looks for, let's
suppose, https://crsplabweb2.example.com/Shibboleth.sso - for it it's
single sign-on. for apache or nginx to talk to the SP, SP needs to run in
the same node ( as far as I know ). So, I am not sure how shibboleth will
be able to communicate with the HAP for its SSO calls.
--imam
On Sun, Oct 28, 2018 at 5:21 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just
one node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by
HAP in Apache thus you get http response instead ssl.
First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu
and crsplabweb1.domain.com certificates inside. More details on
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...
backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000
On the apache side remove the ssl settings (since now HAP will be
<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now,
for the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify
none inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup --
when I connect to HAProxy, let's say with https://proxy.domain.com
, I authenticate with shibboleth, and then the URL in the browser points to
the backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did
not make any difference. But what I noticed is, after I connect, no
traffic go through the proxy anymore, my client ( i.e. laptop) connects
directly to the backend server. Not sure if this good or bad though (?) ,
but, I am not sure how to configure this so that I will go through a
proxy but still be connected in the backend via a private IP and I can (
still ) authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I
break shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache
configs so we can see what is going on (please obfuscate any sensitive
data). Also the use of the "cookie w1" is not clear since you are
not setting it in HAP and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in.
To elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem.
when I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse
proxy with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do
that depends on the backend app you are using but most of them like
apache2, tomcat etc. have specific configs that you can find in their
documentation. For example if your backend is apache2 I bet you don't have
the DomainName set in the config in which case it defaults to the host ip
address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard
coded url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due
to the fact that my backend does not have SSL and HAproxy frontend does
have SSL. At this point, I would avoid that IP address showing up in the
browser. what is the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic <
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following
apache proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my
first try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much
appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response
from the
# backend response
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
<http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
Jarno Huuskonen
2018-10-29 09:09:12 UTC
Permalink
Hi,

Can you describe how you would like this (haproxy -> apache+shib -> jupyter?)
setup ? (Perhaps with some kind of diagram with desired urls / ips
etc).

From what I understand you'd like to use public ip/url only on haproxy
and everything else on private ip's (accessed only from the haproxy host).

AFAIK something like this might work:
haproxy listens on public ip:443 and sends all /jhub /Shibboleth.sso
traffic to apache(shib)+jupyter backend server on port 8443(w/out ssl):

haproxy:
...
acl host_web3 path_beg /jhub
acl host_web3_saml2 path_beg /Shibboleth.sso
use_backend web3_cluster if host_web3 || host_web3_saml2
...
backend web3_cluster
server apache_server_privateip:8443 check inter 2000 cookie w1
# If you've more than 1 server then you'll probably need persistence

apache vhost (plain http vhost, no ssl configured)
Listen 8443
<VirtualHost *:8443>
HostnameLookups off
ServerName https://proxy.example.com
UseCanonicalName On
SetEnv HTTPS on

<Location /jhub> / <LocationMatch ...>
... # your jupyter proxypass / shibboleth auth (remote_user)/ wss config
# Also make sure apache passes or sets:
# X-Scheme/X-Forwarded-Proto and X-Real-Ip/X-Forwarded-For
</VirtualHost>

Configure shibboleth to use https://proxy.example.com/Shibboleth.sso
urls.

Configure jupyter to trust X- headers: NotebookApp.trust_xheaders
and maybe you need to use NotebookApp.custom_display_url so jupyter
knows it's url is https://proxy.example.com/jhub.

-Jarno
--
Jarno Huuskonen
Imam Toufique
2018-10-29 23:11:02 UTC
Permalink
Thanks, Jarno! This is a good tip and it is similar to the one I have
posted last night. I am working on to get the SP entityID setup now ( in
the shib backend ) -- after it gets set up then I can try a few new things
( including your suggestion ).

--imam
Post by Jarno Huuskonen
Hi,
Can you describe how you would like this (haproxy -> apache+shib -> jupyter?)
setup ? (Perhaps with some kind of diagram with desired urls / ips
etc).
From what I understand you'd like to use public ip/url only on haproxy
and everything else on private ip's (accessed only from the haproxy host).
haproxy listens on public ip:443 and sends all /jhub /Shibboleth.sso
...
acl host_web3 path_beg /jhub
acl host_web3_saml2 path_beg /Shibboleth.sso
use_backend web3_cluster if host_web3 || host_web3_saml2
...
backend web3_cluster
server apache_server_privateip:8443 check inter 2000 cookie w1
# If you've more than 1 server then you'll probably need persistence
apache vhost (plain http vhost, no ssl configured)
Listen 8443
<VirtualHost *:8443>
HostnameLookups off
ServerName https://proxy.example.com
UseCanonicalName On
SetEnv HTTPS on
<Location /jhub> / <LocationMatch ...>
... # your jupyter proxypass / shibboleth auth (remote_user)/ wss config
# X-Scheme/X-Forwarded-Proto and X-Real-Ip/X-Forwarded-For
</VirtualHost>
Configure shibboleth to use https://proxy.example.com/Shibboleth.sso
urls.
Configure jupyter to trust X- headers: NotebookApp.trust_xheaders
and maybe you need to use NotebookApp.custom_display_url so jupyter
knows it's url is https://proxy.example.com/jhub.
-Jarno
--
Jarno Huuskonen
--
Regards,
*Imam Toufique*
*213-700-5485*
Imam Toufique
2018-10-31 07:53:52 UTC
Permalink
So, the following HAP confg worked, with lots of work in the shibboleth
land.

frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem crt
/etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets
option httplog
rate-limit sessions 5
log global
log /dev/log local0 debug
mode http
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-request redirect scheme https unless { ssl_fc }
#
#acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
#use_backend webdav_cluster if host_web2
#
acl host_web3 path_beg /jhub
acl host_web3_saml2 path_beg /Shibboleth.sso/
acl host_web3_saml2_secure path_beg /secure/
use_backend web3_cluster if host_web3 || host_web3_saml2 ||
host_web3_saml2_secure


backend web3_cluster
mode http
balance source
cookie SRV2 insert indirect nocache
server web1 10.1.100.156:443 check ssl verify none inter 2000 cookie w1

in the shibboleth SP side, here is what was needed:

a. create a common entityID with the LB name .
https://haproxylb.example.com/shibboleth
b. setup apache vhost in the backend node , with the following:

ServerName https://haproxylb.example.com
UseCanonicalName on
HostnameLookups off

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IFModule>

<Location /Shibboleth.sso>
SetHandler shib
</Location>

<Location /jhub>
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>

<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>

c. the above will allow metadata generation possible with the LB proxyname
and all the redirects will be correctly setup with the proper LB hostname.

One example:

<md:SingleLogoutService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="*https://haproxylb.example.com
<https://haproxylb.example.com>*/Shibboleth.sso/SLO/POST"/>

d. In the ahibboleth.xml file, the following is important, as we can now
pass traffic through the private LAN, after the initial authentication.

<Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
checkAddress="false" handlerSSL="false" cookieProps="http
">


Once all this is set up, shibboleth IDP should be able to fetch SP metadata
correctly.

Thank you, everyone, who helped. A lot of testing is needed, of course.
Once we go to production, I will post the final shibboleth and HAP configs.

I might still ask questions :-) , if I get stuck. But, you guys are
awesome, helped me through every step of the way!

--imam
Post by Jarno Huuskonen
Hi,
Can you describe how you would like this (haproxy -> apache+shib -> jupyter?)
setup ? (Perhaps with some kind of diagram with desired urls / ips
etc).
From what I understand you'd like to use public ip/url only on haproxy
and everything else on private ip's (accessed only from the haproxy host).
haproxy listens on public ip:443 and sends all /jhub /Shibboleth.sso
...
acl host_web3 path_beg /jhub
acl host_web3_saml2 path_beg /Shibboleth.sso
use_backend web3_cluster if host_web3 || host_web3_saml2
...
backend web3_cluster
server apache_server_privateip:8443 check inter 2000 cookie w1
# If you've more than 1 server then you'll probably need persistence
apache vhost (plain http vhost, no ssl configured)
Listen 8443
<VirtualHost *:8443>
HostnameLookups off
ServerName https://proxy.example.com
UseCanonicalName On
SetEnv HTTPS on
<Location /jhub> / <LocationMatch ...>
... # your jupyter proxypass / shibboleth auth (remote_user)/ wss config
# X-Scheme/X-Forwarded-Proto and X-Real-Ip/X-Forwarded-For
</VirtualHost>
Configure shibboleth to use https://proxy.example.com/Shibboleth.sso
urls.
Configure jupyter to trust X- headers: NotebookApp.trust_xheaders
and maybe you need to use NotebookApp.custom_display_url so jupyter
knows it's url is https://proxy.example.com/jhub.
-Jarno
--
Jarno Huuskonen
--
Regards,
*Imam Toufique*
*213-700-5485*
Imam Toufique
2018-10-29 06:30:09 UTC
Permalink
i found something here, might be of good interest, this might work. It
does have some similarities with what you have mentioned . I will try this
out.

https://docs.shib.ncsu.edu/docs/advanced/spscale.html
Post by Igor Cicimov
The DNS, point the DNS record for crsplabweb2.example.com to the public
IP of haproxy.
Post by Imam Toufique
" Well you need to point crsplabweb2.example.com to the haproxy IP
that's the whole point of it running behind a proxy. Or am I missing
something? "
Well, I am not sure what you meant by that comment above.
On Sun, Oct 28, 2018 at 8:07 PM Igor Cicimov <
Post by Igor Cicimov
Well you need to point crsplabweb2.example.com to the haproxy IP that's
the whole point of it running behind a proxy. Or am I missing something?
Post by Imam Toufique
Hi Igor,
Thank you so much, I will definitely try your suggestions, but I am not
sure how it will help my situation. shibboleth SP looks for, let's
suppose, https://crsplabweb2.example.com/Shibboleth.sso - for it it's
single sign-on. for apache or nginx to talk to the SP, SP needs to run in
the same node ( as far as I know ). So, I am not sure how shibboleth will
be able to communicate with the HAP for its SSO calls.
--imam
On Sun, Oct 28, 2018 at 5:21 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi Igor,
Thanks very much for offering to help! I will do this in sections,
hopefully, I can keep this from being too cluttered.
--------------------------------------------------------------------------------------
global
#log /dev/log local0 debug
#log /dev/log local1 debug
log 127.0.0.1 local2
chroot /var/lib/haproxy
stats timeout 30s
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
daemon
defaults
log global
mode http
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
timeout tunnel 9h
option tcp-check
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web2 hdr(host) -i crsplab2.oit.uci.edu/webdav
use_backend webdav_cluster if host_web2
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend webdav_cluster
balance roundrobin
server web1 10.1.100.156:8080 check inter 2000 cookie w1
server web2 10.1.100.160:8080 check inter 2000 cookie w2
backend web3_cluster
server publicIP:443 check ssl verify none inter 2000 cookie w1
-----------------------------------------------------------------------------------------------------
Note: I have a single backend node, as it was easy to test with just
one node, instead of making changes to 2 nodes at a time.
in httpd.conf, only change I have made is ( the rest is a stock
-------------------------------------
ServerName 10.1.100.160:80 ( Internal IP of the backend node)
Redirect permanent /jhub https://crsplabweb1.domain.com/jhub
-------------------------------------
in my ssl.conf, where I access the jupyterhub instance running in
127.0.0.1:8000 . Also, note that the backend is running shibboleth
SP. One of the issues I encountered is, If I did not have SSL , i was
getting a browser warning for not having SSL.
--------------------------------------------------------------------------
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
UseCanonicalName on
ServerName crsplabweb1.domain.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/crsplabweb1.domain.com_cert.cer
SSLCertificateKeyFile /etc/pki/tls/certs/crsplabweb2.key
SSLCertificateChainFile
/etc/pki/tls/certs/crsplabweb1.domain.com_interm_reverse.c
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<Location /jhub>
ProxyPass http://127.0.0.1:8000/jhub
ProxyPassReverse http://127.0.0.1:8000/jhub
RequestHeader unset Accept-Encoding
ProxyPreserveHost on
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shibboleth
ShibUseHeaders On
ShibBasicHijack On
RewriteEngine On
RequestHeader set X-Remote-User %{REMOTE_USER}s
</Location>
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
ProxyPassMatch ws://127.0.0.1:8000/jhub/$1/$2$3
ProxyPassReverse ws://127.0.0.1:8000/jhub/$1/$2$3
</LocationMatch>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
----------------------------------------------------------------------------------
Thanks
Your problem is that you are not using the Forwarded headers set by
HAP in Apache thus you get http response instead ssl.
First for haproxy create a directory where you will keep all your SSL
certs, lets say /etc/haproxy/ssl.d/, and put the crsplab2.oit.uci.edu
and crsplabweb1.domain.com certificates inside. More details on
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-crt
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/ssl.d/ no-sslv3 no-tls-tickets ...
backend web3_cluster
server shibboleth1 10.1.100.160:80 check inter 2000
On the apache side remove the ssl settings (since now HAP will be
<VirtualHost *:80>
ServerName crsplabweb1.domain.com
ServerAlias www.crsplabweb1.domain.com
SetEnvIfNoCase X-Forwarded-Proto https HTTPS=on
# Insure the pages requested over ssl are always over ssl
RewriteEngine On
RewriteCond %{HTTP_X_Forwarded_Proto} ^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
...
</VirtualHost>
Let me know if any further questions.
Post by Imam Toufique
On Fri, Oct 26, 2018 at 8:34 PM Igor Cicimov <
Post by Igor Cicimov
Hi Imam,
Post by Imam Toufique
Hi,
I came up with the following config, things seem to be working now,
for the most part.
frontend http_front
bind :80
bind 0.0.0.0:443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
web3_cluster
backend web3_cluster
mode http
balance source
server crsplabweb1.domain.com publicIP:443 check ssl verify
none inter 2000 cookie w1
The above config gets me to the backend node -- where I have a
jupyterhub instance running + . Shibboleth SP running for authentication.
As I could not get shibboleth SP to work by staying in my private network,
I had to set up a public IP for the backend node, get SSL certs - so
shibboleth authentication could be done. I am sure there is a better
approach to this, but I don't know what it is. I will be trying out SNAT
to see if that will allow me to keep using my private IP for the backend
nodes. If any of you know how to do SNAT, please chime in, it would be
worth the time/effort to try it out.
Now, the interesting thing I have noticed with the above setup --
when I connect to HAProxy, let's say with https://proxy.domain.com
, I authenticate with shibboleth, and then the URL in the browser points to
the backend node.
my proxy address: https://proxy.domain.com/jhub
after I connect to the backend, the URL turns into -
https://crsplabweb1.domain.com/jhub/tree?
...and everything works thereafter.
I tried the rewrite method that Igor has suggested before, that did
not make any difference. But what I noticed is, after I connect, no
traffic go through the proxy anymore, my client ( i.e. laptop) connects
directly to the backend server. Not sure if this good or bad though (?) ,
but, I am not sure how to configure this so that I will go through a
proxy but still be connected in the backend via a private IP and I can (
still ) authenticate via shibboleth.
server crsplabweb1 privateIP:80 inter 2000 cookie w1
and, I set backend apache to accept connection on port 80, then I
break shibboleth authentication.
Any inputs here?
thanks, guys!
I think it is time for you to provide the full HAP and Apache
configs so we can see what is going on (please obfuscate any sensitive
data). Also the use of the "cookie w1" is not clear since you are
not setting it in HAP and is kinda redundant for single backend setup.
Post by Imam Toufique
On Thu, Oct 25, 2018 at 1:21 AM Igor Cicimov <
On Thu, Oct 25, 2018 at 6:31 PM Igor Cicimov <
Post by Igor Cicimov
Post by Imam Toufique
so I almost got this to work, based on the situation I am in.
To elaborate just a bit, my setup involves a shibboleth SP that I need to
authenticate my application. Since I can't set up the HA proxy node with
shibboleth SP - I had to wrap my application in the backend with apache so
I can pass REMOTE_USER to the application. the application I have is -
jupyterhub and it start with its own proxy. Long story short, here is my
frontend
bind :80
bind :443 ssl crt /etc/haproxy/crsplab2_1.pem
stats uri /haproxy?stats
default_backend web1_cluster
option httplog
log global
#option dontlognull
log /dev/log local0 debug
mode http
option forwardfor # forward IP
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
redirect scheme https if !{ ssl_fc }
acl host_web3 path_beg /jhub
use_backend web3_cluster if host_web3
backend
server web1.oit.uci.edu 128.110.80.5:80 check
this works for the most part. But I am confused with a problem.
when I get to my application, my backend IP address shows up in the browser
URL.
http://128.110.80.5/jhub/user/itoufiqu/tree?
http://crsplab2.domain.com/jhub/user/itoufiqu/tree? ( where
crsplab2.domain.com is the URL to get HAproxy )
You need to tell your backend app that it runs behind reverse
proxy with ssl termination and that it's domain/url is
https://crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>. How you do
that depends on the backend app you are using but most of them like
apache2, tomcat etc. have specific configs that you can find in their
documentation. For example if your backend is apache2 I bet you don't have
the DomainName set in the config in which case it defaults to the host ip
address.
rspirep ^Location:\ http://(.*):80(.*) Location:\ https://
crsplab2.domain.com
<http://crsplab2.domain.com/jhub/user/itoufiqu/tree>:443\2 if {
ssl_fc }
to fix the URL but note that this will not save you from hard
coded url's in the returned html pages the way apache does.
Post by Igor Cicimov
Post by Imam Toufique
While I am no expert in HA proxy world, I think this might due
to the fact that my backend does not have SSL and HAproxy frontend does
have SSL. At this point, I would avoid that IP address showing up in the
browser. what is the best way to accomplish this?
thanks for your continues help!
On Tue, Oct 23, 2018 at 8:35 AM Aleksandar Lazic <
Post by Imam Toufique
Hi.
Post by Imam Toufique
I am looking for some help on how to write the following
apache proxypass rules
Post by Imam Toufique
in HAproxy. Not to mention I am at a bit of loss with my
first try :-) . Here
Post by Imam Toufique
ProxyPass http://10.1.100.156:8000/jhub
ProxyPassReverse http://10.1.100.156:8000/jhub
Well ProxyPass and ProxyPassReverse do a lot of thinks not just
rewrites, as
mentioned in the doc
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse
Post by Imam Toufique
<LocationMatch
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)">
Post by Imam Toufique
ProxyPassMatch ws://10.1.100.156:8000/jhub/$1/$2$3
ProxyPassReverse ws://10.1.100.156:8000/jhub/$1/$2$3
</LocationMatch>
As I am not well versed in the massive HAproxy configuration
guide, if any of
Post by Imam Toufique
you can give me a hand with this, I would very much
appreciate it.
I'm also not "that" expert but I would try the following, untested.
###
defaults
mode http
log global
#... maybe some other settings
timeout tunnel 10h
frontend https_001
#... maybe some other settings
acl websocket path_beg /jhub
#... maybe some other acls
use_backend websocket_001 if websocket
backend websocket_001
reqrep "^([^\ :]*)
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# You will need to replace the first column with the response
from the
# backend response
/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
/jhub/\1/\2\3"
# OR
# http-response replace-header Location
"/jhub/(user/[^/]*)/(api/kernels/[^/]+/channels/websocket)(.*)"
"/jhub/\1/\2\3"
# add some checks
server ws_01 10.1.100.156:8000 check
###
Here are some links which may help you also.
https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-reqirep
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-rspirep
I would run haproxy in Debug mode and see how the request pass
haproxy and adopt
the config.
It would be nice when you show us the working conf ;-)
It would be nice to have a
http-request replace-uri <match-regex> <replace-fmt>
to replace the reqrep.
Post by Imam Toufique
thanks
Hth
Aleks
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
<http://encompasscorporation.com/>
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
--
Igor Cicimov | DevOps
p. +61 (0) 433 078 728
w*.* www.encompasscorporation.com
a. Level 4, 65 York Street, Sydney 2000
--
Regards,
*Imam Toufique*
*213-700-5485*
Loading...