Hi,
This is my first post on this list, so please let me know if my request is
appropriate to this list and, most of all, if the question has not been
already posted looong ago and is to be found in list archives or someplace
else on the web.
I've been using Haproxy for 2 years now, both for HTTP LB and RDP LB on two
load-balancers servers (configurations in attachment) with keepalived for
the management of VRRP IP Address.
I recently upgraded to version 1.6.3 on Debian 8.3 to try and solve various
load-balancing issues but in vain.
Regarding the RDP LB, I tried to pick here and there various configuration
samples which could suit my needs which are the following:
- Persistent connections on the same TS Server either in case of
ordinary reconnections after timeout or full session closing.
- Monitoring connections through Zabbix to get a precise
visualization of the repartition of users
- Achieving load(-balancing in terms of numbers of users by server.
Ideally, I would also like to systematically affect some users to a
identified server which hosts a unique resource they need but it is not the
subject of this post.
The situation is the following:
- I implemented a session table shared between the two LB Servers
but it is not identical on either server
- Some users appear in both tables when most of the others do not
(sample tables in attachment)
- The stats I get through scripts in Zabbix (in attachment) do not
show the whole population of connected users
- Sometimes (rarely), a user gets disconnected and is reconnected
on another TS server and I see two different sessions on two different TS
servers in the TS servers farm.
- There are quite big differences in the number of users connected
between the different TS servers (as I write: 6, 6 and 9, the latter (TS4)
gathering always the most users, sometimes as much as the double of each
others).
Obviously, I missed something in the Haproxy configuration but I can't find
where the problem lies.
I'm ashamed to say that even if I spent quite a lot of time trying to
understand the Haproxy documentation, I have a lot of trouble to connect the
various configuration instructions together and figure out the whole picture
on this matter.
So my question is: is there a fully documented tutorial that I couldn't find
yet which covers these matters ?
If not, could anyone give me a few hints about my configuration problem ?
PS: The very simple HTTP configuration works like a charm and is not
included in this post.
Jean.
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
# Create a socket to monitor Haproxy
stats socket /tmp/haproxy.sock
defaults
log global
mode tcp
option dontlognull
timeout connect 5000
timeout client 1h
timeout server 1h
# NEW RDP config
peers lbpeers
peer g3s-dmz-lb1 10.241.2.31:8888
peer g3s-dmz-lb2 10.241.2.32:8888
frontend rdp-in
bind *:3389 name rdp
maxconn 4000
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
option tcplog
option clitcpka
default_backend rdp-out
backend rdp-out
mode tcp
# Load Balancing Mode
balance rdp-cookie(mstshash)
tcp-request inspect-delay 5s
# RDP Cookie management
tcp-request content accept if RDP_COOKIE
#persist rdp-cookie ==> Redondant avec la balncing sur rdp_cookie((mstshash) ?
stick-table type string size 2m expire 120m peers lbpeers
# ACL which determines whether the domain DOM is included at the beginning of the cookie
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i groupe3s
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i GROUPE3S
# applies to DOM\USER
stick on req.rdp_cookie(mstshash),word(2,\) table rdp-out if domain_included
# applies to both USER and USER@DOM
stick on req.rdp_cookie(mstshash),word(1,@) table rdp-out if ! domain_included
#stick on rdp_cookie(mstshash)
# Single connection
tcp-request content reject if { sc1_conn_cur ge 2 }
# Protection against brute force attacks (limit connections attempts)
tcp-request content reject if { sc1_conn_rate ge 10 }
#server TS1 10.241.1.1:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS2 10.241.1.2:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS3 10.241.1.3:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS4 10.241.1.4:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
option tcplog
option redispatch
option abortonclose
option srvtcpka
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
# Create a socket to monitor Haproxy
stats socket /tmp/haproxy.sock
defaults
log global
mode tcp
option dontlognull
timeout connect 5000
timeout client 1h
timeout server 1h
# NEW RDP config
peers lbpeers
peer g3s-dmz-lb1 10.241.2.31:8888
peer g3s-dmz-lb2 10.241.2.32:8888
frontend rdp-in
bind *:3389 name rdp
maxconn 4000
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
option tcplog
option clitcpka
default_backend rdp-out
backend rdp-out
mode tcp
# Load Balancing Mode
balance rdp-cookie(mstshash)
tcp-request inspect-delay 5s
# RDP Cookie management
tcp-request content accept if RDP_COOKIE
#persist rdp-cookie ==> Redondant avec la balncing sur rdp_cookie((mstshash) ?
stick-table type string size 2m expire 120m peers lbpeers
# ACL which determines whether the domain DOM is included at the beginning of the cookie
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i groupe3s
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i GROUPE3S
# applies to DOM\USER
stick on req.rdp_cookie(mstshash),word(2,\) table rdp-out if domain_included
# applies to both USER and USER@DOM
stick on req.rdp_cookie(mstshash),word(1,@) table rdp-out if ! domain_included
#stick on rdp_cookie(mstshash)
# Single connection
tcp-request content reject if { sc1_conn_cur ge 2 }
# Protection against brute force attacks (limit connections attempts)
tcp-request content reject if { sc1_conn_rate ge 10 }
#server TS1 10.241.1.1:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS2 10.241.1.2:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS3 10.241.1.3:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS4 10.241.1.4:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
option tcplog
option redispatch
option abortonclose
option srvtcpka
UserParameter=haproxy.scur, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'rdp-in' | awk -F, '{print $5}'
UserParameter=haproxy.G3S-QNG-TS1.qcur, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $3}'
UserParameter=haproxy.G3S-QNG-TS1.qlimit, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $26}'
UserParameter=haproxy.G3S-QNG-TS1.scur, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $5}'
UserParameter=haproxy.G3S-QNG-TS1.econ, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $14}'
# table: rdp-out, type: string, size:2097152, used:12
0x2177db4: key= use=0 exp=4588852 server_id=3
0x217c654: key=ahembert use=0 exp=5144169 server_id=3
0x217bbd4: key=ecastells use=0 exp=3341472 server_id=3
0x217cf44: key=ereboux use=0 exp=6268522 server_id=1
0x21774c4: key=ggarcia use=0 exp=5502583 server_id=3
0x217df04: key=mpguezenn use=0 exp=4080727 server_id=1
0x2179004: key=mtalagas use=0 exp=2334820 server_id=2
0x217aad4: key=ngizzi use=0 exp=5072664 server_id=2
0x2172c94: key=rlecureur use=0 exp=6722870 server_id=1
0x217a104: key=sriou use=0 exp=79982 server_id=1
0x2172e24: key=svarin use=0 exp=5338885 server_id=2
0x217e124: key=svenisse use=0 exp=6497952 server_id=3
# table: rdp-out, type: string, size:2097152, used:7
0x18ab934: key= use=0 exp=2561997 server_id=3
0x18ab9e4: key=ahembert use=0 exp=3618652 server_id=3
0x18aad84: key=ggarcia use=0 exp=763814 server_id=3
0x18ab884: key=mpguezenn use=0 exp=4065021 server_id=1
0x18aba94: key=ngizzi use=0 exp=5056961 server_id=2
0x18abb44: key=rlecureur use=0 exp=6707176 server_id=1
0x18aab74: key=svarin use=0 exp=5323184 server_id=2
This is my first post on this list, so please let me know if my request is
appropriate to this list and, most of all, if the question has not been
already posted looong ago and is to be found in list archives or someplace
else on the web.
I've been using Haproxy for 2 years now, both for HTTP LB and RDP LB on two
load-balancers servers (configurations in attachment) with keepalived for
the management of VRRP IP Address.
I recently upgraded to version 1.6.3 on Debian 8.3 to try and solve various
load-balancing issues but in vain.
Regarding the RDP LB, I tried to pick here and there various configuration
samples which could suit my needs which are the following:
- Persistent connections on the same TS Server either in case of
ordinary reconnections after timeout or full session closing.
- Monitoring connections through Zabbix to get a precise
visualization of the repartition of users
- Achieving load(-balancing in terms of numbers of users by server.
Ideally, I would also like to systematically affect some users to a
identified server which hosts a unique resource they need but it is not the
subject of this post.
The situation is the following:
- I implemented a session table shared between the two LB Servers
but it is not identical on either server
- Some users appear in both tables when most of the others do not
(sample tables in attachment)
- The stats I get through scripts in Zabbix (in attachment) do not
show the whole population of connected users
- Sometimes (rarely), a user gets disconnected and is reconnected
on another TS server and I see two different sessions on two different TS
servers in the TS servers farm.
- There are quite big differences in the number of users connected
between the different TS servers (as I write: 6, 6 and 9, the latter (TS4)
gathering always the most users, sometimes as much as the double of each
others).
Obviously, I missed something in the Haproxy configuration but I can't find
where the problem lies.
I'm ashamed to say that even if I spent quite a lot of time trying to
understand the Haproxy documentation, I have a lot of trouble to connect the
various configuration instructions together and figure out the whole picture
on this matter.
So my question is: is there a fully documented tutorial that I couldn't find
yet which covers these matters ?
If not, could anyone give me a few hints about my configuration problem ?
PS: The very simple HTTP configuration works like a charm and is not
included in this post.
Jean.
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
# Create a socket to monitor Haproxy
stats socket /tmp/haproxy.sock
defaults
log global
mode tcp
option dontlognull
timeout connect 5000
timeout client 1h
timeout server 1h
# NEW RDP config
peers lbpeers
peer g3s-dmz-lb1 10.241.2.31:8888
peer g3s-dmz-lb2 10.241.2.32:8888
frontend rdp-in
bind *:3389 name rdp
maxconn 4000
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
option tcplog
option clitcpka
default_backend rdp-out
backend rdp-out
mode tcp
# Load Balancing Mode
balance rdp-cookie(mstshash)
tcp-request inspect-delay 5s
# RDP Cookie management
tcp-request content accept if RDP_COOKIE
#persist rdp-cookie ==> Redondant avec la balncing sur rdp_cookie((mstshash) ?
stick-table type string size 2m expire 120m peers lbpeers
# ACL which determines whether the domain DOM is included at the beginning of the cookie
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i groupe3s
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i GROUPE3S
# applies to DOM\USER
stick on req.rdp_cookie(mstshash),word(2,\) table rdp-out if domain_included
# applies to both USER and USER@DOM
stick on req.rdp_cookie(mstshash),word(1,@) table rdp-out if ! domain_included
#stick on rdp_cookie(mstshash)
# Single connection
tcp-request content reject if { sc1_conn_cur ge 2 }
# Protection against brute force attacks (limit connections attempts)
tcp-request content reject if { sc1_conn_rate ge 10 }
#server TS1 10.241.1.1:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS2 10.241.1.2:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS3 10.241.1.3:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS4 10.241.1.4:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
option tcplog
option redispatch
option abortonclose
option srvtcpka
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
# Create a socket to monitor Haproxy
stats socket /tmp/haproxy.sock
defaults
log global
mode tcp
option dontlognull
timeout connect 5000
timeout client 1h
timeout server 1h
# NEW RDP config
peers lbpeers
peer g3s-dmz-lb1 10.241.2.31:8888
peer g3s-dmz-lb2 10.241.2.32:8888
frontend rdp-in
bind *:3389 name rdp
maxconn 4000
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
option tcplog
option clitcpka
default_backend rdp-out
backend rdp-out
mode tcp
# Load Balancing Mode
balance rdp-cookie(mstshash)
tcp-request inspect-delay 5s
# RDP Cookie management
tcp-request content accept if RDP_COOKIE
#persist rdp-cookie ==> Redondant avec la balncing sur rdp_cookie((mstshash) ?
stick-table type string size 2m expire 120m peers lbpeers
# ACL which determines whether the domain DOM is included at the beginning of the cookie
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i groupe3s
acl domain_included req.rdp_cookie(mstshash),bytes(0,8) -m str -i GROUPE3S
# applies to DOM\USER
stick on req.rdp_cookie(mstshash),word(2,\) table rdp-out if domain_included
# applies to both USER and USER@DOM
stick on req.rdp_cookie(mstshash),word(1,@) table rdp-out if ! domain_included
#stick on rdp_cookie(mstshash)
# Single connection
tcp-request content reject if { sc1_conn_cur ge 2 }
# Protection against brute force attacks (limit connections attempts)
tcp-request content reject if { sc1_conn_rate ge 10 }
#server TS1 10.241.1.1:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS2 10.241.1.2:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS3 10.241.1.3:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
server TS4 10.241.1.4:3389 weight 1 check port 3389 inter 10000 rise 2 fall 3 on-marked-down shutdown-sessions
option tcplog
option redispatch
option abortonclose
option srvtcpka
UserParameter=haproxy.scur, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'rdp-in' | awk -F, '{print $5}'
UserParameter=haproxy.G3S-QNG-TS1.qcur, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $3}'
UserParameter=haproxy.G3S-QNG-TS1.qlimit, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $26}'
UserParameter=haproxy.G3S-QNG-TS1.scur, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $5}'
UserParameter=haproxy.G3S-QNG-TS1.econ, echo "show stat" | /usr/bin/sudo /usr/bin/socat /tmp/haproxy.sock stdio | grep -i 'TS1' | awk -F, '{print $14}'
# table: rdp-out, type: string, size:2097152, used:12
0x2177db4: key= use=0 exp=4588852 server_id=3
0x217c654: key=ahembert use=0 exp=5144169 server_id=3
0x217bbd4: key=ecastells use=0 exp=3341472 server_id=3
0x217cf44: key=ereboux use=0 exp=6268522 server_id=1
0x21774c4: key=ggarcia use=0 exp=5502583 server_id=3
0x217df04: key=mpguezenn use=0 exp=4080727 server_id=1
0x2179004: key=mtalagas use=0 exp=2334820 server_id=2
0x217aad4: key=ngizzi use=0 exp=5072664 server_id=2
0x2172c94: key=rlecureur use=0 exp=6722870 server_id=1
0x217a104: key=sriou use=0 exp=79982 server_id=1
0x2172e24: key=svarin use=0 exp=5338885 server_id=2
0x217e124: key=svenisse use=0 exp=6497952 server_id=3
# table: rdp-out, type: string, size:2097152, used:7
0x18ab934: key= use=0 exp=2561997 server_id=3
0x18ab9e4: key=ahembert use=0 exp=3618652 server_id=3
0x18aad84: key=ggarcia use=0 exp=763814 server_id=3
0x18ab884: key=mpguezenn use=0 exp=4065021 server_id=1
0x18aba94: key=ngizzi use=0 exp=5056961 server_id=2
0x18abb44: key=rlecureur use=0 exp=6707176 server_id=1
0x18aab74: key=svarin use=0 exp=5323184 server_id=2