MS Remote Desktop Gateway, HAProxy a me ka ʻōlelo huna

E nā hoa, aloha!

Nui nā ala e hoʻopili ai mai ka home i kāu keʻena hana keʻena. ʻO kekahi o lākou e hoʻohana i ka Microsoft Remote Desktop Gateway. ʻO RDP kēia ma luna o HTTP. ʻAʻole wau makemake e hoʻopā i ka hoʻonohonoho ʻana iā RDGW iā ia iho ma aneʻi, ʻaʻole wau makemake e kūkākūkā i ke kumu he maikaʻi a maikaʻi ʻole paha, e mālama mākou iā ia e like me kekahi o nā mea hana mamao. Makemake au e kamaʻilio e pili ana i ka pale ʻana i kāu kikowaena RDGW mai ka Pūnaewele hewa. I koʻu hoʻonohonoho ʻana i ka server RDGW, ua hopohopo koke wau e pili ana i ka palekana, ʻoi aku ka pale ʻana i ka password brute force. Pīhoihoi au no ka loaʻa ʻole o nā ʻatikala ma ka Pūnaewele e pili ana i ka hana ʻana i kēia. ʻAe, pono ʻoe e hana iā ʻoe iho.

ʻAʻohe pale o RDGW ponoʻī. ʻAe, hiki ke hōʻike ʻia me kahi ʻokoʻa ʻole i kahi pūnaewele keʻokeʻo a e hana maikaʻi ia. Akā, e hōʻoluʻolu kēia i ka luna hoʻoponopono kūpono a i ʻole ka loea palekana ʻike. Eia kekahi, e ʻae iā ʻoe e pale i ke kūlana o ka hoʻopaʻa ʻana i ka moʻokāki, i ka wā i hoʻomanaʻo ai kahi limahana mālama ʻole i ka ʻōlelo huna no kahi moʻokāki hui ma kāna kamepiula home, a laila hoʻololi i kāna ʻōlelo huna.

ʻO kahi ala maikaʻi e pale aku ai i nā kumuwaiwai kūloko mai ke kaiapuni o waho ma o nā proxies like ʻole, nā ʻōnaehana hoʻopuka, a me nā WAF ʻē aʻe. E hoʻomanaʻo kākou ʻo RDGW ka http, a laila noi wale ia e hoʻopili i kahi hopena kūikawā ma waena o nā kikowaena kūloko a me ka Pūnaewele.

ʻIke wau aia nā F5, A10, Netscaler(ADC). Ma ke ʻano he luna hoʻomalu o kekahi o kēia mau ʻōnaehana, e ʻōlelo wau he hiki nō hoʻi ke hoʻonohonoho i ka pale ʻana i ka hana ʻino ma kēia mau ʻōnaehana. A ʻae, e pale pū kēia mau ʻōnaehana iā ʻoe mai nā kahawai syn.

Akā ʻaʻole hiki i kēlā me kēia ʻoihana ke kūʻai aku i kahi hopena (a loaʻa i kahi luna hoʻomalu no ia ʻōnaehana :), akā i ka manawa like hiki iā lākou ke mālama i ka palekana!

Hiki ke hoʻokomo i kahi mana manuahi o HAProxy ma kahi ʻōnaehana hana manuahi. Ua hoʻāʻo wau ma Debian 10, haproxy version 1.8.19 i loko o ka waihona paʻa. Ua hoʻāʻo wau iā ia ma ka mana 2.0.xx mai ka waihona hoʻāʻo.

E haʻalele mākou i ka hoʻonohonoho ʻana iā debian iā ia iho ma waho o ke ʻano o kēia ʻatikala. ʻO ka pōkole: ma ke keʻokeʻo keʻokeʻo, e pani i nā mea āpau koe wale ke awa 443, ma ka ʻaoʻao hina - e like me kāu kulekele, no ka laʻana, e pani pū i nā mea āpau koe wale ke awa 22. Wehe wale i ka mea e pono ai no ka hana (VRRP no ka laʻana, no ka ip lana).

ʻO ka mea mua, ua hoʻonohonoho au i ka haproxy ma ke ʻano hoʻopili SSL (aka http mode) a ua hoʻohuli i ka logging e ʻike i nā mea e hana nei i loko o RDP. No laila e ʻōlelo, ua komo wau i waenakonu. No laila, ua nalowale ke ala /RDWeb i kuhikuhi ʻia ma nā ʻatikala "a pau" ma ka hoʻonohonoho ʻana iā RDGateway. ʻO nā mea a pau he /rpc/rpcproxy.dll a me /remoteDesktopGateway/. I kēia hihia, ʻaʻole hoʻohana ʻia nā noi GET/POST maʻamau; hoʻohana ʻia kā lākou ʻano noi ponoʻī RDG_IN_DATA, RDG_OUT_DATA.

ʻAʻole nui, akā ma ka liʻiliʻi loa.

E hoao kakou.

Hoʻomaka wau i ka mstsc, hele i ke kikowaena, ʻike i nā hewa ʻehā 401 (ʻae ʻole) i nā lāʻau, a laila e hoʻokomo i koʻu inoa inoa / password a ʻike i ka pane 200.

Hoʻopau wau, hoʻomaka hou, a ʻike wau i nā hewa ʻehā ʻehā 401. Hoʻokomo wau i ka login / password hewa a ʻike hou i nā hewa ʻehā 401. ʻO ia kaʻu mea e pono ai. ʻO kēia kā mākou e hopu ai.

