[megoldva] Apache+ProxyPass balancer

Fórumok

A megoldás: https://hup.hu/node/186283#comment-3113609
Hálásan köszönöm mindenkinek, aki idejéből áldozott a rám!

 

Sziasztok!

Adott egy Frontend angularjs, Backend .net alkalmazás. A frontend kiszolgálója windows IIS.
2db egyforma VM -en fut az IIS, mely előtt Sophos van, ami fogadja a webről érkező kéréseket és továbbítja a frontend szerverek felé.

Eddig Sophos látta el az L7 védelmet és továbbította a forgalmat a frontendek felé, most bizonyos okok miatt linux apache+mod-security lenne elé rakva.

Ha HA-Proxy-t alkalmazok, akkor az alkalmazás rendesen működik. Config részlet:

frontend https_front
bind *:443 ssl crt /etc/haproxy/domain.pem
monitor-uri /checkstatus
monitor fail if { nbsrv(https_back) eq 0 }

default_backend https_back

backend https_back
option httpchk
http-check connect ssl
http-check send meth HEAD uri / ver HTTP/2 hdr Host domain.hu
http-check expect status 200

cookie SERVERID insert indirect nocache

 balance roundrobin
 option forwardfor
 http-request set-header Host domain.hu if { srv_id 1 }
 http-request set-header Host domain.hu if { srv_id 2 }
 server fe1 10.x.x.1:443 check ssl verify none
 server fe2 10.x.x.2:443 check ssl verify none
 

Ezzel tehát rendesen megy az alkalmazás.

Az eredeti terv viszont apache+modsecurity lenne. Ezzel addig megy, amíg csak 1 gépnek proxyzom. Ha már balancert használok 2 gép között (vagy akár 1 gép van a balancer alá felvéve), akkor az alkalmazás elkezd betöltődni, majd leáll. Ha az IIS-en elhelyezek egy sima txt fájllt, ott nincs hiba, kiszolgája. 

Íme a sima proxy-s config:

<VirtualHost *:443>
    ServerName tomain.hu
    SSLEngine On
    SSLCertificateFile /etc/apache/SSL/domaincrt.pem
    SSLCertificateKeyFile /etc/apache/SSL/domainkey.pem

   Customlog /var/log/apache2/proxy-access.log combined 
   ErrorLog /var/log/apache2/proxy-error.log

    UseCanonicalPhysicalPort Off
    UseCanonicalName         Off

    SSLProxyEngine on
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off
    SSLVerifyClient none
    SSLProxyVerify none
    SSLProxyVerifyDepth 0
    SSLInsecureRenegotiation on

    ProxyRequests off
    ProxyPreserveHost on
    ProxyErrorOverride on

    AllowEncodedSlashes     NoDecode

    RequestHeader set Host "domain.hu"
    ProxyPass /server-status !   
    ProxyPass        / https://10.x.x.1:443/ flushpackets=On connectiontimeout=300 timeout=300
    ProxyPassReverse / https://10.x.x.1:443/
    ProxyTimeout    300
</VirtualHost>
 

Ezzel pedig már nem működik:

<IfModule mod_proxy.c>
    <proxy balancer://cluster>
       BalancerMember https://10.x.x1:443/ loadfactor=1
       BalancerMember https://10.x.x.2:443/ loadfactor=1
       ProxySet lbmethod=byrequests
    </proxy>
</IfModule> 

 

<VirtualHost *:443>
    ServerName tomain.hu
    SSLEngine On
    SSLCertificateFile /etc/apache/SSL/domaincrt.pem
    SSLCertificateKeyFile /etc/apache/SSL/domainkey.pem

   Customlog /var/log/apache2/proxy-access.log combined 
   ErrorLog /var/log/apache2/proxy-error.log

    UseCanonicalPhysicalPort Off
    UseCanonicalName         Off

    SSLProxyEngine on
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off
    SSLVerifyClient none
    SSLProxyVerify none
    SSLProxyVerifyDepth 0
    SSLInsecureRenegotiation on

    ProxyRequests off
    ProxyPreserveHost on
    ProxyErrorOverride on

    AllowEncodedSlashes     NoDecode

    RequestHeader set Host "domain.hu"

    ProxyPass /server-status !
    ProxyPass /balancer-manager !
    ProxyPass / balancer://cluster/ lbmethod=byrequests
    ProxyPassReverse / balancer://cluster/ lbmethod=byrequests

    ProxyTimeout    300
