Ban 掉來自中國 IP 的流量

前言

隨著我博客來自大陸的流量越來越多, 我逐漸開始有一點擔心. 雖然我已經屏蔽了國內搜索引擎的 Spider, 但是來源於大陸的流量還是和來源於美帝的不相上下. 從各個地方 Ping 的結果也不樂觀, 大陸地區已經出現隨機丟包的現象, 而且很嚴重. 我暫時沒有搞清楚這是針對我的域名還是針對 Cloudflare CDN 的流量.

目前正值建襠百年特別時期, 地鐵站的安檢人員都肉眼可見的增加了數量, 更別說在線管控了. 更加誇張的是, 著名反動博主編程隨想都在5月中旬被消失 ( 我為此傷心了真的非常久 ), 論技術, 我肯定都配不上給編程隨想提鞋, 況且我在用 BugPress 作為博客程序; 要是誰哪天看我不爽來搞我, 我肯定分分鐘去吃國家飯.

然而從我的角度來說, 我肯定不會因為局勢 intense 而乖乖閉嘴: 要我閉嘴不如先去叫我死. 但是隨著我的成長和文章數量的增多, 日後我肯定要浪費大量時間在安全防範上, 而且我目前肉身還在牆內, 物理安全得不到保障.

綜上所述, 雖然我真的很不捨得放棄將近一半的流量, 我還是得這麼做, 幹掉所有來自大陸的流量 (不包括香港, 以及本來就不包括台灣) . 這樣, 至少在我肉身在牆內的階段應該不會有人來找我麻煩 — 這只是一個戰略讓步, 一旦我肉身過牆, 我會立即取消這個設定.

閱讀全文 Ban 掉來自中國 IP 的流量

例行安全檢測 — 加固WordPress

因為我正在使用 cloudflare 提供的內網穿透服務, 相當於整個服務器只對外開放了 Web 服務, 所以我基本是圍繞 Web 服務在加固. 如果讀者的 wordpress 跑在租用的 VPS 上, 極有可能同時開放了數據庫、SSH、FTP 服務, 對這些的防護不在本文討論範圍內.

本文主要是參考了這篇官方教程. 如果你英文好的話, 不妨自己讀一讀這篇教程, 寫的很詳細, 基本每一個改動都有解釋.

檢測手段

https://github.com/wpscanteam/wpscan

下載 wpscan, 然後在終端敲入

wpscan --url https://example.com

可能需要關閉 CF 防火牆.

刪除無關文件

cd /www/wordpress

# 刪除根目錄下無關文件
rm readme.html
rm license.txt

# 遞歸刪除插件、主題 Readme
find . -name readme.txt -type f -print -exec rm -rf {} \;
閱讀全文 例行安全檢測 — 加固WordPress

WordPress + Cloudflared + V2ray 異地組網並隱藏流量

目標

  • 異地組網, 遠程訪問家中環境
  • 結合海外 VPS 翻牆 ( 不在此篇討論 )
  • 使用 V2Ray TLS 加密流量
  • 將 TLS 流量隱藏在正常的 HTTPS 流量中達到混淆目的
  • 使用 Cloudflare 的內網穿透服務, 達到防探測目的 ( 服務器直接和 CF 溝通, 沒有端口暴露 )
  • 使用 Cloudflare 的 CDN 服務, 達到防牆、加速作用

如果你並不是想要做異地組網, 而是想要在 VPS 上跑 (Nginx/Caddy/Apache) + WP + V2Ray, 那麼你其實用不著這麼複雜. 你只需要看這篇文章就可以了.

(這篇博文主要是討論一個沒多少人做過的方案的可行性, 所以你會看到後面還有一大通廢話; 作為教程本文是不合格的, 如果想要尋找教程請出門右轉谷歌搜索. )

網絡拓墣示意圖
閱讀全文 WordPress + Cloudflared + V2ray 異地組網並隱藏流量

Chrome is bad! 切換到 Firefox

