−25%

Windows 年繳方案適用,至 10 月 31 日。 檢視方案

EQVPS
開始使用

如何設定 Alpine Linux VPS:apk、doas、OpenRC 與防火牆

全新 Alpine Linux 3.21 VPS 的第一步:更新並重新開機,建立一個真的能登入的 doas 使用者,關閉 root 與密碼 SSH 登入,裝上 ufw,開啟 cron 與每日更新。另附 ufw 擋不住的 Docker 連接埠。

Alpine Linux 是我們提供的最小映像。在我們的伺服器上,全新的 Alpine 3.21 閒置時使用 55 MB 記憶體和 153 MB 磁碟,而 Ubuntu 24.04 是 313 MB 和 2.7 GB。代價是放棄熟悉的工具。Alpine 用 apk 取代 apt,用 doas 取代 sudo,用 OpenRC 取代 systemd,用 musl 取代 glibc。

以下步驟與在 Debian 或 Ubuntu 上的前十分鐘相同,只是換成 Alpine 的做法。發布前,我們在自己的 Alpine 3.21 映像上執行了每一個指令,其中有兩個第一次就讓我們踩了坑。請用控制台中的密碼以 root 登入。

1. 更新,然後重新開機一次

apk update && apk upgrade
uname -r
ls /lib/modules

伺服器在第一次開機時已經安裝了可用的更新,所以 apk upgrade 通常沒剩多少事。重點看最後兩行。如果那次首次開機更新帶來了新核心,正在執行的核心(uname -r)在磁碟上就已經沒有對應的模組。任何需要載入模組的操作都會失敗,直到重新開機為止。在我們的測試伺服器上,安裝防火牆時輸出了 ERROR: Couldn't determine iptables version。如果兩個版本不同,現在就重新開機:

reboot

我們的測試伺服器不到一分鐘就回來了。

2. 建立能登入的使用者

adduser -D deploy
passwd deploy
adduser deploy wheel

不要略過 passwd。adduser -D 建立的帳號沒有密碼,Alpine 會把它標示為鎖定,而 sshd 會拒絕鎖定的帳號,即使金鑰正確。在我們的測試中,唯一的線索是 /var/log/messages 裡的這一行:

User deploy not allowed because account is locked

密碼之後也會用到:doas 要的就是它。

如果下單時加入了 SSH 金鑰,它就在 root 的 authorized_keys 裡。把它複製給新使用者:

install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys

還沒有金鑰?在自己的電腦上產生一組,把公開金鑰貼到 /home/deploy/.ssh/authorized_keys。

3. 讓 doas 要求輸入密碼

Alpine 用 doas 取代 sudo,我們的映像已經允許 wheel 群組使用它。/etc/doas.d/wheel.conf 裡的規則是 permit nopass :wheel,也就是 wheel 群組的任何成員不必輸入任何東西就能成為 root。改成要求輸入密碼,並在幾分鐘內記住它:

echo 'permit persist :wheel' > /etc/doas.d/wheel.conf

從現在起,doas apk add nano 的用法就和 Ubuntu 上的 sudo apt install nano 一樣。

4. SSH:只用金鑰,禁止 root

sshd 依檔名順序讀取 /etc/ssh/sshd_config.d/ 裡的檔案,每項設定採用它找到的第一個值。在我們的映像中,第一個檔案是 00-eqvps.conf,它允許 root 與密碼登入,方便你第一天進入伺服器。取代它的內容:

cat > /etc/ssh/sshd_config.d/00-eqvps.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sshd -t && rc-service sshd restart
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '

第三行在 Alpine 上很重要。映像使用帶 PAM 的 OpenSSH 版本,只寫前兩行時,我們的測試伺服器仍然提供 keyboard-interactive 登入。三行都寫上之後,不帶金鑰的登入嘗試會得到:

Permission denied (publickey).

保持 root 工作階段不要關閉。在第二個終端機中確認 ssh deploy@YOUR.SERVER.IP 能登入(NAT 方案要加上 -p 和控制台中的專屬連接埠),並確認 doas id 接受密碼。

5. 防火牆:ufw

ufw 在 community 套件庫中,我們的映像已經啟用這個套件庫:

apk add ufw
ufw limit 22/tcp
ufw --force enable
rc-update add ufw default
ufw status

limit 允許 SSH,但會拖慢連續開啟大量連線的一方。這裡 rc-update 很重要,因為如果沒把防火牆加入 runlevel,OpenRC 重新開機後不會啟動它。重新開機後,我們的伺服器回來時顯示 Status: active。在 NAT 方案上,請讓 SSH 留在 22 連接埠:你的專屬外部連接埠會轉送到伺服器內部的 22。在具獨立 IPv4 的方案上,需要時再開放網頁連接埠(ufw allow 80/tcp、ufw allow 443/tcp)。其餘內容請見 ufw 指南。

