MS Remote Desktop Gateway, HAProxy dhe përpjekje për gjetjen e fjalëkalimit

Përshëndetje miq!

Ekzistojnë shumë mënyra për t'u lidhur nga shtëpia në vendin e punës në zyrë. Një nga to është të përdorni Microsoft Remote Desktop Gateway. Ky është RDP mbi HTTP. Nuk dua të diskutoj këtu rregullimin e vetë RDGW, as të flas për arsyet pse është i mirë apo i keq, le të e trajtojmë si një nga mjetet e aksesit të largët. Dua të flas për mbrojtjen e serverit tuaj RDGW nga një internet i keq. Kur e vendosa serverin RDGW, menjëherë mendova për mbrojtjen, veçanërisht për mbrojtjen nga tentativat për të gjetur fjalëkalimin. Më befasoi fakti që nuk gjeta në internet artikuj për mënyrat se si mund ta bëja këtë. Epo, do të duhet ta bëj vetë.

RDGW vetë nuk ka asnjë mbrojtje. Po, mund ta ekspozoni me një ndërfaqe të bardhë në rrjetin publik dhe do të funksionojë shkëlqyer. Por një administrator i duhur ose një ekspert i sigurisë do të ndjehet i shqetësuar për këtë. Për më tepër, kjo ndihmon për të shmangur situatën e bllokimit të llogarisë, kur një punonjës i pakujdesshëm ka marrë fjalëkalimin e llogarisë korporative në kompjuterin e tij shtëpiak dhe pastaj e ndryshon fjalëkalimin e tij.

Një mënyrë e mirë për të mbrojtur burimet e brendshme nga ambienti i jashtëm është të përdoren proksi të ndryshëm, sisteme publikimi dhe WAF të tjera. Le të kujtojmë se RDGW është përfundimisht http, kështu që është e natyrshme të instaloni një zgjidhje të specializuar midis serverëve të brendshëm dhe internetit.

E di që ka F5, A10, Netscaler (ADC) të shkëlqyer. Si një administrator i një prej këtyre sistemeve, mund të them se është gjithashtu e mundur të vendosni mbrojtje nga tentativat për të gjetur fjalëkalime në këto sisteme. Dhe po, këto sisteme do t'ju mbrojnë gjithashtu nga çdo sulm syn flude.

Por nuk është çdo kompani që mund të lejojë blerjen e një zgjidhjeje të tillë (dhe të gjejë një administrator për një sistem të tillë :), por mund të bëjë diçka për sigurinë!

Është plotësisht e mundur të instaloni versionin falas të HAProxy në një sistem operativ falas. E kam provuar në Debian 10, në depozitën e stabilizuar, versioni haproxy 1.8.19. E kam kontrolluar gjithashtu në versionin 2.0.xx nga depozita testing.

Rregullimin e vetë debianit do ta lëmë jashtë këtij artikulli. Shkurt: nën ndërfaqen e bardhë, mbyllni gjithçka, përveç portit 443, nën ndërfaqen gri – sipas politikës tuaj, për shembull, gjithashtu mbyllni gjithçka, përveç portit 22. Hapur vetëm atë që është e nevojshme për funksionimin (VRRP për shembull, për IP-në flotante).

Së pari, kam konfiguruar haproxy në modalitetin SSL bridging (po ashtu në modalitetin http) dhe aktivizova regjistrimin për të parë se çfarë ndodh brenda RDP. Në këtë mënyrë, hidheshim në mes. E pra, rruga e cituar në "të gjitha" artikujt për konfigurimin e RDGateway, \/RDWeb, mungon. E gjithë çfarë ka aty është \/rpc\/rpcproxy.dll dhe \/remoteDesktopGateway\/. Në të njëjtën kohë, nuk përdoren kërkesat standarde GET\/POST, por një lloj kërkese RDG_IN_DATA, RDG_OUT_DATA.

Jo shumë, por ndonjëherë ndihmon.

Le të testojmë.

Filloj të përdor mstsc, shkoj në server, dhe në regjistrat shoh katër gabime 401 (nuk është e autorizuar), pastaj fut emrin e përdoruesit\/fjalëkalimin dhe shoh një përgjigje 200.

E çaktivizoj, e filloj përsëri, dhe në regjistrat shoh të njëjtat katër gabime 401. Fut emrin e përdoruesit\/fjalëkalimin gabim dhe shoh përsëri katër gabime 401. Kjo është ajo që na nevojitet. Këtë do ta ndjekim.

