์กฐ์ง์ ํน์ ์๋ฒ์ ์ก์ธ์คํด์ผ ํ๋ ์ฌ๋์ด ์ฌ์ฉ์์ธ์ง ํํธ๋์ธ์ง์ ๊ด๊ณ์์ด ๊ธฐ์ ํ๊ฒฝ์ ๋ํ ์๊ฒฉ ์ก์ธ์ค๋ฅผ ์ ๊ณตํด์ผ ํ๋ ํ์์ฑ์ด ์ ์ ๋ ์์ฃผ ๋๋๋๊ณ ์์ต๋๋ค.
์ด๋ฌํ ๋ชฉ์ ์ ์ํด ๋๋ถ๋ถ์ ํ์ฌ๋ ์กฐ์ง์ ๋ก์ปฌ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ์ ๊ณตํ๋ ์์ ์ ์ผ๋ก ๋ณดํธ๋๋ ๋ฐฉ๋ฒ์์ด ์ ์ฆ๋ VPN ๊ธฐ์ ์ ์ฌ์ฉํฉ๋๋ค.
์ฐ๋ฆฌ ํ์ฌ๋ ์์ธ๋ ์๋์๊ณ ๋ค๋ฅธ ๋ง์ ํ์ฌ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฐ๋ฆฌ๋ ์ด ๊ธฐ์ ์ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๋ง์ ์ฌ๋๋ค๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก Cisco ASA 55xx๋ฅผ ์๊ฒฉ ์ก์ธ์ค ๊ฒ์ดํธ์จ์ด๋ก ์ฌ์ฉํฉ๋๋ค.
์๊ฒฉ ์ฌ์ฉ์ ์๊ฐ ์ฆ๊ฐํจ์ ๋ฐ๋ผ ์๊ฒฉ์ฆ๋ช ๋ฐ๊ธ ์ ์ฐจ๋ฅผ ๋จ์ํํ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋์์ ์ด๋ ์์ ์ ์นจํดํ์ง ์๊ณ ์ํ๋์ด์ผ ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ์ผํ์ฉ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํ์ฌ Cisco SSL VPN์ ํตํด ์ฐ๊ฒฐํ๊ธฐ ์ํด ์ด์ค ์ธ์ฆ์ ์ฌ์ฉํ๋ ์๋ฃจ์ ์ ์ฐพ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ์ถํ๋ฌผ์์๋ ํ์ํ ์ํํธ์จ์ด์ ๋ํด ์ต์ํ์ ์๊ฐ๊ณผ ๋น์ฉ์ผ๋ก ์ด๋ฌํ ์๋ฃจ์ ์ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค๋๋ค(์ธํ๋ผ์ ์ด๋ฏธ Cisco ASA๊ฐ ์๋ ๊ฒฝ์ฐ).
์์ฅ์๋ ์ผํ์ฑ ๋น๋ฐ๋ฒํธ๋ฅผ ์์ฑํ๊ธฐ ์ํ ๋ฐ์คํ ์๋ฃจ์
์ด ํ๋ถํ๋ฉฐ, SMS๋ฅผ ํตํด ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณด๋ด๊ฑฐ๋ ํ๋์จ์ด์ ์ํํธ์จ์ด(์: ํด๋ํฐ) ๋ชจ๋์์ ํ ํฐ์ ์ฌ์ฉํ๋ ๋ฑ ๋น๋ฐ๋ฒํธ๋ฅผ ์ป๊ธฐ ์ํ ๋ค์ํ ์ต์
์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ํ์ฌ์ ์๊ธฐ ์ํฉ์์ ๋์ ์ ์ฝํ๊ณ ๊ณ ์ฉ์ฃผ๋ฅผ ์ํด ๋์ ์ ์ฝํ๋ ค๋ ์๊ตฌ๋ก ์ธํด ์ผํ์ฉ ์ํธ ์์ฑ ์๋น์ค๋ฅผ ๋ฌด๋ฃ๋ก ๊ตฌํํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ฐพ๊ฒ ๋์์ต๋๋ค. ๋ฌด๋ฃ์ด์ง๋ง ์์
์ฉ ์๋ฃจ์
๋ณด๋ค ์ด๋ฑํ์ง ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ์ด ์ ํ์๋ ์์
์ฉ ๋ฒ์ ์ด ์๋ค๋ ์ ์ ์ฐธ๊ณ ํ์ฌ ์์ฝํด์ผ ํ์ง๋ง ๊ธ์ ์ ๋น์ฉ์ XNUMX์ด ๋ ๊ฒ์ด๋ผ๋ ๋ฐ ๋์ํ์ต๋๋ค.
๋ฐ๋ผ์ ๋ค์์ด ํ์ํฉ๋๋ค.
- ์น์ ํตํด ์๋ฒ์ ์ก์ธ์คํ๊ธฐ ์ํ ๋๊ตฌ ์ธํธ๊ฐ ๋ด์ฅ๋ Linux ์ด๋ฏธ์ง(multiOTP, FreeRADIUS ๋ฐ nginx)(http://download.multiotp.net/ - VMware์ฉ์ผ๋ก ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ง ์ด๋ฏธ์ง ์ฌ์ฉ)
โ ์กํฐ๋ธ ๋๋ ํ ๋ฆฌ ์๋ฒ
โ Cisco ASA ์์ฒด(ํธ์์ ASDM์ ์ฌ์ฉํฉ๋๋ค)
โ TOTP ๋ฉ์ปค๋์ฆ์ ์ง์ํ๋ ๋ชจ๋ ์ํํธ์จ์ด ํ ํฐ(์๋ฅผ ๋ค์ด ์ ๋ Google Authenticator๋ฅผ ์ฌ์ฉํ์ง๋ง ๋์ผํ FreeOTP๋ ์ฌ์ฉํฉ๋๋ค)
์ด๋ฏธ์ง๊ฐ ์ด๋ป๊ฒ ์ ๊ฐ๋๋์ง ์์ธํ ์ค๋ช ํ์ง ์๊ฒ ์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก, ์ด๋ฏธ multiOTP์ FreeRADIUS๊ฐ ์ค์น๋์ด ํจ๊ป ์๋ํ๋๋ก ๊ตฌ์ฑ๋ Debian Linux์ OTP ๊ด๋ฆฌ๋ฅผ ์ํ ์น ์ธํฐํ์ด์ค๊ฐ ์ ๊ณต๋ฉ๋๋ค.
1๋จ๊ณ. ์์คํ
์ ์์ํ๊ณ ๋คํธ์ํฌ์ ๋ง๊ฒ ๊ตฌ์ฑํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์์คํ
์๋ ๋ฃจํธ ๋ฃจํธ ์๊ฒฉ ์ฆ๋ช
์ด ์ ๊ณต๋ฉ๋๋ค. ์ฒ์ ๋ก๊ทธ์ธํ ํ ๋ฃจํธ ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์ข์ ๊ฒ์ด๋ผ๊ณ ๋ค๋ค ์ง์ํ์
จ์ ๊ฒ์
๋๋ค. ๋ํ ๋คํธ์ํฌ ์ค์ ์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค(๊ธฐ๋ณธ์ ์ผ๋ก ๊ฒ์ดํธ์จ์ด๋ '192.168.1.44'์ด๊ณ '192.168.1.1'์
๋๋ค). ๊ทธ๋ฐ ๋ค์ ์์คํ
์ ์ฌ๋ถํ
ํ ์ ์์ต๋๋ค.
Active Directory์์ ์ฌ์ฉ์๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค. otp, ๋น๋ฐ๋ฒํธ ํฌํจ ๋์์ํผ๋น๋ฐ๋ฒํธ.
2๋จ๊ณ. ์ฐ๊ฒฐ ์ค์ ๋ฐ Active Directory ์ฌ์ฉ์ ๊ฐ์ ธ์ค๊ธฐ
์ด๋ ๊ฒ ํ๋ ค๋ฉด ์ฝ์์ ์ก์ธ์คํ๊ณ ํ์ผ์ ์ง์ ์ก์ธ์คํด์ผ ํฉ๋๋ค. multiotp.php, ์ด๋ฅผ ์ฌ์ฉํ์ฌ Active Directory์ ๋ํ ์ฐ๊ฒฐ ์ค์ ์ ๊ตฌ์ฑํฉ๋๋ค.
๋๋ ํ ๋ฆฌ๋ก ์ด๋ /usr/local/bin/multiotp/ ๋ค์ ๋ช ๋ น์ ์ฐจ๋ก๋ก ์คํํฉ๋๋ค.
./multiotp.php -config default-request-prefix-pin=0
์ผํ์ฑ ํ(0 ๋๋ 1)์ ์ ๋ ฅํ ๋ ์ถ๊ฐ(์๊ตฌ) ํ์ด ํ์ํ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
./multiotp.php -config default-request-ldap-pwd=0
์ผํ์ฉ PIN(0 ๋๋ 1)์ ์ ๋ ฅํ ๋ ๋๋ฉ์ธ ๋น๋ฐ๋ฒํธ๊ฐ ํ์ํ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
./multiotp.php -config ldap-server-type=1
LDAP ์๋ฒ ์ ํ์ด ํ์๋ฉ๋๋ค(0 = ์ผ๋ฐ LDAP ์๋ฒ, ์ด ๊ฒฝ์ฐ 1 = Active Directory).
./multiotp.php -config ldap-cn-identifier="sAMAccountName"
์ฌ์ฉ์ ์ด๋ฆ์ ํ์ํ ํ์์ ์ง์ ํฉ๋๋ค(์ด ๊ฐ์ ๋๋ฉ์ธ ์์ด ์ด๋ฆ๋ง ํ์ํฉ๋๋ค).
./multiotp.php -config ldap-group-cn-identifier="sAMAccountName"
๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ๊ทธ๋ฃน์๋ง ํด๋น๋ฉ๋๋ค.
./multiotp.php -config ldap-group-attribute="memberOf"
์ฌ์ฉ์๊ฐ ๊ทธ๋ฃน์ ์ํ๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๋ฐฉ๋ฒ์ ์ง์ ํฉ๋๋ค.
./multiotp.php -config ldap-ssl=1
LDAP ์๋ฒ์ ๋ํ ๋ณด์ ์ฐ๊ฒฐ์ ์ฌ์ฉํด์ผ ํ ๊น์(๋ฌผ๋ก ๊ทธ๋ ์ต๋๋ค!)
./multiotp.php -config ldap-port=636
LDAP ์๋ฒ ์ฐ๊ฒฐ์ฉ ํฌํธ
./multiotp.php -config ldap-domain-controllers=adSRV.domain.local
Active Directory ์๋ฒ ์ฃผ์
./multiotp.php -config ldap-base-dn="CN=Users,DC=domain,DC=local"
๋๋ฉ์ธ์์ ์ฌ์ฉ์ ๊ฒ์์ ์์ํ ์์น๋ฅผ ๋ํ๋ ๋๋ค.
./multiotp.php -config ldap-bind-dn="[email protected]"
Active Directory์์ ๊ฒ์ ๊ถํ์ด ์๋ ์ฌ์ฉ์๋ฅผ ์ง์ ํฉ๋๋ค.
./multiotp.php -config ldap-server-password="MySuperPassword"
Active Directory์ ์ฐ๊ฒฐํ๊ธฐ ์ํ ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ง์ ํ์ธ์.
./multiotp.php -config ldap-network-timeout=10
Active Directory ์ฐ๊ฒฐ ์๊ฐ ์ด๊ณผ ์ค์
./multiotp.php -config ldap-time-limit=30
์ฌ์ฉ์ ๊ฐ์ ธ์ค๊ธฐ ์์ ์ ๋ํ ์๊ฐ ์ ํ์ ์ค์ ํ์ต๋๋ค.
./multiotp.php -config ldap-activated=1
Active Directory ์ฐ๊ฒฐ ๊ตฌ์ฑ ํ์ฑํ
./multiotp.php -debug -display-log -ldap-users-sync
Active Directory์์ ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
3๋จ๊ณ. ํ ํฐ์ฉ QR ์ฝ๋ ์์ฑ
์ฌ๊ธฐ์ ๋ชจ๋ ๊ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ์์ OTP ์๋ฒ์ ์น ์ธํฐํ์ด์ค๋ฅผ ์ด๊ณ ๋ก๊ทธ์ธํ ํ(๊ด๋ฆฌ์์ ๊ธฐ๋ณธ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์์ง ๋ง์ธ์!) "์ธ์" ๋ฒํผ์ ํด๋ฆญํ์ธ์.
์ด ์์
์ ๊ฒฐ๊ณผ๋ ๋ ๊ฐ์ QR ์ฝ๋๊ฐ ํฌํจ๋ ํ์ด์ง๊ฐ ๋ฉ๋๋ค. ์ฐ๋ฆฌ๋ ๊ทธ ์ค ์ฒซ ๋ฒ์งธ ์ฝ๋๋ฅผ ๋๋ดํ๊ฒ ๋ฌด์ํ๊ณ (Google Authenticator / Authenticator / 2 Steps Authenticator๋ผ๋ ๋งค๋ ฅ์ ์ธ ๋น๋ฌธ์๋ ๋ถ๊ตฌํ๊ณ ) ๋ค์ ๋๋ดํ๊ฒ ๋ ๋ฒ์งธ ์ฝ๋๋ฅผ ์ ํ์ ์ํํธ์จ์ด ํ ํฐ์ผ๋ก ์ค์บํฉ๋๋ค.
(์, QR ์ฝ๋๋ฅผ ์ฝ์ ์ ์๋๋ก ์๋์ ์ผ๋ก ์์์์ผฐ์ต๋๋ค.)
์ด๋ฌํ ์์ ์ ์๋ฃํ๋ฉด XNUMX์ด๋ง๋ค ์ ํ๋ฆฌ์ผ์ด์ ์์ XNUMX์๋ฆฌ ๋น๋ฐ๋ฒํธ๊ฐ ์์ฑ๋๊ธฐ ์์ํฉ๋๋ค.
ํ์คํ ํ๋ ค๋ฉด ๋์ผํ ์ธํฐํ์ด์ค์์ ํ์ธํ ์ ์์ต๋๋ค.
ํด๋ํฐ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์๋ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ์ผํ์ฉ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ๋ฉด ๋ฉ๋๋ค. ๊ธ์ ์ ์ธ ๋ต๋ณ์ ๋ฐ์๋์? ๊ทธ๋ผ ๊ณ์ ์งํํ๊ฒ ์ต๋๋ค.
4๋จ๊ณ. FreeRADIUS ์๋์ ์ถ๊ฐ ๊ตฌ์ฑ ๋ฐ ํ
์คํธ
์์์ ์ธ๊ธํ๋ฏ์ด multiOTP๋ ์ด๋ฏธ FreeRADIUS์ ์๋ํ๋๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฏ๋ก ํ
์คํธ๋ฅผ ์คํํ๊ณ VPN ๊ฒ์ดํธ์จ์ด์ ๋ํ ์ ๋ณด๋ฅผ FreeRADIUS ๊ตฌ์ฑ ํ์ผ์ ์ถ๊ฐํ๋ ๊ฒ๋ง ๋จ์์ต๋๋ค.
์๋ฒ ์ฝ์์ ๋๋ ํ ๋ฆฌ๋ก ๋์๊ฐ๋๋ค. /usr/local/bin/multiotp/, ์ ๋ ฅํ๋ค:
./multiotp.php -config debug=1
./multiotp.php -config display-log=1
๋ ์์ธํ ๋ก๊น ์ ํฌํจํฉ๋๋ค.
FreeRADIUS ํด๋ผ์ด์ธํธ ๊ตฌ์ฑ ํ์ผ(/etc/freeradius/clinets.conf) ๋ค์๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ์ค์ ์ฃผ์ ์ฒ๋ฆฌํฉ๋๋ค. ๋ก์ปฌ ํธ์คํธ ๋ ๊ฐ์ ํญ๋ชฉ์ ์ถ๊ฐํฉ๋๋ค.
client localhost {
ipaddr = 127.0.0.1
secret = testing321
require_message_authenticator = no
}
- ํ ์คํธ์ฉ
client 192.168.1.254/32 {
shortname = CiscoASA
secret = ConnectToRADIUSSecret
}
โ VPN ๊ฒ์ดํธ์จ์ด์ ๊ฒฝ์ฐ.
FreeRADIUS๋ฅผ ๋ค์ ์์ํ๊ณ ๋ก๊ทธ์ธ์ ์๋ํฉ๋๋ค.
radtest username 100110 localhost 1812 testing321
์ด๋์์ ์ฌ์ฉ์ ์ด๋ฆ = ์ฌ์ฉ์ ์ด๋ฆ, 100110 = ์ ํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ๊ณตํ ๋น๋ฐ๋ฒํธ, ๋ก์ปฌ ํธ์คํธ = RADIUS ์๋ฒ ์ฃผ์, 1812 โ RADIUS ์๋ฒ ํฌํธ, testing321 โ RADIUS ์๋ฒ ํด๋ผ์ด์ธํธ ๋น๋ฐ๋ฒํธ(๊ตฌ์ฑ์์ ์ง์ ).
์ด ๋ช ๋ น์ ๊ฒฐ๊ณผ๋ ๋๋ต ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค.
Sending Access-Request of id 44 to 127.0.0.1 port 1812
User-Name = "username"
User-Password = "100110"
NAS-IP-Address = 127.0.1.1
NAS-Port = 1812
Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=44, length=20
์ด์ ์ฌ์ฉ์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ธ์ฆ๋์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํด multiotp ์์ฒด์ ๋ก๊ทธ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
tail /var/log/multiotp/multiotp.log
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง ํญ๋ชฉ์ด ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ:
2016-09-01 08:58:17 notice username User OK: User username successfully logged in from 127.0.0.1
2016-09-01 08:58:17 debug Debug Debug: 0 OK: Token accepted from 127.0.0.1
๊ทธ๋ฌ๋ฉด ๋ชจ๋ ๊ฒ์ด ์์กฐ๋กญ๊ฒ ์งํ๋์ด ์๋ฃํ ์ ์์ต๋๋ค.
5๋จ๊ณ: Cisco ASA ๊ตฌ์ฑ
Active Directory์ ํจ๊ป ๊ตฌ์ฑ๋ SLL VPN์ ํตํ ์ก์ธ์ค๋ฅผ ์ํ ๊ทธ๋ฃน ๋ฐ ์ ์ฑ
์ด ์ด๋ฏธ ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ ์ด ํ๋กํ์ ๋ํ XNUMX๋จ๊ณ ์ธ์ฆ์ ์ถ๊ฐํด์ผ ํ๋ค๋ ์ ์ ๋์ํ๊ฒ ์ต๋๋ค.
1. ์ AAA ์๋ฒ ๊ทธ๋ฃน์ ์ถ๊ฐํฉ๋๋ค.
2. ๋ฉํฐOTP ์๋ฒ๋ฅผ ๊ทธ๋ฃน์ ์ถ๊ฐํฉ๋๋ค:
3. ํธ์งํ๋ค ์ฐ๊ฒฐ ํ๋กํ, Active Directory ์๋ฒ ๊ทธ๋ฃน์ ๊ธฐ๋ณธ ์ธ์ฆ ์๋ฒ๋ก ์ค์ :
4. ํญ ๊ณ ๊ธ -> ์ธ์ฆ ๋ํ Active Directory ์๋ฒ ๊ทธ๋ฃน์ ์ ํํฉ๋๋ค.
5. ํญ ๊ณ ๊ธ -> ๋ณด์กฐ ์ธ์ฆ์ ์ํด์๋ ํด๋น ๋ฉํฐOTP ์๋ฒ๊ฐ ๋ฑ๋ก๋์ด ์๋ ์์ฑ๋ ์๋ฒ ๊ทธ๋ฃน์ ์ ํํ์ธ์. ์ธ์
์ฌ์ฉ์ ์ด๋ฆ์ ๊ธฐ๋ณธ AAA ์๋ฒ ๊ทธ๋ฃน์์ ์์๋ฉ๋๋ค.
์ค์ ์ ์ ์ฉํ๊ณ
6๋จ๊ณ, ๋ง์ง๋ง ๋จ๊ณ๋ผ๊ณ ๋ ํจ
SLL VPN์ ๋ํด XNUMX๋จ๊ณ ์ธ์ฆ์ด ์๋ํ๋์ง ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
์ง์! Cisco AnyConnect VPN ํด๋ผ์ด์ธํธ๋ฅผ ํตํด ์ฐ๊ฒฐํ ๋ ๋ ๋ฒ์งธ ์ผํ์ฉ ๋น๋ฐ๋ฒํธ๋ ์
๋ ฅํ๋ผ๋ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
์ด ๊ธ์ด ๋๊ตฐ๊ฐ์๊ฒ ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ, ๋๊ตฐ๊ฐ์๊ฒ ์ด ๊ธ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์๊ฐํ ๊ฑฐ๋ฆฌ๋ฅผ ์ค ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๋ฌด๋ฃ ๊ธฐํ ์์
์ ์ํ OTP ์๋ฒ. ์ํ์๋ฉด ๋๊ธ๋ก ๊ณต์ ํด์ฃผ์ธ์.
์ถ์ฒ : habr.com