Multiple Site
自從有了 Let’s Encrypt 以後,網站的 ssl 憑證都是用他們家
免費的憑証,原本的設定都是把 nginx 擺在前面,利用 virtual host
的方式,可以對應到多個站點,用 acme.sh
command line 的工具去管理,多個站點的 ssl 憑証更新,時間久了,還是
覺得麻煩,後來乾脆,直接只跑一個 golang 的 server 同時 host 多個站點
這一個範例選用的是 gorilla mux
單純就是他已經有 Host 的功能可以直接用
還有很多其他的選擇,一般來說都會比較快,像是介面同
golang standard library 的 go-zoo/bone
或是 go-chi 都是小而美的選擇,盡量如果標準的
library 介面的能解決,就不需要用 framework 來解,很容易陷入學習
framework 的寫法,而不是語言本身的寫作方式
寫起來大概像是這樣(實際請還是自己看一下文件,程式只有大概)
import (
"crypto/tls"
"net/http"
"github.com/gorilla/mux"
"golang.org/x/crypto/acme/autocert"
)
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
func main(){
r := mux.NewRouter()
blogRouter := r.Host("blog.yours.net").Subrouter()
appRouter := r.Host("coolapp.net").Subrouter()
blogRouter.PathPrefix("/").Handler(http.FileServer(http.Dir("./public")))
appRouter.HandleFunc("/", Index).Methods("GET")
certManager := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("blog.yours.net", "coolapp.net"),
Cache: autocert.DirCache("certs"), //folder for storing certificates
}
server := &http.Server{
Addr: ":443",
Handler: r,
TLSConfig: &tls.Config{
GetCertificate: certManager.GetCertificate,
},
}
go func() {
log.Printf("Starting HTTPS service on :443 ...")
server.ListenAndServeTLS("", "") //key and cert are comming from Let's Encrypt
}()
log.Printf("Starting HTTP service on :80")
http.ListenAndServe(":80", certManager.HTTPHandler(r))
}