Skip to content

์•ˆ๋…•ํ•˜์„ธ์š” Mambo ์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋ฅผ ํ™œ์šฉํ•œ TLS ์˜คํ”„๋กœ๋“œ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ์ง€๋‚œ SSL ์ธ์ฆ์„œ์—์„œ๋Š” HTTPS๋ฅผ ์›น ์„œ๋น„์Šค์— ์ ์šฉํ•˜๋Š” ์ด์œ ์™€ ํ•จ๊ป˜ SSL ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰ํ•˜๊ณ  TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์•„๋งˆ์กด ์›น ์„œ๋น„์Šค์˜ ELB(Elastic Load Balancing)์—์„œ ์ง€์›ํ•˜๋Š” TLS ํ•ธ๋“œ์‰์ดํฌ ๋ฐ TLS ์˜คํ”„๋กœ๋”ฉ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ์ฐธ๊ณ ํ•ด์•ผํ•  ์ •๋ณด๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

SSL ์˜คํ”„๋กœ๋“œ โ€‹

TLS(SSL) ์˜คํ”„๋กœ๋“œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ  ํŠธ๋ž˜ํ”ฝ์ด ์ „๋‹ฌ๋˜๊ธฐ ์ „ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์—์„œ SSL ์ธ์ฆ์„œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์›น ์„œ๋น„์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์šด์šฉํ•˜์ง€ ์•Š๊ณ  ํŠธ๋ž˜ํ”ฝ ๊ทœ๋ชจ์— ๋”ฐ๋ผ ์œ ์—ฐํ•˜๊ฒŒ ํ™•์žฅํ•˜๊ณ  ํ™•์žฅ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์— ํŠธ๋ž˜ํ”ฝ์„ ๊ท ๋“ฑํ•˜๊ฒŒ ๋ถ„์‚ฐ์‹œํ‚ค๊ธฐ ์œ„ํ•˜์—ฌ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ์กด ์›น ์„œ๋น„์Šค์˜ ELB ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ์œ ํ˜• ์ค‘ NLB์™€ ALB๋Š” SSL ์ธ์ฆ์„œ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์™€ TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ์ด EC2 ์ธ์Šคํ„ด์Šค ๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ๋กœ ์ „๋‹ฌํ•˜๋Š” TLS ์˜คํ”„๋กœ๋”ฉ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

Mutual TLS โ€‹

์›น ์„œ๋น„์Šค์˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ์˜ X.509 ์ธ์ฆ์„œ๋ฅผ ํ† ๋Œ€๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํด๋ผ์ด์–ธํŠธ์™€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๋ชจ๋‘ ์ธ์ฆ์„œ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ Mutual TLS๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ž๋ฐ” ๊ธฐ๋ฐ˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋Š” javax.servlet.request.X509Certificate ์†์„ฑ์„ ํ†ตํ•ด X.509 ์ธ์ฆ์„œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์›น ์š”์ฒญ์ด ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์— ์˜ํ•ด ํŠธ๋ž˜ํ”ฝ์ด ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ Nginx๋ฅผ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์š”์ฒญ ์‹œ ํฌํ•จ๋œ ํด๋ผ์ด์–ธํŠธ์˜ ์ธ์ฆ์„œ ์ •๋ณด๊ฐ€ X-SSL-CERT์™€ ๊ฐ™์€ ๋น„ํ‘œ์ค€ ํ—ค๋”๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์š”์ฒญ ํ—ค๋”๋กœ ์ธ์ฆ์„œ๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๊นŒ์ง€ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์‹ค์ œ ์•„์ดํ”ผ๋ฅผ ์•Œ๊ธฐ ์œ„ํ•˜์—ฌ ์‚ฌ์šฉ๋˜๋Š” ํ‘œ์ค€ ํ—ค๋” X-Forwarded-For์™€ ๋น„์Šทํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

AWS NLB โ€‹

