MS远程桌面网关,HAProxy和密码猜测

嗨,朋友们!

有许多种方法可以从家里连接到办公室的工作场所。其中之一是使用Microsoft远程桌面网关。这是基于HTTP的RDP。我不想谈论RDGW本身的配置,我不想讨论它的优缺点,让我们将其视为远程访问工具之一。我想谈谈保护RDGW服务器免受恶意Internet攻击的问题。设置RDGW服务器时,我立即开始忙于保护,尤其是密码保护。令我感到惊讶的是,我没有在互联网上找到有关如何执行此操作的文章。好吧,你必须自己做。

RDGW本身没有任何保护。是的,可以将裸露的铁路接口暴露在白色的网中,并且可以正常工作。但是正确的管理员或IB'shnik会因此而烦躁不安。此外,它还可以避免因疏忽大意的员工在家用计算机上记住公司帐户的密码,然后更改其密码而导致帐户被封锁的情况。

保护内部资源不受外部环境影响的一种好方法是通过各种代理,发布系统和其他WAF。回想一下,RDGW都是相同的http,然后它直接乞求在内部服务器和Internet之间使用专门的解决方案。

我知道有很酷的F5,A10,Netscaler(ADC)。作为这些系统之一的管理员,我会说,还可以在这些系统上设置防止破坏的保护措施。是的,这些系统将保护您免受一路泛滥的威胁。

但是并不是每个公司都能买得起这样的解决方案(并找到这样一个系统的管理员:),但是它可以确保安全!

可以在免费操作系统上安装HAProxy的免费版本。我在稳定的haproxy 1.8.19版本的Debian 10上进行了测试。我还从测试库中检查了版本2.0.xx。

设置debian本身不在本文讨论范围之内。简要地说:在白色界面上,关闭除443端口以外的所有内容,在灰色界面上-根据您的策略,例如,关闭除22个端口以外的所有内容。仅打开工作所需的内容(例如,对于浮动IP,VRRP)。

首先,我将haproxy配置为SSL桥接模式(也称为模式http),并打开日志记录以查看RDP内部的内容。可以这么说,爬在中间。因此,缺少有关配置RDGateway的“所有”文章中指定的/ RDWeb路径。那里只有/rpc/rpcproxy.dll和/ remoteDesktopGateway /。在这种情况下,不使用标准的GET / POST请求,它自己的请求类型为RDG_IN_DATA,RDG_OUT_DATA。

不多,但至少有一些。

让我们测试一下。

我启动mstsc,转到服务器,在日志中看到四个401错误(未经授权),然后输入登录名/密码,然后看到答案200。我

关闭,再次启动,在日志中看到相同的四个401错误。我输入了错误的用户名/密码,我又看到了四个错误401。您需要什么。这就是我们要抓住的。

由于无法确定登录URL,此外,我不知道如何在haproxy中捕获401错误,因此我将捕获(实际上不是捕获,而是计算)所有4xx错误。也乐于解决问题。

保护的本质是,我们将计算每单位时间4xx错误(在后端)的数量,如果超过指定的限制,则在指定的时间内拒绝(在前端)该IP的所有其他连接。

从技术上讲,这不是密码保护,而是4xx错误保护。例如,如果您经常请求一个不存在的URL(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大师还很远。我不明白为什么,例如,
如果{sc_http_err_rate(0)gt 4}
允许您在操作之前出错约10条,则http-request拒绝deny_status 429

我对柜台的编号感到困惑。 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”开始。根据Wikipedia的说法这足够了。

链接:

从HAProxy配置rdp-gateway 唯一我发现密码破解困扰的
文章

All Articles