用 let's Encrypt 實現 HTTPS 示例( fasthttp 與net/http)

tsingson發表於2019-08-08

[摘要] let's Encrypt 是一個免費提供 HTTPS 的簽名服務, 這裡提供一個示例,用 certmagic 實現 fasthttp 與 net/http 上支援 HTTPS

0. 基本配置

我的域名, 包括 tsingson.io 與 www.tsingson.io , 在 DNS 上加上 A 記錄, 指向我的伺服器 IP

為了在 let's Encrypt 獲取 HTTPS 簽名證書, 使用 tsingson_at_me_com 這個郵箱進行管理

伺服器上, 把 HTTPS 簽名證書檔案存在 /home/go/bin/ 路徑下

1. 使用 certmagic 庫獲取 HTTPS證書, 生產模式( 另有測試模式)

package autotls

import (
    "github.com/mholt/certmagic"
    "golang.org/x/xerrors"
)

// LetsEncryptTLS the management of let's Encrypt to get domain's key and cert file
// path to save the cache of key/cert file
// email is your email , to manage domain in let's Encrypt
// domainName , like tsingson.io / www.tsingson.io ... the domain name list
func LetsEncryptTLS(path string, email string, domainName ...string) (err error) {
    config := certmagic.Config{
        Agreed:  true,
        Storage: &certmagic.FileStorage{Path: path},
        CA:      certmagic.LetsEncryptProductionCA, //  use certmagic.LetsEncryptStagingCA for testing
        Email:   email,                             // your email to management let's Encrypt
    }

    cache := certmagic.NewCache(certmagic.CacheOptions{
        GetConfigForCert: func(cert certmagic.Certificate) (certmagic.Config, error) {
            return config, nil
        },
    })

    magic := certmagic.New(cache, config)

    if len(domainName) == 0 {
        return xerrors.New("Need one DomainName at least")
    }
    err = magic.Manage(domainName)
    if err != nil {
        return
    }

    return
}

呼叫方式, 見程式碼


go autotls.LetsEncryptTLS("/home/go/bin/", "tsingson@me.com", "www.tsingson.io", "tsingson.io")

time.Sleep(1 * time.Minute) // 等待一下, 讓 HTTPS 證書快取成功........

首次執行前, 請建立 /home/go/bin 路徑

執行時會列印日誌, 約有 3秒左右, 會成功獲取 HTTPS 簽名證書, 存在以下路徑( 注: 生產模式 )


/home/go/bin/acme #  tree .
.
└── acme-v02.api.letsencrypt.org
    ├── challenge_tokens
    ├── sites
    │   ├── tsingson.io
    │   │   ├── tsingson.io.crt
    │   │   ├── tsingson.io.json
    │   │   └── tsingson.io.key
    │   └── www.tsingson.io
    │       ├── www.tsingson.io.crt
    │       ├── www.tsingson.io.json
    │       └── www.tsingson.io.key
    └── users
        └── tsingson@me.com
            ├── tsingson.json
            └── tsingson.key

7 directories, 8 files

certmagic 的 Manage 將來會自動更新 HTTPS 證書

注: 測試模式, 快取的 HTTPS 證書儲存路徑不太一樣, 請自行檢查路徑

2. 在 net/http 上使用

package main

import (
    // "fmt"
    // "io"
    "net/http"
    "log"

    "github.com/tsingson/vk/fast/autotls"
)

func HelloServer(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("This is an example server.\n"))
    // fmt.Fprintf(w, "This is an example server.\n")
    // io.WriteString(w, "This is an example server.\n")
}

func main() {

    go autotls.LetsEncryptTLS("/home/go/bin/", "tsingson@me.com", "www.tsingson.io", "tsingson.io")
    time.Sleep(1 * time.Minute)

    http.HandleFunc("/hello", HelloServer)
    err := http.ListenAndServeTLS(":443", "/home/go/bin/acme-v02.api.letsencrypt.org/site/tsingson.io/tsingson.io.crt", "/home/go/bin/acme-v02.api.letsencrypt.org/site/tsingson.io/tsingson.io.key", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

3. 在 fasthttp 上使用

package main

import (
    "log"

    "github.com/valyala/fasthttp"
    "github.com/tsingson/vk/fast/autotls"
)

func main() {

    go autotls.LetsEncryptTLS("/home/go/bin/", "tsingson@me.com", "www.tsingson.io", "tsingson.io")
    time.Sleep(1 * time.Minute)

    fs := &fasthttp.FS{
        // Path to directory to serve.
        Root: "/home/www/static-site",

        // Generate index pages if client requests directory contents.
        GenerateIndexPages: true,

        // Enable transparent compression to save network traffic.
        Compress: true,
    }

    // Create request handler for serving static files.
    h := fs.NewRequestHandler()

    s := &fasthttp.Server{
        Handler: h,
    }

    // Start the server.
    if err := fasthttp.ListenAndServeTLS(":443", "/home/go/bin/acme-v02.api.letsencrypt.org/site/tsingson.io/tsingson.io.crt", "/home/go/bin/acme-v02.api.letsencrypt.org/site/tsingson.io/tsingson.io.key", h); err != nil {
        log.Fatalf("error in ListenAndServe: %s", err)
    }
}

4. 小結

瀏覽器上驗證, 步驟省略.........

Done. 完美.......

let's Encrypt 的測試模式, 在瀏覽器上驗證, 會提示, 不是安全的 HTTPS 簽名證書.

換成生產模式就好了...........

_

_

_

關於我

網名 tsingson (三明智, 江湖人稱3爺)

原 ustarcom IPTV/OTT 事業部播控產品線技術架構溼/解決方案工程溼角色(8年), 自由職業者,

喜歡音樂(口琴,是第三/四/五屆廣東國際口琴嘉年華的主策劃人之一), 攝影與越野,

喜歡 golang 語言 (商用專案中主要用 postgres + golang )

_

_ tsingson 寫於中國深圳 小羅號口琴音樂中心, 2019/08/07

相關文章