์•„๋งˆ์กด ์›น ์„œ๋น„์Šค์˜ NLB(Network Load Balancer)๋Š” L4 ๋ ˆ๋ฒจ์˜ ELB ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ์œ ํ˜•์ž…๋‹ˆ๋‹ค. NLB๋Š” L4 ๋ ˆ๋ฒจ์—์„œ ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ํ”„๋กœํ† ์ฝœ๊ณผ ํฌํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง€์ •๋œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋Œ€์ƒ ๊ทธ๋ฃน์œผ๋กœ ์š”์ฒญ์„ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๊ทœ๋ชจ ํŠธ๋ž˜ํ”ฝ์„ ๋น ๋ฅด๊ฒŒ EC2 ์ธ์Šคํ„ด์Šค๋กœ ์ „๋‹ฌ๋˜๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ELB์˜ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ์œ ํ˜• ๋น„๊ต์—์„œ ๋‚˜์™€์žˆ๋“ฏ์ด NLB๋Š” TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์— ์ธ์ฆ์„œ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด NLB์˜ ๋ฆฌ์Šค๋„ˆ ์„ค์ • ์‹œ TLS ํ”„๋กœํ† ์ฝœ์„ ์„ ํƒํ•˜๊ณ  TLS ๋ฒ„์ „๊ณผ ์•”ํ˜ธํ™” ์Šค์œ„ํŠธ ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋ณด์•ˆ ์ •์ฑ… ๊ทธ๋ฆฌ๊ณ  SSL ์ธ์ฆ์„œ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ECC ์ธ์ฆ์„œ ๋ฏธ์ง€์› โ€‹

TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ์ง€์›ํ•œ๋‹ค๊ณ  ๋‚˜์™€์žˆ์ง€๋งŒ ๋ชจ๋“  SSL ์ธ์ฆ์„œ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ํšŒ์‚ฌ์—์„œ ์‚ฌ์šฉ์ค‘์ธ ์ธ์ฆ์„œ์™€ ๊ฐ™์€ ํƒ€์› ๊ณก์„ ํ˜• ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ECC ์ธ์ฆ์„œ๋ฅผ ๋“ฑ๋กํ•˜๊ฒŒ ๋˜๋ฉด ์•„๋งˆ์กด ์›น ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์•Œ๋ฆผ์„ ๋ฐ›๊ฒŒ๋˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋กœ ํŠธ๋ž˜ํ”ฝ์ด ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š” ์ƒํƒœ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

NLB์— ๋Œ€ํ•œ ๋ฆฌ์Šค๋„ˆ ์„ค์ • ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด 2048 ์ด์ƒ์˜ ๋น„ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” RSA ํ‚ค ๋˜๋Š” EC ํ‚ค๋กœ๋œ ์ธ์ฆ์„œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ผ๊ณ  ๊ฒฝ๊ณ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๊ธฐ๊นŒ์ง€ ์ด๋Ÿฌํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์˜์™ธ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ECC ์ธ์ฆ์„œ์— ๋Œ€ํ•ด์„œ๋Š” NLB์—์„œ TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ SSL ์ธ์ฆ์„œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๋ฐฐํฌ ์‹œ Elastic Beanstalk์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Java SE ํ”Œ๋žซํผ์„ ํ†ตํ•ด EC2 ์ธ์Šคํ„ด์Šค์— Nginx๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์—ญ๋ฐฉํ–ฅ ํ”„๋ก์‹œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

ํšŒ์‚ฌ์—์„œ ์šด์˜์ค‘์ธ ์›น ์„œ๋น„์Šค๋Š” Nginx๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  NLB์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋กœ ํŠธ๋ž˜ํ”ฝ์ด ์ „๋‹ฌ๋˜๋„๋ก ๊ตฌ์„ฑํ–ˆ์—ˆ์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง์œผ๋กœ ์ธํ•˜์—ฌ ๋‚ด๋ถ€์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์ž‘์—…์ด ๋งŽ์•„์ง์— ๋”ฐ๋ผ TLS ํ•ธ๋“œ์‰์ดํฌ ๋ถ€ํ•˜๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์—์„œ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•˜์—ฌ Nginx์—์„œ TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์ „ํ™˜ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

