1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        一個比 Nginx 功能更強大的 Web 服務器

        共 10022字,需瀏覽 21分鐘

         ·

        2021-02-24 12:37


        原文:https://mritd.com/2021/01/07/lets-start-using-caddy2/

        Caddy 簡介

        Caddy 是一個 Go 編寫的 Web 服務器,類似于 Nginx,Caddy 提供了更加強大的功能,隨著 v2 版本發(fā)布 Caddy 已經(jīng)可以作為中小型站點 Web 服務器的另一個選擇;相較于 Nginx 來說使用 Caddy 的優(yōu)勢如下:

        • 自動的 HTTPS 證書申請(ACME HTTP/DNS 挑戰(zhàn))
        • 自動證書續(xù)期以及 OCSP stapling 等
        • 更高的安全性包括但不限于 TLS 配置以及內(nèi)存安全等
        • 友好且強大的配置文件支持
        • 支持 API 動態(tài)調(diào)整配置(有木有人可以搞個 Dashboard)
        • 支持 HTTP3(QUIC)
        • 支持動態(tài)后端,例如連接 Consul、作為 k8s ingress 等
        • 后端多種負載策略以及健康檢測等
        • 本身 Go 編寫,高度模塊化的系統(tǒng)方便擴展(CoreDNS 基于 Caddy1 開發(fā))
        • ……

        就目前來說,Caddy 對于我個人印象唯一的缺點就是性能沒有 Nginx 高,但是這是個仁者見仁智者見智的問題;相較于提供的這些便利性,在性能可接受的情況下完全有理由切換到 Caddy。

        編譯 Caddy2

        注意: 在 Caddy1 時代,Caddy 官方發(fā)布的預編譯二進制文件是不允許進行商業(yè)使用的,Caddy2 以后已經(jīng)全部切換到 Apache 2.0 License。

        在默認情況下 Caddy2 官方提供了預編譯的二進制文件,以及自定義 build 下載頁面,不過對于需要集成一些第三方插件時,我們?nèi)孕璨捎霉俜教峁┑?xcaddy 來進行自行編譯;以下為具體的編譯過程:

        Golang 環(huán)境安裝

        本部分編譯環(huán)境默認為 Ubuntu 20.04 系統(tǒng),同時使用 root 用戶,其他環(huán)境請自行調(diào)整相關(guān)目錄以及配置;編譯時自行處理好科學上網(wǎng)相關(guān)配置,也可以直接用國外 VPS 服務器編譯。

        首先下載 go 語言的 SDK 壓縮包,其他平臺可以從 https://golang.org/dl/ 下載對應的壓縮包:

        wget?https://golang.org/dl/go1.15.6.linux-amd64.tar.gz

        下載完成后解壓并配置相關(guān)變量:

        #?解壓
        tar?-zxvf?go1.15.6.linux-amd64.tar.gz

        #?移動到任意目錄
        mkdir?-p?/opt/devtools
        mv?go?/opt/devtools/go

        #?創(chuàng)建?go?相關(guān)目錄
        mkdir?-p?${HOME}/gopath/{src,bin,pkg}

        #?調(diào)整變量配置,將以下變量加入到?shell?初始化配置中
        #?bash?用戶請編輯?~/.bashrc
        #?zsh?用戶請編輯?~/.zshrc
        export?GOROOT='/opt/devtools/go'
        export?GOPATH="${HOME}/gopath"
        export?GOPROXY='https://goproxy.cn'?#?如果已經(jīng)解決了科學上網(wǎng)問題,GOPROXY?變量可以刪除,否則可能會起反作用
        export?PATH="${GOROOT}/bin:${GOPATH}/bin:${PATH}"

        #?讓配置生效
        #?bash?用戶替換成?~/.basrc
        #?重新退出登錄也可以
        source?~/.zshrc

        配置完成后,應該在命令行執(zhí)行 go version 并有以下成功返回:

        bleem???~?go?version
        go?version?go1.15.6?linux/amd64

        安裝 xcaddy

        按照官方文檔直接命令行執(zhí)行 go get -u github.com/caddyserver/xcaddy/cmd/xcaddy 安裝即可:

        bleem???~?go?get?-u?github.com/caddyserver/xcaddy/cmd/xcaddy
        go:?downloading?github.com/caddyserver/xcaddy?v0.1.7
        go:?found?github.com/caddyserver/xcaddy/cmd/xcaddy?in?github.com/caddyserver/xcaddy?v0.1.7
        go:?downloading?github.com/Masterminds/semver/v3?v3.1.0
        go:?github.com/Masterminds/semver/v3?upgrade?=>?v3.1.1
        go:?downloading?github.com/Masterminds/semver/v3?v3.1.1
        .....

        安裝完成后應當在命令行可以直接執(zhí)行 xcaddy 命令:

        #?xcaddy?并沒有提供完善的命令行支持,所以?`--help`?報錯很正常
        bleem????~?xcaddy?--help
        go:?cannot?match?"all":?working?directory?is?not?part?of?a?module
        2021/01/07?12:15:56?[ERROR]?exec?[go?list?-m?-f={{if?.Replace}}{{.Path}}?=>?{{.Replace}}{{end}}?all]:?exit?status?1:

        編譯 Caddy2

        編譯之前系統(tǒng)需要安裝 jq、curl、git 命令,沒有的請使用

        apt?install?-y?curl?git?jq?

        命令安裝;

        自行編譯的目的是增加第三方插件方便使用,其中官方列出的插件可以從 Download 頁面獲取到:

        其他插件可以從 GitHub 上尋找或者自行編寫,整理好這些插件列表以后只需要使用 xcaddy 編譯即可:

        #?獲取最新版本號,其實直接去?GitHub?realse?頁復制一下就行
        #?這里轉(zhuǎn)化為腳本是為了方便自動化
        export?version=$(curl?-s?"https://api.github.com/repos/caddyserver/caddy/releases/latest"?|?jq?-r?.tag_name)

        #?使用?xcaddy?編譯
        xcaddy?build?${version}?--output?./caddy_${version}?\
        ????????--with?github.com/abiosoft/caddy-exec?\
        ????????--with?github.com/caddy-dns/cloudflare?\
        ????????--with?github.com/caddy-dns/dnspod?\
        ????????--with?github.com/caddy-dns/duckdns?\
        ????????--with?github.com/caddy-dns/gandi?\
        ????????--with?github.com/caddy-dns/route53?\
        ????????--with?github.com/greenpau/caddy-auth-jwt?\
        ????????--with?github.com/greenpau/caddy-auth-portal?\
        ????????--with?github.com/greenpau/caddy-trace?\
        ????????--with?github.com/hairyhenderson/caddy-teapot-module?\
        ????????--with?github.com/kirsch33/realip?\
        ????????--with?github.com/porech/caddy-maxmind-geolocation?\
        ????????--with?github.com/caddyserver/format-encoder?\
        ????????--with?github.com/mholt/caddy-webdav

        編譯過程日志如下所示,稍等片刻后將會生成編譯好的二進制文件:

        編譯成功后可以通過 list-modules 子命令查看被添加的插件是否成功編譯到了 caddy 中:

        bleem????~?./caddy_v2.3.0?list-modules
        admin.api.load
        admin.api.metrics
        caddy.adapters.caddyfile
        caddy.listeners.tls
        caddy.logging.encoders.console
        caddy.logging.encoders.filter
        caddy.logging.encoders.filter.delete
        caddy.logging.encoders.filter.ip_mask
        caddy.logging.encoders.formatted
        caddy.logging.encoders.json
        caddy.logging.encoders.logfmt
        caddy.logging.encoders.single_field
        caddy.logging.writers.discard
        caddy.logging.writers.file
        caddy.logging.writers.net
        caddy.logging.writers.stderr
        caddy.logging.writers.stdout
        caddy.storage.file_system
        dns.providers.cloudflare
        dns.providers.dnspod
        dns.providers.duckdns
        dns.providers.gandi
        dns.providers.route53
        exec
        http
        http.authentication.hashes.bcrypt
        http.authentication.hashes.scrypt
        http.authentication.providers.http_basic
        http.authentication.providers.jwt
        ......

        安裝 Caddy2

        宿主機安裝

        宿主機安裝 Caddy2 需要使用 systemd 進行守護,幸運的是 Caddy2 官方提供了各種平臺的安裝包以及 systemd 配置文件倉庫;目前推薦的方式是直接采用包管理器安裝標準版本的 Caddy2,然后替換自編譯的可執(zhí)行文件:

        #?安裝標準版本?Caddy2
        sudo?apt?install?-y?debian-keyring?debian-archive-keyring?apt-transport-https
        curl?-1sLf?'https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key'?|?sudo?apt-key?add?-
        curl?-1sLf?'https://dl.cloudsmith.io/public/caddy/stable/cfg/setup/config.deb.txt?distro=debian&version=any-version'?|?sudo?tee?-a?/etc/apt/sources.list.d/caddy-stable.list
        sudo?apt?update
        sudo?apt?install?caddy

        #?替換二進制文件
        systemctl?stop?caddy
        rm?-f?/usr/bin/caddy
        mv?./caddy_v2.3.0?/usr/bin/caddy

        Docker 安裝

        Docker 用戶可以通過 Dockerfile 自行編譯 image,目前我編寫了一個基于 xcaddy 的 Dockerfile,如果有其他插件需要集成自行修改重新編譯即可;當前 Dockerfile 預編譯的鏡像已經(jīng)推送到了 Docker Hub 中,鏡像名稱為 mritd/caddy。

        配置 Caddy2

        Caddy2 的配置文件核心采用 json,但是 json 可讀性不強,所以官方維護了一個轉(zhuǎn)換器,抽象出稱之為 Caddyfile 的新配置格式;關(guān)于 Caddyfile 的完整語法請查看官方文檔 https://caddyserver.com/docs/caddyfile,本文僅做一些基本使用的樣例。

        配置片段

        Caddyfile 支持類似代碼中 function 一樣的配置片段,這些配置片段可以在任意位置被 import,同時可以接受參數(shù),以下為配置片斷示例:

        #?括號內(nèi)為片段名稱,可以自行定義
        (TLS)?{
        ????protocols?tls1.2?tls1.3
        ????ciphers?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
        }

        #?在任意位置可以引用此片段從而達到配置復用
        import?TLS

        配置模塊化

        import 指令除了支持引用配置片段以外,還支持引用外部文件,同時支持通配符,有了這個命令以后我們就可以方便的將配置文件進行模塊化處理:

        #?引用外部的?/etc/caddy/*.caddy
        import?/etc/caddy/*.caddy

        站點配置

        針對于站點域名配置,Caddyfile 比較自由化,其格式如下:

        地址?{
        ????站點配置
        }

        關(guān)于這個 “地址” 接受多種格式,以下都為合法的地址格式:

        localhost
        example.com
        :443
        http://example.com
        localhost:8080
        127.0.0.1
        [::1]:2015
        example.com/foo/*
        *.example.com
        http://

        環(huán)境變量

        Caddyfile 支持直接引用系統(tǒng)環(huán)境變量,通過此功能可以將一些敏感信息從配置文件中剔除:

        #?引用環(huán)境變量?GANDI_API_TOKEN
        dns?gandi?{$GANDI_API_TOKEN}

        配置片段參數(shù)支持

        針對于配置片段,Caddyfile 還支持類似于函數(shù)代碼的參數(shù)支持,通過參數(shù)支持可以讓外部引用時動態(tài)修改配置信息:

        (LOG)?{
        ????log?{
        ????????format?json??{
        ????????????time_format?"iso8601"
        ????????}
        ????????#?"{args.0}"?引用傳入的第一個參數(shù),此處用于動態(tài)傳入日志文件名稱
        ????????output?file?"{args.0}"?{
        ????????????roll_size?100mb
        ????????????roll_keep?3
        ????????????roll_keep_for?7d
        ????????}
        ????}
        }

        #?引用片段
        import?LOG?"/data/logs/mritd.com.log"

        自動證書申請

        在啟動 Caddy2 之前,如果目標域名(例如: www.example.com)已經(jīng)解析到了本機,那么 Caddy2 啟動后會嘗試自動通過 ACME HTTP 挑戰(zhàn)申請證書;如果期望使用 DNS 的方式申請證書則需要其他 DNS 插件支持,比如上面編譯的 --with github.com/caddy-dns/gandi 為 gandi 服務商的 DNS 插件;關(guān)于使用 DNS 挑戰(zhàn)的配置編寫方式需要具體去看其插件文檔,目前 gandi 的配置如下:

        tls?{
        ?dns?gandi?{env.GANDI_API_TOKEN}
        }

        配置完成后 Caddy2 會通過 ACME DNS 挑戰(zhàn)申請證書,值得注意的是即使通過 DNS 申請證書默認也不會申請泛域名證書,如果想要調(diào)整這種細節(jié)配置請使用 json 配置或管理 API。

        完整模塊化配置樣例

        了解了以上基礎(chǔ)配置信息,我們就可以實際編寫一個站點配置了;以下為本站的 Caddy 配置樣例:

        目錄結(jié)構(gòu):

        caddy
        ├──?Caddyfile
        ├──?mritd.com.caddy
        └──?mritd.me.caddy

        Caddyfile

        Caddyfile 主要包含一些通用的配置,并將其抽到配置片段中,類似于 nginx 的 nginx.conf 主配置;在最后部分通過 import 關(guān)鍵字引入其他具體站點配置,類似 nginx 的 vhost 配置。

        (LOG)?{
        ????log?{
        ????????#?日志格式參考?https://github.com/caddyserver/format-encoder?插件文檔
        ????????format?formatted?"[{ts}]?{request>remote_addr}?{request>proto}?{request>method}?<-?{status}?->?{request>host}?{request>uri}?{request>headers>User-Agent>[0]}"??{
        ????????????time_format?"iso8601"
        ????????}
        ????????output?file?"{args.0}"?{
        ????????????roll_size?100mb
        ????????????roll_keep?3
        ????????????roll_keep_for?7d
        ????????}
        ????}
        }

        (TLS)?{
        ????#?TLS?配置采用?https://mozilla.github.io/server-side-tls/ssl-config-generator/?生成,SSL?Labs?評分?A+
        ????protocols?tls1.2?tls1.3
        ????ciphers?TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256?TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256?TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384?TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256?TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
        }

        (HSTS)?{
        ????#?HSTS?(63072000?seconds)
        ????header?/?Strict-Transport-Security?"max-age=63072000"
        }

        (ACME_GANDI)?{
        ????#?從環(huán)境變量獲取?GANDI_API_TOKEN
        ????dns?gandi?{$GANDI_API_TOKEN}
        }

        #?聚合上面的配置片段為新的片段
        (COMMON_CONFIG)?{
        ????#?壓縮支持
        ????encode?zstd?gzip

        ????#?TLS?配置
        ????tls?{
        ????????import?TLS
        ????????import?ACME_GANDI
        ????}

        ????#?HSTS
        ????import?HSTS
        }

        #?開啟?HTTP3?實驗性支持
        {
        ????servers?:443?{
        ????????protocol?{
        ????????????experimental_http3
        ????????}
        ????}
        }

        #?引入其他具體的站點配置
        import?/etc/caddy/*.caddy

        mritd.com.caddy

        mritd.com.caddy 為主站點配置,主站點配置內(nèi)主要編寫一些路由規(guī)則,TLS 等都從配置片段引入,這樣可以保持統(tǒng)一。

        www.mritd.com?{
        ????#?重定向到?mritd.com(默認?302)
        ????redir?https://mritd.com{uri}

        ????#?日志
        ????import?LOG?"/data/logs/mritd.com.log"

        ????#?TLS、HSTS、ACME?等通用配置
        ????import?COMMON_CONFIG
        }

        mritd.com?{
        ????#?路由
        ????route?/*?{
        ????????reverse_proxy?mritd_com:80
        ????}

        ????#?日志
        ????import?LOG?"/data/logs/mritd.com.log"

        ????#?TLS、HSTS、ACME?等通用配置
        ????import?COMMON_CONFIG
        }

        mritd.me.caddy

        mritd.me.caddy 為老站點配置,目前主要將其 301 到新站點即可。

        www.mritd.me?{
        ????#?重定向到?mritd.com
        ????#?最后的?"code"?支持三種參數(shù)
        ????#?temporary?=>?302
        ????#?permanent?=>?301
        ????#?html?=>?HTML?document?redirect
        ????redir?https://mritd.com{uri}?permanent

        ????#?日志
        ????import?LOG?"/data/logs/mritd.com.log"

        ????#?TLS、HSTS、ACME?等通用配置
        ????import?COMMON_CONFIG
        }

        mritd.me?{
        ????#?重定向
        ????redir?https://mritd.com{uri}?permanent

        ????#?日志
        ????import?LOG?"/data/logs/mritd.com.log"

        ????#?TLS、HSTS、ACME?等通用配置
        ????import?COMMON_CONFIG
        }

        啟動與重載

        配置文件編寫完成后,通過 systemctl start caddy 可啟動 caddy 服務器;每次配置修改后可以通過 systemctl reload caddy 進行配置重載,重載期間 caddy 不會重啟(實際上調(diào)用 caddy reload 命令),當配置文件書寫錯誤時,重載只會失敗,不會影響正在運行的 caddy 服務器。

        總結(jié)

        本文只是列舉了一些簡單的 Caddy 使用樣例,在強大的插件配合下,Caddy 可以實現(xiàn)各種 “神奇” 的功能,這些功能依賴于復雜的 Caddy 配置,Caddy 配置需要仔細閱讀官方文檔,關(guān)于 Caddyfile 的每個配置段在文檔中都有詳細的描述。

        值得一提的是 Caddy 本身內(nèi)置了豐富的插件,例如內(nèi)置 “file_server”、內(nèi)置各種負載均衡策略等,這些插件組合在一起可以實現(xiàn)一些復雜的功能;Caddy 是采用 go 編寫的,官方也給出了詳細的開發(fā)文檔,相較于 Nginx 來說通過 Lua 或者 C 來開發(fā)編寫插件來說,Caddy 的插件開發(fā)上手要容易得多;Caddy 本身針對數(shù)據(jù)存儲、動態(tài)后端、配置文件轉(zhuǎn)換等都內(nèi)置了擴展接口,這為有特定需求的擴展開發(fā)打下了良好基礎(chǔ)。

        最終總結(jié),綜合來看目前 Caddy2 的性能損失可接受的情況下,相較于 Nginx 絕對是個絕佳選擇,各種新功能都能夠滿足現(xiàn)代化 Web 站點的需求,真香警告。

        良許個人微信


        添加良許個人微信即送3套程序員必讀資料


        → 精選技術(shù)資料共享

        → 高手如云交流社群





        本公眾號全部博文已整理成一個目錄,請在公眾號里回復「m」獲??!

        推薦閱讀:

        Nginx 從入門到實踐,萬字詳解!

        17個在 Linux 運維中定要掌握的實用技巧

        太真實了!程序員之間的鄙視鏈...


        5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機,樹莓派,等等。在公眾號內(nèi)回復「1024」,即可免費獲?。?!


        瀏覽 67
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            中文在线第一页 | 天堂а在线中文在线新版 | 大炕上的风流大棒 | 黄色片全黄色1级黄色 | 青青手机视频 | 国产精品久久久久久久久婷婷 | 黄色工厂-这里只有精品 | 俺来俺去 | 亚洲激情视频网 | 年轻女教师高潮 |