MS 遠端桌面閘道、HAProxy 和密碼暴力破解

朋友們,你們好!

有多種方法可以從家中連接到辦公室工作區。 其中之一是使用 Microsoft 遠端桌面閘道。 這是基於 HTTP 的 RDP。 我不想在這裡討論 RDGW 本身的設置,我不想討論它的好壞,讓我們將它視為遠端存取工具之一。 我想談談如何保護您的 RDGW 伺服器免受邪惡互聯網的侵害。 當我設定 RDGW 伺服器時,我立即開始擔心安全性,尤其是防止密碼暴力破解。 令我驚訝的是,我在互聯網上沒有找到任何有關如何執行此操作的文章。 好吧,你必須自己做。

RDGW本身沒有任何保護。 是的,它可以透過裸介面暴露到白色網絡,並且效果很好。 但這會讓合適的管理員或資安專家感到不安。 此外,它還可以讓您避免帳戶被封鎖的情況,即粗心的員工在他的家庭電腦上記住了公司帳戶的密碼,然後更改了密碼。

保護內部資源免受外部環境影響的一個好方法是透過各種代理商、發布系統和其他 WAF。 讓我們記住,RDGW 仍然是 http,那麼它只是請求在內部伺服器和互聯網之間插入專門的解決方案。

我知道有很酷的F5、A10、Netscaler(ADC)。 身為這些系統之一的管理員,我會說還可以在這些系統上設定針對暴力破解的保護。 是的,這些系統還將保護您免受任何同步洪水的影響。

但並不是每個公司都有能力購買這樣的解決方案(並為這樣的系統找到管理員:),但同時他們可以照顧安全!

完全可以在免費作業系統上安裝免費版本的 HAProxy。 我在穩定儲存庫中的 Debian 10、haproxy 版本 1.8.19 上進行了測試。 我還在測試存儲庫中的 2.0.xx 版本上對其進行了測試。

我們將把 Debian 本身的設定排除在本文的討論範圍之外。 簡而言之:在白色介面上,關閉除連接埠 443 之外的所有內容,在灰色介面上 - 根據您的策略,例如,也關閉除連接埠 22 之外的所有內容。 僅開啟工作所需的內容(例如 VRRP,用於浮動 ip)。

首先,我在 SSL 橋接模式(也稱為 http 模式)下配置 haproxy,並開啟日誌記錄以查看 RDP 內部發生的情況。 可以這麼說,我是夾在中間的。 因此,有關設定 RDGateway 的「所有」文章中指定的 /RDWeb 路徑遺失。 那裡只有 /rpc/rpcproxy.dll 和 /remoteDesktopGateway/。 在這種情況下,不使用標準的 GET/POST 請求;使用它們自己的請求類型 RDG_IN_DATA、RDG_OUT_DATA。

不多,但至少有些東西。

我們來測試一下。

我啟動 mstsc,轉到伺服器,在日誌中看到四個 401(未經授權)錯誤,然後輸入我的使用者名稱/密碼並看到回應 200。

我將其關閉,再次啟動,在日誌中我看到相同的四個 401 錯誤。我輸入錯誤的登入/密碼,然後再次看到四個 401 錯誤。這就是我需要的。 這就是我們要抓住的。

由於無法確定登入網址,而且我不知道如何在 haproxy 中捕獲 401 錯誤,因此我將捕獲(實際上不是捕獲,而是計數)所有 4xx 錯誤。 也適合解決問題。

保護的本質是,我們將計算每單位時間(在後端)的 4xx 錯誤數量,如果超過指定的限制,則在指定時間內拒絕(在前端)來自該 ip 的所有進一步連接。

從技術上講,這不會防止密碼暴力破解,而是防止 4xx 錯誤。 例如,如果您經常要求不存在的網址(404),那麼保護也會起作用。

最簡單、最有效的方法是依靠後端並報告是否有任何額外情況:

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

這不是最好的選擇,讓我們把它複雜化。 我們將依靠後端並阻止前端。

我們將粗魯地對待攻擊者並斷開他的 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

同樣的事情,但禮貌地,我們將返回錯誤 http 429(請求過多)

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

我檢查:我啟動 mstsc 並開始隨機輸入密碼。 第三次嘗試後,10 秒內它把我踢了回來,並且 mstsc 給出了錯誤。 從日誌中可以看出。

解釋。 我距離 haproxy 大師還很遠。 我不明白為什麼,例如
http請求拒絕deny_status 429 if { sc_http_err_rate(0) gt 4 }
允許你犯下大約 10 個錯誤才起作用。

我對計數器的編號感到困惑。 haproxy的大師們,如果你們補充我、糾正我、讓我變得更好,我將非常高興。

在評論中您可以建議其他保護 RD 網關的方法,研究起來會很有趣。

關於Windows遠端桌面用戶端(mstsc),值得注意的是它不支援TLS1.2(至少在Windows 7中),所以我不得不離開TLS1; 不支援目前的密碼,所以我也不得不離開舊的。

對於那些什麼都不懂、剛學習並且已經想做得好的人,我會給你整個配置。

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

為什麼後端有兩台伺服器? 因為這就是容錯的方法。 Haproxy也可以做兩個浮動的白色ip。

運算資源:您可以從「兩個千兆、兩個核心的遊戲 PC」開始。 根據 維基百科 這就足夠了。

引用:

從 HAProxy 設定 rdp 網關
我發現的唯一一篇他們費盡心思暴力破解密碼的文章

來源: www.habr.com

添加評論