AWS ALB โ€‹

ECC ์ธ์ฆ์„œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” NLB์™€ ๋‹ค๋ฅด๊ฒŒ ALB(Application Load Balancer)๋Š” 4096 ๋น„ํŠธ ํ‚ค ๊ธธ์ด์˜ RSA ์ธ์ฆ์„œ์™€ ECDSA๋กœ ์„œ๋ช…๋œ EC ์ธ์ฆ์„œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํšŒ์‚ฌ์—์„œ ์šด์˜์ค‘์ธ ์›น ์„œ๋น„์Šค๋ฅผ NLB์—์„œ ALB๋กœ ์ „ํ™˜ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ์™„์ „ํ•œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ„๋„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•ด์•ผํ•˜๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ์ธํ•ด ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋กœ ํŠธ๋ž˜ํ”ฝ์ด ์ „๋‹ฌ๋˜๋„๋ก NLB๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

IT ๋ถ„์•ผ๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ๊ธฐ์ˆ ์ด ์ ์ฐจ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ์กด ์›น ์„œ๋น„์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค ๊ธฐ๋Šฅ๋„ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ 2019๋…„์— ์ž‘์„ฑ๋œ ๊ณ ์ • ์„ธ์…˜ ๊ด€๋ จ ๊ธ€์—์„œ๋Š” NLB๊ฐ€ ๊ณ ์ • ์„ธ์…˜ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๋‚˜์™€์žˆ์ง€๋งŒ ํ˜„์žฌ ELB์˜ ์ œํ’ˆ ๋น„๊ตํ‘œ์™€ ๋น„๊ตํ•ด๋ณด๋ฉด ๋ฐฑ์—”๋“œ ์•”ํ˜ธํ™”, ๊ณ ์ • ์„ธ์…˜ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ELB TLSv1.3 ๋ฏธ์ง€์› โ€‹

์•„๋งˆ์กด ์›น ์„œ๋น„์Šค์˜ ELB์—์„œ TLS ์˜คํ”„๋กœ๋“œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€๋งŒ ๋ณด์•ˆ ์ •์ฑ…์— ๋”ฐ๋ผ TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๋Š” TLS 1.3์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. TLS 1.3์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ์ž‘์—…์€ ์•„์ง ์ง„ํ–‰์ค‘์ด๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ TLS 1.3์„ ์ง€์›ํ•˜๊ณ ์žํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ELB์—์„œ TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์—†๊ณ  NLB์˜ TCP ๋ฆฌ์Šค๋„ˆ๋ฅผ ์„ค์ •ํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ์ด EC2 ์ธ์Šคํ„ด์Šค๋กœ ์ „๋‹ฌ๋˜๋„๋กํ•˜๊ณ  EC2 ์ธ์Šคํ„ด์Šค์— ์‹คํ–‰๋˜์–ด์žˆ๋Š” Nginx๋ฅผ ํ†ตํ•ด TLS 1.3์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Elastic Beanstalk TLS ์˜คํ”„๋กœ๋“œ โ€‹

ELB์—์„œ๋Š” TLS 1.3์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ NLB์—์„œ๋Š” ECC ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์œผ๋ฏ€๋กœ Elastic Beanstalk์œผ๋กœ ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ ์‹œ Nginx์—์„œ SSL ์ธ์ฆ์„œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ๊ฐ€ TLS 1.3 ๋ฒ„์ „์œผ๋กœ TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€๋ฅผ ๊ฒ€์ฆํ•ด๋ณด๊ณ  ๋งˆ๋ฌด๋ฆฌ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Elastic Beanstalk Java SE ํ”Œ๋žซํผ โ€‹

์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Java SE ํ”Œ๋žซํผ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, ์ƒ˜ํ”Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ Beanstalk ํ™˜๊ฒฝ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์›น ์„œ๋ฒ„ ํ™˜๊ฒฝ ์„ ํƒ

