內容目錄

FS2 專案 (go2see.me) — 第二階段

現在進入 Phase 2,不過我想調整一下方向。

我們先不要急著寫 Portal

因為有一件事比 Portal 更重要:

把 Apache 設定改成可維護。

你現在每個使用者都有一段:

Alias /johnny ...

...

7 個人還可以接受。

如果以後變成:

  • 20 人
  • 50 人
  • 100 人

這個檔會變成上千行,很難維護。


我建議 Phase 2 分成三個小階段

Phase 2A(先做)

整理 Apache

/etc/apache2/

sites-available/
    fs2-le-ssl.conf

conf-available/
    fs2-users.conf
    fs2-common.conf

把共用設定抽出來。

例如:

DAV On
Options Indexes
AuthType Basic
AuthName "FS2"
AuthUserFile ...

只寫一次。

這樣 Apache 設定會乾淨很多。


Phase 2B

建立 FS2 Portal

https://fs2.go2see.me

首頁:

Public

Info

Share

My Folder

Change Password

先不用登入。

只是漂亮首頁。


Phase 2C

再加入:

Login

Change Password

Admin

我還想做一件事

目前:

users.password

只有一份。

我想把它搬到:

/etc/fs2/

users.password
groups

理由:

  • /etc 放設定
  • /srv 放資料
  • /var/www 放網站

符合 Linux 標準。

Apache 也只要改:

AuthUserFile /etc/fs2/users.password
AuthGroupFile /etc/fs2/groups

之後備份也更容易。


我希望順便整理整個 FS2

最後應該變成:

/srv/fs2/
        真正資料

/etc/fs2/
        所有設定

/var/www/fs2/
        Portal

/opt/fs2/
        安裝、更新工具

/backup/fs2/
        備份

職責非常清楚。


我建議現在先做這件事

FS2 目錄標準化(約 10 分鐘)

/etc/fs2/
    users.password
    groups

/opt/fs2/
    install/
    update/
    backup/
    tools/

/srv/fs2/
    storage

/var/www/fs2/
    portal

這樣後面 Portal、MariaDB、更新腳本都會很乾淨。


我的建議

下一步不要寫 Portal。

先把 FS2 的目錄、Apache 設定與備份機制整理成正式版本

之後再開始寫 Portal,整個專案會更容易維護,也更符合你希望做成長期使用系統的目標。這一步完成後,我們再開始設計 Portal 的登入與「修改自己密碼」功能。

🎯 Phase 2A:FS2 標準化

我們的目標是讓整個專案符合 Linux FHS(Filesystem Hierarchy Standard)。


最終目錄

/
├── srv/
│   └── fs2/
│       ├── pub/
│       ├── info/
│       ├── share/
│       ├── private/
│       ├── recycle/
│       ├── backup/
│       └── temp/
│
├── etc/
│   └── fs2/
│       ├── users.password
│       ├── groups
│       ├── fs2.conf
│       └── quota.conf
│
├── var/
│   ├── www/
│   │   ├── fs2-index/
│   │   └── fs2/          ← Portal(未來)
│   │
│   └── log/
│       └── fs2/
│
├── opt/
│   └── fs2/
│       ├── install/
│       ├── update/
│       ├── backup/
│       ├── tools/
│       ├── sql/
│       └── version/
│
└── backup/
    └── fs2/

第一件事:搬設定

目前:

/var/www/apache/var/

改成:

sudo mkdir -p /etc/fs2

sudo mv /var/www/apache/var/users.password /etc/fs2/
sudo mv /var/www/apache/var/groups /etc/fs2/

sudo cp /var/www/apache/var/DavLock /etc/fs2/DavLock

DavLock 有兩種選擇:

  • 保留在 /var/lib/dav(Debian/Ubuntu 常見)
  • /etc/fs2(目前也可以)

我比較推薦改成:

sudo mkdir -p /var/lib/fs2
sudo mv /var/www/apache/var/DavLock /var/lib/fs2/

因為 Lock DB 是執行時資料,不是設定檔

所以未來:

/etc/fs2
    users.password
    groups

/var/lib/fs2
    DavLock

會更符合 Linux 慣例。


第二件事:建立專案目錄

sudo mkdir -p /opt/fs2/{install,update,backup,tools,sql,version}
sudo mkdir -p /var/log/fs2
sudo mkdir -p /var/www/fs2

第三件事:建立版本

echo "FS2 1.0.0" | sudo tee /opt/fs2/version/VERSION

以後:

cat /opt/fs2/version/VERSION

直接知道版本。


第四件事:Apache

修改:

AuthUserFile /etc/fs2/users.password
AuthGroupFile /etc/fs2/groups

DavLockDB /var/lib/fs2/DavLock

全部一起改。


第五件事:建立設定檔

sudo nano /etc/fs2/fs2.conf

例如:

FS2_NAME=FS2
DOMAIN=fs2.go2see.me
STORAGE=/srv/fs2
BACKUP=/backup/fs2
LOG=/var/log/fs2
VERSION=1.0.0

以後 PHP、Shell Script 都讀同一份設定。


我還想加入一個功能(從一開始就做好)