在我的 Macbook 上使用了幾個月 Chrome 下來, 發現使用期間電池損耗非常之快. 在 Google 上搜索之後, 結果幾乎清一色指向了 Keystone, 一個 Chrome 的更新程式. 根據 Chrome is bad, Keystone 將自己植入系統服務, 瘋狂吃資源, 一度讓 WindowServer CPU 佔用達到 80%. Google 聲稱 Keystone 是用來更新 Chrome 的, 我對此存疑. 更新一個程式需要吃 CPU 吃到 80%? 真當我腦癱啊?

然而要改變習慣也不是那麼容易, 我就很不習慣 Safari 和 Edge 的操作介面. 況且我習慣只有一套密碼, 要切換瀏覽器, 就得先把舊瀏覽器上的密碼通通刪除.

提醒: 如果你也想要轉移到 Firefox, 請不要著急著刪除 Chrome, 在轉移插件和密碼時它還用得到.

Chromium 使用報告

為了解決這個問題, 我先嘗試 Chrome 係的 Chromium ( 通過 Brew 安裝 ), 寄希望於它是一個開源軟件, 不會附帶垃圾代碼.

結果我徹徹底底的錯了. Chromium 一不支持 MacArm, ( 而 Chrome 則是支持的 ), 而來佔用比 Chrome 還要高三到五倍, 最離譜的是, 我用 Brew 卸載掉了它居然還在佔我 CPU. 這怎麼忍?

通過 Brew 卸載之後, Chromium 居然還佔用 將近 100% 的 CPU

除了高佔用以外, Chromium 還移除了大部分 Google API. 也就是說, 谷歌翻譯、密碼同步、谷歌帳號等功能全部無法使用. 從這點就可以看出來, 作為一個商業巨頭的 Google, 本質上就是一個財閥, 其第一要務就是盈利.

失望之餘, 我徹底刪除了 Chromium.

轉移並清除 Chrome 保存的資料

匯出密碼

要跳出 Chrome 的舒適圈, 將密碼轉移到 Firefox 上是一個好主意. 然而我現在正在使用 Keepass ( 一個開源密碼管理器 ), 絕大部分密碼並不儲存在瀏覽器裡. 因此我只要登錄到 Google 帳號, 刪除掉儲存在裡面的密碼就可以了.

要先匯出你的密碼, 或是關閉自動保存, 點擊這個鏈接, 登入 Google 帳戶, 點擊 “Export”.

Export 出來的東西可以導入 Keepass, 也可以導入 Firefox. 我個人偏向於前者.

匯出書籤

在 Chrome 中打開這個鏈接, 點擊右上角的三個點然後點擊 “匯出”.

我個人並沒有選擇從 Chrome 匯出書籤, 我覺得切換瀏覽器也是一個小小的新開始, 那些老的書籤大部分我一生都不會再看一次, 不如直接刪掉好了.

我沒有保留除了 Chrome 書籤欄裡的其他任何東西, 而且我其實也基本不使用書籤功能.

匯出插件

遺憾的是, Chrome 並沒有為插件提供一鍵匯出功能. 在 Chrome 種打開這個鏈接, 手動轉移插件吧. 一些插件提供了到匯出配置功能, 會讓整個操作簡單很多.

刪除 Chrome 相關的所有資料

之前的操作只是匯出了這些資料而已, 接下來要做的是完全刪除這些資料.
Chrome 官方提供了一個一鍵 GoodBye 的功能, 我個人感覺還是非常有良心的.

點擊這個鏈接, 確定你已經匯出了所有這些資料之後, 點擊刪除.

這會刪除你帳戶中關於 Chrome 的所有資料.

刪除帳戶活動

以上操作已經完全抹除了你和 Chrome 的關係了, 但是能不能再進一步呢?

瀏覽紀錄除了被儲存在 Chrome 裡面, 還儲存在 Google 活動裡面, 作為 Google 帳戶資料的一部分. 要完全清除, 我們還要執行下面的操作.