์ƒ˜ํ”Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์‹œ์ž‘

Beanstalk ํ™˜๊ฒฝ ๊ตฌ์„ฑ ์‹œ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ์ถ”๊ฐ€ ์˜ต์…˜ ๊ตฌ์„ฑ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์„ค์ •์„ ์ง„ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

JVM ์˜ต์…˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜

๋ฐฐํฌํ•˜๊ณ  ๋ณด๋‹ˆ ์˜คํƒ€๊ฐ€ ์žˆ์—ˆ๋„ค์š” ๐Ÿ˜ƒ

๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ ์ธ์Šคํ„ด์Šค

NLB ์„ ํƒ ๋ฐ ๋ฆฌ์Šค๋„ˆ ๊ตฌ์„ฑ

๊ทธ๋ฆฌ๊ณ  EC2 ์ธ์Šคํ„ด์Šค ์ ‘๊ทผ์„ ์œ„ํ•œ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๋Š” ๋“ฑ ๋ถ€๊ฐ€ ์„ค์ •์„ ํ•˜๊ณ  ํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ˜ํ”Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฐฐํฌ๋˜๋Š” ํ™˜๊ฒฝ์ด ์ค€๋น„๋ฉ๋‹ˆ๋‹ค.

Java SE ํ”Œ๋žซํผ ํ™˜๊ฒฝ ์ƒ์„ฑ ์™„๋ฃŒ

์ฒ˜์Œ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ Beanstalk์—์„œ๋Š” ํ™˜๊ฒฝ ์‚ญ์ œ ๋ฒ„ํŠผ์ด ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์•„ ๋‹นํ™ฉํ•  ์ˆ˜ ์žˆ์œผ๋‚˜ CloudFormation ์„œ๋น„์Šค๋กœ ์ด๋™ํ•˜์—ฌ Beanstalk ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑ์ค‘์ธ ์Šคํƒ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒจํ‚ค์ง• ๋ฐ Java SE ํ”Œ๋žซํผ ํ™•์žฅ โ€‹

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•œ Java SE ํ”Œ๋žซํผ์ด ์ƒ์„ฑ๋˜์—ˆ์œผ๋‹ˆ ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํŒจํ‚ค์ง•ํ•˜์—ฌ Beanstalk์— ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•œ ์†Œ์Šค ๋ฒˆ๋“ค ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†Œ์Šค ๋ฒˆ๋“ค์—๋Š” ํŒจํ‚ค์ง•๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Jar ํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๋ฅผ ์œ„ํ•œ Procfile์„ ํฌํ•จ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

groovy
task procfile(dependsOn: bootJar) {
    doFirst {
        new File("build/libs", "Procfile").text = "web: java -Xmx1g -Dfile.encoding=UTF-8 -jar ${bootJar.archiveName}"
    }
}

task awsbuild(type: Zip, dependsOn: procfile) {
    from ('.beanstalk/.ebextensions') { into '.ebextensions' }
    from ('.beanstalk/.platform') { into '.platform' }
    from ('build/libs') {
        include('Procfile')
        include(bootJar.archiveName)
    }
    baseName = 'beanstalk'
}

์ž์„ธํ•œ ๋‚ด์šฉ์€ Procfile์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋กœ์„ธ์Šค ๊ตฌ์„ฑ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

Java SE ํ”Œ๋žซํผ ํ™•์žฅ ๊ตฌ์„ฑ โ€‹

Beanstalk๋Š” .ebextensions์™€ .platform์„ ํ™œ์šฉํ•˜์—ฌ EC2 ์ธ์Šคํ„ด์Šค ํ™˜๊ฒฝ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” HTTP๋กœ ์‹คํ–‰๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์™€ ํ•จ๊ป˜ TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  Nginx๋ฅผ ๊ตฌ์„ฑํ•ด์•ผํ•˜๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑ ๋ฐ ํ”Œ๋žซํผ ํ™•์žฅ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Nginx์—์„œ ์‚ฌ์šฉํ•  SSL ์ธ์ฆ์„œ ํŒŒ์ผ ์ƒ์„ฑ

yaml
files:
    /etc/nginx/cert/server.crt:
        mode: "000400"
        owner: nginx
        group: nginx
        content: |
            -----BEGIN CERTIFICATE-----
            #### PROTECTED ####
            -----END CERTIFICATE-----
    /etc/nginx/cert/server.key:
        mode: "000400"
        owner: nginx
        group: nginx
        content: |
            -----BEGIN EC PARAMETERS-----
            #### PROTECTED ####
            -----END EC PARAMETERS-----
            -----BEGIN EC PRIVATE KEY-----
            #### PROTECTED ####
            -----END EC PRIVATE KEY-----
    /etc/nginx/cert/server-ca-bundle:
        mode: "000400"
        owner: nginx
        group: nginx
        content: |
            -----BEGIN CERTIFICATE-----
            #### PROTECTED ####
            -----END CERTIFICATE-----
            -----BEGIN CERTIFICATE-----
            #### PROTECTED ####
            -----END CERTIFICATE-----
            -----BEGIN CERTIFICATE-----
            #### PROTECTED ####
            -----END CERTIFICATE-----

commands:
    00-chain-ca-bundle:
        cwd: /etc/nginx/cert
        command: |
            cat server.crt server-ca-bundle > server-ca.pem
            chown nginx:nginx server-ca.pem
            chmod 400 server-ca.pem
    99-remove-bak:
        cwd: /etc/nginx/cert
        command: rm -f *.bak

ํšŒ์‚ฌ ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ์ธ์ฆ์„œ์ด๋ฏ€๋กœ ์ธ์ฆ์„œ ๋‚ด์šฉ์€ ๋งˆ์Šคํ‚น ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Nginx ์„ค์ • ํŒŒ์ผ ํ™•์žฅ

nginx
location / {
    return 301 https://$host$request_uri;
}

๊ธฐ๋ณธ์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” 00_application.conf ํŒŒ์ผ์€ 80 ํฌํŠธ์— ๋Œ€ํ•˜์—ฌ 5000 ํฌํŠธ๋กœ ์ „๋‹ฌ๋˜๋„๋ก ๊ตฌ์„ฑํ•˜๋ฏ€๋กœ 443 ํฌํŠธ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋„๋ก ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.

nginx
user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    32768;

events {
    use  epoll;
    worker_connections  1024;
}