Pasi nuk arrita të përcaktoj login url dhe gjithashtu nuk e di si në haproxy të kap gabimin 401, do të kap të gjitha gabimet 4xx. Edhe kjo do të ishte e mjaftueshme për zgjidhjen e detyrës.

Qëllimi i mbrojtjes do të përbhet nga numërimi i gabimeve 4xx (në backend) në një njësi kohe dhe nëse ata kalojnë një kufi të caktuar, të refuzohen (në frontend) të gjitha lidhjet e mëtejshme nga ky ip për një kohë të caktuar.

Teknikisht, kjo nuk do të jetë mbrojtje nga provat e fjalëkalimit, do të jetë mbrojtje nga gabimet 4xx. Për shembull, nëse kërkoni shpesh një url që nuk ekziston (404), atëherë mbrojtja do të aktivizohet gjithashtu.

Mënyra më e thjeshtë dhe funksionale — është të llogarisim dhe të bllokojmë në backend, në rast se ndonjë gjë e panevojshme 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
    ...

    #krijoni një tabelë, varg, 1000 elementësh, skadon pas 15 sekondash, regjistroni numrin e gabimeve për 10 sekondat e fundit
    stick-table type string len 128 size 1k expire 15s store http_err_rate(10s)
    #mbani mend ip-n
    http-request track-sc0 src
    #ndaloni me gabimin http 429, nëse për 10 sekondat e fundit janë 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ë llogarisim në backend, dhe do të bllokojmë në frontend.

Me sulmuesin do të veprojmë ashpër, do të 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ë adresash IP, 1000 elemente, do të skadojë pas 15 sekondash, mbajtnumrin nga numëruesi global
    stick-table type ip size 1k expire 15s store gpc0
    #merr burimin
    tcp-request connection track-sc0 src
    #refuzo lidhjen tcp nëse numëruesi 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ë adresash IP, 1000 elemente, do të skadojë pas 15 sekondash, ruaj numrin e gabimeve për 10 sekonda
    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    #shumë gabime, nëse numri i gabimeve për 10 sekonda kalon 8
    acl errors_too_fast sc1_http_err_rate gt 8
    #shënoj sulmin në numëruesin global (rrit numëruesin)
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    #zero numëruesin global
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    #merr burimin
    tcp-request content track-sc1 src
    #refuzo, shëno si sulm
    tcp-request content reject if errors_too_fast mark_as_abuser
    #lejoo, ripno 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

e njëjta gjë, por me mirësjellje, do të kthejmë gabimin 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 kontrolloj: nis mstsc dhe filloj të fut gjithçka kushedi çfarë fjalëkalimesh. Pas përpjekjes së tretë brenda 10 sekondash, më hedh jashtë, dhe mstsc jep një gabim. Kjo është e dukshme në ditarë.

Shpjegime. Unë nuk jam ndonjë mjeshtër në 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ë funksionojë.

Po ngatërrohem me numërimin e numëruesve. Mjeshtra të haproxy, do të isha i lumtur nëse do të më plotësonit, të më korrigjoni, e të bëni më mirë.

Në komentet mund të propozojmë mënyra të tjera për të mbrojtur RD Gateway, do të ishte e interesant të studiojmë.

Sa i përket klientit të desktopit të largët Windows (mstsc), është e rëndësishme të theksohet se ai nuk mbështet TLS1.2 (të paktën në Windows 7), kështu që m'u desh të lejoja TLS1; nuk mbështet cipher aktuale, kështu që gjithashtu m'u desh të lija ato të vjetra.

Për ata që asgjë nuk kuptojnë, vetëm po mësojnë dhe tashmë duan të bëjnë një punë të mirë, do të jap 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

        # Vendet e parazgjedhura për materialin SSL
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # Shih: 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

Pse ka dy servera në backend? Sepse kështu mund të krijoni qëndrueshmëri. Haproxy gjithashtu mund të bëjë dy me një IP të bardhë pl floating.

Burimet llogaritëse: mund të filloni me ‘dy gig, dy bërthamë, një PC lojrash’. Sipas Wikipedia kështu do të jetë e mjaftueshme me rezerve.

Lidhjet:

Konfigurimi i rdp-gateway nga HAProxy
Artikulli i vetëm që kam gjetur, ku është shqetësuar për kalimin e fjalës.

Burimi: habr.com

Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS 🔥 Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS | ProHoster