HAProxy kasutamine
Sissejuhatus
HAProxy http://www.haproxy.org/ on C keeles programmeeritud vaba tarkvaraline lahendus selleks, et tcp ja http põhiste rakenduste puhul saavutada
- kõrgkäideldavus (ingl. k. high availability)
- koormusjaotus (ingl. k. load balancing)
- vahendamine (ingl. k. proxing)
HAProxy projekti eestvedaja on Willy Tarreau. HAProxy tegutseb samas valdkonnas BIGIP F5 või A10 toodetega. HAProxy kommerts variant asub aadressil https://www.haproxy.com/.
Mõisted
- HAPEE (HAProxy Enterprise Edition) - ...
- ALOHA
- connection
- session
- frontend
- backend
Tööpõhimõte
- http vahendamine (ingl. k. proxy)
- https sni vahendamine (ingl. k. proxy)
- https offload - tls termineerimine
- üldine tcp protokolli kasutava teenuse vahendamine (nt smtp)
- tcp-põhiste protokollide multipleksimine (ühe pordi peal kahe erineva protokolli toetamine, nt https ja ssh)
- HAProxy 'PROXY protocol' protokolli tugi
Tarkvara paigaldamine
Debian v. 9 Jessie paketihalduses on HAProxy v. 1.7, tarkvara paigaldamiseks sobib öelda
# apt-get install haproxy
Tulemusena tekib failisüsteemi
- /etc/init.d/haproxy - sys v käivitusskript
- /lib/systemd/system/haproxy.service - systemd seadistusfail
- /etc/haproxy/haproxy.cfg - peamine seadistusfail
- /etc/rsyslog.d/49-haproxy.conf - rsyslog seadistus
- /etc/default/haproxy
Tundub, et logimise käivitumiseks tuleb peale haproxy paigaldust öelda lisaks
# systemctl restart rsyslog
Hea alternatiiv on tarkvara paigaldada aadressilt https://haproxy.debian.net/.
HAProxy töö jälgimist abistavaks programmiks on socat
# apt-get install socat
Keskkonna ettevalmistamine
HAProxy efektiivseks kasutamiseks tuleb pöörata tähelepanu sellistele operatsioonisüsteemi seadistustele
- füüsiline riistvara (cpu, mälu jms)
- võrgukaardid
- operatsioonisüsteem (tuuma ja userspace tarkvara versioon)
Protsessor
- lõpetada irqbalanced protsess
# systemctl stop irqbalance # systemctl mask irqbalance
Võrgukaart
- multi-queue seadistused
OS kerneli seadistused
- paketifiltris lülitada välja port 80/tcp jaoks conntrack
Võrguarhitektuur
- TODO
Seadistamine
TODO
Käivitamine
# systemctl start haproxy
Logimine
Kui haproxy protsessid on chrootitud, siis tõenäoliselt töötab nende logi kogumisega selline rsyslog reegel (mis tuleb paketihaldusest kaasa)
# cat /etc/rsyslog.d/49-haproxy.conf # Create an additional socket in haproxy's chroot in order to allow logging via # /dev/log to chroot'ed HAProxy processes $AddUnixListenSocket /var/lib/haproxy/dev/log # Send HAProxy messages to a dedicated logfile if $programname startswith 'haproxy' then /var/log/haproxy.log &~
TCP logi paistab selline
Aug 17 18:40:35 post-fend haproxy[535]: 127.0.0.1:33583 [17/Aug/2015:18:40:35.153] clamd clamd/clamd-1 1/0/10 11 -- 0/0/0/0/0 0/0 Aug 17 18:40:37 post-fend haproxy[535]: 127.0.0.1:33587 [17/Aug/2015:18:40:37.079] clamd clamd/clamd-2 1/0/10 11 -- 0/0/0/0/0 0/0 Aug 17 18:40:38 post-fend haproxy[535]: 127.0.0.1:33590 [17/Aug/2015:18:40:38.622] clamd clamd/clamd-1 1/0/11 11 -- 0/0/0/0/0 0/0
kus
- TODO
Statistika
listen stats :1936 mode http stats enable stats hide-version stats realm Haproxy\ Statistics stats uri / stats auth kasutajanimi:parool
http ja sni https proxy
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy daemon defaults log global # mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend http-in bind *:80 mss 600 mode http option forwardfor acl host_www_moraal_ee hdr(host) -i www.moraal.ee acl host_www_auul_pri_ee hdr(host) -i www.auul.pri.ee use_backend backend_host_www_moraal_ee if host_www_moraal_ee use_backend backend_host_www_auul_pri_ee if host_www_auul_pri_ee backend backend_host_www_moraal_ee mode http balance roundrobin server webserver1 www.moraal.ee:80 option httpchk backend backend_host_www_auul_pri_ee mode http balance roundrobin server webserver2 www.auul.pri.ee:80 option httpchk frontend https-in bind *:443 mss 600 mode tcp tcp-request inspect-delay 1000 tcp-request content accept if { req.ssl_hello_type 1 } use-server www_moraal_ee if { req_ssl_sni www.moraal.ee } server www_moraal_ee www.moraal.ee:443 check use_backend backend_https_www_auul_pri_ee if { req.ssl_sni www.auul.pri.ee } backend backend_https_www_auul_pri_ee mode tcp server webserver8 www.auul.pri.ee:443
kus
- TODO
Osutub, et haproxy seadistust saab esitada ka kompaktsemalt, nt acl ja backend valiku kokku kirjutada, kasutades seejuures ühe acl juures mitut Host: väärtust
.. use_backend backend_http_ftp_moraal_ee if { hdr(host) -i ftp.moraal.ee ftp.auul.pri.ee } backend backend_http_ftp_moraal_ee mode http balance roundrobin server server_ftp_moraal_ee ftp.moraal.ee:80 option httpchk .. forontend https-in ... use-server server_www_moraal_ee if { req_ssl_sni www.moraal.ee moraal.ee media.moraal.ee } server server_www_moraal_ee www.moraal.ee:443 check
HAProxy 'PROXY protocol' kasutamine
HAProxy PROXY protokolli ambitsioon on lahendada üldine probleem, et nö tcp kihis proksides klienti rakendusserverile ei näe rakendusserver klienti algset ip aadressi. HAProxy PROXY protokolliga edastatakse kliendile nö tavalised andmed + info tegeliku klindi ip aadressi jms kohta. HAProxy PROXY protokolli tugi on mitmetel rakendustel, nt
- Postfix
- Dovecot
- Apache
- NginX
TODO
Kasulikud lisamaterjalid
Tuunimine
Eeldusel, et kliendi ja backend serveri vahel on kõige nõrgem lüli HAProxy teenus, siis vaikeseadistustega HAProxy ja Linux teenindavad ära nii 10k tcp ühendust, igale ühendusele vastab üks http päring (non-keepalive juhtum).
Probleemid
- Liiga palju haproxy ja backend vahelisi ühendusi
backend backend_http_moraal_ee http-reuse aggressive ...
- Liiga vähe src porte - sel juhul ilmub haproxy.log logisse teade
Aug 2 23:49:57 hap haproxy[7439]: Connect() failed for backend backend_http_moraal_ee: no free ports.
aitab
# sysctl -w net.ipv4.ip_local_port_range="5000 60000"
või kasutada sama backendi aga erineva src ip aadressiga
.. backend backend_http_moraal_ee mode http balance roundrobin server server_http_moraal_ee 10.20.40.50:80 check inter 30s source 192.168.1.44 server server_http_moraal_ee 10.20.30.50:80 check inter 30s source 192.168.1.45 ...
35k saavutamine
Tuunides on li
Tuunimine sisaldab
- HAProxy seadistusfailis kasutatakse nt rida
default { nbproc 8 ... }
- Linux tuuma parameetrite väärtust muudetakse
# sysctl ...
- TODO
200 k saavutamine
TODO
Kasulikud lisamaterjalid
- https://www.linangran.com/?p=547
- https://www.haproxy.com/blog/haproxy-high-mysql-request-rate-and-tcp-source-port-exhaustion/
Koormustest
haproxy koormustesimisel tuleb jälgida, et haproxy oleks kõige nõrgem koht ahelas
klient 1 klient 2 backend server 1 klient .. ------> HAProxy ----> backend server 2 klient N backend server 3
Klient
Tundub, et kliendina sobiks ab.
Server
Tundub, et backend serveriks sobib NginX, vt ...
Statistika
TODO
HAtop
Paigaldamiseks sobib öelda
# apt-get install hatop
HAProxy seadistusfaili genereerimine
TODO
iptables paketifiltri seadistamine
TODO
Küsida käesolevat väärtust
# sysctl net.netfilter.nf_conntrack_max
ja sättida vajadusel suurem, nt
# sysctl -w net.netfilter.nf_conntrack_max=10485760
Sageduspiirangud
Sageduspiirangu töö jälgimiseks sobib öelda nt
# for i in `seq 1 100`; do echo "show table http-in" | socat unix:/run/haproxy/admin.sock -; sleep 1; done # table: http-in, type: ip, size:1048576, used:2 0x24eddac: key=10.20.96.209 use=6 exp=9999 gpc0=17142 http_req_rate(10000)=17151 bytes_in_rate(10000)=1835050 0x25266dc: key=10.20.117.226 use=17 exp=10000 gpc0=10457 http_req_rate(10000)=10466 bytes_in_rate(10000)=1119434 # table: http-in, type: ip, size:1048576, used:2 0x24eddac: key=10.20.96.209 use=6 exp=10000 gpc0=19173 http_req_rate(10000)=19182 bytes_in_rate(10000)=2051832 0x25266dc: key=10.20.117.226 use=17 exp=10000 gpc0=15965 http_req_rate(10000)=15974 bytes_in_rate(10000)=1707399 # table: http-in, type: ip, size:1048576, used:3 0x293c1ec: key=10.20.96.209 use=3 exp=9998 gpc0=10044 http_req_rate(10000)=10053 bytes_in_rate(10000)=1075564 0x24ee30c: key=10.20.96.210 use=19 exp=10000 gpc0=80622 http_req_rate(10000)=80631 bytes_in_rate(10000)=8626447 0x293c29c: key=10.20.117.226 use=43 exp=10000 gpc0=47246 http_req_rate(10000)=47255 bytes_in_rate(10000)=5054038 ...
Nt selliste omadustega sageduspiirangu kehtestamiseks sobib kasutada alltoodud frontend ja backend sektsioone
- eesti ja mitte-eesti src ip pealt pöördujatele kehtestatakse erinevad sageduspiirangud
- sageduspiirangu ületajatele esitatakse haproxy'ga samas arvutis töötava nginx abil vastavat teadet
- kui teenust pakkuvat backend serverit ei ole kasutada, siis esitatakse haproxy'ga samas arvutis töötava nginx abil vastavat teadet
frontend http-in bind *:80 mode http option forwardfor stick-table type ip size 100k expire 30s store conn_rate(3s) acl src_conn_rate_eesti src_conn_rate gt 30 acl src_conn_rate_non_eesti src_conn_rate gt 10 acl src_eesti src -f /etc/haproxy/src_eesti.lst acl src_wl src -f /etc/haproxy/src_wl.lst use_backend backend_http_localhost_overlimit if !src_wl src_eesti src_conn_rate_eesti use_backend backend_http_localhost_overlimit if !src_wl !src_eesti src_conn_rate_non_eesti tcp-request connection track-sc1 src use_backend backend_http_moraal_ee use_backend backend_http_auul_pri_ee backend backend_http_moraal_ee mode http balance roundrobin server server_http_moraal_ee 10.20.100.249:80 check inter 30s source 10.20.39.44 server server_http_moraal_ee 10.20.100.249:80 check inter 30s source 10.20.39.45 server server_backup 127.0.0.1:8090 check inter 30s backup send-proxy backend backend_http_auul_pri_ee mode http balance roundrobin server server_http_auul_pri_ee 10.20.100.250:80 check inter 30s source 10.20.39.44 server server_http_auul_pri_ee 10.20.100.250:80 check inter 30s source 10.20.39.45 server server_backup 127.0.0.1:8090 check inter 30s backup send-proxy backend backend_http_localhost_overlimit mode http server server_http_localhost_overlimit 127.0.0.1:8080 check inter 30s send-proxy
kus
- TODO
Märkused
- https:// sageduspiirangu ja vastava backup ja overlimit teenuse tekitamiseks on tarvis sertifikaati; soovitavalt samasugust nagu teenus ise kasutab, või vast ka nt Let's Encrypt oma ajab asja ära eeldusel, et teenus ise ei kasuta HPKP vms tehnikat
- reeglina haproxy https proximine kasutab sni tehnikat, testimisel tuleb arvestada, et ab utiliit ei oska 2017 aastal SNI kasutada (nt testimiseks eemaldada vastav osa haproxy seadistusest)
Testimisel on mõnus jälgida kolme asja kooskõla
- ab väljundi päringute arv sekundis (ilma -k keepalive juhtumil)
# ab -c 100 -n 10000 https://www.moraal.ee/tst.html
- conntrack ja pv abil ühenduste tempo jälgimiseks (see arvu on läbiminevate ühenduste puhul 2x suurem kui ab)
# conntrack -p tcp --dport 443 -E -e NEW | pv -l -i 1 -r > /dev/null
- haproxy soketi kasutamine for kordusega
# for i in `seq 1 100`; do echo "show table https-tcp-proxy" | socat unix:/run/haproxy/admin.sock -; sleep 1; done
Kui limiidi ületajate vastata selliselt
tcp-request connection reject if !src_wl !src_eesti src_conn_rate_non_eesti
siis tõrjutakse nad nö esimesel võimalusel ja haproxy logisse ei kirjutata midagi. Võrkuliikluses on näha rcp ack-rst paketid (10.172.24.141 on server)
# tcpdump -ni any src port 443 and src host 10.172.24.141 and 'tcp[13] & 4 != 0' and 'tcp[13] & 16 != 0' tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes 23:53:41.667057 IP 10.172.24.141.443 > 10.80.117.226.37512: Flags [R.], seq 3494484503, ack 3992745540, win 231, options [nop,nop,TS val 136160396 ecr 218651198], length 0 23:53:41.667084 IP 10.172.24.141.443 > 10.80.117.226.37514: Flags [R.], seq 3733491049, ack 1964571190, win 231, options [nop,nop,TS val 136160396 ecr 218651198], length 0 23:53:41.667102 IP 10.172.24.141.443 > 10.80.117.226.37516: Flags [R.], seq 1725446391, ack 3716300254, win 223, options [nop,nop,TS val 136160396 ecr 218651198], length 0 23:53:41.667560 IP 10.172.24.141.443 > 10.80.117.226.37518: Flags [R.], seq 2159315275, ack 823832973, win 231, options [nop,nop,TS val 136160396 ecr 218651198], length 0 23:53:41.667601 IP 10.172.24.141.443 > 10.80.117.226.37520: Flags [R.], seq 1697621908, ack 392157293, win 231, options [nop,nop,TS val 136160396 ecr 218651198], length 0 ...
Kasulikud lisamaterjalid
- https://blog.serverfault.com/2010/08/26/1016491873/
- https://blog.codecentric.de/en/2014/12/haproxy-http-header-rate-limiting/
- https://www.haproxy.com/blog/use-a-load-balancer-as-a-first-row-of-defense-against-ddos/
- https://jve.linuxwall.info/ressources/taf/haproxy-aws/
- https://debian-administration.org/article/709/Using_the_haproxy_load-balancer_for_increased_availability
- https://danielmiessler.com/study/tcpflags/
Protocol multiplexing
TODO
Kasulikud lisamaterjalid
SSL offload
SSL offload toimub nt selliste frontend ja backend sektsioonidega
frontend https-in bind *:443 ssl crt /etc/ssl/localcerts/moraal.ee.pem mode http http-request deny if { path_beg /mail } !{ ssl_c_used } use_backend backend_http_moraal_ee backend backend_http_moraal_ee mode http server server_http_moraal_ee 192.168.1.15:80
kus
- ssl - toimub offload
- crt - argumendiks on ühte faili kokku ühendatud privaatne võti, end entity sertifikaat ja ahel
Kliendi sertifikaadi küsimine
Kliendi sertifikaadi küsimiseks sobib kasutada sellist frontend ja backend sektsiooni
frontend https-in bind *:443 ssl crt /etc/ssl/localcerts/moraal.ee.pem ca-file /etc/ssl/localcerts/id.crt verify optional mode http http-request deny if { path_beg /mail } !{ ssl_c_used } use_backend backend_http_moraal_ee backend backend_http_moraal_ee mode http server server_http_moraal_ee 192.168.1.15:80
kus
- haproxy tarkvarale on iseloomulik, et klienti sertifikaadi küsimist ei saa teha uri täpsusega, ainult kogu veebikoha kohta globaalselt (st kui id kaardi lugeja on seadmes, siis alati esitatakse sertifikaadi küsimise dialoog)
- kliendi serdi olemasolu nõuet saab täpsustada http-request abil
- ca-file sees on aktsepteeritud kliendi sertifikaadi väljaandjad
Kasulikud lisamaterjalid
Kasulikud lisamaterjalid
- https://cbonte.github.io/haproxy-dconv/configuration-1.5.html
- https://scriptthe.net/2015/02/08/pass-through-ssl-with-haproxy/
- http://stuff-things.net/2016/11/30/haproxy-sni/
- https://www.haproxy.com/blog/enhanced-ssl-load-balancing-with-server-name-indication-sni-tls-extension/
- https://seanmcgary.com/posts/haproxy---route-by-domain-name
- https://www.digitalocean.com/community/tutorials/how-to-implement-ssl-termination-with-haproxy-on-ubuntu-14-04
- https://tecadmin.net/how-to-setup-haproxy-load-balancing-on-ubuntu-linuxmint/
- https://www.haproxy.com/blog/play_with_maxconn_avoid_server_slowness_or_crash/
- https://www.haproxy.com/blog/haproxy-high-mysql-request-rate-and-tcp-source-port-exhaustion/
- Keepalived kasutamine
- https://www.slideshare.net/haproxytech/haproxy-best-practice
- https://jve.linuxwall.info/blog/index.php?post/2015/10/04/SHA1/SHA256-certificate-switching-with-HAProxy
- https://www.bizety.com/2016/01/27/haproxy-load-balancing-primer/