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