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 kështu do të jetë e mjaftueshme me rezerve.
Lidhjet:
Burimi: habr.com
