์ธํฐ๋ท์ด ๋งค์ฐ ์ ๋์ ์ธ ํ๊ฒฝ์ด๋ผ๋ ๊ฒ์ ๋น๋ฐ์ด ์๋๋๋ค. ์๋ฒ๋ฅผ ์ฌ๋ฆฌ์๋ง์ ์ฆ์ ๋๊ท๋ชจ ๊ณต๊ฒฉ๊ณผ ์ฌ๋ฌ ์ฐจ๋ก์ ์ค์บ์ ๋ฐ๊ฒ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด
Tarpit์ ๋ค์ด์ค๋ ์ฐ๊ฒฐ ์๋๋ฅผ ๋ฆ์ถ๋ ๋ฐ ์ฌ์ฉ๋๋ ํธ๋ฉ ํฌํธ์ ๋๋ค. ํ์ฌ ์์คํ ์ด ์ด ํฌํธ์ ์ฐ๊ฒฐ๋ ๊ฒฝ์ฐ ์ฐ๊ฒฐ์ ๋น ๋ฅด๊ฒ ์ข ๋ฃํ ์ ์์ต๋๋ค. ์์คํ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๊ณ ์ฐ๊ฒฐ ์๊ฐ์ด ์ด๊ณผ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฑฐ๋ ์๋์ผ๋ก ์ฐ๊ฒฐ์ ์ข ๋ฃํด์ผ ํฉ๋๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฐฉ์ํฌ๋ ๋ณดํธ๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. ์ด ๊ธฐ์ ์ ์ปดํจํฐ ์์ผ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ์ฒ์ ๊ฐ๋ฐ๋์์ต๋๋ค. ์ด์ ์ด๋ ๋ชจ๋ IP ์ฃผ์๋ฅผ ์ฐ์์ ์ผ๋ก ๊ด๋ฒ์ํ๊ฒ ์ค์บ๋ํ๋ ์คํจ๋จธ์ ์ฐ๊ตฌ์์ ์ถ์ ๋ง์น๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค(Habrรฉ์ ์:
Chris Wellons๋ผ๋ ์์คํ
๊ด๋ฆฌ์ ์ค ํ ๋ช
์ ๋ถ๋ช
ํ ์ด ์์น๋ฅผ ์ง์ผ๋ณด๋ ๋ฐ ์ง์ณค์ผ๋ฉฐ ์์ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ต๋๋ค.
์ ํธ๋ฆฌํฐ ์ค์น:
$ make
$ ./endlessh &
$ ssh -p2222 localhost
์ ์ ํ๊ฒ ๊ตฌํ๋ ํํ์ ์ฌ์ฉ์๋ณด๋ค ๊ณต๊ฒฉ์๋ก๋ถํฐ ๋ ๋ง์ ๋ฆฌ์์ค๋ฅผ ์๋ชจํฉ๋๋ค. ํ์ง๋ง ์์์ ๋ฌธ์ ๋ ์๋๋๋ค. ์๊ฐ
์๋ ๋ชจ๋์์๋ ํ๋ฆฌ๊ฑด์ด ํ๊บผ๋ฒ์ ๋ ธํฌํ๋ ์ผ๋ฐ ํฌํธ 22์ Endlessh ์๋ฒ๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค. ํ์ค ๋ณด์ ๊ถ์ฅ ์ฌํญ์ ํญ์ SSH๋ฅผ ๋ค๋ฅธ ํฌํธ๋ก ์ด๋ํ์ฌ ๋ก๊ทธ ํฌ๊ธฐ๋ฅผ ์ฆ์ ์ค์ผ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
Chris Wellons๋ ์์ ์ ํ๋ก๊ทธ๋จ์ด ์ฌ์์ ํ ๋จ๋ฝ์ ํ์ฉํ๋ค๊ณ ๋งํฉ๋๋ค. SSH-
.
์ด๊ฒ์ด ๋ฐ๋ก Endlessh ํ๋ก๊ทธ๋จ์ด ํ๋ ์ผ์
๋๋ค. ๋ณด๋ ๋์ด์๋ ๋ฌด์์๋ก ์์ฑ๋ ๋ฐ์ดํฐ ์คํธ๋ฆผ, RFC 4253์ ์ค์ํฉ๋๋ค. ์ฆ, ์ธ์ฆ ์ ์ ์ ์ก๋๋ฉฐ ๊ฐ ์ค์ ๋ค์์ผ๋ก ์์๋ฉ๋๋ค. SSH-
์ค ๋ ๋ฌธ์๋ฅผ ํฌํจํ์ฌ 255์๋ฅผ ์ด๊ณผํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ด ํ์ค์ ๋ฐ๋ฆ
๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ ํจํท ์ ์ก ์ฌ์ด์ 10์ด๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํด๋ผ์ด์ธํธ๊ฐ ์๊ฐ ์ด๊ณผ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ผ๋ฏ๋ก ํด๋ผ์ด์ธํธ๊ฐ ์์ํ ๊ฐํ๊ฒ ๋ฉ๋๋ค.
์ํธํ๊ฐ ์ ์ฉ๋๊ธฐ ์ ์ ๋ฐ์ดํฐ๊ฐ ์ ์ก๋๋ฏ๋ก ํ๋ก๊ทธ๋จ์ด ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์ํธ๋ฅผ ๊ตฌํํ ํ์๊ฐ ์์ผ๋ฉฐ ์ฌ๋ฌ ํ๋กํ ์ฝ์ ์ง์ํฉ๋๋ค.
์์ฑ์๋ ์ ํธ๋ฆฌํฐ๊ฐ ์ต์ํ์ ๋ฆฌ์์ค๋ฅผ ์๋นํ๊ณ ์์คํ ์์ ์์ ํ ๋์ ๋์ง ์๊ฒ ์๋ํ๋๋ก ๋ ธ๋ ฅํ์ต๋๋ค. ์ต์ ๋ฐ์ด๋ฌ์ค ๋ฐฑ์ ๋ฐ ๊ธฐํ "๋ณด์ ์์คํ "๊ณผ ๋ฌ๋ฆฌ ์ปดํจํฐ ์๋๊ฐ ๋๋ ค์ง์ง ์์ต๋๋ค. ๊ทธ๋ ์ฝ๊ฐ ๋ ๊ต๋ฌํ ์ํํธ์จ์ด ๊ตฌํ์ผ๋ก ์ธํด ํธ๋ํฝ๊ณผ ๋ฉ๋ชจ๋ฆฌ ์๋น๋ฅผ ๋ชจ๋ ์ต์ํํ์ต๋๋ค. ๋จ์ํ ์ ์ฐ๊ฒฐ์์ ๋ณ๋์ ํ๋ก์ธ์ค๋ฅผ ์์ํ๋ ๊ฒฝ์ฐ ์ ์ฌ์ ์ธ ๊ณต๊ฒฉ์๋ ์ฌ๋ฌ ์ฐ๊ฒฐ์ ์ด์ด ์์คํ ์ ๋ฆฌ์์ค๋ฅผ ์์ง์์ผ DDoS ๊ณต๊ฒฉ์ ์์ํ ์ ์์ต๋๋ค. ์ฐ๊ฒฐ๋น ํ๋์ ์ค๋ ๋๋ ์ต์ ์ ์ ํ์ด ์๋๋๋ค. ์ปค๋์ด ์ค๋ ๋๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๊ฒ์ด ๋ฐ๋ก Chris Wellons๊ฐ Endlessh๋ฅผ ์ํด ๊ฐ์ฅ ๊ฐ๋ฒผ์ด ์ต์
์ธ ๋จ์ผ ์ค๋ ๋ ์๋ฒ๋ฅผ ์ ํํ ์ด์ ์
๋๋ค. poll(2)
์ฌ๊ธฐ์ ํธ๋ฉ์ ํด๋ผ์ด์ธํธ๋ ์ปค๋์ ์์ผ ๊ฐ์ฒด์ Endlessh์์ ์ถ์ ํ๊ธฐ ์ํ ์ถ๊ฐ 78๋ฐ์ดํธ๋ฅผ ๊ณ์ฐํ์ง ์๊ณ ์ฌ์ค์ ์ถ๊ฐ ๋ฆฌ์์ค๋ฅผ ์๋นํ์ง ์์ต๋๋ค. ๊ฐ ํด๋ผ์ด์ธํธ์ ๋ํด ์์ ๋ฐ ์ก์ ๋ฒํผ๋ฅผ ํ ๋นํ ํ์๊ฐ ์๋๋ก Endlessh๋ ์ง์ ์ก์ธ์ค ์์ผ์ ์ด๊ณ ๊ฑฐ์ ์ ์ฒด ์ด์ ์ฒด์ TCP/IP ์คํ์ ์ฐํํ์ฌ TCP ํจํท์ ์ง์ ๋ณํํฉ๋๋ค. ๋ค์ด์ค๋ ๋ฐ์ดํฐ์ ๊ด์ฌ์ด ์๊ธฐ ๋๋ฌธ์ ๋ค์ด์ค๋ ๋ฒํผ๋ ์ ํ ํ์ํ์ง ์์ต๋๋ค.
์ ์๋ ํ๋ก๊ทธ๋จ ๋น์์ ์ด๋ ๊ฒ ๋งํ์ต๋๋ค.
import asyncio
import random
async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass
async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()
asyncio.run(main())
Asyncio๋ ํํ ์์ฑ์ ์ด์์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ์ด ํํฌ๋ Firefox, Chrome ๋๋ HTTP ์๋ฒ์ ์ฐ๊ฒฐ์ ์๋ํ๋ ๊ธฐํ ํด๋ผ์ด์ธํธ๋ฅผ ๋ช ์๊ฐ ๋์ ์ ์ง์ํต๋๋ค.
import asyncio
import random
async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass
async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()
asyncio.run(main())
Tarpit์ ์จ๋ผ์ธ ๊ดด๋กญํ์ ์ฒ๋ฒํ๋ ํ๋ฅญํ ๋๊ตฌ์
๋๋ค. ์ฌ์ค, ๋ฐ๋๋ก ํน์ ์๋ฒ์ ๋น์ ์์ ์ธ ๋์์ ์ฃผ์๋ฅผ ๋ ์ํ์ด ์์ต๋๋ค. ์ด๋ค ์ฌ๋
ํ๋ธ:
Python, ์ ๋ณด๋ณด์, ์ํํธ์จ์ด, ์์คํ
๊ด๋ฆฌ
ํ๊ทธ :
SSH, Endlessh, ํ๋ฅดํ, ํ๋ฅดํ, ํธ๋ฉ, ์์์์ค
๋ค์ด์ค๋ SSH ์ฐ๊ฒฐ์ ์ํ ํธ๋ฉ(ํ๋ฅดํ)
์ธํฐ๋ท์ด ๋งค์ฐ ์ ๋์ ์ธ ํ๊ฒฝ์ด๋ผ๋ ๊ฒ์ ๋น๋ฐ์ด ์๋๋๋ค. ์๋ฒ๋ฅผ ์ฌ๋ฆฌ์๋ง์ ์ฆ์ ๋๊ท๋ชจ ๊ณต๊ฒฉ๊ณผ ์ฌ๋ฌ ์ฐจ๋ก์ ์ค์บ์ ๋ฐ๊ฒ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด
Tarpit์ ๋ค์ด์ค๋ ์ฐ๊ฒฐ ์๋๋ฅผ ๋ฆ์ถ๋ ๋ฐ ์ฌ์ฉ๋๋ ํธ๋ฉ ํฌํธ์ ๋๋ค. ํ์ฌ ์์คํ ์ด ์ด ํฌํธ์ ์ฐ๊ฒฐ๋ ๊ฒฝ์ฐ ์ฐ๊ฒฐ์ ๋น ๋ฅด๊ฒ ์ข ๋ฃํ ์ ์์ต๋๋ค. ์์คํ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๊ณ ์ฐ๊ฒฐ ์๊ฐ์ด ์ด๊ณผ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฑฐ๋ ์๋์ผ๋ก ์ฐ๊ฒฐ์ ์ข ๋ฃํด์ผ ํฉ๋๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฐฉ์ํฌ๋ ๋ณดํธ๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. ์ด ๊ธฐ์ ์ ์ปดํจํฐ ์์ผ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ์ฒ์ ๊ฐ๋ฐ๋์์ต๋๋ค. ์ด์ ์ด๋ ๋ชจ๋ IP ์ฃผ์๋ฅผ ์ฐ์์ ์ผ๋ก ๊ด๋ฒ์ํ๊ฒ ์ค์บ๋ํ๋ ์คํจ๋จธ์ ์ฐ๊ตฌ์์ ์ถ์ ๋ง์น๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค(Habrรฉ์ ์:
Chris Wellons๋ผ๋ ์์คํ
๊ด๋ฆฌ์ ์ค ํ ๋ช
์ ๋ถ๋ช
ํ ์ด ์์น๋ฅผ ์ง์ผ๋ณด๋ ๋ฐ ์ง์ณค์ผ๋ฉฐ ์์ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ต๋๋ค.
์ ํธ๋ฆฌํฐ ์ค์น:
$ make
$ ./endlessh &
$ ssh -p2222 localhost
์ ์ ํ๊ฒ ๊ตฌํ๋ ํํ์ ์ฌ์ฉ์๋ณด๋ค ๊ณต๊ฒฉ์๋ก๋ถํฐ ๋ ๋ง์ ๋ฆฌ์์ค๋ฅผ ์๋ชจํฉ๋๋ค. ํ์ง๋ง ์์์ ๋ฌธ์ ๋ ์๋๋๋ค. ์๊ฐ
์๋ ๋ชจ๋์์๋ ํ๋ฆฌ๊ฑด์ด ํ๊บผ๋ฒ์ ๋ ธํฌํ๋ ์ผ๋ฐ ํฌํธ 22์ Endlessh ์๋ฒ๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค. ํ์ค ๋ณด์ ๊ถ์ฅ ์ฌํญ์ ํญ์ SSH๋ฅผ ๋ค๋ฅธ ํฌํธ๋ก ์ด๋ํ์ฌ ๋ก๊ทธ ํฌ๊ธฐ๋ฅผ ์ฆ์ ์ค์ผ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
Chris Wellons๋ ์์ ์ ํ๋ก๊ทธ๋จ์ด ์ฌ์์ ํ ๋จ๋ฝ์ ํ์ฉํ๋ค๊ณ ๋งํฉ๋๋ค. SSH-
.
์ด๊ฒ์ด ๋ฐ๋ก Endlessh ํ๋ก๊ทธ๋จ์ด ํ๋ ์ผ์
๋๋ค. ๋ณด๋ ๋์ด์๋ ๋ฌด์์๋ก ์์ฑ๋ ๋ฐ์ดํฐ ์คํธ๋ฆผ, RFC 4253์ ์ค์ํฉ๋๋ค. ์ฆ, ์ธ์ฆ ์ ์ ์ ์ก๋๋ฉฐ ๊ฐ ์ค์ ๋ค์์ผ๋ก ์์๋ฉ๋๋ค. SSH-
์ค ๋ ๋ฌธ์๋ฅผ ํฌํจํ์ฌ 255์๋ฅผ ์ด๊ณผํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ด ํ์ค์ ๋ฐ๋ฆ
๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ ํจํท ์ ์ก ์ฌ์ด์ 10์ด๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํด๋ผ์ด์ธํธ๊ฐ ์๊ฐ ์ด๊ณผ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ผ๋ฏ๋ก ํด๋ผ์ด์ธํธ๊ฐ ์์ํ ๊ฐํ๊ฒ ๋ฉ๋๋ค.
์ํธํ๊ฐ ์ ์ฉ๋๊ธฐ ์ ์ ๋ฐ์ดํฐ๊ฐ ์ ์ก๋๋ฏ๋ก ํ๋ก๊ทธ๋จ์ด ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์ํธ๋ฅผ ๊ตฌํํ ํ์๊ฐ ์์ผ๋ฉฐ ์ฌ๋ฌ ํ๋กํ ์ฝ์ ์ง์ํฉ๋๋ค.
์์ฑ์๋ ์ ํธ๋ฆฌํฐ๊ฐ ์ต์ํ์ ๋ฆฌ์์ค๋ฅผ ์๋นํ๊ณ ์์คํ ์์ ์์ ํ ๋์ ๋์ง ์๊ฒ ์๋ํ๋๋ก ๋ ธ๋ ฅํ์ต๋๋ค. ์ต์ ๋ฐ์ด๋ฌ์ค ๋ฐฑ์ ๋ฐ ๊ธฐํ "๋ณด์ ์์คํ "๊ณผ ๋ฌ๋ฆฌ ์ปดํจํฐ ์๋๊ฐ ๋๋ ค์ง์ง ์์ต๋๋ค. ๊ทธ๋ ์ฝ๊ฐ ๋ ๊ต๋ฌํ ์ํํธ์จ์ด ๊ตฌํ์ผ๋ก ์ธํด ํธ๋ํฝ๊ณผ ๋ฉ๋ชจ๋ฆฌ ์๋น๋ฅผ ๋ชจ๋ ์ต์ํํ์ต๋๋ค. ๋จ์ํ ์ ์ฐ๊ฒฐ์์ ๋ณ๋์ ํ๋ก์ธ์ค๋ฅผ ์์ํ๋ ๊ฒฝ์ฐ ์ ์ฌ์ ์ธ ๊ณต๊ฒฉ์๋ ์ฌ๋ฌ ์ฐ๊ฒฐ์ ์ด์ด ์์คํ ์ ๋ฆฌ์์ค๋ฅผ ์์ง์์ผ DDoS ๊ณต๊ฒฉ์ ์์ํ ์ ์์ต๋๋ค. ์ฐ๊ฒฐ๋น ํ๋์ ์ค๋ ๋๋ ์ต์ ์ ์ ํ์ด ์๋๋๋ค. ์ปค๋์ด ์ค๋ ๋๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๊ฒ์ด ๋ฐ๋ก Chris Wellons๊ฐ Endlessh๋ฅผ ์ํด ๊ฐ์ฅ ๊ฐ๋ฒผ์ด ์ต์
์ธ ๋จ์ผ ์ค๋ ๋ ์๋ฒ๋ฅผ ์ ํํ ์ด์ ์
๋๋ค. poll(2)
์ฌ๊ธฐ์ ํธ๋ฉ์ ํด๋ผ์ด์ธํธ๋ ์ปค๋์ ์์ผ ๊ฐ์ฒด์ Endlessh์์ ์ถ์ ํ๊ธฐ ์ํ ์ถ๊ฐ 78๋ฐ์ดํธ๋ฅผ ๊ณ์ฐํ์ง ์๊ณ ์ฌ์ค์ ์ถ๊ฐ ๋ฆฌ์์ค๋ฅผ ์๋นํ์ง ์์ต๋๋ค. ๊ฐ ํด๋ผ์ด์ธํธ์ ๋ํด ์์ ๋ฐ ์ก์ ๋ฒํผ๋ฅผ ํ ๋นํ ํ์๊ฐ ์๋๋ก Endlessh๋ ์ง์ ์ก์ธ์ค ์์ผ์ ์ด๊ณ ๊ฑฐ์ ์ ์ฒด ์ด์ ์ฒด์ TCP/IP ์คํ์ ์ฐํํ์ฌ TCP ํจํท์ ์ง์ ๋ณํํฉ๋๋ค. ๋ค์ด์ค๋ ๋ฐ์ดํฐ์ ๊ด์ฌ์ด ์๊ธฐ ๋๋ฌธ์ ๋ค์ด์ค๋ ๋ฒํผ๋ ์ ํ ํ์ํ์ง ์์ต๋๋ค.
์ ์๋ ํ๋ก๊ทธ๋จ ๋น์์ ์ด๋ ๊ฒ ๋งํ์ต๋๋ค.
import asyncio
import random
async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass
async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()
asyncio.run(main())
Asyncio๋ ํํ ์์ฑ์ ์ด์์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ์ด ํํฌ๋ Firefox, Chrome ๋๋ HTTP ์๋ฒ์ ์ฐ๊ฒฐ์ ์๋ํ๋ ๊ธฐํ ํด๋ผ์ด์ธํธ๋ฅผ ๋ช ์๊ฐ ๋์ ์ ์ง์ํต๋๋ค.
import asyncio
import random
async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass
async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()
asyncio.run(main())
Tarpit์ ์จ๋ผ์ธ ๊ดด๋กญํ์ ์ฒ๋ฒํ๋ ํ๋ฅญํ ๋๊ตฌ์
๋๋ค. ์ฌ์ค, ๋ฐ๋๋ก ํน์ ์๋ฒ์ ๋น์ ์์ ์ธ ๋์์ ์ฃผ์๋ฅผ ๋ ์ํ์ด ์์ต๋๋ค. ์ด๋ค ์ฌ๋
์ถ์ฒ : habr.com