由於不習慣用 Hugo 管理內容, 且文章漸漸多了起來, 我在家中的樹莓派上跑起了一個 WordPress. 一切都進行的很順利, 直到我發現發佈這個網站並不是我想像中的那麼容易.
這篇文章是一篇踩坑文, 就是說我會把我在設置中遇到的一切困難完整的紀錄在文章中, 因此你不應當將其當作教程來看. 如果需要教程的話, 我推薦 官方文檔 , 或者 土豆不好吃 的教程.
前言
失敗的嘗試
首先, 我的樹莓派跑在內網, 我需要在路由器上配置一個端口轉發. 借助 Openwrt 的圖像介面, 我輕鬆的完成了轉發.
其次, 我還需要一個公網 IP. 撥打了電信的電話, 我成功的要到了公網 IP.
因為 “維穩” 需求, 電信是封殺 80, 443, 等常見的端口的. 因此我將 443 端口轉發到了 2053 端口上. ( HTTPS 證書是 Cloudflare 的原站證書 ) 2053 端口確定可以訪問.
在然後, 每次撥號的時候 IP 都會改變, 我需要配置一個 DDNS. 為了解決這個問題, 我找到了一個 Cloudflare DDNS 腳本跑在 Openwrt 裡來動態更新我的 IP.
一個類似 ip.justin.education:2053
的地址為免有些太過不友好, 於是我使用 CF-Workers 反向代理網站到 proxy.justin-zhang.workers
, 再將其 CNAME 到 justin.education
.
如果是靜態頁面這個時候已經可以訪問了, 但是 WordPress 並不支持多個域名, 一直在執著的 301 重定向. 我不能配置其地址為 justin.education
, 因為那樣我就沒辦法登錄後台: CF 反代不支持保存 Cookies.
我於是在 Openwrt 上用 Docker 跑了一個 Nginx 來反代網站, 放棄了簡單的端口轉發的方案. 這次成功了, 不過我遇到了一些圖片和CSS不能加載的問題. 安裝插件之後我配置了替換 Header 的規則, 總算是可以看了.
但是由於 CF Workers 的緣故, 評論還是不工作. 而且攻擊者只要知道了我的端口是 2053, 他可以全網搜索 ip.justin.education:2053
的證書來找到我的真是 ip; 這顯然太冒險.
這個方案失敗之後, 還剩下的就是使用 frp 內網穿透的方案. 然而我並不想用我的翻牆服務器來代理網站, 我經常換 ip, 而且不安全, 而且效率太低.
看起來我已經被逼到絕路了.
柳暗花明
CF 經常被戲稱為做公益. 確實, 免費 CDN、雲端運行JS、免費證書、DDOS防護都看起來太美好了一點; 而且這些技術在捍衛隱私、對抗專制方面有奇效. 比如說: CDN可以用於隱藏翻牆服務器IP, 雲端 JS 可以做反向代理瀏覽器, 而且都完全不需要備案.
而就在 4月, CF 把 Argo Tunnel 免費對公眾開放 ( Tunnels for everyone ), 正好解決了我用樹莓派在家 Host Web 的需求! 說幹就幹, 立馬上手玩起來吧!
安裝 Cloudflared
樹莓派架構問題
我的是樹莓派 4B, 但是下載 Arm64 的版本跑不起來, 提示 “可執行檔格式錯誤”, 應當是說架構不對.
$ uname -m armv7l $ getconf LONG_BIT 32 $ cat /proc/cpuinfo processor : 3 model name : ARMv7 Processor rev 3 (v7l) BogoMIPS : 270.00 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3 Hardware : BCM2711 Revision : d03114 Serial : 1000000038a6ce51 Model : Raspberry Pi 4 Model B Rev 1.4


這就有一點迷糊了, 我的樹莓派明明是 64 位的 Armv8, 為什麼顯示是 32 位的 Armv7 ?
經過一番搜索之後, 我發現我通過 Rpi-Imager 刷入的系統默認是32 位的. 根據 樹莓派官網, 我嘗試修改系統架構.