光刪除這些並沒有完全刪除你在 Google 留下的痕跡. 接下來需要轉到 Google – 我的活動 來刪除雲端的瀏覽紀錄.

請點擊這個鏈接, 點擊 刪除 – 不限時間 – 全部勾選 – 刪除.

如果以後都不想要 Google 紀錄你的活動, 可以如圖關閉這三個選項.

要刪除其他服務, 請點擊這個鏈接, 自行選擇並刪除.

我個人感覺, 在一一刪除這些資料時, 我處在一種擔憂與爽感並存的狀態. 然而, 在完全刪除之後, 又釋然了. 隱私與自由有的時後和大麻一樣, 都是一種一旦沾上就再也不想失去的東西, 只不過前者是完全無害的.

安裝 Firefox

Firefox 作為一個開源軟件, 而且有大名鼎鼎的 Mozilla 基金會為它背書. Firefox 的主題、插件市場都不下 Chrome AppStore, 也支持同步設置和密碼. 除了手機上的 Firefox 比較不堪以外 (近年來已經大大改善!) , 好像它一直都是 Chrome 的一個絕佳替代方案.

要安裝 Firefox, 可以使用內建的 Brew 包管理器. 順便一提, Firefox 已經支持 M1 晶片.

brew install --cask firefox

成功!

安裝完畢之後, 整個過程基本就完成了! 享受這個新的瀏覽器吧!

Android5 – Termux

我有一支舊手機, 華為 TAG-AL00; 目前閒置無事可幹, 於是我便動起歪腦筋想要將其改造成一台服務器.
如果你的手機已 root, 你大可以安裝 Linux Deploy, 通過 chroot 技術來部署 Linux, 安裝更快也運行更高效.

下載 Termux

首先不得不提的是, 作為有中國社會主義特色的流氓企業, 華為早就 Ban 掉了大部分手機刷機的渠道. 而華為自己的系統又太坑爹, 而且根本沒有系統更新, 導致我想給他刷一個 LineageOS 的嘗試直接打水漂. 所以接下來的一切都是在蛋疼的 Android5 上完成的.

Termux 早在 2020.01.01 就宣布不再支持 Android5/6. 因為是安卓5的緣故, 我們只能下載古老一點的版本. 經過我實測, 不僅是 20 年年初的版本無法安裝, 19 年年末的幾個版本 (如 0.75) 也裝不起來. 所以我只好選擇了更加古老的 Termux 0.70, 可以在這個鏈接下載到.

基礎配置

首先得配置好軟件源, 倒不是翻牆的問題, 而是這個版本 Termux 自帶的軟件源已經失效. 沒有軟件源其他一切都是扯淡. 複製以下命令到手機中執行:

( 如果執行完出錯, 請清除數據或重裝, 然後僅執行 apt update, 便可挑過此步. )

sed -i '[email protected]^\(deb.*stable main\)[email protected]#\1\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/termux-packages-24 stable [email protected]' $PREFIX/etc/apt/sources.list
sed -i '[email protected]^\(deb.*games stable\)[email protected]#\1\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/game-packages-24 games [email protected]' $PREFIX/etc/apt/sources.list.d/game.list
sed -i '[email protected]^\(deb.*science stable\)[email protected]#\1\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/science-packages-24 science [email protected]' $PREFIX/etc/apt/sources.list.d/science.list
pkg update -y

接下來的問題就是我不想要再在巴掌大的玻璃上戳來戳去了. 配置 SSH.

# 在手機上執行
apt install openssh -y
sshd # 開放 8022 端口
vi ~/.ssh/authorized_keys # 複製公鑰進去
ipconfig -a # 查看 ip 信息

# 在電腦上執行
ssh 192.168.10.116 -p 8022

安裝 Debian

