Lua-resty-auto-ssl: μΈμ¦μ„œ λ°œκΈ‰ μ‹œ IP μ£Όμ†Œ λ¬΄μ‹œ

에 λ§Œλ“  2016λ…„ 09μ›” 27일  Β·  8μ½”λ©˜νŠΈ  Β·  좜처: auto-ssl/lua-resty-auto-ssl

LetsEncryptκ°€ IP에 λŒ€ν•œ μΈμ¦μ„œλ₯Ό λ°œκΈ‰ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점을 κ³ λ €ν•˜λ©΄, letsEncrypt에 μš”μ²­μ„ 보내기 전에 ν•΄λ‹Ή 논리λ₯Ό allow_domain ꡬ성/κΈ°λŠ₯에 μΆ”κ°€ν•˜λŠ” 것보닀 IP μ£Όμ†Œλ₯Ό κ°μ§€ν•˜κ³  λ¬΄μ‹œν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

enhancement

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

ν™”μ΄νŠΈλ¦¬μŠ€νŒ…μ€ κ³Όλ„ν•œ μ—”μ§€λ‹ˆμ–΄λ§μ΄ μ•„λ‹ˆλΌ μ˜¬λ°”λ₯΄κ²Œ μˆ˜ν–‰ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ°œλ°œμžλ“€μ΄ ν™”μ΄νŠΈλ¦¬μŠ€νŒ… λŒ€μ‹  λΈ”λž™λ¦¬μŠ€νŒ…μ„ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ„Έμƒμ—λŠ” λ³΄μ•ˆ 사고가 λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€.

κ·€ν•˜μ˜ μˆ˜ν‘œλŠ” λ˜ν•œ IPv6 μ£Όμ†Œλ₯Ό κ±΄λ„ˆλ›°κ³  μ‹€μ œλ‘œ κ³Όλ„ν•˜κ²Œ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

if string.match(domain, "(%d+).(%d+).(%d+).(%d+)") or string.find(domain, ":", 1, true) then
    return false
end

λͺ¨λ“  8 λŒ“κΈ€

λ‚˜λŠ” 그것에 λŒ€ν•œ μˆ˜ν‘œλ₯Ό 썼고, 이미 κ½€ 일찍 μ‹€νŒ¨ν–ˆλ‹€λŠ” 것을 μ•Œμ•„λƒˆμŠ΅λ‹ˆλ‹€.

ssl_certificate(): auto-ssl: μš”μ²­μ— λŒ€ν•œ 도메인을 κ²°μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€(SNIκ°€ μ§€μ›λ˜μ§€ μ•ŠμŠ΅λ‹ˆκΉŒ?) - λŒ€μ²΄ μ‚¬μš© -

λΈŒλΌμš°μ €κ°€ IP μ£Όμ†Œλ₯Ό μš”μ²­ν•  λ•Œ SNI 헀더λ₯Ό 보내지 μ•ŠμœΌλ―€λ‘œ "도메인"도 μ„€μ •λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‚΄ μš”μ²­μ΄ μ•”ν˜Έν™”λ₯Ό ν—ˆμš©ν•˜λΌλŠ” μš”μ²­μ„ 보낸 μ΄μœ κ°€ ν™•μ‹€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 그런 λ‹€μŒ SSL μΈμ¦μ„œλ₯Ό IP둜 λ“±λ‘ν•˜λŠ” 것에 λŒ€ν•œ 였λ₯˜λ₯Ό λ³΄λ‚΄λŠ” μ€‘μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

@discobean : 이것을 λ³΄μ•˜μ„ λ•Œ λ°œμƒν•˜λŠ” νŠΉμ • 였λ₯˜ λ©”μ‹œμ§€κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

@GUI λ•Œλ•Œλ‘œ 같은 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€. λ‚΄ 생각에 이것은 ν΄λΌμ΄μ–ΈνŠΈ(μŠ€μΊλ„ˆ 봇일 수 있음)κ°€ λŒ€μƒ IP μ£Όμ†Œμ™€ λ™μΌν•œ 호슀트 헀더λ₯Ό 보내기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 예:

2018/02/20 02:10:44 [warn] 490#490: *2723 [lua] init_by_lua:11: allow_domain(): auto-ssl: debug allow_domain domain XXX.XXX.XX.XX, context: ssl_certificate_by_lua*, client: 107.170.236.113, server: 0.0.0.0:8443
2018/02/20 02:10:49 [error] 490#490: *2723 [lua] lets_encrypt.lua:41: issue_cert(): auto-ssl: dehydrated failed: env HOOK_SECRET=XXXXX HOOK_SERVER_PORT=8999 /usr/local/bin/resty-auto-ssl/dehydrated --cron --accept-terms --no-lock --domain XXX.XXX.XX.XX --challenge http-01 --config /etc/resty-auto-ssl/letsencrypt/config --hook /usr/local/bin/resty-auto-ssl/letsencrypt_hooks status: 256 out: # INFO: Using main config file /etc/resty-auto-ssl/letsencrypt/config
Processing XXX.XXX.XX.XX
 + Signing domains...
 + Creating new directory /etc/resty-auto-ssl/letsencrypt/certs/XXX.XXX.XX.XX ...
 + Generating private key...
 + Generating signing request...
 + Requesting authorization for XXX.XXX.XX.XX...
 err:   + ERROR: An error occurred while sending post-request to https://acme-v01.api.letsencrypt.org/acme/new-authz (Status 400)

Details:
{
  "type": "urn:acme:error:malformed",
  "detail": "Error creating new authz :: Issuance for IP addresses not supported",
  "status": 400
}

, context: ssl_certificate_by_lua*, client: 107.170.236.113, server: 0.0.0.0:8443
2018/02/20 02:10:49 [error] 490#490: *2723 [lua] ssl_certificate.lua:97: issue_cert(): auto-ssl: issuing new certificate failed: dehydrated failure, context: ssl_certificate_by_lua*, client: 107.170.236.113, server: 0.0.0.0:8443
2018/02/20 02:10:49 [error] 490#490: *2723 [lua] ssl_certificate.lua:286: auto-ssl: could not get certificate for XXX.XXX.XX.XX - using fallback - failed to get or issue certificate, context: ssl_certificate_by_lua*, client: 107.170.236.113, server: 0.0.0.0:8443

μ—¬κΈ°μ„œ XXX.XXX.XX.XX λŠ” μ‹€μ œ μ„œλ²„ IP μ£Όμ†Œμž…λ‹ˆλ‹€.

μ €λŠ” μ½”λ“œμ—μ„œ 이것을 μ°¨λ‹¨ν•˜λŠ” 데 μ°¬μ„±ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ, eh: "not for these"(λΈ”λž™λ¦¬μŠ€νŠΈ μ ‘κ·Ό 방식)κ°€ μ•„λ‹Œ (ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ μ ‘κ·Ό 방식)에 λŒ€ν•΄ μΈμ¦μ„œκ°€ μƒμ„±λ˜κΈ°λ₯Ό μ›ν•˜λŠ” FQDN을 allow_domain() _only_ ν—ˆμš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

allow_domain()μ—μ„œ λ‹¨μˆœνžˆ "trueλ₯Ό λ°˜ν™˜"ν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€. μ‹œμŠ€ν…œμ— 뢀담을 μ£Όκ³  LE에 λŒ€ν•œ μ‹€νŒ¨λ₯Ό λˆ„μ ν•©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μš°λ¦¬λŠ” ν•œ 단계 더 λ‚˜μ•„κ°€κ³  μžˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” λͺ¨λ“  μ›Ήν˜ΈμŠ€νŒ… 고객 λͺ©λ‘μ„ λ””μŠ€ν¬μ˜ Lua ν…Œμ΄λΈ” 파일둜 내보내고 이λ₯Ό 읽고 nginx λ‚΄λΆ€μ˜ SHM ν‚€/κ°’ μ €μž₯μ†Œμ— μ €μž₯ν•˜λ―€λ‘œ μΈμ¦μ„œλ₯Ό 생성해야 ν•˜λŠ”μ§€ μ—¬λΆ€λ₯Ό μ‰½κ²Œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

관리 호슀트 이름에 λŒ€ν•΄ μ—¬λŸ¬ 개의 μ™€μΌλ“œμΉ΄λ“œ μΈμ¦μ„œκ°€ μžˆμœΌλ―€λ‘œ ν•΄λ‹Ή SSL μΈμ¦μ„œκ°€ ν¬ν•¨λœ ꡐ체된 SSL 체인으둜 일찍 μ’…λ£Œν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” IP μ£Όμ†Œμ™€ localhostμ—μ„œ 일찍 μ’…λ£Œν•©λ‹ˆλ‹€. 그런 λ‹€μŒ λ§ˆμ§€λ§‰μœΌλ‘œ DNSλ₯Ό ν™•μΈν•˜κ³  이름이 μ‹€μ œλ‘œ μ‹œμŠ€ν…œμ— κ΅¬μ„±λœ 도메인 λͺ©λ‘μ— μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

μ΄λŸ¬ν•œ κ²€μ‚¬μ˜ λŒ€λΆ€λΆ„μ€ μ‹œκ°„μ΄ μ§€λ‚˜λ©΄ 성곡할 수 μžˆμ§€λ§Œ μ‹€μ œλ‘œ ν•„μš”ν•œ 것은 μ•„λ‹™λ‹ˆλ‹€. μš”μ : λΈ”λž™λ¦¬μŠ€νŠΈ λŒ€μ‹  ν™”μ΄νŠΈλ¦¬μŠ€νŠΈλ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€. 일반적인 μ½”λ“œ μ—°μŠ΅μ΄κΈ°λ„ ν•©λ‹ˆλ‹€. μ£„μ†‘ν•©λ‹ˆλ‹€λ³΄λ‹€ 더 μ•ˆμ „.

그리고 λ•Œλ‘œλŠ” 또 λ‹€λ₯Έ μ‹€νŒ¨ 지점이 될 수 μžˆλŠ” λ‹€μ–‘ν•œ 검사λ₯Ό κ³Όλ„ν•˜κ²Œ μ—”μ§€λ‹ˆμ–΄λ§ν•˜κ³  κ±΄λ„ˆλ›°μ§€ μ•ŠλŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. 특히 맀우 동적인 ν™˜κ²½μ΄ μžˆλŠ” 경우.

λ‚˜λŠ” 이것이 lua-resty-auto-sslμ—μ„œ μ°¨λ‹¨λ˜μ–΄μ•Ό ν•œλ‹€κ³  λ§ν•˜λŠ” 것이 μ•„λ‹ˆλΌ λ‹€λ₯Έ μ‚¬λžŒμ΄ 이 문제λ₯Ό μš°μ—°νžˆ λ°œκ²¬ν•˜λŠ”μ§€ ν…ŒμŠ€νŠΈν•˜λŠ” λ™μ•ˆ λ°œκ²¬ν•œ 것을 κ³΅μœ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

allow_domain 의 λΉ λ₯Έ ν•΄ν‚Ή:

          local ip_chunks = {domain:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")}
          if (#ip_chunks == 4) then
            return false
          end

ν™”μ΄νŠΈλ¦¬μŠ€νŒ…μ€ κ³Όλ„ν•œ μ—”μ§€λ‹ˆμ–΄λ§μ΄ μ•„λ‹ˆλΌ μ˜¬λ°”λ₯΄κ²Œ μˆ˜ν–‰ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ°œλ°œμžλ“€μ΄ ν™”μ΄νŠΈλ¦¬μŠ€νŒ… λŒ€μ‹  λΈ”λž™λ¦¬μŠ€νŒ…μ„ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ„Έμƒμ—λŠ” λ³΄μ•ˆ 사고가 λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€.

κ·€ν•˜μ˜ μˆ˜ν‘œλŠ” λ˜ν•œ IPv6 μ£Όμ†Œλ₯Ό κ±΄λ„ˆλ›°κ³  μ‹€μ œλ‘œ κ³Όλ„ν•˜κ²Œ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

if string.match(domain, "(%d+).(%d+).(%d+).(%d+)") or string.find(domain, ":", 1, true) then
    return false
end

당신은 우리의 상황을 λͺ¨λ₯΄μ§€λ§Œ λΉ λ₯΄κ²Œ νŒλ‹¨ν•©λ‹ˆλ‹€. μš”μ μ„ μ•Œμ•˜μ–΄.

λͺ¨λ“  μ‚¬λžŒμ„ 더 μ•ˆμ „ν•˜κ²Œ λ§Œλ“€κΈ° μœ„ν•΄ true λ₯Ό λ°˜ν™˜ν•˜λŠ” 것보닀 PR을 λ§Œλ“€κ³  README.md의 allow_domain λ₯Ό 더 합리적인 κ²ƒμœΌλ‘œ λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰

κ΄€λ ¨ 문제

kshnurov picture kshnurov  Β·  3μ½”λ©˜νŠΈ

byrnedo picture byrnedo  Β·  16μ½”λ©˜νŠΈ

n11c picture n11c  Β·  13μ½”λ©˜νŠΈ

jasonbouffard picture jasonbouffard  Β·  6μ½”λ©˜νŠΈ

ronaldgrn picture ronaldgrn  Β·  8μ½”λ©˜νŠΈ