</VirtualHost>

 

 

Nem értem, hogy hol a hiba. HA-proxyval pöccre megy. Apache-csal is, ha nincs balancer. Ha balancerrel oldom meg, akár csak egy célgép felé, akkor már rögtön nem megy.
Hol a probléma?

A fejlesztő keresi az okot, egyelőre nem találjuk. Nem mi fejlesztettük, csak úgy vettük át. Van benne elvileg ajaxos kérés, visszacsatolás. Itt kapiskál, de nem biztos ő sem a dologban.
Abból indulok ki, ha a ha-proxyval megy, ráadásul ha-proxy esetén 2 fronend között balance-olva is működik rendesen.Apache-csal is illene rendesen.
A logokból semmi értelmes nem derül ki. A proxy-access logban minden kérés 200 HTTP státusszal tér vissza, majd pár másodperc után megáll a kérés folyam. Az oldal pedig üres megjelenítve. Forráskód szinten lefut teljesen a nyitótól a záró html tagig. A közepe erősen hiányos :)

Firefox hibakereső módban ezt találtam, ami csak balancer esetén mutatkozik:

Error: Invalid response Content-Type: text/html, from URL: https://domain.hu/.well-known/openid-configuration

A fejlesztő szerint itt egy jsnek kellene lefutnie, ehhez képest mappát akar megnyitni.
Szóval több ponton nem értjük. Nem is biztos, hogy innen ered a probléma. Ismétlem,  proxy módban balancer nélkül tökéletes az oldal.

Van valakinek tippje miből adódhat ez az eltérés balancer használata esetén?

 

Hozzászólások

milyen modulok vannak betoltve?

neked aztan fura humorod van...

Eléggé lecsontosítottam. Mindent kivettem, amiért nem sírt. Cél volt, hogy minél fürgébb legyen. Másfelől ami nincs betöltve, az nem törhető.

proxy01:~$ ls -1 /etc/apache2/mods-enabled/
authz_core.load
authz_host.load
headers.load
lbmethod_byrequests.load
mime.conf
mime.load
mpm_event.conf
mpm_event.load
proxy_balancer.conf
proxy_balancer.load
proxy.conf
proxy_hcheck.load
proxy_http.load
proxy.load
slotmem_shm.load
socache_shmcb.load
ssl.conf
ssl.load
status.conf
status.load
 

Nem, teljesen "jól" kezeli. Ha egy .txt-t hívok be, akkor behozza. Ha elírom a headerben átküldött hostnevet, akkor pl. 404-et dob az IIS neki, mert nincs olyan domain kezelve az IIS-ben. Tehát látszólag minden szép és jó, csak valami leakad menet közben.
Használtam én már ezt a balancer dolgot máshol. Ott egyszerűbb volt a fogadó oldal.
Itt valami 2 dolog együttállása lehet, proxy és IIS-ben lévő alkalmazás oldalon, csak nem tudom mi.
Az az egy biztató, hogy ha-proxyval megy. Meg előtte Sophos-szal is ment. Annyira nem lehet elcseszve a fejlesztett alkalmazás.

Ha semmi megoldás, akkor a következő megugrandó feladat: ha-proxy + mod-security helyes házasítása lesz. Csak ettől tartok, mert githubos community megoldást dobot a google.
Debianban meg csak ilyen van: libapache2-mod-security2

 

LoadBalancer Status for balancer://cluster[pee78b742_cluster]

MaxMembers StickySession DisableFailover Timeout FailoverAttempts Method Path Active
1 [1 Used] (None) Off 0 0 byrequests / Yes

 

Worker URL Route RouteRedir Factor Set Status Elected Busy Load To From HC Method HC Interval Passes Fails HC uri HC Expr
https://10.1.8.200/     1.00 0 Init Ok 0 0 0 0 0 NONE 30000ms 1 (0) 1 (0)    
Szerkesztve: 2024. 09. 13., p – 18:16