http {
    include         /etc/nginx/mime.types;
    default_type    application/octet-stream;

    log_format      main    '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';

    include conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
      default     "upgrade";
    }

    server {
        listen                80 default_server;
        access_log            /var/log/nginx/access.log main;

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        gzip                  off;
        gzip_comp_level       4;
        gzip_types            text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/*.conf;
    }


    server {
        listen                   443 ssl default_server;
        server_name              springboot;
        ssl_certificate          /etc/nginx/cert/server-ca.pem;
        ssl_certificate_key      /etc/nginx/cert/server.key;
        ssl_protocols            TLSv1.2 TLSv1.3;
        ssl_ciphers              HIGH:!aNULL:!MD5;
        ssl_verify_client        optional_no_ca;

        location / {
            proxy_pass          http://127.0.0.1:5000;
            proxy_http_version  1.1;
            proxy_set_header    Connection          $connection_upgrade;
            proxy_set_header    Upgrade             $http_upgrade;
            proxy_set_header    Host                $host;
            proxy_set_header    X-Real-IP           $remote_addr;
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header    X-SSL-CERT          $ssl_client_escaped_cert;
            proxy_buffering     off;
        }
    }

}

์ž์„ธํ•œ ๋‚ด์šฉ์€ Elastic Beanstalk Linux ํ”Œ๋žซํผ ํ™•์žฅ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. elastic-beanstalk-samples์ฒ˜๋Ÿผ ์ƒ˜ํ”Œ ํŒŒ์ผ๋„ ๊ณต์œ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ์ƒ˜ํ”Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋Œ€์‹  ์šฐ๋ฆฌ๊ฐ€ ์ค€๋น„ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์†Œ์Šค ๋ฒˆ๋“ค์„ ์—…๋กœ๋“œํ•˜๋ฉด Benstalk ์—”์ง„์ด ์†Œ์Šค ๋ฒˆ๋“ค์„ ์ถ”์ถœํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. Route 53์œผ๋กœ Beanstalk ํ™˜๊ฒฝ ์ฃผ์†Œ๋ฅผ DNS๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  ์ ‘์†ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด TLS ํ•ธ๋“œ์‰์ดํฌ๊ฐ€ ์ˆ˜ํ–‰๋˜์—ˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

NLB๋Š” ํŠธ๋ž˜ํ”ฝ์„ EC2 ์ธ์Šคํ„ด์Šค์˜ 443 ํฌํŠธ๋กœ ์ „๋‹ฌํ–ˆ์„ ๋ฟ TLS ์˜คํ”„๋กœ๋“œ๋Š” Nginx์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ตฌ์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” TLS 1.3 ๋ฒ„์ „์œผ๋กœ TLS ํ•ธ๋“œ์‰์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์•„๋งˆ์กด ์›น ์„œ๋น„์Šค์—์„œ TLS 1.3์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” NLB์˜ TCP ๋ฆฌ์Šค๋„ˆ์™€ Nginx์˜ TLS ์˜คํ”„๋กœ๋“œ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐ€๋Šฅํ•จ์„ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.

ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… โ€‹

Elastic Beanstalk๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌํ•˜๋Š” ๊ณผ์ •์—์„œ ์ƒ๊ฐ๋ณด๋‹ค ์˜ค๋ฅ˜๊ฐ€ ๋งŽ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋‚ด์šฉ์€ Benstalk์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋„์›€์ด ๋˜๋Š” ํ•ญ๋ชฉ์„ ์ •๋ฆฌํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผํ•ด๋ณด๋Š” ๋ถ„๋“ค์—๊ฒŒ ๋„์›€์ด ๋˜์…จ์œผ๋ฉด ํ•˜๋Š” ๋ฐ”๋žจ์œผ๋กœ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

๊ฒฝ๋กœ์šฉ๋„
/etc/nginx/Nginx ๊ตฌ์„ฑ
/var/app/current์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์†Œ์Šค ๋ฒˆ๋“ค ์ถ”์ถœ ๊ฒฝ๋กœ
/var/log/eb-engine.logBeanstalk ๋กœ๊ทธ
/var/log/nginxNginx ๋กœ๊ทธ
/var/log/web.stdout.out์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ

Beanstalk ๋กœ๊ทธ๋Š” Beanstalk ์—”์ง„์ด ํ”Œ๋žซํผ ํ™•์žฅ ํŒŒ์ผ๋“ค์„ ์‹คํ–‰ํ•˜๊ณ  ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ด ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ์–ด๋А ๋‹จ๊ณ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ ๋ฐ ์ „ํ™˜์ด ์‹คํŒจํ•˜์˜€๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ๋กœ๊ทธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ํ•ญ๋ชฉ์„ ํ†ตํ•ด ์„ค์ •ํ•œ ๊ตฌ์„ฑ ๋ฐ ํ™•์žฅ ํŒŒ์ผ์ด ์ œ๋Œ€๋กœ ์ถ”์ถœ๋˜์–ด ๋ณต์‚ฌ๋˜์—ˆ๋Š”์ง€ Nginx๊ฐ€ ELB์— ์˜ํ•ด ์ „๋‹ฌ๋œ ํŠธ๋ž˜ํ”ฝ์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊นŒ์ง€ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Nginx์— ๋Œ€ํ•ด์„œ ์ž์„ธํžˆ ์•„๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ์„ค์ • ํŒŒ์ผ์ด ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์–‘ํ•ด ๋ฐ”๋ผ๋ฉฐ ์ž˜๋ชป๋œ ์ ์€ ํŒจ๋“œ๋ฐฑ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Released under the MIT License.