No ka mea ʻaʻole hiki ke hoʻoholo i ka url login, a ma waho aʻe, ʻaʻole wau i ʻike pehea e hopu ai i ka hewa 401 ma haproxy, e hopu wau (ʻaʻole hopu maoli, akā helu) nā hewa 4xx āpau. He kūpono no ka hoʻoponopono ʻana i ka pilikia.

ʻO ke kumu o ka palekana e helu mākou i ka helu o nā hewa 4xx (ma ka hope) i kēlā me kēia ʻāpana o ka manawa a inā ʻoi aku ia ma mua o ka palena i ʻōlelo ʻia, a laila hōʻole (ma ka ʻaoʻao mua) nā pili hou aʻe mai kēia ip no ka manawa i ʻōlelo ʻia. .

ʻO ka ʻenehana, ʻaʻole ia e pale aku i ka password brute force, e pale ia i nā hewa 4xx. No ka laʻana, inā noi pinepine ʻoe i kahi url ʻole (404), a laila e hana pū ka pale.

ʻO ke ala maʻalahi a ʻoi aku ka maikaʻi o ka helu ʻana ma ka hope a hōʻike i hope inā ʻike ʻia kekahi mea ʻē aʻe:

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
    ...

    #создать таблицу, строковую, 1000 элементов, протухает через 15 сек, записать кол-во ошибок за последние 10 сек
    stick-table type string len 128 size 1k expire 15s store http_err_rate(10s)
    #запомнить ip
    http-request track-sc0 src
    #запретить с http ошибкой 429, если за последние 10 сек больше 4 ошибок
    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

ʻAʻole ka koho maikaʻi loa, e hoʻopili mākou. E helu mākou ma ka hope a me ka poloka ma ka mua.

E hana ʻino mākou i ka mea hoʻouka a hoʻokuʻu i kāna pilina TCP.

frontend fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/ertelecom_ru_2020_06_11.pem
    mode http
    ...
    #создать таблицу ip адресов, 1000 элементов, протухнет через 15 сек, сохрянять из глобального счётчика
    stick-table type ip size 1k expire 15s store gpc0
    #взять источник
    tcp-request connection track-sc0 src
    #отклонить tcp соединение, если глобальный счётчик >0
    tcp-request connection reject if { sc0_get_gpc0 gt 0 }
	
    ...
    default_backend be_rdp_tsc


backend be_rdp_tsc
    ...
    mode http
    ...
	
    #создать таблицу ip адресов, 1000 элементов, протухнет через 15 сек, сохранять кол-во ошибок за 10 сек
    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    #много ошибок, если кол-во ошибок за 10 сек превысило 8
    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
	
    ...
    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

ka mea like, akā me ka mahalo, e hoʻihoʻi mākou i ka hewa http 429 (Nā noi he nui)

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
    ...

Nānā au: Hoʻomaka wau i ka mstsc a hoʻomaka e hoʻokomo i nā ʻōlelo huna. Ma hope o ke kolu o ka ho'āʻo ʻana, i loko o 10 kekona e hoʻihoʻi iaʻu, a hāʻawi ʻo mstsc i kahi hewa. E like me ka mea i ʻike ʻia ma nā lāʻau.

Nā wehewehe. Ua mamao wau mai kahi haku haproxy. ʻAʻole maopopo iaʻu ke kumu, no ka laʻana
http-noi hōʻole hōʻole i ke kūlana 429 inā { sc_http_err_rate(0) gt 4 }
hiki iā ʻoe ke hana ma kahi o 10 mau hewa ma mua o ka hana.

Pioloke au i ka helu ʻana i nā helu helu. E nā haku o ka haproxy, e hauʻoli wau inā hoʻokō ʻoe iaʻu, hoʻoponopono iaʻu, hoʻomaikaʻi iaʻu.

Ma nā ʻōlelo hiki iā ʻoe ke kuhikuhi i nā ala ʻē aʻe e pale aku ai i ka RD Gateway, e hoihoi ke aʻo.

E pili ana i ka Windows Remote Desktop Client (mstsc), pono e hoʻomaopopo ʻaʻole ia i kākoʻo iā TLS1.2 (ma ka liʻiliʻi loa ma Windows 7), no laila pono wau e haʻalele iā TLS1; ʻAʻole kākoʻo i ka cipher o kēia manawa, no laila pono wau e haʻalele i nā mea kahiko.

No ka poʻe i maopopo ʻole i kekahi mea, ke aʻo wale nei, a ke makemake nei e hana maikaʻi, e hāʻawi wau iā ʻoe i ka config holoʻokoʻa.

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

No ke aha ʻelua mau kikowaena ma ka hope? No ka mea ʻo ia ke ala e hiki ai iā ʻoe ke hana i ka hoʻomanawanui hewa. Hiki iā Haproxy ke hana i ʻelua me kahi ip keʻokeʻo e lana ana.

Nā kumuwaiwai helu: hiki iā ʻoe ke hoʻomaka me "ʻelua gig, ʻelua cores, PC pāʻani." Wahi a Wikipedia e lawa ai keia.

Nā Manaʻo:

Hoʻonohonoho i ka rdp-puka mai HAProxy
ʻO ka ʻatikala wale nō aʻu i loaʻa ai kahi i hoʻopilikia ai lākou i ka hoʻoikaika ʻana i ka ʻōlelo huna

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka