Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイッチ / The construction of large scale TLS certificates management system with AWS

aereal
September 08, 2018

ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイッチ / The construction of large scale TLS certificates management system with AWS

talked at builderscon tokyo 2018

aereal

September 08, 2018
Tweet

More Decks by aereal

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • id:aereal • GitHub: aereal • Twitter: aereal •

    ϒϩά౷߹νʔϜ
 ΞϓϦέʔγϣϯΤϯδχΞ
 ςοΫϦʔυ
  2. Let's Encrypt • ISRG = Internet Security Research Group͕ఏڙ͢Δ
 ϓϩάϥϚϒϧʹΞΫηεՄೳͳೝূہ

    (CA) • ͜Ε·ͰTLSূ໌ॻΛൃߦ͢Δʹ͸
 ͦͦ͜͜ͷֹۚͱख͕ؒඞཁ͕ͩͬͨɺͦΕΛม͑ͨCA • LEͷొ৔ʹΑΓTLSূ໌ॻͷେྔൃߦ͕ݱ࣮తʹͳͬͨ
  3. SAN? • = Subject Alternative Names
 1ͭͷূ໌ॻʹෳ਺υϝΠϯΛඥ෇͚Δ֦ு • ݁࿦͔Βݴ͏ͱ͸ͯͳϒϩάͷέʔεͰ͸೉͍͠ •

    LEͰSANΛར༻͢Δ৔߹ɺACME challenge͸dns-01ͷΈ ར༻Ͱ͖Δ (ݱࡏ) • DNSઃఆ͸֤ϢʔβʔʹҕͶΒΕΔͷͰࣗಈԽͰ͖ͳ͍
  4. ACME? • ACME: Automated Certificate Management Environment • ূ໌ॻൃߦͳͲͷ࡞ۀΛ
 ࣗಈԽ͢ΔϓϩτίϧΛ·ͱΊͨ࢓༷

    • ACME challenge: υϝΠϯͷॴ༗ݖݶΛ֬ೝ͢Δํ๏ • Google AnalyticsͷΞϨΈ͍ͨͳ΍ͭ • LE͕ࡦఆɾ࠾༻͍ͯ͠Δ
  5. ແޮͳυϝΠϯͷ࡟আ • ແޮͳυϝΠϯ = ඞͣACME challengeʹࣦഊ͢Δ • LEʹ͸ΞΧ΢ϯτ * time

    window͝ͱʹࣦഊͷ্ݶ͕͋Δ • ์ஔ͢ΔͱඞͣAPI limitʹ͋ͨͬͯ͠·͏ • ࣦഊͨ͠υϝΠϯ͸ඞͣ࡟আ
  6. ূ໌ॻൃߦ: ෆ࣮֬ੑ • υϝΠϯͷ༗ޮੑ͸มΘΓ͏Δ • ՝ۚऴྃ • DNSϨίʔυҟৗ • ֎෦API

    = LEͱͷ౷߹ • API Limit • ద੾ͳϦτϥΠͱΤϥʔϦΧόϦ͕ඞਢ
  7. ূ໌ॻൃߦ: εέʔϥϏϦςΟ • ର৅υϝΠϯ਺ͷ૿Ճʹର͠εέʔϧ͢Δ࢓૊Έʹ͍ͨ͠ • SELECT * FROM custom_domain WHERE

    id > ?
 Έ͍ͨͳΫΤϦ͸ආ͚͍ͨ • υϝΠϯ਺͕૿͑Δͱϖʔδϯά͕ඞཁ • ࣮ߦ్தͰࣦഊͨ͠ΒɺϦτϥΠΩϡʔʹೖΕ௚͢Α͏ ͳ޻෉ΛڽΒ͞ͳ͍ͱ͍͚ͳ͘ͳΔ
  8. ഑৴γεςϜ • ngx_mruby: ূ໌ॻಡΈࠐΈ࣌ʹmrubyͷίʔυΛ࣮ߦ • cache gateway΁HTTP GET͢Δ͚ͩ • https://github.com/matsumotory/ngx_mruby

    • cache gateway (Go): HTTP GET͢Δͱূ໌ॻΛฦ͢ • DynamoDB: ূ໌ॻΛอଘ͢ΔσʔλετΞ
  9. cache gateway • AWS (DynamoDB) APIݺͼग़͠ΛHTTP APIʹม͑Δ • mrubyʹ͸AWS SDK͕ͳ͍

    • ಉډ͢Δmemcachedʹ΋ಡΈॻ͖͠ɺ
 DynamoDB΁ͷΞΫηεΛͰ͖Δ͚ͩݮΒ͢
  10. ূ໌ॻൃߦγεςϜ • cert-updater-state: AWS StepFunctions; ֤LambdaΛىಈ • Τϥʔ಺༰ʹԠͨ͡ϦΧόϦɾϦτϥΠ (ޙड़) •

    cert-updater-function: AWS Lambda; ূ໌ॻΛൃߦɺ DynamoDB΁ॻ͖ࠐΈ • cert-update-notifier: Lambda; ੒൱Λ͸ͯͳϒϩά΁௨஌
  11. AWS SFn: ϦτϥΠ "Retry": [ { "ErrorEquals": ["ErrMaybeRecoverable"], "IntervalSeconds": 1,

    "MaxAttempts": 3, "BackoffRate": 2.0 } ], "Catch": [ { "ErrorEquals": ["States.TaskFailed"], "Next": "Notify result to Hatena-Epic" } ],
  12. AWS SFn: ϦτϥΠ "Retry": [ { "ErrorEquals": ["ErrMaybeRecoverable"], "IntervalSeconds": 1,

    "MaxAttempts": 3, "BackoffRate": 2.0 } ], "Catch": [ { "ErrorEquals": ["States.TaskFailed"], "Next": "Notify result to Hatena-Epic" } ],
  13. AWS SFn: ϦτϥΠ "Retry": [ { "ErrorEquals": ["ErrMaybeRecoverable"], "IntervalSeconds": 1,

    "MaxAttempts": 3, "BackoffRate": 2.0 } ], "Catch": [ { "ErrorEquals": ["States.TaskFailed"], "Next": "Notify result to Hatena-Epic" } ],
  14. AWS SFn: ϦτϥΠ "Retry": [ { "ErrorEquals": ["ErrMaybeRecoverable"], "IntervalSeconds": 1,

    "MaxAttempts": 3, "BackoffRate": 2.0 } ], "Catch": [ { "ErrorEquals": ["States.TaskFailed"], "Next": "Notify result to Hatena-Epic" } ],
  15. cert-lifecycle-store
 (DynamoDB) Domain: ex1.example.com ExpiresAt: 2018-05-23T02:00:00 Domain: ex2.example.com ExpiresAt: 2018-05-23T03:00:00

    Domain: ex2.example.com ExpiresAt: 2018-05-23T04:00:00 Domain: ex2.example.com ExpiresAt: 2018-05-23T05:00:00
  16. cert-reissue-state "Determine next state": { "Comment": "࣍ͷঢ়ଶΛܾఆ͠·͢", "Type": "Choice", "Choices":

    [ { "Variable": "$.UpdateRequired", "BooleanEquals": true, "Next": "Call reissue of certificate" }, { "Variable": "$.UpdateRequired", "BooleanEquals": false, "Next": "Clean up of certificate" } ] },
  17. cert-reissue-state "Determine next state": { "Comment": "࣍ͷঢ়ଶΛܾఆ͠·͢", "Type": "Choice", "Choices":

    [ { "Variable": "$.UpdateRequired", "BooleanEquals": true, "Next": "Call reissue of certificate" }, { "Variable": "$.UpdateRequired", "BooleanEquals": false, "Next": "Clean up of certificate" } ] },
  18. cert-reissue-state "Determine next state": { "Comment": "࣍ͷঢ়ଶΛܾఆ͠·͢", "Type": "Choice", "Choices":

    [ { "Variable": "$.UpdateRequired", "BooleanEquals": true, "Next": "Call reissue of certificate" }, { "Variable": "$.UpdateRequired", "BooleanEquals": false, "Next": "Clean up of certificate" } ] },
  19. // ϫʔΫϑϩʔΤϯδϯͷঢ়ଶ { "domain": "www.example.com", "endpoint": "https://...." } // ͋Δόονͷೖྗ

    { "domain": "www.example.com" } άϩʔόϧঢ়ଶΛҾ਺΁ม׵͢Δ
 (όον͔Βͷมߋ͸ෆՄ)
  20. // ϫʔΫϑϩʔΤϯδϯͷঢ়ଶ { "updateRequired": true, "domain": "www.example.com", "endpoint": "https://...." }

    // ͋Δόονͷग़ྗ { "updateRequired": true } όονͷग़ྗΛάϩʔόϧͳঢ়ଶ΁ม׵
 (౰વɺग़ྗ͸ޙ͔ΒมߋෆՄ)
  21. ࠶: ΅͘ͷ͔Μ͕͍͖͑ͨ͞ΐ͏ ͷϐλΰϥεΠον • ϫʔΫϑϩʔΤϯδϯͷಋೖ • ࣮ߦεςοϓશ༰Λ೺Ѳ͠΍͘͢ • ͦΕͱߴ౓ʹ౷߹͞Εͨόον࣮ߦ؀ڥ͕͋Δͱͳ͓Α͍ •

    pub/subϞσϧͰର৅σʔλͷ૿Ճʹର͠εέʔϧͤ͞Δ • ॲཧ͢Δσʔλ୯ҐΛෳ਺ˠ1ͭ΁ • ͍ͭͰʹσʔλετΞ΁ঢ়ଶ͕ڽू͞ΕΔ
  22. ׬