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์—์„œ๋„ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฐ๋น„์•ˆ ์ž์ฒด ์„ค์ •์€ ์ด ๊ธ€์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ํฐ์ƒ‰ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ๋Š” ํฌํŠธ 443์„ ์ œ์™ธํ•œ ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋‹ซ๊ณ , ํšŒ์ƒ‰ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ๋Š” ์ •์ฑ…์— ๋”ฐ๋ผ ํฌํŠธ 22๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ํ•ญ๋ชฉ๋„ ๋‹ซ์Šต๋‹ˆ๋‹ค. ์—…๋ฌด์— ๊ผญ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์—ด์–ด์ฃผ์„ธ์š”(์˜ˆ๋ฅผ ๋“ค์–ด ์œ ๋™IP์˜ ๊ฒฝ์šฐ VRRP).

์šฐ์„  SSL ๋ธŒ๋ฆฌ์ง• ๋ชจ๋“œ(http ๋ชจ๋“œ๋ผ๊ณ ๋„ ํ•จ)์—์„œ haproxy๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  RDP ๋‚ด๋ถ€์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊น…์„ ์ผฐ์Šต๋‹ˆ๋‹ค. ๋งํ•˜์ž๋ฉด, ๋‚˜๋Š” ์ค‘๊ฐ„์— ๋“ค์–ด๊ฐ”๋‹ค. ๋”ฐ๋ผ์„œ RDGateway ์„ค์ •์— ๋Œ€ํ•œ "๋ชจ๋“ " ๋ฌธ์„œ์— ์ง€์ •๋œ /RDWeb ๊ฒฝ๋กœ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์กด์žฌํ•˜๋Š” ๊ฒƒ์€ /rpc/rpcproxy.dll ๋ฐ /remoteDesktopGateway/๋ฟ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ํ‘œ์ค€ GET/POST ์š”์ฒญ์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ ๊ณ ์œ ํ•œ ์š”์ฒญ ์œ ํ˜•์ธ RDG_IN_DATA, RDG_OUT_DATA๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋งŽ์ง€๋Š” ์•Š์ง€๋งŒ ์ ์–ด๋„ ๋ญ”๊ฐ€.

ํ…Œ์ŠคํŠธํ•ด๋ณด์ž.

mstsc๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์„œ๋ฒ„๋กœ ์ด๋™ํ•˜์—ฌ ๋กœ๊ทธ์—์„œ 401(์ธ์ฆ๋˜์ง€ ์•Š์€) ์˜ค๋ฅ˜ 200๊ฐœ๋ฅผ ํ™•์ธํ•œ ๋‹ค์Œ ์‚ฌ์šฉ์ž ์ด๋ฆ„/๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  XNUMX ์‘๋‹ต์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ „์›์„ ๊ป๋‹ค๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฉด ๋กœ๊ทธ์— ๋™์ผํ•œ 401 ์˜ค๋ฅ˜๊ฐ€ 401๊ฐœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ๋กœ๊ทธ์ธ/๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ–ˆ๋Š”๋ฐ XNUMX ์˜ค๋ฅ˜๊ฐ€ ๋‹ค์‹œ XNUMX๊ฐœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ์ œ๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ์žก์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ 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 ๋งˆ์Šคํ„ฐ์™€๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์™œ ๊ทธ๋Ÿฐ์ง€ ์ดํ•ด๊ฐ€ ์•ˆ ๋ผ์š”.
http-request ๊ฑฐ๋ถ€ ๊ฑฐ๋ถ€_์ƒํƒœ 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๋กœ ๋‘ ๊ฐœ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปดํ“จํŒ… ๋ฆฌ์†Œ์Šค: "XNUMX๊ฐœ์˜ ๊ธฐ๊ฐ€, XNUMX๊ฐœ์˜ ์ฝ”์–ด, ๊ฒŒ์ด๋ฐ PC"๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์— ๋”ฐ๋ฅด๋ฉด ์œ„ํ‚ค ๋ฐฑ๊ณผ ์ด ์ •๋„๋ฉด ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งํฌ :

HAProxy์—์„œ rdp-gateway ์„ค์ •
๋‚ด๊ฐ€ ์ฐพ์€ ์œ ์ผํ•œ ๊ธฐ์‚ฌ๋Š” ๊ทธ๋“ค์ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ฌด์ฐจ๋ณ„ ๋Œ€์ž…ํ•˜์—ฌ ์‹œ๋„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€