Csak gyorsan futottam át most. Amit én beállítanák / átállítanék:
- stickyness (https://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html)
- játszani az lbmethoddal, hogy befolyásolja-e a hibát
- vedd le a záró / jelet a BalancerMember sorok végéről (BalancerMember https://10.x.x1:443 loadfactor=1)

Ugye ReWrite rule-ok nincsenek?

"- vedd le a záró / jelet a BalancerMember sorok végéről (BalancerMember https://10.x.x1:443 loadfactor=1)"

 

Basszus ez volt. Pedig ilyen / jellel már játszottam, de ezek szerint a balancer://cluster/ résznél.
Na szép. Ilyen vackon elcsúszni.
Köszönöm! Úgy néz ki, most jól működik. Holnap leteszteltetem a fejlesztővel. Uh, felénk jársz szólj előtte, jövök egy sörrel :)

A tippem, amit valószínűleg egy tcpdump igazolna:

- A .txt fájl kiszolgálása 1 lépésben megtörténik. Bejön a kérés, eljut a backendig, az meg visszaküldi a fájlt. Done.

- Viszont itt van angularjs. Azaz folyamatosan, több lépésben megy a kommunikáció a kliens és backend között, amíg összeáll a végső eredmény. És a kérések-válaszok egymásra épülnek. Ha valahol // van az URL-ben, akkor elhal a folyamat. Egyszerűen nem fogja tudni feldolgozni. Tippre a angularjs oldalon hal el valamelyik kapott válasz után. Ezért sincs semmi hiba Apache, IIS oldalon. Mondjuk egy warningot küldhetne rá az Apache megfelelő loglevel mellett.

Kliens  -(kérés1)-> Proxy ---> Backend -(válasz1)-> Proxy --> Kliens -(kérés2) --> ....

Szívesen segítettem. Még nem tudom, hogy mikor járok arrafelé. :)

Amúgy ez a / jel egy disznó dolog. Hol kell, hol nem. Apache doksi (https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#balancermember) ezt írja:
"Trailing slashes should typically be removed from the URL of a BalancerMember."

Szerkesztve: 2024. 09. 13., p – 21:16

kapcsold ki a halon beluli https-t a backended fele es mehet a tcpdump. abbol okosabbak lesztek.
ha mar se apache se iis logok nincsenek, vagy nem nezitek oket.

Apache oldalon semmi érdemleges log bejegyzés. IIS oldalon a fejlesztőre még várni kell.
Hozott anyag, valahol https redirect van a kódban, ezért a 80-ason történő kiszolgálás redirect loopba fulladt. Volt próbálkozás, de nem jó helyre nyúlt.
Gondoltam addig megkérdem én is, mi a bánat lehet proxy oldalon, amit nem kezel le úgy, mint a ha-proxy.

Megoldás a cél, de az erőforrások nem a legideálisabbak. Én win IIS meg ilyen js alkalmazás xarokhoz nem értek. Én a proxyt adnám alá a Sophos helyett, de elakadt a projekt. Várni kell a kollégára, aki próbálja megérteni ezt a varázs kódot, amit a beszállító összerakott. A projekt lement, a beszállító "amnéziás", a doksi meg nem terjed ki mindenre. Szóval a szokásos :)

hat, en siman el tudom kepzelni, hogy a problem onnan indul, h by-request balanszolsz, dobalod a forgalmat innen-oda onnan-ide, mialatt a backend errol semmit nem tud (kozos session es tarsai)

en nginx-szel szoptam hasonlot, ott ez a(z egyik) megoldas erre:

upstream valami {
                ip_hash;
                server "192.168.0.7:8080";
                server "192.168.0.8:8080";
                server "192.168.0.9:8080";
}

igy az 1 ip felol jovo keresek mindig ugyanoda futnak be. mondjuk itt nem terheles-elosztas, hanem redundancia volt a cel.

Köszönöm, igen. Ilyenbe mi is belefutottunk anno nginx alatt. Ez a mostani eset egy backenddel is probléma volt. A megoldással frissítettem a nyitó postot.

Nem tudom tudod-e, az apache annyiból lehet érdekesebb, mint az nginx, hogy neki van aktiv health-check funkciója. Azaz nem csak valós request esetén veszi észre, hogy timeoutra fut egy backend, hanem aktívan ellenőrzi meghatározott időnként. Ha lehalt, ideje korán kiveszi a listából. Ott használtuk eddig ezt a funkciót, ahol egy bejövő kérés sem veszhet el és azonnal ki kell szolgálni.

Egyébként jobban szeretem az nginx-t proxyra, egyszerűbb, jobban megy. A domaint sem kell átdobni headerben külön. Magától megteszi és érti a backend.