rpi-update # 先更新樹莓派固件 reboot echo 'kernel=kernel8.img' >> /boot/config.txt echo 'arm_64bit=1' >> /boot/config.txt reboot
要完成上述操作並保證可以正常啟動, 你需要滿足所有以下條件:
- /boot 非只讀 ( 你可以在
- 保證 /boot/kernel8.img 存在
- /boot/condfig.txt 不存在衝突的配置
然而, 失敗了. LONG_BIT 提示 32.
我嘗試下載 文件之後運行, 結果提示找不到文件. I beg your parden ? 大白天活見鬼.
我只好重裝了 64bit 的 PiOS, 現在運行這個程序應該沒有問題了.
下載並配置 Cloudfalred
wget https://github.com/cloudflare/cloudflared/releases/download/2021.5.6/cloudflared-linux-arm64 chmod +x ./cloudflared-linux-arm64 mv ./cloudflared-linux-arm64 /usr/local/bin/cloudflared
執行以下命令並將提示的 URL 複製到瀏覽器中打開, 點擊授權按鈕.
$ cloudflared tunnel login Please open the following URL and log in with your Cloudflare account: https://dash.cloudflare.com/argotunnel?callback=https%3A%2F%2Flogin.argotunnel.com%2FFFFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFFFFFFFF%3D Leave cloudflared running to download the cert automatically. You have successfully logged in. If you wish to copy your credentials to a server, they have been saved to: /root/.cloudflared/cert.pem
創建並配置 Tunnel
創建 Tunnel
$ cloudflared tunnel create wpblog Tunnel credentials written to /root/.cloudflared/00000000-aaaa-bbbb-1111-000000000000.json. cloudflared chose this file based on where your origin certificate was found. Keep this file secret. To revoke these credentials, delete the tunnel. Created tunnel blog with id 00000000-aaaa-bbbb-1111-000000000000
配置 Tunnel
touch /root/.cloudflared/config.yml cat > config.yml <<EOF tunnel: 00000000-aaaa-bbbb-1111-000000000000 credentials-file: /root/.cloudflared/00000000-aaaa-bbbb-1111-000000000000.json ingress: - hostname: justin.education service: http://localhost:80 - service: http_status:404 EOF
根據 Cloudflare 文檔 的解釋, 最後這一條是一個 “catch-all rule”, 也就是保底規則. 當有流量被導到我的樹莓派這裡, cloudflared 會一條條匹配 hostname, 如果都沒匹配到, 就返回 404. ( 你可以在樹莓派上跑其他服務比如說 gitlab, 郵件服務器之類的, 這個時候就更凸顯出 catch-all rule 的意義. )
設置 Cloudflare DNS
5 月 23 日 更新:
請直接跳過這一步. 最新版的 Cloudflare 已經無需手動配置 DNS, 如果配置了還會要求你刪除.
根據 官方文檔 , 接下來需要將要配置 Tunnel 的域名解析到 [id].cfargotunnel.com
來讓配置生效.
由於我的 WordPress 是跑在 Docker 裡面的, 要配置 HTTPS 需要掛上一層 Nginx 的反向代理. 而 CF 正好解決了這個問題 ( Cloudflare -> SSL -> 完全 ), 而且還附帶了免費無需備案的 CDN, 說他做公益真的不是玩笑啊🤔
還可以額外配置一個重定向, 讓 www.justin.education
重定向到 justin.education
. 因為前者真的很醜…
註冊服務並運行
在執行以下操作之前, 先保證 DNS 服務器設置為 1.1.1.1
. 用 Openwrt 可以在 網絡/接口/Wan/高級設置 處取消勾選 “使用對端通告的 DNS 服務器” (即運營商提供的 DNS), 然後寫上 1.1.1.1
. 普通路由器可以按照型號在網上搜索.
理想狀態是執行以下命令之後返回 _origintunneld._tcp.argotunnel.com.
$ dig srv _origintunneld._tcp.argotunnel.com ; <<>> DiG 9.11.5-P4-5.1+deb10u5-Debian <<>> srv _origintunneld._tcp.argotunnel.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36844 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ;_origintunneld._tcp.argotunnel.com. IN SRV ;; ANSWER SECTION: _origintunneld._tcp.argotunnel.com. 300 IN SRV 2 1 7844 region2.argotunnel.com. _origintunneld._tcp.argotunnel.com. 300 IN SRV 1 1 7844 region1.argotunnel.com. ;; Query time: 156 msec ;; SERVER: 192.168.10.1#53(192.168.10.1) ;; WHEN: 日 5月 16 22:48:51 CST 2021 ;; MSG SIZE rcvd: 147
滿足以上條件之後, 運行以下命令註冊 cloudflared 為 service
cloudflared service install
在我的這個版本, cloudflared.service 的啟動參數實際上是設置 /etc/cloudflared/config.yaml
為其配置文件的. 所以如果某一天你想添加一個服務, 然後不管怎麼改 ~/.cloudflared/config.yaml
都是 404, 那就是你沒有改對地方. 你可以通過 cat /etc/systemd/system/cloudflared.service
來檢查啟動參數, 如果確實是這樣的話, 直接將 home 目錄下的配置文件軟鏈接過去就可以了.
rm /etc/cloudflared/config.yml ln -s $HOME/.cloudflared/config.yml /etc/cloudflared/config.yml
然後應該可以使用 systemctl
來控制 cloudflared 的運行和停止了.
systemctl enable cloudflared systemctl start cloudflared systemctl status cloudflared
成功!
做完以上所有步驟之後等待 3 -5 分鐘, 應該已經可以透過無痕模式看到網站了. 這個時候設置就基本成功了.
由於我正在使用 WordPress, 我碰到了幾個問題, 羅列如下:
問題 | 解決方案 |
圖片路徑不正確 | 在數據庫中查找替換掉舊的網址 |
網頁加載太慢 | 啟用 Cloudflare 插件和 Jetpack 插件 準備將圖片批量轉化爲 Webp 格式 |
郵件發不出去 | Docker中跑 Mailu 郵件服務器 安裝 WP Mail 插件 |
首頁顯示錯誤 (把電腦端當成移動端處理) | 自己好了 可能是缓存没刷过来的问题 |