使用 Debian 主要的原因, 除了它比較人性化且持續被維護, 是它的佔用非常之小, 完全可以運行在 “嵌入式設備上”. 在這一個老舊的手機上運行完全沒問題. 另外一個類似的嵌入式系統 Alpine 我不熟, 因此不想安裝.

# 資源來自 AnLinux
cd ~
apt install wget openssl-tool proot -y && hash -r && wget https://raw.githubusercontent.com/EXALAB/AnLinux-Resources/master/Scripts/Installer/Debian/debian.sh
bash debian.sh

執行這個命令花費的時間不多, 所以不要被嚇到.
安裝完成之後, 只要輸入 ./debian-start.sh 便可以啟動 Debian 了!

Cloudflare Tunnel Self WebHosting

由於不習慣用 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, 而且不安全, 而且效率太低.

看起來我已經被逼到絕路了.

閱讀全文 Cloudflare Tunnel Self WebHosting

WordPress Enligher 插件適配主題

感覺博客缺少一個代碼高亮插件, 所以我就挑了一個免費的, 功能比較多的插件 Enligher 安裝到博客.

好用但是挺好用, 但是好像和當前的主題不太兼容, 具體症狀請見下圖:

可以看見, 不管是編輯器還是實際文章, 這個插件都有兼容性問題.

所以我馬上要做的事情, 就是找出問題並自己解決掉.

我沒有學過任何關於 CSS 或者 JS 的知識, 以下所有紀錄都來源於常識… 如果我有哪邊做錯, 歡迎在評論區指正😄

(下文所有的修改都會寫在文末的 patch 文件中)

編輯器部分

錯位修正

margin 的左右都是 0

這個比較簡單, 修改 enlighter/resources/gutenberg/enlighterjs.gutenberg.min.css , 如下所示:

div[data-type="enlighter/codeblock"] {
	border: 1px solid #cccbcb;
	border-radius: 5px;
	/* max-width: 100%; */
	padding: 15px
}

刪除/移動 干擾信息

右下角的提示 “EnligherJS Syntax Highlighter” 一直都在那裡, 非常佔空間而且還會產生打擾的效果, 所以我們不能讓它達到目的, 可以直接把它刪掉. 另外, 左上角的粗體字提示 Highlighting 種類未免有些太過喧賓奪主, 要是可以把它移到右下角的話豈不完美.

所以我就將 enlighter-footer 的部分刪掉, 然後將 enlighter-title 的部分移到 原來的 footer 的部分. 目前一切進行的都比較順利.

wp.element.createElement("div", {
                    className: "enlighter-header"
                },
                    /*wp.element.createElement("div", {
                        className: "enlighter-title"
                    }, (e = t.language, s()[e] || "Unknown language"))), wp.element.createElement(u, {
                        value: t.content,
                        onChange: function (e) {
                            return n({
                                content: e
                            })
                        },
                        placeholder: "Insert Sourcecode..",
                        "aria-label": "Code"
                    }),*/
                    /*wp.element.createElement("div", {
                        className: "enlighter-footer"
                    },
                        wp.element.createElement("div", {
                            className: "enlighter-footer-label"
                        },
                            wp.element.createElement("strong", null, "EnlighterJS"), " Syntax Highlighter"))*/
                    wp.element.createElement(u, {
                        value: t.content,
                        onChange: function (e) {
                            return n({
                                content: e
                            })
                        },
                        placeholder: "Insert Sourcecode..",
                        "aria-label": "Code"
                    }), wp.element.createElement("div", {
                        className: "enlighter-footer"
                    }, wp.element.createElement("div", {
                        className: "enlighter-footer-label",
                    }, (e = t.language, s()[e] || "Unknown language")))),

美化

到這一步, 編輯器 Enlighter 區塊的效果是這個樣子的:

不夠完美啊!

從使用的角度來說, 它已經夠用了.
但是右下角的那一行字總覺得有點不和諧.

所以我就把它往下移動了一點點, 並且加粗.

div[data-type="enlighter/codeblock"] {
	border: 1px solid #cccbcb;
	border-radius: 5px;
	padding: 15px;
	padding-block-end: 1px /* New */
}
div[data-type="enlighter/codeblock"] .enlighter-footer-label {
	text-align: right;
	font-size: 10px;
	font-family: Menlo,Consolas,monaco,monospace;
	color: #23282d;
	cursor: pointer;
	padding-top: 3px; /* New */
	font-weight: 800 /* New */
}

( 以上所有代碼全部由我目測得到, 且並不理解其含義, 均未考慮兼容性. 使用前請再三考慮 )

最終效果

現在感覺好多了 👌

網頁展示部分

EnlighterJS 官網按鈕倒不難去掉, 插件提供了開關可以直接把它關掉.

將 EnlighterJS website button 設為 Disable 就可以了

那麼接下來要做到就是適配暗黑模式.

適配暗黑模式的話… (撓頭) 要改的變量好像有點太多了, 暫時就不寫了吧.
本身 MDX 的暗黑模式就不太好看, 我的解決方法就是 徹 . 底 . 不 . 開 ! 這下不會有問題了吧?

Patch via Gist

樹莓派 4B 安裝 Arm64 PiOS

安裝系統

  1. 在 Ubuntu 中安裝 Rpi-imager 來準備鏡像
sudo apt update -y && sudo apt upgrade -y
sudo snap install rpi-imager

2. 從 清華大學鏡像 下載 Arm64 的 PiOS_Lite.

3. 使用 Rpi-Imager 刷入鏡像. 使用 Ubuntu 自帶的磁碟工具擴展 rootfs 容量到最大. (也可以不要, 最新版本的系統第一次開機會自動 Resize Partitions 將 / 分區擴到最大)

4. 在 boot 目錄下新建空白的 ssh 文件

cd ~/media/boot/
touch ssh
  1. 彈出 SD 卡, 插入樹莓派並通電.

基礎配置

0. 連線到樹莓派.

ssh [email protected] #raspberry
  1. 修改登錄方式
# 設置密碼
sudo passwd pi
sudo passwd root
​
# 配置 SSH 登錄
su
cd ~/
mkdir .ssh
chmod 700 .ssh
vi /root/.ssh/authorized_keys # 複製你的公鑰進去
chmod 644 /root/.ssh/authorized_keys
vi /etc/ssh/sshd_config # 配置ssh登錄

2. 在 sshd_config 中修改以下幾句.

LoginGraceTime 10m                 # afk達10min自動登出
PermitRootLogin prohibit-password  # 只允許root用ssh登錄
MaxAuthTries 6                     # 最多允許三次錯誤登錄嘗試
MaxSessions 10                     # 最多允許三個client同時登錄
​
PubkeyAuthentication yes           # 開啓公鑰登錄
​
AuthorizedKeysFile      .ssh/authorized_keys #開啓公鑰
​
PasswordAuthentication no          # 不允許任何用戶使用密碼登錄
PermitEmptyPasswords no            # 不允許任何空密碼用戶登錄

3. 繼續執行一下語句, 確定 status 沒有報錯之後登出.

systemctl restart sshd.service
systemctl status sshd.service
exit

4. 重新以 root 身份登錄.

5. 更新/設置系統

apt update && apt upgrade -y
​
# 更新系統 (不推荐)
#rpi-update # 更新 Kernel
#reboot
#rpi-eeprom-update # 更新 Bootloader
#raspi-config # 6 -> A7 -> E1
​
# 設置系統
raspi-config
​
# 重新登錄
exit

更新: 不推荐执行 rpi-update 更新系统, 因为这行命令实际上是拉取了最新的不稳定的 Linux 内核. 如果已经执行了这个命令的同学, 可以考虑执行以下命令回滚内核:

sudo apt install --reinstall libraspberrypi0 libraspberrypi-{bin,dev,doc} raspberrypi-bootloader raspberrypi-kernel

具体的内容参考这篇官方文档: 点我跳转树莓派官网

設置系統的部分自己選擇, 畢竟選項和提示都寫的很清楚.

我是比較喜歡開啟 Overlay Filesystem + ReadOnly Boot Partition 的, 前者就是一個開機一鍵還原, 後者是防止突然斷電破壞 boot 分區. 我覺得這兩個都比較實用, 建議全部設置完之後開啟.

至於語言 (Locale) 設定, 我喜歡把所有 zh 開頭的都勾上, 然後選用 zh_CN.UTF8, 可以保證亂碼不會出現.

至於測試的話, 只要 mkdir 測試, 然後 ls 一看看一看中文是否正常顯示就可以了.

軟件安裝

  1. 基本設置於基礎軟件安裝
# 安裝基本軟件
apt install vim git make wget -y

# 設置 UFW
apt install ufw -y
ufw allow from 192.168.10.1/24
ufw default deny
ufw enable
ufw status

# 設置 NTP 服務
apt install ntpdate -y
echo '@reboot ntpdate 192.168.10.1' >> /etc/crontab

# 設置 開機掛載硬盤
mkdir /mnt/data
mount /dev/sda1 /mnt/data
blkid # 複製顯示的 uuid 和 type
echo 'UUID=2e2e58b1-8fe8-4f5c-9478-f5eef65c5aa5 /mnt/data ext4 defaults 1 2' >> /etc/fstab
mount -a # 確定沒有報錯!

# 開機掛載網絡硬盤
sudo apt install -y curlftpfs
echo '@reboot curlftpfs -o rw,allow_other ftp://username:[email protected]/ /media/ftpdrive' >> /etc/crontab

# 安裝 ZSH & OH MY ZSH
apt install zsh -y
sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"

# 重啟
reboot

簡單的解釋一下為什麼我上面是這樣配置:

  • 我因為樹莓派完全運行在家庭網絡裡面, 所有流量都要經過轉發, 所以防火牆只允許家裡設備訪問最穩妥.
  • 因為路由器的系統是 Openwrt, 開著 NTP 服務, 所以可以直接向它更新時間.
  • 插上硬盤之後, 最新的系統應該會自動創建一個掛載點 /media/pi/... , 我不想要它, 所以已經把它 unmount 掉了.

2. 安裝 Docker

# 安裝 Docker
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
docker -v
systemctl enable docker.service
systemctl enable containerd.service

# 將 Docker 數據卷掛到外接硬盤
systemctl stop docker
systemctl stop containerd

# 第一次裝系統使用這個方法
rsync -av /var/lib/docker /mnt/data/
rsync -av /var/lib/containerd /mnt/data/
rm -r /var/lib/docker /var/lib/containerd

# 如果重裝過系統想要恢復數據
# mv /var/lib/docker /var/lib/docker.bak
# mv /var/lib/containerd /var/lib/containerd.bak

ln -s /mnt/data/docker /var/lib/docker
ln -s /mnt/data/containerd /var/lib/containerd

systemctl start docker
systemctl start containerd

3. 安裝 Docker-compose ( 使用 pip3 因為 Github 上下載不到針對 Arm 的二進制包 )

apt install python3-venv python3-pip
apt install libffi-dev # 構建環境, 完成後可以卸載掉
pip3 install docker-compose
docker-compose -v

# 刪除構建緩存
rm -r ~/.cache/pip

4. 最後可以啟用 Overlay Filesystem + ReadOnly Boot Partition 了. 之後要是想裝東西可以直接使用 Docker, 改動會保存在外接硬碟中, 就算重裝系統也可以輕鬆恢復數據, 是目前我找到的最好的方案.

raspi-config

5月26日附: 在插拔 HDMI 线的时候不小心把电源也带出来了,赶紧插上,开机没发现任何问题,一分钟后博客恢复访问,lost+found下没添加任何文件。Overlay filesystem 确实是,高!