6. 開啟 cron 與每日更新

全新的 Alpine 伺服器完全沒有執行 cron。把它打開:

rc-update add crond default
rc-service crond start

Alpine 中 root 的 crontab 已經會在每天 02:00 執行 /etc/periodic/daily 裡的所有內容。把更新指令碼放進去:

cat > /etc/periodic/daily/apk-upgrade <<'EOF'
#!/bin/sh
apk upgrade --update-cache --no-progress >> /var/log/apk-auto.log 2>&1
EOF
chmod +x /etc/periodic/daily/apk-upgrade
run-parts --test /etc/periodic/daily

最後一個指令會列出 cron 將執行的指令碼,你的指令碼應該在清單中。這樣你就能持續取得 3.21 的修正。升級到下一個 Alpine 版本是另一個需要手動進行的步驟。核心更新仍然需要重新開機:偶爾重複第 1 步的 uname -r / ls /lib/modules 檢查。

7. 一張表看懂 OpenRC

如果你熟悉 systemd,改變的大致就是這些:

工作systemdAlpine (OpenRC)
啟動服務systemctl start nginxrc-service nginx start
開機自動啟動systemctl enable nginxrc-update add nginx default
狀態systemctl status nginxrc-service nginx status
正在執行的服務systemctl list-unitsrc-status
系統日誌journalctl/var/log/messages

8. Docker,以及 ufw 擋不住的連接埠

Alpine 很適合當 Docker 主機,因為系統本身幾乎不礙事:

apk add docker docker-cli-compose
rc-update add docker default
rc-service docker start
docker run --rm hello-world

在我們的伺服器上,連同下載共花了 12 秒。Docker 背景程式執行後,已用記憶體從 57 MB 增加到 124 MB。

有一個陷阱並非 Alpine 獨有:Docker 會寫入自己的防火牆規則。在 ufw 只允許 SSH 的情況下,我們用 -p 8080:80 啟動 nginx,結果從伺服器外部透過 8080 連接埠存取到了它。ufw 沒有擋下。如果某個容器只應透過同一台伺服器上的反向代理存取,請把它發布在 localhost:

docker run -d -p 127.0.0.1:8080:80 nginx:alpine

選哪個方案

Alpine 幾乎把全部記憶體留給你自己的軟體。Nano 方案(2 vCPU、1 GB、15 GB,$3/月)足以執行一個小服務或幾個容器。這是 NAT 方案,SSH 透過專屬連接埠進入。如果需要對網際網路開放 80 和 443 連接埠,Nano-IP 具獨立 IPv4,$8/月。較重的 Docker 堆疊可以選 Micro,2 GB,$5/月。

Alpine 3.21 位於 Alpine VPS 頁面,所有 VPS Linux 方案都可選。付款方式為 Base、Ethereum 或 Polygon 網路上的 USDT、USDC 或 ETH,不需證件,也不需信用卡。

常見問題

為什麼 Alpine 比 Ubuntu 或 Debian 小這麼多?

它用 musl 取代 glibc,用 BusyBox 提供基本指令,用 OpenRC 取代 systemd。在我們的伺服器上,全新的 Alpine 3.21 閒置時使用 55 MB 記憶體和 153 MB 磁碟。Ubuntu 24.04 使用 313 MB 和 2.7 GB。

金鑰沒錯,為什麼新使用者還是出現 "account is locked"?

adduser -D 建立的帳號沒有密碼,Alpine 會把它標示為鎖定,sshd 接著即使遇到有效金鑰也會拒絕該使用者。日誌中的那一行是 "User deploy not allowed because account is locked"。用 passwd 為使用者設定密碼,金鑰登入就能使用。

為什麼 SSH 通道在 Alpine 上無法使用?

Alpine 預設的 /etc/ssh/sshd_config 設定了 AllowTcpForwarding no,所以 ssh -L 轉送會被拒絕。如果需要通道,在該檔案中改成 yes,再執行 rc-service sshd restart。

我的程式能在 Alpine 上執行嗎?

Alpine 套件庫裡的東西都能執行,以任何基礎映像建立的 Docker 容器也能執行。為 glibc 編譯的現成 Linux 執行檔在 musl 上常常無法啟動。請找 Alpine 或 musl 版本,或在 Docker 中執行程式。gcompat 套件對部分簡單的 glibc 執行檔有幫助。

Alpine 用哪個方案就夠?

每月 $3 的 1 GB Nano 方案綽綽有餘:系統本身只用約 55 MB。如果需要對網際網路開放 80 和 443 連接埠,請選每月 $8、具獨立 IPv4 的 Nano-IP。

評論

目前還沒有評論。歡迎成為第一位。

發表評論

評論在顯示前會經過審核。