Let's Encryptã¯ãElectronic Frontier Foundationã®Certbotã䜿çšããŠãSSL蚌ææžãååŸããããã»ã¹ãèªååããŸãã Unixã©ã€ã¯ãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã äžã§å®è¡ãããããŸããŸãªçš®é¡ã®WebãµãŒããŒïŒApacheãnginxãªã©ïŒããµããŒãããŸãã ãµãŒããŒãLet's Encryptã®ã·ã¹ãã èŠä»¶ãæºãããŠããå Žåãããã¯ãã»ãŒå®å šã«èªåã¢ãŒãã§èšŒææžãååŸã§ããããšãæå³ããŸãã æ®å¿µãªãããNode.js / Express.js Let's Encryptãã³ãã«ã¯ãµããŒãããŠããŸããã ã€ãŸãããã®å ŽåãCertbotãã蚌ææžãèªåçã«ååŸããããšã¯ã§ããŸããã ãã ãããã¹ãŠã倱ãããããã§ã¯ãããŸããã Let's EncryptãšCertbotã䜿çšãããšã蚌ææžãæäœæ¥ã§ååŸããã®ã¯ããã»ã©é£ãããããŸããã
äºåæ å ±
Certbotãwebrootã¢ãŒãã§äœ¿çšãã--webroot
--webroot
ãŸãã äžèšã§èšãã°ããã®ã¢ãŒãã§ã¯ãCertbotã¯ãµãŒããŒã®ç¹å®ã®ãã£ã¬ã¯ããªã«ãã¡ã€ã«ãé 眮ããŸãããã®ãã£ã¬ã¯ããªã¯HTTPçµç±ã§ã¢ã¯ã»ã¹ã§ããã¯ãã§ãã
Expressã䜿çšãããšã
express.static()
é¢æ°ã䜿çšããŠéçãã¡ã€ã«ãå«ããã£ã¬ã¯ããªãæäŸã§ããŸãã
webroot ã¢ãŒãã® Certbotããã¥ã¡ã³ãã»ã¯ã·ã§ã³ãèŠããšãCertbotã¯
http://<your_server_url>/.well-known/acme-challenge/
ãµãŒããŒäžã®ãã¡ã€ã«ãæ€çŽ¢ããŠããããšã
http://<your_server_url>/.well-known/acme-challenge/
ãŸãã æå®ããããã£ã¬ã¯ããªã«é 眮ãããHTTPãã¡ã€ã«ãæ£åžžã«åä¿¡ã§ããå Žåããã®ãµãŒããŒã®SSL蚌ææžãäœæããŸãã
ããã§ã¯å§ããŸãããã
äœæ¥èšç»
蚌ææžãååŸããŠãã®é¢é£æ§ãç¶æããã«ã¯ã5ã€ã®æ®µéãçµãå¿ èŠããããŸãã
- é©åãªããŒãããªãã€ã¬ã¯ãããŸãã
- éçãã¡ã€ã«ã®ãã£ã¬ã¯ããªæ§é ãæ§æããExpressã䜿çšããŠãã®ã¡ã³ããã³ã¹ãæŽçããŸãã
- Certbotãã€ã³ã¹ããŒã«ããŠå®è¡ããŸãã
- HTTPSã䜿çšããããã«Expressãæ§æããŸãã
- 90æ¥åŸã«Let's Encrypt蚌ææžãæŽæ°ããŸãã
以äžã«ãã³ãŒããšã³ãã³ãã®äŸã䜿çšããŠããããã®æé ããã詳现ã«èª¬æããŸãã
ããŒã転é
ããã§åé¡ãçºçããããšã¯ãªããšç¢ºä¿¡ããŠããŸãããå®å šãæãããã«ããã®æé ã«ã€ããŠèª¬æããŸãã
æ€èšŒãæåãããã«ã¯ããµãŒããŒURLãå¿ èŠã§ãã Certbotã¯ãã®URLã䜿çšããŠãµãŒããŒã«æ¥ç¶ããHTTPçµç±ã§ããŒã¿ãååŸããŸãã ããã¯ãæäŸãããURLã®ããŒã80ãã€ã³ã¿ãŒãããããã¢ã¯ã»ã¹å¯èœã§ãªããã°ãªããªãããšãæå³ããŸãã ããã¯ããã©ã«ãã®HTTPSããŒãã§ãããããããŒã443ãéããŠã害ã¯ãããŸããã
å人çã«ã¯ãExpressãµãŒããŒã1024ãè¶ ããããŒãã«ä¿æãããªãã€ã¬ã¯ãã«ãŒã«ã䜿çšããŠãããŒã80ãŸãã¯443ãããµãŒããŒã«ãã©ãã£ãã¯ã転éããããšã奜ã¿ãŸãã ãã®çµæãç¹ã«WebãµãŒããŒãæœåšçã«å±éºãªãã©ãã£ãã¯ãåŠçããããšãèãããšãExpressã®ææ Œãããç¹æš©ãäžããå¿ èŠã¯ãããŸããã
ãããã¯ãŒã¯èšå®ã確èªããã«ã¯ã
curl
ãŠãŒãã£ãªãã£ã䜿çšã§ããŸãã ããšãã°ããµãŒããŒãã·ã¹ãã ããã¹ãããããã®ã¢ãã¬ã¹ãæã£ãŠããå ŽåïŒåžžã«äŸ¿å©ã§ãïŒã
curl
ã䜿çšããŠãã®ã¢ãã¬ã¹ãžã®èŠæ±ãè¡ãããšãã§ããŸãã ãµãŒããŒã次ã®ããã«æ§æãããŠãããšããŸãã
// filename: app.js const app = require('express')(); app.get('/health-check', (req, res) => res.sendStatus(200)); app.listen(8080);
curl
ã䜿çšããŠ
health-check
ãšã³ããã€ã³ãã«ã¢ã¯ã»ã¹ãããšããã¹ãŠã
health-check
ã§ãããHTTP 200å¿çã瀺ãããŸãã
curl http://<your_server_url>/health-check
ãããã¯ãŒã¯ãšãµãŒããŒã䜿çšããæºåãã§ããããéçãã¡ã€ã«ã®ãµãŒãã¹ã®æ§æã«é²ãããšãã§ããŸãã
éçãã¡ã€ã«ã®æäŸ
åè¿°ã®ããã«ããµãŒããŒã確èªããããã«Certbotãé£çµ¡ããã¢ãã¬ã¹ã¯
/.well-known/acme-challenge
ã§ãã Expressã¯
express.static()
é¢æ°ã䜿çšããŠããã®é¢æ°ã§æå®ããããã¹ã«æ²¿ã£ãŠéçãã¡ã€ã«ãæäŸããŸãã ãã®ãã¹ã¯ãµãŒããŒã®ã«ãŒãã«ãªããŸãã å€ãã®å ŽåãWebãµã€ãã®éçããŒã¿ãæ ŒçŽãããã©ã«ããŒã¯
public
ãŸãã¯
static
ãšåŒã°ããããšãã°ããã¡ã€ã«ã·ã¹ãã ã«
/static/test-text/mytextfile.txt
ãšããŠããã¹ããã¡ã€ã«ã衚瀺ãããŠããå Žåãå€éšããã¢ã¯ã»ã¹ã§ããŸãã
http://<your_server_url/test-text/mytextfile.txt
ã ããã念é ã«çœ®ããŠãCertbotã®ããŒãºã«åãããŠãã£ã¬ã¯ããªæ§é ãäœæããExpressã«ãã©ã°ã€ã³ããŸãã
cd static mkdir -p .well-known/acme-challenge
äžèšã®ã³ãã³ãã¯ãããžã§ã¯ãã«ãŒãããå®è¡ãããéçããŒã¿ã®ãã£ã¬ã¯ããªã¯staticãšåŒã°ãããšæ³å®ãããŠã
static
ã
// filename: app.js const express = require('express'); const app = express(); app.use(express.static('static')); app.listen(8080);
次ã«ãExpressãæ£ãããã©ã«ããŒãæäŸããããã«æ§æãããåŸãã·ã¹ãã ã®ããã©ãŒãã³ã¹ã確èªããŸãã
echo "this is a test" > static/.well-known/acme-challenge/9001 curl http://<your_server_url>/.well-known/acme-challenge/9001
ãããã¯ãã¹ãã§ãããšããããã¹ããã³ã³ãœãŒã«ã«è¡šç€ºããããããã®æé ã¯æ£åžžã«å®äºããŠãããããããã«é²ãã§æ°ããSSL蚌ææžãäœæã§ããŸãã
èªèšŒããã
ãã®æ®µéã®æåã®ã¹ãããã¯ãCertbotãã€ã³ã¹ããŒã«ããããšã§ãã ã€ã³ã¹ããŒã«æé ã¯ãã¡ãã«ãããŸã ã ã€ãŸãããããã衚瀺ããã«ã¯ã[ 䜿çšäž]ãã£ãŒã«ãã§ãäžèšã® [ ãªã]ãéžæãã次ã®ãã£ãŒã«ãã§OSãéžæããŸãã ãã®åŸãã€ã³ã¹ããŒã«ã³ãã³ãã衚瀺ãããŸãã ããšãã°ãUbuntu 16.04ïŒxenialïŒã®å Žåããã®ã³ãã³ãã¯æ¬¡ã®ããã«ãªããŸãïŒ
sudo apt-get install letsencrypt
次ã®ã¹ãããã¯ã蚌ææžãçæããããšã§ãã æ¢ã«è¿°ã¹ãããã«ãCertbotãwebrootã¢ãŒãã§èµ·åããŸãã ãããè¡ãã«ã¯ãWebãµãŒããŒã®ã«ãŒããšããŠäœ¿çšããããã¹ïŒ
âw
ã䜿çšïŒãšãã¡ã€ã³åïŒ
âd
ã¹ã€ããã䜿çšïŒãæž¡ãå¿ èŠããããŸãã ãã®å Žåãã³ãã³ãã¯æ¬¡ã®ããã«ãªããŸãã
letsencrypt --webroot -w ./static -d <your_server_url>
ããã§ã¯ããããžã§ã¯ããã£ã¬ã¯ããªã«ãããšããåæããé²ã¿ãŸãã ã³ãã³ããæ£åžžã«å®è¡ããããšã察å¿ããã¡ãã»ãŒãžãšçæããããã¡ã€ã«ã®å Žæã«é¢ããæ å ±ã衚瀺ãããŸãã ãããã¯éåžž
/etc/letsencrypt/live/<your_server_url>
ãŸãã ãããã®ãã¡ã€ã«ãäœã§ãããã¯ã Certbotããã¥ã¢ã«ã®Webrootã»ã¯ã·ã§ã³ã§ç¢ºèªã§ããŸãã ExpressãµãŒããŒã§
fullchain.pem
ããã³
privkey.pem
ãã¡ã€ã«ã䜿çšããŸãã
ãããïŒ ããããæ°ããSSL蚌ææžã§ãã ä»ããã䜿çšããŸãã
Expressããã³HTTPS
Expressã¯ãã€ã³ã¹ããŒã«çŽåŸã«HTTPçµç±ã§ã®ã¿æ©èœããŸãã Node
https
ã¢ãžã¥ãŒã«ã䜿çšããŠãExpressã§HTTPSã®äœ¿çšãæ§æã§ããŸãã ãããè¡ãã«ã¯ã蚌ææžãšç§å¯éµã®2ã€ã®ãã¡ã€ã«ãå¿ èŠã§ãã ã¡ãªã¿ã«ããµãŒããŒã®ç§å¯éµãpr玢奜ããªç®ããå®ããç§å¯éµãã¡ã€ã«ãžã®ã¢ã¯ã»ã¹ãèš±å¯ããããŠãŒã¶ãŒã®ã¿ã«äžããŠãã ããã
ããã«ã
fullchain.pem
ããã³
privkey.pem
ããããžã§ã¯ããã£ã¬ã¯ããªã«ã³ããŒããããããããžã®ã·ã³ããªãã¯ãªã³ã¯ãäœæããããšããå§ãããŸãã ã·ã³ããªãã¯ãªã³ã¯ãäœæãããšãæŽæ°ããã»ã¹ãç°¡åã«ãªããŸãããéžæã¯ãŠãŒã¶ãŒæ¬¡ç¬¬ã§ãã
以äžã®ã³ãŒãã¯ã
fullchain.pem
ããã³
privkey.pem
ããããžã§ã¯ããã£ã¬ã¯ããªã®
sslcert
ãã©ã«ããŒã«ãããšããåæã«åºã¥ããŠããŸãã
// filename: app.js const https = require('https'); const fs = require('fs'); const express = require('express'); const app = express(); // Express const options = { cert: fs.readFileSync('./sslcert/fullchain.pem'), key: fs.readFileSync('./sslcert/privkey.pem') }; express.listen(8080); https.createServer(options, app).listen(8443);
ããã«ã Helmet.jsã¯ããã§ã¯åé¡ãããŸããã ãã®ããã±ãŒãžã¯ãHTTPããããŒã管çããããšã§ExpressãµãŒããŒãä¿è·ããã®ã«åœ¹ç«ã¡ãŸãã ç¹ã«ã HSTSãè¿œå ããX-Powered-ByããããŒãåé€ããX-Frame-OptionsããããŒãèšå®ããŠã¯ãªãã¯ãžã£ããã³ã°ãé²ããŸãã
ã€ã³ã¹ããŒã«ã¯ãšãŠãç°¡åã§ãïŒ
npm install --save helmet
Helmetãã€ã³ã¹ããŒã«ãããšãExpressã§ããŒã¿åŠçã®äžéå±€ãšããŠäœ¿çšã§ããŸãã
// filename: app.js app.use(require('helmet')());
æåŸã«ããã¹ãŠãæ©èœããããšãæçµçã«ç¢ºèªããããã«ã SSL Server Testã®ãããªãã®ã䜿çšããŠãµãŒããŒããã§ãã¯ã§ããŸã ã
蚌ææžã®æŽæ°
Let's Encrypt蚌ææžã¯90æ¥éæå¹ã§ãã ç¹ã«èšŒææžãæŽæ°ããããã»ã¹ãéåžžã«åçŽã§ããããšãèãããšããããè¯ããæªãããè°è«ããã®ã¯ç¡æå³ã§ãã ã€ãŸãã蚌ææžãæŽæ°ããã«ã¯ã
letsencrypt renew
ã³ãã³ããå®è¡ããã ãã§ååã§ã
letsencrypt renew
ã¯æ°ãã蚌ææžãçºè¡ããŸãã
cron
ãžã§ããŸãã¯
systemd
ãªã©ã䜿çšããŠããã®ããã»ã¹ãèªååããããšããå§ãããŸãã
çµè«
ãã®çµæãç¹å®ã®ãã¹ã§éçãã¡ã€ã«ãæäŸããããã«ExpressãµãŒããŒãæ§æããwebrootã¢ãŒãã§Certbotã䜿çšããŠãµãŒããŒèšŒææžãäœæããäœæãã蚌ææžã䜿çšããŠHTTPSãExpressã«æ¥ç¶ããŸããã Certbotãšå¯Ÿè©±ããèªåããã»ã¹ã¯å©çšã§ããŸããããå¿ èŠãªãã¹ãŠãæåã§è¡ãããšã¯ããã»ã©é£ãããããŸããã
è¿ãå°æ¥ãCertbotã«Node.jsã®ãµããŒããè£ åãããããšãæåŸ ãããŠããŸãã
ExpressãµãŒããŒã®SSL蚌ææžã¯ã©ã®ããã«ååŸããŸããïŒ Let's Encryptã®èšŒææžã䜿çšããŠããŸããïŒ