fs2ctl

就像:

systemctl

一樣。

例如:

sudo fs2ctl status
sudo fs2ctl backup
sudo fs2ctl users
sudo fs2ctl version

以後甚至:

sudo fs2ctl update

全部都由一個入口管理。


我建議的開發路線

完成 Phase 2A 後:

  1. 整理目錄與設定(現在)
  2. 建立 fs2ctl 管理工具
  3. 建立 Portal 首頁
  4. 建立自助修改密碼
  5. 建立 Admin 後台
  6. 最後再導入 MariaDB 管理

這樣整個 FS2 就會像一個真正的 Linux 服務,而不是零散的 Apache 設定。後續無論是升級到 Ubuntu 24.04,或增加功能,都會容易很多。

Phase 2A 實作:搬設定 + 改 Apache + 測試

sudo -s 後開始繼續。

1. 建正式目錄

mkdir -p /etc/fs2
mkdir -p /var/lib/fs2
mkdir -p /var/log/fs2
mkdir -p /opt/fs2/{install,update,backup,tools,sql,version}
mkdir -p /var/www/fs2
mkdir -p /backup/fs2

2. 搬帳號與群組檔

mv /var/www/apache/var/users.password /etc/fs2/
mv /var/www/apache/var/groups /etc/fs2/
mv /var/www/apache/var/DavLock /var/lib/fs2/

如果某個檔案已經搬過,出現 No such file 沒關係,先查:

ls -l /etc/fs2
ls -l /var/lib/fs2

3. 設權限

chown root:www-data /etc/fs2/users.password /etc/fs2/groups
chmod 640 /etc/fs2/users.password /etc/fs2/groups

chown www-data:www-data /var/lib/fs2/DavLock
chmod 660 /var/lib/fs2/DavLock

4. 建 FS2 設定檔

cat > /etc/fs2/fs2.conf <<'EOF'
FS2_NAME=FS2
DOMAIN=fs2.go2see.me
STORAGE=/srv/fs2
BACKUP=/backup/fs2
LOG=/var/log/fs2
VERSION=1.0.0
EOF

5. 建版本檔

echo "FS2 1.0.0" > /opt/fs2/version/VERSION

6. 修改 Apache 設定

nano /etc/apache2/sites-available/fs2-le-ssl.conf

/etc/apache2/sites-available/fs2-le-ssl.conf 的所有:

AuthUserFile /var/www/apache/var/users.password
AuthGroupFile /var/www/apache/var/groups
DavLockDB /var/www/apache/var/DavLock

改成:

AuthUserFile /etc/fs2/users.password
AuthGroupFile /etc/fs2/groups
DavLockDB /var/lib/fs2/DavLock

==》 直接用指令:

sed -i 's#/var/www/apache/var/users.password#/etc/fs2/users.password#g' /etc/apache2/sites-available/fs2-le-ssl.conf
sed -i 's#/var/www/apache/var/groups#/etc/fs2/groups#g' /etc/apache2/sites-available/fs2-le-ssl.conf
sed -i 's#/var/www/apache/var/DavLock#/var/lib/fs2/DavLock#g' /etc/apache2/sites-available/fs2-le-ssl.conf

7. 測試 Apache

apache2ctl configtest
systemctl reload apache2

8. 重新測一次權限

curl -I https://fs2.go2see.me/
curl -I https://fs2.go2see.me/pub/
curl -I https://fs2.go2see.me/info/

curl -u cyue https://fs2.go2see.me/info/
curl -u johnny https://fs2.go2see.me/share/
curl -u johnny https://fs2.go2see.me/johnny/
curl -u johnny https://fs2.go2see.me/cyue/

預期仍然跟剛才一樣。完成後,FS2 目錄標準化就完成。


Phase 2B 先做一個管理工具 fs2ctl

把方向修正一下,我們先不要做 Portal。
原因:
以後你會常做:

  • 新增使用者
  • 刪除使用者
  • 重設密碼
  • 建立私人目錄
  • 備份
  • 更新
    如果都靠:
htpasswd
mkdir
chown
nano

久了會很累。


我希望變成:

sudo fs2ctl user add johnny

自動完成:

✓ htpasswd
✓ mkdir /srv/fs2/private/johnny
✓ chown
✓ chmod
✓ Apache reload

例如

sudo fs2ctl passwd johnny

==> 修改密碼


例如

sudo fs2ctl backup

==> 備份


例如

sudo fs2ctl version

==>

FS2 1.0.0

目錄

建立:

mkdir -p /opt/fs2/bin

裡面放:

/opt/fs2/bin/fs2ctl

再建立:

ln -s /opt/fs2/bin/fs2ctl /usr/local/bin/fs2ctl

以後:

fs2ctl

就可以用了。


第一版功能

fs2ctl status
fs2ctl version
fs2ctl backup
fs2ctl users
fs2ctl adduser
fs2ctl passwd
fs2ctl removeuser

Status

例如:

FS2 Version
1.0.0
Apache
Running
Storage
OK
Backup
OK
Users
7

Users

例如:

cyue
shari
johnny
tony
may
yuhan
yuchen

直接從:

/etc/fs2/users.password

讀出。


Add User

例如:

sudo fs2ctl adduser tom

自動:

建立密碼
建立 private/tom
加入 member
reload apache

完全不用手工。


Remove User

例如:

sudo fs2ctl removeuser tom

詢問:

Delete Home ?
Y/N

Backup

就是:

sudo fs2ctl backup

執行:

/opt/fs2/tools/backup_fs2.sh

不過,我想再調整一件事情

目前使用者資訊分散在:

  • /etc/fs2/users.password
  • /etc/fs2/groups
  • /srv/fs2/private/

未來要新增一位使用者,需要修改三個地方。

我建議我們在 Phase 2B 就建立一個小小的設定檔,例如:

users:
  - username: cyue
    role: maintainer
  - username: shari
    role: member
  - username: johnny
    role: member
  ...

以後 fs2ctl adduserfs2ctl removeuser 都依這份設定更新 Apache、群組、私人目錄。

這樣使用者資料只有一份來源(Single Source of Truth),將來即使導入 MariaDB,也只要讓 fs2ctl 從資料庫讀寫即可,不需要重寫整個管理工具。

我認為這會是 FS2 最值得投資的基礎設計。

FS2 管理工具 fs2ctl 第一版

1. 建目錄

mkdir -p /opt/fs2/bin
mkdir -p /opt/fs2/tools

2. 建立 fs2ctl

nano /opt/fs2/bin/fs2ctl

貼上:

#!/bin/bash
set -e

FS2_CONF="/etc/fs2/fs2.conf"
USER_FILE="/etc/fs2/users.password"
GROUP_FILE="/etc/fs2/groups"
STORAGE="/srv/fs2"
VERSION_FILE="/opt/fs2/version/VERSION"
BACKUP_SCRIPT="/opt/fs2/tools/backup_fs2.sh"

cmd="$1"
arg="$2"

need_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "Please run as root."
        exit 1
    fi
}

case "$cmd" in
    status)
        echo "FS2 Status"
        echo "----------"
        echo -n "Version: "
        cat "$VERSION_FILE" 2>/dev/null || echo "unknown"

        echo -n "Apache: "
        systemctl is-active apache2

        echo -n "Storage: "
        [ -d "$STORAGE" ] && echo "OK" || echo "Missing"

        echo -n "User file: "
        [ -f "$USER_FILE" ] && echo "OK" || echo "Missing"

        echo -n "Group file: "
        [ -f "$GROUP_FILE" ] && echo "OK" || echo "Missing"

        echo -n "Users: "
        if [ -f "$USER_FILE" ]; then
            cut -d: -f1 "$USER_FILE" | wc -l
        else
            echo "0"
        fi
        ;;

    version)
        cat "$VERSION_FILE"
        ;;

    users)
        cut -d: -f1 "$USER_FILE"
        ;;

    passwd)
        need_root
        if [ -z "$arg" ]; then
            echo "Usage: fs2ctl passwd USER"
            exit 1
        fi
        htpasswd "$USER_FILE" "$arg"
        systemctl reload apache2
        echo "Password updated: $arg"
        ;;

    adduser)
        need_root
        if [ -z "$arg" ]; then
            echo "Usage: fs2ctl adduser USER"
            exit 1
        fi

        if grep -q "^${arg}:" "$USER_FILE"; then
            echo "User already exists: $arg"
            exit 1
        fi

        htpasswd "$USER_FILE" "$arg"

        mkdir -p "$STORAGE/private/$arg"
        chown -R www-data:www-data "$STORAGE/private/$arg"
        chmod 775 "$STORAGE/private/$arg"

        if grep -q "^members:" "$GROUP_FILE"; then
            sed -i "s/^members:.*/& $arg/" "$GROUP_FILE"
        else
            echo "members: $arg" >> "$GROUP_FILE"
        fi

        echo ""
        echo "IMPORTANT:"
        echo "You still need to add this user's Alias block in Apache:"
        echo "  /etc/apache2/sites-available/fs2-le-ssl.conf"
        echo ""
        systemctl reload apache2
        echo "User added: $arg"
        ;;

    backup)
        need_root
        "$BACKUP_SCRIPT"
        ;;

    reload)
        need_root
        apache2ctl configtest
        systemctl reload apache2
        ;;

    *)
        echo "FS2 Control Tool"
        echo ""
        echo "Usage:"
        echo "  fs2ctl status"
        echo "  fs2ctl version"
        echo "  fs2ctl users"
        echo "  fs2ctl passwd USER"
        echo "  fs2ctl adduser USER"
        echo "  fs2ctl backup"
        echo "  fs2ctl reload"
        ;;
esac

3. 權限與捷徑

chmod +x /opt/fs2/bin/fs2ctl
ln -sf /opt/fs2/bin/fs2ctl /usr/local/bin/fs2ctl

4. 測試

fs2ctl status
fs2ctl version
fs2ctl users

5. 測試備份

fs2ctl backup

這版先完成基本管理。下一步再把 Apache 使用者 Alias 也自動化。


下一步做 fs2ctl v1.1:自動產生使用者 Apache Alias 設定

目前 adduser 還要手動改 Apache,這不完整。改成:

/etc/apache2/conf-available/fs2-users.conf

fs2ctl 自動生成。

1. 建立使用者設定檔

nano /etc/fs2/users.list

貼:

cyue:maintainer
shari:member
johnny:member
tony:member
may:member
yuhan:member
yuchen:member

2. 啟用 Apache include

修改:

nano /etc/apache2/sites-available/fs2-le-ssl.conf

把所有個人目錄 Alias 區塊刪掉,也就是這類都刪:

Alias /cyue /srv/fs2/private/cyue

...

刪掉 cyue/shari/johnny/tony/may/yuhan/yuchen 全部個人段落。

然後在 </VirtualHost> 前面加入:

IncludeOptional /etc/apache2/conf-available/fs2-users.conf

3. 建產生腳本

sudo nano /opt/fs2/tools/generate_apache_users.sh

貼上:

#!/bin/bash
set -e

USER_LIST="/etc/fs2/users.list"
OUT="/etc/apache2/conf-available/fs2-users.conf"
STORAGE="/srv/fs2"
AUTH_FILE="/etc/fs2/users.password"

cat > "$OUT" <<'EOF'
# Auto-generated by FS2.
# Do not edit manually.

EOF

while IFS=: read -r user role; do
    [ -z "$user" ] && continue
    [[ "$user" =~ ^# ]] && continue

    cat >> "$OUT" <
    DAV On
    Options Indexes
    AllowOverride None

    AuthType Basic
    AuthName "FS2"
    AuthUserFile $AUTH_FILE
    Require user $user


EOF
done < "$USER_LIST"

apache2ctl configtest
systemctl reload apache2

echo "Generated: $OUT"

4. 權限

sudo chmod +x /opt/fs2/tools/generate_apache_users.sh

5. 產生設定

sudo /opt/fs2/tools/generate_apache_users.sh

6. 測試

curl -u johnny https://fs2.go2see.me/johnny/
curl -u johnny https://fs2.go2see.me/cyue/

預期:

/johnny/ 成功
/cyue/ 失敗

完成後,下一步再把 fs2ctl adduser 改成自動更新 users.list、建立目錄、重建 Apache 使用者設定。


繼續做 fs2ctl v1.2

adduser 自動更新 users.list、groups、目錄、Apache Alias。

1. 改 fs2ctl

sudo nano /opt/fs2/bin/fs2ctl

把整份換成下面這版:

#!/bin/bash
set -e

USER_FILE="/etc/fs2/users.password"
GROUP_FILE="/etc/fs2/groups"
USER_LIST="/etc/fs2/users.list"
STORAGE="/srv/fs2"
VERSION_FILE="/opt/fs2/version/VERSION"
BACKUP_SCRIPT="/opt/fs2/tools/backup_fs2.sh"
GEN_APACHE_USERS="/opt/fs2/tools/generate_apache_users.sh"

cmd="$1"
arg="$2"

need_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo "Please run as root."
        exit 1
    fi
}

case "$cmd" in
    status)
        echo "FS2 Status"
        echo "----------"
        echo -n "Version: "
        cat "$VERSION_FILE" 2>/dev/null || echo "unknown"
        echo -n "Apache: "
        systemctl is-active apache2
        echo -n "Storage: "
        [ -d "$STORAGE" ] && echo "OK" || echo "Missing"
        echo -n "User file: "
        [ -f "$USER_FILE" ] && echo "OK" || echo "Missing"
        echo -n "Group file: "
        [ -f "$GROUP_FILE" ] && echo "OK" || echo "Missing"
        echo -n "User list: "
        [ -f "$USER_LIST" ] && echo "OK" || echo "Missing"
        echo -n "Users: "
        [ -f "$USER_LIST" ] && grep -v '^#' "$USER_LIST" | grep -v '^$' | wc -l || echo "0"
        ;;

    version)
        cat "$VERSION_FILE"
        ;;

    users)
        if [ -f "$USER_LIST" ]; then
            cat "$USER_LIST"
        else
            cut -d: -f1 "$USER_FILE"
        fi
        ;;

    passwd)
        need_root
        [ -z "$arg" ] && echo "Usage: fs2ctl passwd USER" && exit 1
        htpasswd "$USER_FILE" "$arg"
        systemctl reload apache2
        echo "Password updated: $arg"
        ;;

    adduser)
        need_root
        [ -z "$arg" ] && echo "Usage: fs2ctl adduser USER" && exit 1

        if ! [[ "$arg" =~ ^[a-zA-Z0-9._-]+$ ]]; then
            echo "Invalid username: $arg"
            exit 1
        fi

        if grep -q "^${arg}:" "$USER_FILE" 2>/dev/null; then
            echo "User already exists in password file: $arg"
            exit 1
        fi

        if grep -q "^${arg}:" "$USER_LIST" 2>/dev/null; then
            echo "User already exists in users.list: $arg"
            exit 1
        fi

        htpasswd "$USER_FILE" "$arg"

        mkdir -p "$STORAGE/private/$arg"
        chown -R www-data:www-data "$STORAGE/private/$arg"
        chmod 775 "$STORAGE/private/$arg"

        echo "$arg:member" >> "$USER_LIST"

        if grep -q "^members:" "$GROUP_FILE"; then
            sed -i "s/^members:.*/& $arg/" "$GROUP_FILE"
        else
            echo "members: $arg" >> "$GROUP_FILE"
        fi

        "$GEN_APACHE_USERS"

        echo "User added: $arg"
        ;;

    backup)
        need_root
        "$BACKUP_SCRIPT"
        ;;

    reload)
        need_root
        apache2ctl configtest
        systemctl reload apache2
        ;;

    gen-apache)
        need_root
        "$GEN_APACHE_USERS"
        ;;

    *)
        echo "FS2 Control Tool"
        echo ""
        echo "Usage:"
        echo "  fs2ctl status"
        echo "  fs2ctl version"
        echo "  fs2ctl users"
        echo "  fs2ctl passwd USER"
        echo "  fs2ctl adduser USER"
        echo "  fs2ctl backup"
        echo "  fs2ctl reload"
        echo "  fs2ctl gen-apache"
        ;;
esac

2. 加執行權限

sudo chmod +x /opt/fs2/bin/fs2ctl

3. 測試狀態

fs2ctl status
fs2ctl users

4. 測試產生 Apache user config

sudo fs2ctl gen-apache

5. 測試新增一個臨時使用者

sudo fs2ctl adduser testuser

測:

curl -u testuser https://fs2.go2see.me/testuser/
curl -u testuser https://fs2.go2see.me/cyue/

預期:

/testuser/ 成功
/cyue/ 失敗

測完如果要移除,我下一步給你做 removeuser


繼續做 fs2ctl v1.3:removeuser

1. 修改 fs2ctl

sudo nano /opt/fs2/bin/fs2ctl

adduser) 那段後面、backup) 前面,加入這段:

    removeuser)
        need_root
        [ -z "$arg" ] && echo "Usage: fs2ctl removeuser USER" && exit 1

        if [ "$arg" = "cyue" ]; then
            echo "Refuse to remove maintainer: cyue"
            exit 1
        fi

        if ! grep -q "^${arg}:" "$USER_FILE" 2>/dev/null; then
            echo "User not found in password file: $arg"
            exit 1
        fi

        echo "Removing user: $arg"
        read -p "Delete private folder /srv/fs2/private/$arg ? Type YES to delete: " confirm

        htpasswd -D "$USER_FILE" "$arg" || true

        if [ -f "$USER_LIST" ]; then
            sed -i "/^${arg}:/d" "$USER_LIST"
        fi

        if [ -f "$GROUP_FILE" ]; then
            sed -i "s/^members:.*/$(grep '^members:' "$GROUP_FILE" | sed "s/ $arg//g")/" "$GROUP_FILE"
            sed -i "s/^maintainers:.*/$(grep '^maintainers:' "$GROUP_FILE" | sed "s/ $arg//g")/" "$GROUP_FILE"
        fi

        if [ "$confirm" = "YES" ]; then
            rm -rf "$STORAGE/private/$arg"
            echo "Private folder deleted: $STORAGE/private/$arg"
        else
            echo "Private folder kept: $STORAGE/private/$arg"
        fi

        "$GEN_APACHE_USERS"

        echo "User removed: $arg"
        ;;

然後在最下面 Usage 區加一行:

echo "  fs2ctl removeuser USER"

2. 測試語法

sudo fs2ctl status

如果有錯,多半是插入位置錯,要確保每個段落都是:

    command)
        ...
        ;;

3. 測試移除 testuser

sudo fs2ctl removeuser testuser

它會問:

Delete private folder /srv/fs2/private/testuser ? Type YES to delete:

輸入:

YES

4. 驗證

fs2ctl users
grep testuser /etc/fs2/users.password
grep testuser /etc/fs2/groups
ls -ld /srv/fs2/private/testuser
curl -u testuser https://fs2.go2see.me/testuser/

預期:

users.list 沒有 testuser
users.password 沒有 testuser
groups 沒有 testuser
private/testuser 不存在
curl 登入失敗

我們目前其實已經不是在做 WebDAV,而是在做一套 FS2 Server

接下來如果再一直加功能,Shell Script 會開始變得很難維護。


我建議從這裡開始改架構(很重要)

目前

fs2ctl
    1000+
    行

以後會變成

2000+
3000+

不好維護。


我建議改成

/opt/fs2/
bin/
    fs2ctl
lib/
    adduser.sh
    removeuser.sh
    passwd.sh
    backup.sh
    apache.sh
    users.sh
tools/
config/
version/

也就是

fs2ctl adduser

只是:

source lib/adduser.sh

維護非常容易。


Phase 3 開始建立 FS2 Framework

例如:

/opt/fs2/
bin/
    fs2ctl
lib/
config/
sql/
portal/
api/
tools/
version/
docs/

像真正的產品。


Portal

我建議不要放:

/var/www/html

改:

/var/www/fs2

裡面:

index.php
login.php
profile.php
logout.php
admin/
api/
assets/
css/
js/
img/

API

以後全部 API:

/api/
login.php
password.php
announcement.php
users.php

Portal 不直接碰 Shell。


fs2ctl

最後會變成:

fs2ctl

lib/*.sh

Apache

WebDAV


最重要的一件事

不要再用 htpasswd 當唯一資料來源。

我希望改成:

users.yml

例如:

version: 1
users:
  - username: cyue
    role: maintainer
  - username: johnny
    role: member
  - username: may
    role: member

然後:

users.yml
↓
generate htpasswd
↓
generate groups
↓
generate apache
↓
generate portal

只有一份來源(Single Source of Truth)


最終架構

users.yml
       │
       ▼
+--------------------+
|   fs2ctl build     |
+--------------------+
       │
       ├── users.password
       ├── groups
       ├── fs2-users.conf
       └── Portal Cache

以後:

sudo fs2ctl build

全部重新產生。


我認為這是整個專案最重要的一步

我們現在就停在這裡,不再增加零散功能,而是把 FS2 變成一個有建置流程(Build Process)的專案。

我建議從這一版開始,我們建立:

FS2 v2.0

特點:

  • 一份設定users.yml
  • 自動產生:Apache、群組、htpasswd 等設定。
  • 模組化fs2ctl 只負責調用各個子模組。
  • 未來可切換:如果之後改用 MariaDB 或 LDAP,只要改 build 模組,不需要重寫整個系統。

我認為這會比一直在 htpasswdgroups、Apache 設定之間同步修改,更容易維護,也更符合你想把 FS2 做成長期專案的目標。


繼續。下一步做

FS2 v2.0 Framework

先把結構整理起來,但不破壞現在已經可用的 Phase 1。

1. 建立 Framework 目錄

# sudo -s
mkdir -p /opt/fs2/{bin,lib,config,tools,sql,portal,api,docs,version}
mkdir -p /etc/fs2

2. 建立使用者主設定

nano /etc/fs2/users.yml

貼:

version: 1

users:
  - username: cyue
    role: maintainer

  - username: shari
    role: member

  - username: johnny
    role: member

  - username: tony
    role: member

  - username: may
    role: member

  - username: yuhan
    role: member

  - username: yuchen
    role: member

3. 建立 build 腳本

nano /opt/fs2/lib/build.sh

貼:

#!/bin/bash
set -e

USERS_YML="/etc/fs2/users.yml"
USERS_LIST="/etc/fs2/users.list"
GROUPS="/etc/fs2/groups"
APACHE_USERS="/etc/apache2/conf-available/fs2-users.conf"
STORAGE="/srv/fs2"
AUTH_FILE="/etc/fs2/users.password"

[ -f "$USERS_YML" ] || {
    echo "Missing $USERS_YML"
    exit 1
}

echo "# Generated from users.yml" > "$USERS_LIST"

grep "username:" "$USERS_YML" | awk '{print $3}' | while read -r user; do
    role=$(grep -A1 "username: $user" "$USERS_YML" | grep "role:" | awk '{print $2}')

    echo "$user:$role" >> "$USERS_LIST"

    mkdir -p "$STORAGE/private/$user"
    chown -R www-data:www-data "$STORAGE/private/$user"
    chmod 775 "$STORAGE/private/$user"
done

members=$(awk -F: '$2=="member" || $2=="maintainer" {printf "%s ", $1}' "$USERS_LIST")
maintainers=$(awk -F: '$2=="maintainer" {printf "%s ", $1}' "$USERS_LIST")

cat > "$GROUPS" < "$APACHE_USERS" <> "$APACHE_USERS" <
    DAV On
    Options Indexes
    AllowOverride None

    AuthType Basic
    AuthName "FS2"
    AuthUserFile $AUTH_FILE
    Require user $user


EOF
done

apache2ctl configtest
systemctl reload apache2

echo "FS2 build completed."

4. 權限

chmod +x /opt/fs2/lib/build.sh

5. 修改 fs2ctl 加上 build

nano /opt/fs2/bin/fs2ctl

case "$cmd" in 裡面加入:

    build)
        need_root
        /opt/fs2/lib/build.sh
        ;;

Usage 區加入:

echo "  fs2ctl build"

6. 執行 build

sudo fs2ctl build

7. 驗證

cat /etc/fs2/users.list
cat /etc/fs2/groups
head -80 /etc/apache2/conf-available/fs2-users.conf

curl -u johnny https://fs2.go2see.me/johnny/
curl -u johnny https://fs2.go2see.me/cyue/

預期:

/johnny/ 成功
/cyue/ 失敗

這一步完成後,使用者主資料就從 users.list 升級為 users.yml

不要急著做 users.yml

原因是目前 users.yml 需要額外工具(例如 yq)或自己解析 YAML,Shell 不太適合處理,後面如果加入 Email、Quota、Role 等欄位,維護成本會提高。

我建議改用 INI 格式

建立:

sudo nano /etc/fs2/users.conf

內容:

[cyue]
role=maintainer
email=
quota=100G

[shari]
role=member
email=
quota=20G

[johnny]
role=member
email=
quota=20G

[tony]
role=member
email=
quota=20G

[may]
role=member
email=
quota=20G

[yuhan]
role=member
email=
quota=20G

[yuchen]
role=member
email=
quota=20G

優點:

  • Shell 很容易讀取。
  • PHP 也可以直接用 parse_ini_file()
  • 未來改成 MariaDB 時也容易轉換。
  • 不需要安裝任何額外工具。

然後建立 FS2 主設定

sudo nano /etc/fs2/fs2.conf

內容:

FS2_NAME=FS2
DOMAIN=fs2.go2see.me
VERSION=1.0.0

STORAGE=/srv/fs2
CONFIG=/etc/fs2
BACKUP=/backup/fs2
LOG=/var/log/fs2

USER_FILE=/etc/fs2/users.password
GROUP_FILE=/etc/fs2/groups
USER_CONF=/etc/fs2/users.conf

確認目前目錄

請執行:

tree -L 2 /opt/fs2
tree -L 2 /etc/fs2
tree -L 2 /srv/fs2

如果沒有 tree

sudo apt install tree

把輸出貼給我。

tree -L 2 /opt/fs2
tree -L 2 /etc/fs2
tree -L 2 /srv/fs2
/opt/fs2
├── api
├── backup
├── bin
│   └── fs2ctl
├── config
├── docs
├── install
├── lib
│   └── build.sh
├── portal
├── sql
├── tools
│   └── generate_apache_users.sh
├── update
└── version
    └── VERSION

12 directories, 4 files
/etc/fs2
├── fs2.conf
├── groups
├── users.conf
├── users.list
├── users.password
└── users.yml

0 directories, 6 files
/srv/fs2
├── backup
├── info
│   └── test-cyue.txt
├── private
│   ├── cyue
│   ├── johnny
│   ├── may
│   ├── shari
│   ├── tony
│   ├── yuchen
│   └── yuhan
├── pub
├── recycle
├── share
│   └── test-johnny.txt
└── temp

14 directories, 2 files

接下來(Phase 2C)

我們不再新增 Shell 功能,而是開始建立 FS2 Portal

/var/www/fs2/

├── index.php
├── login.php
├── logout.php
├── profile.php
├── css/
├── js/
├── img/
└── api/

Portal 第一版先做到:

  • 首頁
  • 系統狀態
  • 公告
  • 各資料夾入口(pub、info、share、個人目錄)
  • 不需要登入

等 Portal 穩定後,再加入登入與修改密碼功能。這樣會比一直擴充 fs2ctl 更有價值,也更接近你最初希望建立的完整檔案服務。

下一步可以做:

FS2 Portal v1.0
/var/www/fs2
首頁 + 快速連結 + 公告 + 系統資訊

這一步會讓 https://fs2.go2see.me/ 看起來像正式服務,而不是普通 Apache 首頁。


開始做 FS2 Portal v1.0

先做靜態 PHP 首頁,不碰登入、不影響 WebDAV。

1. 建 Portal 目錄

# sudo -s

mkdir -p /var/www/fs2/{assets,css,js,img}

2. 建首頁

nano /var/www/fs2/index.php

貼上:





    
    FS2 - go2see.me
    
    


FS2

go2see.me File Server · WebDAV · Version

公告:FS2 Phase 1 已完成。Public、Information、Share 與個人資料夾已啟用。

快速入口

WebDAV 位址

Public:https:///pub/

Information:https:///info/

Share:https:///share/

個人資料夾:https:///帳號名稱/

FS2 · go2see.me · Apache WebDAV

3. 改 Apache 首頁 DocumentRoot

nano /etc/apache2/sites-available/fs2-le-ssl.conf

把:

DocumentRoot /var/www/fs2-index

改成:

DocumentRoot /var/www/fs2

把:

改成:

4. 確認 PHP 模組

apache2ctl -M | grep php

如果沒有看到 PHP module,安裝:

apt install libapache2-mod-php php
systemctl reload apache2

5. 測試

apache2ctl configtest
systemctl reload apache2
curl -I https://fs2.go2see.me/

預期:

HTTP/1.1 200 OK
Content-Type: text/html

然後瀏覽器打開:

https://fs2.go2see.me/

很好,目前我們已經完成了 FS2 的核心

我幫你整理一下目前的成果:

⭐⭐⭐⭐⭐  Phase 1:完成
⭐⭐⭐⭐⭐  Phase 2A:完成
⭐⭐⭐⭐⭐  Portal v1:完成

這已經不是一般的 WebDAV,而是一個有架構的檔案服務。


我建議現在不要急著增加功能

而是把目前的專案整理成 FS2 v1.0 Release

我會先做這五件事

① README

/opt/fs2/

README.md

記錄:

  • 安裝
  • 更新
  • 備份
  • 使用者
  • 目錄

② CHANGELOG

CHANGELOG.md

例如

1.0.0

Initial Release

Apache WebDAV

HTTPS

Portal

User Management

③ install.sh

做到:

sudo ./install.sh

全部安裝。

不用再一條一條打。


④ update.sh

以後:

sudo ./update.sh

自動:

  • backup
  • reload
  • configtest

⑤ health check

例如:

fs2ctl health

檢查:

Apache

SSL

Storage

Password File

Groups

LockDB

Portal

Backup

如果哪個壞掉:

FAIL

立即知道。


然後才開始 v1.1

我建議下一版:

登入

修改密碼

公告

Dashboard

而不是先做管理員。


我的建議(很重要)

我不建議自己開發完整登入系統。

Portal 可以有登入,但WebDAV 仍然使用 Apache Basic Authentication

這樣:

  • Windows
  • macOS
  • iPhone
  • Android

全部都不用改。

Portal 只是:

Dashboard

Announcement

Change Password

Profile

即可。


v1.2

再加入:

Admin

User

Group

Quota

Log

v2

最後才:

MariaDB

SSO

2FA

Email

API

我們已經完成的比你原本規劃的大很多

最初只是:

「重構 dav2,改成 fs2。」

現在已經變成:

  • ✅ 標準 Linux 目錄
  • ✅ HTTPS
  • ✅ WebDAV
  • ✅ 公開 / 公告 / 共用 / 私人
  • ✅ 七位使用者
  • ✅ 管理工具 (fs2ctl)
  • ✅ Portal 首頁
  • ✅ 專案目錄 (/opt/fs2)
  • ✅ 設定集中 (/etc/fs2)
  • ✅ 備份架構

我認為現在應該先把 FS2 v1.0 封版,之後再以 v1.1、v1.2 的方式逐步增加功能,而不是一直累加到一個難以維護的版本。

下一步我建議做的不是新功能,而是產出一份完整的《FS2 System Administrator Guide》(安裝、備份、還原、升級、使用者管理、故障排除)。有了這份文件,未來不論重灌 VM、升級 Ubuntu,或交接給其他人,都能快速重建整套系統。這會是讓 FS2 真正成為一個可長期維護專案的最後一塊拼圖。


很好,那我們把 FS2 v1.0 正式封版

我建議從今天開始,FS2 不再只是聊天中的設定,而是一個有版本、有文件、有更新流程的專案。

FS2 v1.0 Release

Release Date: 2026-07-02

已完成功能

核心服務

  • ✅ Ubuntu 22.04
  • ✅ Apache 2.4
  • ✅ HTTPS(Let's Encrypt)
  • ✅ WebDAV

儲存架構

  • /srv/fs2/pub
  • /srv/fs2/info
  • /srv/fs2/share
  • /srv/fs2/private/<user>

使用者

  • ✅ cyue(Maintainer)
  • ✅ shari
  • ✅ johnny
  • ✅ tony
  • ✅ may
  • ✅ yuhan
  • ✅ yuchen

權限

  • pub:公開唯讀
  • info:成員唯讀,Maintainer 可寫
  • share:成員可讀寫
  • ✅ 個人目錄:僅本人可存取

系統管理

  • fs2ctl
  • ✅ 自動產生 Apache User Alias
  • ✅ 備份腳本
  • ✅ Portal 首頁

建議的 Git 專案

現在開始,我建議把 /opt/fs2 變成 Git Repository。

cd /opt/fs2

git init

git add .

git commit -m "FS2 v1.0 Initial Release"

之後每次修改:

git add .
git commit -m "v1.0.1 Fix Apache User Generator"

這樣任何設定變更都有歷史紀錄。


建議加入的文件

我會建立這些文件:

/opt/fs2/docs/

Architecture.md
Install.md
Upgrade.md
Backup.md
Restore.md
Apache.md
Users.md
Portal.md
ReleaseNotes.md

其中最重要的是:

  • Architecture.md:整體架構、目錄、權限。
  • Install.md:從乾淨 Ubuntu 建立 FS2 的完整步驟。
  • Backup.md / Restore.md:備份與還原流程。
  • Users.md:新增、停用、重設密碼、權限管理。

建議的版本規劃

版本 內容
1.0 WebDAV、HTTPS、Portal 首頁、fs2ctl(完成)
1.1 Portal 登入、修改密碼、公告
1.2 管理介面、使用者管理、容量管理
1.5 Portal 檔案管理(Upload、Rename、Move、Delete)
2.0 MariaDB、API、SSO、2FA

Ubuntu 24.04 升級

等到 FS2 v1.1 完成後,我們再安排:

  1. 完整備份 VM。
  2. 升級到 Ubuntu 24.04。
  3. 驗證 Apache、PHP、WordPress、FS2。
  4. 更新文件。

這樣風險最低。


我建議的下一個工作

接下來不要再零碎地增加功能,而是建立一個完整的 FS2 專案目錄

/opt/fs2
├── bin/
├── lib/
├── tools/
├── docs/
├── install/
├── update/
├── sql/
├── version/
├── CHANGELOG.md
├── README.md
└── LICENSE

然後我會幫你撰寫一套完整的 《FS2 System Administrator Guide》,內容包含:

  • 系統架構
  • 安裝流程
  • Apache 設定說明
  • 使用者管理
  • 備份與還原
  • 升級流程
  • 常見故障排除

這份文件會成為 FS2 的正式維運手冊,之後重建、搬遷或升級系統時,都能依照文件快速完成。


發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *