MS Remote Desktop Gateway, HAProxy dhe kalimi i fjalëkalimeve

Përshëndetje, miq!

Ekzistojnë shumë mënyra për t'u lidhur nga shtëpia në vendin e punës në zyrë. Një prej tyre është përdorimi i Microsoft Remote Desktop Gateway. Ky është RDP mbi HTTP. Nuk dëshiroj të flas për konfigurimin e vetë RDGW, s'po diskutojmë pse është i mirë ose i keq, le të e shohim atë si një nga mjetet e aksesit të largët. Dëshiroj të flas për mbrojtjen e serverit tuaj RDGW nga interneti i keq. Kur kam configurur serverat RDGW, menjëherë m'u bë e qartë se duhet të mendoj për mbrojtjen, sidomos mbrojtjen nga përpjekjet për të thyer fjalëkalimin. Më befasoi që nuk gjetëm artikuj në internet se si ta bëjmë këtë. Epo, duket se do të duhet ta bëjmë vetë.

RDGW vetë nuk ka asnjë mbrojtje. Po, mund ta vendosësh me një ndërfaqe të hapur në rrjetin publik dhe do të funksionojë mirë. Por një administrator i duhur ose një specialist i sigurisë do të jetë i shqetësuar për këtë. Për më tepër, ky mund të ndihmojë në shmangien e situatave të bllokimit të llogarive, kur një punonjës i pahijshëm kishte memorizuar fjalëkalimin e llogarisë korporative në kompjuterin e tij dhe më pas e ndryshoi atë.

Një mënyrë e mirë për të mbrojtur burimet e brendshme nga mjedisi i jashtëm është përdorimi i proxy-ve të ndryshëm, sistemeve të publikimit dhe WAF-ve të tjera. Të kujtojmë se RDGW është përfundimisht http, kështu që është e qartë që duhet të vendosim një zgjidhje të specializuar midis serverëve të brendshëm dhe internetit.

Unë e di se ekzistojnë F5 të jashtëzakonshme, A10, Netscaler (ADC). Si administrator i një prej këtyre sistemeve, mund të them se është e mundur të konfigurosh mbrojtjen kundër përpjekjeve për të thyer në këto sisteme gjithashtu. Dhe po, këto sisteme gjithashtu do t'ju mbrojnë nga çdo lloj syn flud.

Por jo çdo kompani mund ta lejojë veten të blejë një zgjidhje të tillë (dhe të gjejë një administrator për një sistem të tillë :), dhe për sigurinë, gjithsesi, mund të kemi kujdes!

Është plotësisht e mundur të instaloni një version falas të HAProxy në një sistem operativ falas. E kam testuar në Debian 10, dhe në depot stabil kam versionin haproxy 1.8.19. Kam kontrolluar gjithashtu versionet 2.0.xx nga depot testing.

Ne do ta lëmë konfigurimin e debianit jashtë këtij artikulli. Në mënyrë të shkurtër: në ndërfaqen publike, mbyllni gjithçka përveç portit 443, në ndërfaqen e gjashtë — sipas politikës tuaj, për shembull mbyllni gjithçka përveç portit 22. Hapni vetëm atë që është e nevojshme për funksionimin (si VRRP për shembull, për IP-në e lëvizshme).

Së pari, kam konfiguruar haproxy në modin SSL bridging (i njohur gjithashtu si mod HTTP) dhe aktivizova regjistrimin, për të parë se çfarë ndodh brenda RDP. Pra, vendosa të hyj në mes. Sidoqoftë, rruga e cituar në "të gjitha" artikujt për konfigurimin e RDGateway ndodhet /RDWeb mungon. E gjithë ajo që ekziston është /rpc/rpcproxy.dll dhe /remoteDesktopGateway/. Në të njëjtën kohë nuk përdoren kërkesat standarde GET/POST, përdoret një lloj i veçantë kërkese RDG_IN_DATA, RDG_OUT_DATA.

Nuk është shumë, por është diçka.

Le të bëjmë disa teste.

Po filloj mstsc, shkoj në server, në regjistrat shoh katër gabime 401 (të paautorizuara), pastaj vendos përdoruesin/fjalëkalimin dhe shoh përgjigjen 200.

Po çaktivizoj dhe e nis përsëri, shoh po ato katër gabime 401 në log. Shkruaj një emër përdoruesi/faqe të gabuar dhe shoh përsëri katër gabime 401. Kjo është ajo që na duhet. Këtu do të përqendrohemi.

Duke pasur parasysh se nuk arrita të përcaktoj URL-në e login-it dhe për më tepër nuk di si të kap gabimin 401 në haproxy, do të numëroj të gjitha gabimet 4xx. Kjo gjithashtu do të funksionojë për zgjidhjen e çështjes.

Thelbi i mbrojtjes do të jetë t'u numërojmë gabimet 4xx (në backend) në një njësi kohe dhe nëse ato kalojnë një kufi të caktuar, do të bllokojmë (në frontend) të gjitha lidhjet e mëtejshme nga ky IP për një kohë të caktuar.

Teknikisht, kjo nuk do të ishte një mbrojtje kundër shfrytëzimeve të fjalëkalimeve, por një mbrojtje kundër gabimeve 4xx. Për shembull, nëse kërkoni shpesh një URL që nuk ekziston (404), mbrojtja do të aktivizohet.

Mënyra më e thjeshtë dhe funksionale — është të numëroj dhe të bllokoj, nëse ndonjë gjë e tepruar shfaqet:

frontend fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/desktop.example.com.pem
    mode http
    ...
    default_backend be_rdp_tsc


backend be_rdp_tsc
    ...
    mode http
    ...

    #krijo një tabelë, lloji string, 1000 elemente, skadon pas 15 sekondash, regjistro numrin e gabimeve gjatë 10 sekondave të fundit
    stick-table type string len 128 size 1k expire 15s store http_err_rate(10s)
    #mbaj mend IP-në
    http-request track-sc0 src
    #ndalo me gabim http 429, nëse gjatë 10 sekondave të fundit ka më shumë se 4 gabime
    http-request deny deny_status 429 if { sc_http_err_rate(0) gt 4 }
	
	...
    server rdgw01 192.168.1.33:443 maxconn 1000 weight 10 ssl check cookie rdgw01
    server rdgw02 192.168.2.33:443 maxconn 1000 weight 10 ssl check cookie rdgw02

Nuk është opsioni më i mirë, do ta komplikohemi. Do të numërojmë në backend, por do të bllokojmë në frontend.

Me sulmuesin do të sillemi ashpër, do ta heqim lidhjen TCP.

frontend fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/ertelecom_ru_2020_06_11.pem
    mode http
    ...
    #krijo një tabelë IP-sh, 1000 elemente, skadon pas 15 sekondash, ruaj nga numri global
    stick-table type ip size 1k expire 15s store gpc0
    #merr burimin
    tcp-request connection track-sc0 src
    #ndalo lidhjen TCP, nëse numri global >0
    tcp-request connection reject if { sc0_get_gpc0 gt 0 }
	
    ...
    default_backend be_rdp_tsc


backend be_rdp_tsc
    ...
    mode http
    ...
	
    #krijo një tabelë IP-sh, 1000 elemente, skadon pas 15 sekondash, ruaj numrin e gabimeve gjatë 10 sekondave
    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    #gabime shumë, nëse numri i gabimeve gjatë 10 sekondave kalon 8
    acl errors_too_fast sc1_http_err_rate gt 8
    #vendos etiketën sulmi në numrin global (rrit numrin)
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    #zeron numrin global
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    #merr burimin
    tcp-request content track-sc1 src
    #ndalo, etiketojeni si sulm
    tcp-request content reject if errors_too_fast mark_as_abuser
    #lejo, shfaq flamurin e sulmit
    tcp-request content accept if !errors_too_fast clear_as_abuser
	
    ...
    server rdgw01 192.168.1.33:443 maxconn 1000 weight 10 ssl check cookie rdgw01
    server rdgw02 192.168.2.33:443 maxconn 1000 weight 10 ssl check cookie rdgw02

i njëjti koncept, por me mirësjellje, do të kthejmë një gabim http 429 (Too Many Requests)

frontend fe_rdp_tsc
    ...
    stick-table type ip size 1k expire 15s store gpc0
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc0_get_gpc0 gt 0 }
    ...
    default_backend be_rdp_tsc

backend be_rdp_tsc
    ...
    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    acl errors_too_fast sc1_http_err_rate gt 8
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    http-request track-sc1 src
    http-request allow if !errors_too_fast clear_as_abuser
    http-request deny deny_status 429 if errors_too_fast mark_as_abuser
    ...

Po të verifikoj: e hap mstsc dhe filloj të fut paswordet rastësisht. Pas përpjekjes së tretë brenda 10 sekondash, më dëbon, dhe mstsc jep një gabim. Kjo është e dukshme në log.

Shpjegime. Unë nuk jam ekspert i haproxy. Nuk kuptoj pse, për shembull
http-request deny deny_status 429 if { sc_http_err_rate(0) gt 4 }
lejon të bëhen rreth 10 gabime, përpara se të ndodhë.

Kam konfuzion me numërimin e numëruesve. Ekspertë të haproxy, do të isha i lumtur nëse do të më plotësoni, korrigjoni, bëni më mirë.

Në komente mund të ndani metoda të tjera mbrojtjeje për RD Gateway, do të ishte interesante të studiohen.

Sa i përket klientit të desktopit të largët të Windows (mstsc), duhet të theksoj se ai nuk mbështet TLS1.2 (në çdo rast në Windows 7), prandaj drejtuam TLS1; nuk mbështet cifrat aktuale, kështu që gjithashtu e lamë të vjetër.

Për ata që nuk kuptojnë asgjë dhe po mësojnë, dhe tashmë duan të bëjnë mirë, do të sjell të gjithë konfigurimin.

haproxy.conf

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        #ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE
-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        #ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
        ssl-default-bind-options no-sslv3
        ssl-server-verify none


defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  15m
        timeout server  15m
        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 fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/dektop.example.com.pem
    mode http
    capture request header Host len 32
    log global
    option httplog
    timeout client 300s
    maxconn 1000

    stick-table type ip size 1k expire 15s store gpc0
    tcp-request connection track-sc0 src
    tcp-request connection reject if { sc0_get_gpc0 gt 0 }

    acl rdweb_domain hdr(host) -i beg dektop.example.com
    http-request deny deny_status 400 if !rdweb_domain
    default_backend be_rdp_tsc


backend be_rdp_tsc
    balance source
    mode http
    log global

    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    acl errors_too_fast sc1_http_err_rate gt 8
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    tcp-request content track-sc1 src
    tcp-request content reject if errors_too_fast mark_as_abuser
    tcp-request content accept if !errors_too_fast clear_as_abuser

    option forwardfor
    http-request add-header X-CLIENT-IP %[src]

    option httpchk GET /
    cookie RDPWEB insert nocache
    default-server inter 3s    rise 2  fall 3
    server rdgw01 192.168.1.33:443 maxconn 1000 weight 10 ssl check cookie rdgw01
    server rdgw02 192.168.2.33:443 maxconn 1000 weight 10 ssl check cookie rdgw02


frontend fe_stats
    mode http
    bind *:8080
    acl ip_allow_admin src 192.168.66.66
    stats enable
    stats uri /stats
    stats refresh 30s
    #stats admin if LOCALHOST
    stats admin if ip_allow_admin

Pseudoserverat në backend? Sepse kështu mund të krijoni qëndrueshmëri. Haproxy gjithashtu mund të ketë dy me një IP të lëvizshme.

Burimet kompjuterike: mund të nisni me "dy gigabajt, dy bërthama, një PC për lojëra". Sipas wiki kështu do të jetë më se mjaft.

Linket:

Konfigurimi i rdp-gateway nga HAProxy
Artikulli i vetëm që kam gjetur ku u shqetësuan për thyerjen e fjalëve kaluese

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster