You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

698 lines
23 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="en-us">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "BlogPosting",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https:\/\/h.cowbay.org"
},
"articleSection" : "post",
"name" : "[筆記] 在 ubuntu 20.04 底下用certbot 透過Cloudflare 申請全域的 Letsencrypt 憑證",
"headline" : "[筆記] 在 ubuntu 20.04 底下用certbot 透過Cloudflare 申請全域的 Letsencrypt 憑證",
"description" : "\x3cp\x3e之前用caddy 作為反向代理其中一個優勢就是caddy 會自動處理Letsencrypt 憑證的問題\x3c\/p\x3e\n\x3cp\x3e也不用煩惱怎麼去更新一堆有的沒的\x3c\/p\x3e\n\x3cp\x3e不過實際應用上還是偶爾會拿這些憑證檔案來用的狀況\x3c\/p\x3e\n\x3cp\x3e雖然可以從caddy 上面取得這些檔案\x3c\/p\x3e\n\x3cp\x3e但是基本上這些檔案都是綁定一個特定的hostname\x3c\/p\x3e\n\x3cp\x3e可是我想要有一個憑證可以給同網域底下的機器用 ( Wildcard certificates )\x3c\/p\x3e",
"inLanguage" : "en",
"author" : "Eric Chang",
"creator" : "Eric Chang",
"publisher": "Eric Chang",
"accountablePerson" : "Eric Chang",
"copyrightHolder" : "Eric Chang",
"copyrightYear" : "2020",
"datePublished": "2020-09-02 15:55:40 \x2b0800 CST",
"dateModified" : "2020-09-02 15:55:40 \x2b0800 CST",
"url" : "https:\/\/h.cowbay.org\/post\/ubuntu-letsencrypt-cloudflare-wildcard\/",
"wordCount" : "469",
"image" : "https://h.cowbay.orghttps://h.cowbay.org/images/post-default-4.jpg"",
"keywords" : [ ""certbot"",""Cloudflare"",""Letsencrypt"","Blog" ]
}
</script>
<title>[筆記] 在 ubuntu 20.04 底下用certbot 透過Cloudflare 申請全域的 Letsencrypt 憑證 </title>
<meta name="description" content="some articles about job,food,passion sisters" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all,follow">
<meta name="googlebot" content="index,follow,snippet,archive">
<link rel="stylesheet" id="ct-tracks-google-fonts-css" href="https://fonts.googleapis.com/css?family=Raleway%3A400%2C700&amp;subset=latin%2Clatin-ext&amp;ver=4.7.2" type="text/css" media="all">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<link href="https://h.cowbay.org/css/style.css?v=1629957884" rel="stylesheet" id="theme-stylesheet" type='text/css' media='all'>
<link href="https://h.cowbay.org/css/custom.css?v=1629957884" rel="stylesheet" type='text/css' media='all'>
<link rel="shortcut icon" href="https://h.cowbay.org/img/favicon.ico" type="image/x-icon">
<link rel="icon" href="https://h.cowbay.org/img/favicon.ico" type="image/x-icon">
<script type="application/javascript">
var doNotTrack = false;
if (!doNotTrack) {
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-138954876-1', 'auto');
ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
</head>
<body class="post-template-default single single-post single-format-standard ct-body singular singular-post not-front standard">
<div id="overflow-container" class="overflow-container">
<a class="skip-content" href="#main">Skip to content</a>
<header id="site-header" class="site-header" role="banner">
<div class='top-navigation'>
<div class='container'>
<div id="menu-secondary" class="menu-container menu-secondary" role="navigation">
<button id="toggle-secondary-navigation" class="toggle-secondary-navigation"><i class="fas fa-plus"></i></button>
<div class="menu">
<ul id="menu-secondary-items" class="menu-secondary-items">
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/ansible">ansible</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/linux">linux</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/proxmox">proxmox</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/ps">ps</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/%E7%A2%8E%E5%BF%B5">碎念</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/%E7%AD%86%E8%A8%98">筆記</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/%E7%BE%A4%E6%9A%89">群暉</a>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category">
<a href="/categories/%E9%9B%9C%E5%BF%B5">雜念</a>
</li>
</ul>
</div>
</div>
<ul class="social-media-icons">
<li>
<a href="full%20Social%20profile%20url%20in%20facebook" data-animate-hover="pulse" class="facebook" target="_blank">
<i class="fab fa-facebook-square" title="facebook"></i>
<span class="screen-reader-text">facebook</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20googleplus" data-animate-hover="pulse" class="gplus" target="_blank">
<i class="fab fa-google-plus-g" title="googleplus"></i>
<span class="screen-reader-text">googleplus</span>
</a>
</li>
<li>
<a href="chang0206" data-animate-hover="pulse" class="twitter" target="_blank">
<i class="fab fa-twitter-square" title="twitter"></i>
<span class="screen-reader-text">twitter</span>
</a>
</li>
<li>
<a href="chang0206" data-animate-hover="pulse" class="instagram" target="_blank">
<i class="fab fa-instagram" title="instagram"></i>
<span class="screen-reader-text">instagram</span>
</a>
</li>
<li>
<a href="mailto:mc@hotshraingmy.info" data-animate-hover="pulse" class="email">
<i class="fas fa-envelope" title="email"></i>
<span class="screen-reader-text">email</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20linkedin" data-animate-hover="pulse" class="linkedin" target="_blank">
<i class="fab fa-linkedin-in" title="linkedin"></i>
<span class="screen-reader-text">linkedin</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20stackoverflow" data-animate-hover="pulse" class="stackoverflow" target="_blank">
<i class="fab fa-stack-overflow" title="stackoverflow"></i>
<span class="screen-reader-text">stackoverflow</span>
</a>
</li>
<li>
<a href="changchichung" data-animate-hover="pulse" class="github" target="_blank">
<i class="fab fa-github" title="github"></i>
<span class="screen-reader-text">github</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20pinterest" data-animate-hover="pulse" class="pinterest" target="_blank">
<i class="fab fa-pinterest" title="pinterest"></i>
<span class="screen-reader-text">pinterest</span>
</a>
</li>
<li>
<a href="https://h.cowbay.org/index.xml" data-animate-hover="pulse" class="rss" target="_blank">
<i class="fas fa-rss" title="rss"></i>
<span class="screen-reader-text">rss</span>
</a>
</li>
</ul></div>
</div>
<div class="container">
<div id="title-info" class="title-info">
<div id='site-title' class='site-title'>
<a href="/"> MC部落 </a>
</div>
</div>
<button id="toggle-navigation" class="toggle-navigation">
<i class="fas fa-bars"></i>
</button>
<div id="menu-primary-tracks" class="menu-primary-tracks"></div>
<div id="menu-primary" class="menu-container menu-primary" role="navigation">
<p class="site-description">Whats the Worst That Could Happen?</p>
<div class="menu">
<ul id="menu-primary-items" class="menu-primary-items">
<li class='menu-item menu-item-type-custom menu-item-object-custom '>
<a href="https://h.cowbay.org/">Home</a>
</li>
<li class='menu-item menu-item-type-post_type menu-item-object-page '>
<a href="https://h.cowbay.org/about/">About</a>
</li>
<li class='menu-item menu-item-type-post_type menu-item-object-page '>
<a href="https://h.cowbay.org/contact/">Get in touch</a>
</li>
</ul>
</div>
</div>
</div>
</header>
<div id="main" class="main" role="main">
<div id="loop-container" class="loop-container">
<div class="post type-post status-publish format-standard has-post-thumbnail hentry category-design tag-design tag-standard-2 tag-tagalicious tag-travel entry full-without-featured odd excerpt-1">
<div class='featured-image lazy lazy-bg-image' data-background="https://h.cowbay.org/images/post-default-4.jpg">
</div>
<div class="entry-meta">
<span class="date">02 September</span> <span> / </span>
<span class="author">
<a href="https://github.com/changchichung" title="Posts by Eric Chang" rel="author">Eric Chang</a>
</span>
<span class="category">
<span> / </span>
<a href="/categories/%E7%AD%86%E8%A8%98">筆記</a>
</span>
</div>
<div class='entry-header'>
<h1 class='entry-title'> [筆記] 在 ubuntu 20.04 底下用certbot 透過Cloudflare 申請全域的 Letsencrypt 憑證</h1>
</div>
<div class="entry-container">
<div class="entry-content">
<article>
<p>之前用caddy 作為反向代理其中一個優勢就是caddy 會自動處理Letsencrypt 憑證的問題</p>
<p>也不用煩惱怎麼去更新一堆有的沒的</p>
<p>不過,實際應用上,還是偶爾會拿這些憑證檔案來用的狀況</p>
<p>雖然可以從caddy 上面取得這些檔案</p>
<p>但是基本上這些檔案都是綁定一個特定的hostname</p>
<p>可是我想要有一個憑證,可以給同網域底下的機器用 ( Wildcard certificates )</p>
<p>要申請Wildcard certificates ,必須要採用 DNS 驗證的方式</p>
<p>一般手動操作的步驟,會先產生一組亂數字串,然後更新 DNS 上面去</p>
<p>如果要改成自動化,要多一些步驟</p>
<h3 id="安裝-certbot-及-cloudflare-外掛">安裝 certbot 及 Cloudflare 外掛</h3>
<p>首先,先來安裝會用到的套件</p>
<pre><code>sudo apt install certbot letsencrypt python3-certbot-dns-cloudflare
</code></pre><h3 id="設定-cloudflare-api">設定 cloudflare API</h3>
<p>這個步驟我測了好久網路上的說明似乎都過期了造成cloudflare API 那邊會發生錯誤</p>
<p>先登入 cloudflare 管理界面的API token 設定</p>
<p><a href="https://dash.cloudflare.com/profile/api-tokens">https://dash.cloudflare.com/profile/api-tokens</a></p>
<p>建立一組token</p>
<p>內容如下</p>
<p><img src="'https://i.imgur.com/3dZN6qC.png'" alt="&lsquo;cloudflare API&rsquo;"></p>
<p>在權限設定的地方,選擇三個項目</p>
<p>zone-zone settings-edit
zone-zone-edit
zone-DNS-edit</p>
<p>在下一個 zone resources 選擇 include-All zones</p>
<p>存檔後會產生一組 API token ,接著就是用這組 token 來做DNS更新</p>
<h3 id="編輯-cloudflare-設定檔">編輯 cloudflare 設定檔</h3>
<p>在 /etc底下新增一個 cloudflare.ini</p>
<p>內容如下</p>
<pre><code>sudo vim /etc/cloudflare.ini
dns_cloudflare_email = #email@address.here
dns_cloudflare_api_key = #API token here
</code></pre><p>存檔後離開然後改一下權限不然等一下certbot 會跳警告</p>
<pre><code>sudo chmod 0600 /etc/cloudflare.ini
</code></pre><h3 id="執行certbot-取得憑證">執行certbot 取得憑證</h3>
<p>執行以下的指令</p>
<pre><code>sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare.ini --preferred-challenges=dns --email admin@abc.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d abc.com -d *.abc.com
</code></pre><p>正常的話,會是這樣的結果</p>
<pre><code>sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare.ini --preferred-challenges=dns --email admin@abc.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d abc.com -d *.abc.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for abc.com
dns-01 challenge for abc.com
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/abc.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/abc.com/privkey.pem
Your cert will expire on 2020-12-01. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
&quot;certbot renew&quot;
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
</code></pre><p>這樣子就取得了全域通用的SSL 憑證檔案</p>
<p>如果看到底下這種錯誤</p>
<pre><code>administrator@ubuntu:~$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare.ini --preferred-challenges=dns --email admin@abc.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d abc.com -d *.abc.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for abc.com
dns-01 challenge for abc.com
Cleaning up challenges
Error determining zone_id: 6003 Invalid request headers. Please confirm that you have supplied valid Cloudflare API credentials. (Did you copy your entire API key?)
</code></pre><p>那就是cloudflare API 那邊的權限設定錯了,我就是在這邊卡很久&hellip;</p>
<p>請參照上面的步驟和圖片正確的設定</p>
<p>可以用 certbot certificates 來驗證看看</p>
<pre><code>administrator@ubuntu:~$ sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: abc.com
Domains: abc.com *.abc.com
Expiry Date: 2020-12-01 05:31:31+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/abc.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/abc.com/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
</code></pre><p>之後就可以用</p>
<pre><code>sudo certbot renew
</code></pre><p>來更新憑證</p>
<p>寫到/etc/crontab 去排程每個月的1號自動更新</p>
<pre><code>administrator@ubuntu:~$ echo &quot;* * 1 * * root /usr/bin/certbot renew&quot; |sudo tee -a /etc/crontab
* * 1 * * root /usr/bin/certbot renew
administrator@ubuntu:~$
</code></pre><p>接下來就等三個月之後,檢查看看憑證是否有自動更新了!</p>
</article>
</div>
<div class='entry-meta-bottom'>
<div class="entry-categories"><p><span>Categories</span>
<a href="/categories/%E7%AD%86%E8%A8%98" title="View all posts in 筆記">筆記</a>
</p>
</div>
<div class="entry-tags"><p><span>Tags</span>
<a href="/tags/certbot" title="View all posts tagged certbot">certbot</a>
<a href="/tags/cloudflare" title="View all posts tagged Cloudflare">Cloudflare</a>
<a href="/tags/letsencrypt" title="View all posts tagged Letsencrypt">Letsencrypt</a>
</p></div> </div>
<div class="author-meta">
<div class="author">
<img alt='Eric Chang' src="https://www.gravatar.com/avatar/23f8ed94e007297499ac8df1641b3ff5?s=100&d=identicon" class='avatar avatar-72 photo' height='72' width='72'>
<span>
Written by:<a href="https://github.com/changchichung" title="Posts by Eric Chang" rel="author">Eric Chang</a> </span>
</div>
<div class="bio">
<p>塵世裡一個迷途小書僮</p>
<a class="facebook" target="_blank"
href="full%20Social%20profile%20url%20in%20facebook">
<i class="fab fa-facebook-f"
title="facebook icon"></i>
</a>
<a class="googleplus" target="_blank"
href="full%20profile%20url%20in%20googleplus">
<i class="fab fa-google-plus-g"
title="googleplus icon"></i>
</a>
<a class="twitter" target="_blank"
href="chang0206">
<i class="fab fa-twitter-square"
title="twitter icon"></i>
</a>
<a class="linkedin" target="_blank"
href="full%20profile%20url%20in%20linkedin">
<i class="fab fa-linkedin"
title="linkedin icon"></i>
</a>
<a class="email" target="_blank"
href="mailto:mc@hotshraingmy.info">
<i class="fas fa-envelope"
title="email icon"></i>
</a>
<a class="instagram" target="_blank"
href="chang0206">
<i class="fab fa-instagram"
title="instagram icon"></i>
</a>
<a class="stackoverflow" target="_blank"
href="full%20profile%20url%20in%20stackoverflow">
<i class="fab fa-stack-overflow"
title="stackoverflow icon"></i>
</a>
<a class="github" target="_blank"
href="changchichung">
<i class="fab fa-github"
title="github icon"></i>
</a>
<a class="pinterest" target="_blank"
href="full%20profile%20url%20in%20pinterest">
<i class="fab fa-pinterest"
title="pinterest icon"></i>
</a>
</div>
</div>
</div>
</div>
<section id="comments" class="comments">
<div id="disqus_thread"></div>
<script type="application/javascript">
var disqus_config = function () {
};
(function() {
if (["localhost", "127.0.0.1"].indexOf(window.location.hostname) != -1) {
document.getElementById('disqus_thread').innerHTML = 'Disqus comments not available by default when the website is previewed locally.';
return;
}
var d = document, s = d.createElement('script'); s.async = true;
s.src = '//' + "h-cowbay-org-1" + '.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="https://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</section>
</div>
</div>
<footer id="site-footer" class="site-footer" role="contentinfo">
<h1>
<a href=""> MC部落 </a>
</h1>
<p class="site-description">Whats the Worst That Could Happen?</p>
<div id="menu-footer" class="menu-container menu-footer" role="navigation">
<div class="menu">
<ul id="menu-footer-items" class="menu-footer-items">
</ul>
</div> </div>
<ul class="social-media-icons">
<li>
<a class="facebook" target="_blank"
href="full%20Social%20profile%20url%20in%20facebook" >
<i class="fab fa-facebook-f" title="facebook"></i>
<span class="screen-reader-text">facebook</span>
</a>
</li>
<li>
<a class="googleplus" target="_blank"
href="full%20profile%20url%20in%20googleplus" >
<i class="fab fa-google-plus-g" title="googleplus"></i>
<span class="screen-reader-text">googleplus</span>
</a>
</li>
<li>
<a href="chang0206" class="twitter" target="_blank">
<i class="fab fa-twitter-square" title="twitter"></i>
<span class="screen-reader-text">twitter</span>
</a>
</li>
<li>
<a href="chang0206" class="instagram" target="_blank">
<i class="fab fa-instagram" title="instagram"></i>
<span class="screen-reader-text">instagram</span>
</a>
</li>
<li>
<a href="mailto:mc@hotshraingmy.info" class="email">
<i class="fas fa-envelope" title="email"></i>
<span class="screen-reader-text">email</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20linkedin" class="linkedin" target="_blank">
<i class="fab fa-linkedin-in" title="linkedin"></i>
<span class="screen-reader-text">linkedin</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20stackoverflow" class="stackoverflow" target="_blank">
<i class="fab fa-stack-overflow" title="stackoverflow"></i>
<span class="screen-reader-text">stackoverflow</span>
</a>
</li>
<li>
<a href="changchichung" class="github" target="_blank">
<i class="fab fa-github" title="github"></i>
<span class="screen-reader-text">github</span>
</a>
</li>
<li>
<a href="full%20profile%20url%20in%20pinterest" class="pinterest" target="_blank">
<i class="fab fa-pinterest" title="pinterest"></i>
<span class="screen-reader-text">pinterest</span>
</a>
</li>
<li>
<a href="https://h.cowbay.org/index.xml" data-animate-hover="pulse" class="rss" target="_blank">
<i class="fas fa-rss" title="rss"></i>
<span class="screen-reader-text">rss</span>
</a>
</li>
</ul> <div class="design-credit">
<p>© 2018 Göran Svensson</p>
<p>Nederburg Hugo Theme by <a href="https://appernetic.io">Appernetic</a>.</p>
<p>A port of Tracks by Compete Themes.</p>
</div>
</footer>
</div>
<script src="https://h.cowbay.org/js/jquery.min.js"></script>
<script src="https://h.cowbay.org/js/jquerymigrate.js"></script>
<script src="https://h.cowbay.org/js/production.min.js?v=1629957884"></script>
</body>
</html>