為官方 Nginx 鏡像安裝 Extras 插件

要用到 Nginx 的額外功能, 我需要安裝插件合集 nginx-extras . 但是官方 Nginx 鏡像並不提供插件功能, 而我也不想就為了這麽一個小功能就去用別人自己 Build 的鏡像, 鬼知道裡面有什麼東西.

我了解到 官方 Nginx, 如果沒有特殊指定的話, 是基於 Debian 的. 那麼在 Debian 裡面如果我想要安裝這個插件, 我只需要執行以下命令, 就可以用了

apt-get update && apt-get install -y nginx-extras

經過簡單的搜索, 我發現 Docker 提供 Dockerfile 的方法來構建自己的鏡像. 就是一個小腳本, 有點像 Git Actions 那樣的小腳本, 不過比那個還簡單.

Dockerfile Cheatsheet, 截取自 devhints.io

知道了 Dockerfile 怎麼使用之後, 就可以上手了

FROM nginx:latest
RUN apt-get update
RUN apt-get install -y nginx-extras
docker build -t nginx_extras .
docker image ls

因為我用了 Portainer, 我可以直接替換鏡像為我自己構建的 nginx_extras .

你也可以手動 rm 掉舊的容器然後用新的鏡像創建容器

到此為止, Nginx 已經可以用上這些插件了.

Docker 日誌塞滿服務器修復

早晨我例行的摸了一下鏈接到樹莓派的硬盤,結果發現它不轉了。Nani?
於是我立即嘗試登錄寶塔面板,結果發現卡在登錄頁面。
使用SSH重啓之後根本重連不上,網關提示根本沒給它分配IP,就是說它現在不能聯網。
我把樹莓派強制斷電後插電,可以連上了,但是提示的消息卻讓我比較震驚…

空間佔用 100% ?

於是我決心把他弄懂。

問題初步排查

首先肯定是要確定磁盤佔用是這樣…

$ df -h

Filesystem                                     Size  Used Avail Use% Mounted on
tmpfs                                          782M   60M  723M   8% /run
/dev/mmcblk0p2                                 117G  117G     0 100% /
tmpfs                                          3.9G     0  3.9G   0% /dev/shm
tmpfs                                          5.0M     0  5.0M   0% /run/lock
tmpfs                                          4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mmcblk0p1                                 253M  152M  101M  60% /boot/firmware
/dev/sda1                                      916G   95G  776G  11% /media/backup
tmpfs                                          782M  4.0K  782M   1% /run/user/0

是這樣沒錯,然後要定位到主目錄,看看到底那個文件夾出了問題。

$ cd /
$ du -h -x --max-depth=1 

74M    ./home
2.9G    ./usr
8.0K    ./.disk
24K    ./snap
4.0K    ./mnt
4.0K    ./srv
114M    ./root
72K    ./tmp
117M    ./boot
16K    ./opt
8.0K    ./patch
6.1M    ./etc
4.0K    ./media
4.1G    ./www
110G    ./var       <- 問題根源
16K    ./lost+found
117G    .

經過一番定位之後,現在可以發現問題的根源在這個文件夾裏:

/var/lib/docker/containers/6c8a****13f4/

進一步定位那個文件出了問題:

$ ll


total 112907424
drwx------ 4 root root         4096 Jan  7 04:41 ./
drwx------ 4 root root         4096 Feb  3 21:06 ../
-rw-r----- 1 root root 115617058816 Feb 18 13:05 6c8a****13f4-json.log
drwx------ 2 root root         4096 Feb  3 16:33 checkpoints/
-rw------- 1 root root         3958 Jan  7 04:41 config.v2.json
-rw-r--r-- 1 root root         1513 Jan  7 04:41 hostconfig.json
-rw-r--r-- 1 root root           13 Feb  5 13:29 hostname
-rw-r--r-- 1 root root          174 Feb  5 13:29 hosts
drwx------ 3 root root         4096 Feb  3 16:33 mounts/
-rw-r--r-- 1 root root          612 Feb  5 13:29 resolv.conf
-rw-r--r-- 1 root root           71 Feb  5 13:29 resolv.conf.hash

恐怖的發現…這個日誌文件竟然佔了這麼多的大小…

修復問題

看了一下日誌,整個日誌基本全是 P2P文件交換的記錄。
離譜的是這個日誌居然是以毫秒記錄的,有的地方甚至一毫秒幾十行…這個樹莓派是怎麼支撐過來的?
因爲沒有值得注意的東西,我就直接 rm 掉了。瞬間執行,滿足感還是很高的, WinServer不知道刪到猴年馬月去。
(Ext4文件系統刪除文件時並沒有對數據進行操作,我的理解中是將記錄文件信息的索引釋放掉了,在系統的想法裏這片空間又變回可寫的了)

$ df -h

Filesystem                                     Size  Used Avail Use% Mounted on
tmpfs                                          782M   79M  703M  11% /run
/dev/mmcblk0p2                                 117G  9.3G  103G   9% /
tmpfs                                          3.9G     0  3.9G   0% /dev/shm
tmpfs                                          5.0M     0  5.0M   0% /run/lock
tmpfs                                          4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mmcblk0p1                                 253M  152M  101M  60% /boot/firmware
/dev/sda1                                      916G   95G  776G  11% /media/backup
tmpfs                                          782M  4.0K  782M   1% /run/user/0

很好,空間佔用回到正常了。

防止問題重複

既然知道了是日誌文件的問題,現在就要搞清楚到底那個容器出了問題。

$ docker ps -a

CONTAINER ID        IMAGE
84e1a7934eb6        linuxserver/syncthing:latest
6c8a506e5aca        linuxserver/resilio-sync:latest

現在就知道哪裡出現問題了。可以看到,resilio-sync 的id對應了那個日誌文件的開頭。

我更改了resilio sync中的設置,分別更改爲

log_size = 0
log_ttl = 0
disk_low_priority = true

希望這樣可以有效果,我會在幾天後再來查看。

实测这样子并没有效果,看起來是Docker鏡像製作時留下來的問題, 直接在容器裡更改配置不起作用.

那這不簡單.

docker pause ResilioSync
rm 6c8a****13f4-json.log
ln -s /dev/null 6c8a****13f4-json.log
$ ll

總計 36K
drwx------ 2 root root 4.0K  1月  1  2038 checkpoints
-rw------- 1 root root 4.9K  5月  5 10:25 config.v2.json
lrwxrwxrwx 1 root root    9  5月  5 10:26 6c8a****13f4-json.log -> /dev/null
-rw-r--r-- 1 root root 2.2K  5月  5 10:25 hostconfig.json
-rw-r--r-- 1 root root   13  5月  4 22:14 hostname
-rw-r--r-- 1 root root  174  5月  4 22:14 hosts
drwx-----x 2 root root 4.0K  1月  1  2038 mounts
-rw-r--r-- 1 root root   61  5月  4 22:14 resolv.conf
-rw-r--r-- 1 root root   71  5月  4 22:14 resolv.conf.hash
docker unpause ResilioSync

问题到此解决

沒解決.

這樣做之後確實一時爽, 但是過了一天我回來看, 發現容器停止運行, 原因是

/mnt/data/docker/containers/6c8a****13f4-json.log/dev/null no file or directory

所以問題到底怎麼解決呢?

經過一番搜索(現在才想起來有谷歌這回事)之後, 我得到了結果, 問題完美解決.

原來是可以通過配置 docker-compose 來限制logsize的, 比如說我要限制 nginx 的 logsize 為5g, 我可以

nginx: 
  image: 
  restart: always 
  logging: 
    driver: “json-file” 
    options: 
      max-size: “5g” 

那麼我是用portainer管理docker的, 我可以

問題到此真正完美解決.