๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐Ÿ” ๋ณด์•ˆ

์†Œ๊ฐœโ€‹

๋ณด์•ˆ์€ Semaphore UI์˜ ์ตœ์šฐ์„  ๊ณผ์ œ์ž…๋‹ˆ๋‹ค. ํ•ต์‹ฌ ์ธํ”„๋ผ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๋“  ๋ฏผ๊ฐํ•œ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ํŒ€ ์ ‘๊ทผ์„ ๊ด€๋ฆฌํ•˜๋“ , Semaphore UI๋Š” ๋ณ„๋„ ์„ค์ • ์—†์ด๋„ ๊ฒฌ๊ณ ํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์šด์˜๋˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” Semaphore๊ฐ€ ๋ณด์•ˆ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•  ๋•Œ ๋ฌด์—‡์„ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌโ€‹

Semaphore๋Š” ์•ˆ์ „ํ•œ ์ธ์ฆ๊ณผ ์œ ์—ฐํ•œ ๊ถŒํ•œ ๋ถ€์—ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

  • ๋กœ๊ทธ์ธ ๋ฐฉ์‹:

    • ์‚ฌ์šฉ์ž ์ด๋ฆ„/๋น„๋ฐ€๋ฒˆํ˜ธ
      Semaphore ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ์ž๊ฒฉ ์ฆ๋ช…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ณธ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๊ฐ•๋ ฅํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜(bcrypt)์œผ๋กœ ํ•ด์‹œ๋ฉ๋‹ˆ๋‹ค.

    • LDAP
      ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ๋””๋ ‰ํ„ฐ๋ฆฌ ์„œ๋น„์Šค์™€์˜ ํ†ตํ•ฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž/๊ทธ๋ฃน ํ•„ํ„ฐ๋ง๊ณผ LDAPS๋ฅผ ํ†ตํ•œ ๋ณด์•ˆ ์—ฐ๊ฒฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

    • OpenID Connect (OIDC)
      Google, Azure AD, Keycloak ๋“ฑ์˜ ID ๊ณต๊ธ‰์ž๋ฅผ ํ†ตํ•œ ์‹ฑ๊ธ€ ์‚ฌ์ธ์˜จ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ ˆ์ž„๊ณผ ๊ทธ๋ฃน ๋งคํ•‘์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

  • 2๋‹จ๊ณ„ ์ธ์ฆ(2FA)
    TOTP ๊ธฐ๋ฐ˜ 2FA๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋ณ„๋กœ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๊ณ  ์„ ํƒ์ ์œผ๋กœ ๋ณต๊ตฌ ์ฝ”๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์˜ต์…˜ auth.totp.enabled ๋ฐ auth.totp.allow_recovery๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • ์—ญํ•  ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด
    ์‚ฌ์šฉ์ž์—๊ฒŒ Admin, Maintainer, Viewer ๋“ฑ ์„œ๋กœ ๋‹ค๋ฅธ ์—ญํ• ์„ ํ• ๋‹นํ•˜์—ฌ ์ฑ…์ž„์— ๋”ฐ๋ผ ์ ‘๊ทผ์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์„ธ์…˜ ๊ด€๋ฆฌ
    ์„ธ์…˜์€ ๋ณด์•ˆ HTTP ์ฟ ํ‚ค๋กœ ๋ณดํ˜ธ๋ฉ๋‹ˆ๋‹ค. ์„ธ์…˜ ๋งŒ๋ฃŒ ๋ฐ ๋กœ๊ทธ์•„์›ƒ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ๋…ธ์ถœ์„ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.

๋น„๋ฐ€ ์ •๋ณด ๋ฐ ์ž๊ฒฉ ์ฆ๋ช…โ€‹

๋น„๋ฐ€ ์ •๋ณด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค:

  • ์•”ํ˜ธํ™”๋œ ํ‚ค ์ €์žฅ์†Œ
    ์ž๊ฒฉ ์ฆ๋ช…๊ณผ ๋น„๋ฐ€ ๋ณ€์ˆ˜๋Š” AES ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ €์žฅ ์‹œ ์•”ํ˜ธํ™”๋ฉ๋‹ˆ๋‹ค.

  • ํ™˜๊ฒฝ ๊ฒฉ๋ฆฌ
    ๋น„๋ฐ€ ์ •๋ณด๋Š” ์‹คํ–‰ ์‹œ์ ์—๋งŒ ์ž‘์—…์— ์ „๋‹ฌ๋˜๋ฉฐ ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์— ์ง์ ‘ ๋…ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • SSH ํ‚ค ๋ฐ token
    ์œ ํšจํ•œ SSH ํ‚ค์™€ token์„ ์—…๋กœ๋“œํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ์ฑ…์ž„์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ ์•”ํ˜ธํ™”๋˜์–ด ์ž‘์—… ์‹คํ–‰ ์‹œ์—๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • HashiCorp Vault ํ†ตํ•ฉ(Pro)
    ๋น„๋ฐ€ ์ •๋ณด๋ฅผ ์™ธ๋ถ€ Vault ์ธ์Šคํ„ด์Šค์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„๋ฐ€ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ํŽธ์ง‘ํ•  ๋•Œ ๋น„๋ฐ€ ์ •๋ณด๋ณ„๋กœ ์ €์žฅ์†Œ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™”โ€‹

๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์•”ํ˜ธํ™”๋œ ํ˜•ํƒœ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. Access Key ์•”ํ˜ธํ™”๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๊ตฌ์„ฑ ํŒŒ์ผ์—์„œ ๊ตฌ์„ฑ ์˜ต์…˜ access_key_encryption์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

head -c32 /dev/urandom | base64

์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ / playbook ์‹คํ–‰โ€‹

Semaphore๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ playbook๊ณผ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฏ€๋กœ ์œ„ํ—˜์ด ๋”ฐ๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ์ปจํ…Œ์ด๋„ˆ ๊ฒฉ๋ฆฌ
    ์ž‘์—…์€ ๊ฒฉ๋ฆฌ๋œ Docker ์ปจํ…Œ์ด๋„ˆ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ์ปจํ…Œ์ด๋„ˆ๋Š” ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ์ตœ์†Œ ๊ถŒํ•œ
    ์ปจํ…Œ์ด๋„ˆ๋Š” ์ตœ์†Œํ•œ์˜ ๊ถŒํ•œ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ Docker ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”๊ฐ€๋กœ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • chroot ์‹คํ–‰
    Semaphore๋Š” ์‹คํ–‰ ํ™˜๊ฒฝ์„ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์œผ๋กœ๋ถ€ํ„ฐ ๋”์šฑ ๊ฒฉ๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด chroot jail ๋‚ด๋ถ€์—์„œ ์ž‘์—…์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ž‘์—… ํ”„๋กœ์„ธ์Šค ์‚ฌ์šฉ์ž
    ์ž ์žฌ์ ์ธ ์ต์Šคํ”Œ๋กœ์ž‡์˜ ์˜ํ–ฅ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ž‘์—…์„ ์ „์šฉ ๋น„๋ฃจํŠธ ์‹œ์Šคํ…œ ์‚ฌ์šฉ์ž(์˜ˆ: semaphore)๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ์‹œ์Šคํ…œ ์ •์ฑ…์— ๋”ฐ๋ผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ์ „ํ•œ ๋ฐฐํฌโ€‹

Semaphore๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐฐํฌํ•˜๋ ค๋ฉด:

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

    ๋‚ด์žฅ HTTPS ์ง€์›์„ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด config.json์— ๋‹ค์Œ ๋ธ”๋ก์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค:

    {
    ...
    "tls": {
    "enabled": true,
    "cert_file": "/path/to/cert/example.com.cert",
    "key_file": "/path/to/key/example.com.key"
    }
    ...
    }
  • ๋ฐฉํ™”๋ฒฝ ๋’ค์—์„œ ์‹คํ–‰
    Semaphore UI์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” IP๋กœ๋งŒ ์ œํ•œํ•˜์‹ญ์‹œ์˜ค.

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณด์•ˆ
    ๊ฐ•๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ์„ Semaphore๋กœ๋งŒ ์ œํ•œํ•˜์‹ญ์‹œ์˜ค.

์—…๋ฐ์ดํŠธ ๋ฐ ํŒจ์น˜ ๊ด€๋ฆฌโ€‹

๋ณด์•ˆ ์—…๋ฐ์ดํŠธ๋Š” ์ •๊ธฐ์ ์œผ๋กœ ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค:

  • ์ตœ์‹  ์ƒํƒœ ์œ ์ง€
    ํ•ญ์ƒ ์ตœ์‹  ์•ˆ์ • ๋ฆด๋ฆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

  • ๋ณ€๊ฒฝ ๋กœ๊ทธ
    ์—…๋ฐ์ดํŠธ ์ „์— GitHub์—์„œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฒ€ํ† ํ•˜์‹ญ์‹œ์˜ค.

  • ์ž๋™ ์—…๋ฐ์ดํŠธ
    Docker๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ •๊ธฐ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์ž๋™ํ™” pipeline์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

์ทจ์•ฝ์  ์‹ ๊ณ โ€‹

์ทจ์•ฝ์ ์„ ๋ฐœ๊ฒฌํ•˜์…จ์Šต๋‹ˆ๊นŒ? Semaphore๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์‹ญ์‹œ์˜ค:

  • ์ฑ…์ž„ ์žˆ๋Š” ๊ณต๊ฐœ
    [email protected]์œผ๋กœ ์ด๋ฉ”์ผ์„ ๋ณด๋‚ด ์ฃผ์‹ญ์‹œ์˜ค.

์ทจ์•ฝ์  ํ•ด๊ฒฐ ๋ชฉํ‘œโ€‹

์‹ ๊ณ ๋œ ์ทจ์•ฝ์ ์€ ๋‹ค์Œ ๋ชฉํ‘œ ๊ธฐ๊ฐ„ ๋‚ด์— ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค:

  • Critical: 30์ผ ์ด๋‚ด
  • High: 60์ผ ์ด๋‚ด
  • Medium: 90์ผ ์ด๋‚ด
  • Low: ์ตœ์„ ์˜ ๋…ธ๋ ฅ, ์ผ๋ฐ˜์ ์œผ๋กœ 180์ผ ์ด๋‚ด

์ตœ์‹  ์•ˆ์ • ๋ฆด๋ฆฌ์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์‹ค์ œ ์•…์šฉ ์ค‘์ธ ๋ฌธ์ œ์— ๋Œ€ํ•ด์„œ๋Š” ์ •๊ทœ ์ฃผ๊ธฐ ์™ธ์˜ ํŒจ์น˜๊ฐ€ ๋ฆด๋ฆฌ์Šค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ ๋ณด์•ˆ ๋„๊ตฌโ€‹

์ฝ”๋“œ๋ฒ ์ด์Šค์™€ ์˜์กด์„ฑ์„ ๋ถ„์„ํ•˜๊ณ  ์˜์กด์„ฑ ์—…๋ฐ์ดํŠธ๋ฅผ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•ด CodeQL, Codacy, Snyk, Renovate๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ๊ณต๊ฐœ ์ต์Šคํ”Œ๋กœ์ž‡ ๊ธˆ์ง€
    ํŒจ์น˜๋˜๊ธฐ ์ „๊นŒ์ง€ ์ทจ์•ฝ์ ์„ ๊ณต๊ฐœ์ ์œผ๋กœ ๊ณต์œ ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

  • ๊ฐ์‚ฌ์˜ ํ‘œ์‹œ
    ์›ํ•˜์‹œ๋Š” ๊ฒฝ์šฐ ๋ณด์•ˆ ์—ฐ๊ตฌ์ž์˜ ์ด๋ฆ„์„ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์— ๊ธฐ์žฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.