# Hospital Media Server 筆記 ## 主機資訊 - IP: `106.105.181.40` - SSH 別名: `hospital_media` - 檔案擁有者: `tpech_1duan` / `sftpuser` / `root` ## 全部容器一覽 | 容器名稱 | Image | 網路 | 用途 | |----------|-------|------|------| | `caddy` | `caddy` | host | 反向代理、SSL 終端、靜態檔案 | | `antmedia` | `antmediaserver:2.13.2` | host | Ant Media Server(串流) | | `php` | `timmy/php_base:v1.0` | port 8888→80 | 正式環境 PHP 應用 | | `php-staging` | `timmy/php_base:v1.0` | port 6666→80 | 測試環境 PHP 應用(ISO27001 驗證用) | | `coturn` | `coturn` | port 3478 | TURN/STUN 伺服器 | | `phpmyadmin` | `phpmyadmin` | port 1888→80 | 資料庫管理介面 | | `mysql-container` | `mysql:latest` | port 3306 | MySQL 資料庫 | 所有容器皆設為 `restart: always`。 --- ## Caddy 反向代理 - 部署路徑: `/opt/caddy` - 使用 `docker-compose.yaml` 管理,`--network host` 模式 - Volume 掛載:`Caddyfile`、`caddy_data`、SSL 憑證、`tel-server` 靜態檔案 ### 操作腳本 ```bash ./run.sh # docker-compose up -d ./stop.sh # docker-compose down ./restart.sh # stop + run ./shell.sh # docker exec -it caddy sh ./list-containers.sh # docker-compose ps ./view-output-from-containers.sh # docker-compose logs -f ``` ### 路由規則(Caddyfile) | 入口 | 後端 | 說明 | |------|------|------| | `tel.tpech.gov.tw:443` | `127.0.0.1:8888`(php 容器) | 正式環境,HTTPS | | `tel.tpech.gov.tw:443/phpmyadmin/*` | `10.200.251.40:1888` | phpMyAdmin(strip prefix 後轉發) | | `tel.tpech.gov.tw:80` | `127.0.0.1:8888` | 正式環境,HTTP | | `:1443` | `127.0.0.1:6666`(php-staging 容器) | 測試環境(ISO27001) | | `tel-server.tpech.gov.tw:80/443` | `/srv/tel-server` | 靜態檔案服務(用於 PKI 驗證 `.well-known`) | | `:443` / `:80` | `127.0.0.1:8888` | 其他網域的 fallback | | `:8081` | — | 健康檢查(回傳 "I am 8081") | - `auto_https off`:不使用 Caddy 自動 HTTPS,手動管理憑證 ### Caddy SSL 憑證 | 項目 | 值 | |------|-----| | 網域 | `tel.tpech.gov.tw` | | 簽發者 | 中華電信 HiPKI OV TLS CA - G1 | | 有效期 | 2025-04-23 ~ 2026-04-23 | | 憑證路徑(主機) | `/opt/caddy/fullchain.pem`、`/opt/caddy/privkey.pem` | | 憑證路徑(容器內) | `/etc/caddy/ssl/fullchain.pem`、`/etc/caddy/ssl/privkey.pem` | 更新 Caddy 憑證: ```bash # 1. 上傳新憑證到主機 scp fullchain.pem privkey.pem hospital_media:/opt/caddy/ # 2. 重啟 Caddy(volume 掛載會自動載入新憑證) ssh hospital_media "cd /opt/caddy && ./restart.sh" # 3. 驗證 openssl s_client -connect tel.tpech.gov.tw:443 -servername tel.tpech.gov.tw < /dev/null 2>/dev/null | openssl x509 -noout -dates ``` ### 憑證備份(hospital/) | 目錄 | 內容 | |------|------| | `hospital/ssl_tel_tpech_gov_tw_2025/` | `tel.tpech.gov.tw` 2025 年憑證(key + csr + fullchain) | | `hospital/ssl_tel_server_tpech_gov_tw_2025/` | `tel-server.tpech.gov.tw` 2025 年憑證(key + csr + fullchain) | --- ## Ant Media Server - 部署路徑: `/opt/antmediaserver` ### 服務狀態 | 項目 | 值 | |------|-----| | 容器名稱 | `antmedia` | | Docker Image | `antmediaserver:2.13.2` | | 安裝包 | `ant-media-server-enterprise-2.13.2-20250207_1708.zip` | | 基礎映像 | `ubuntu:22.04` | | 網路模式 | `--network host` | | 時區 | `Asia/Taipei` | | 重啟策略 | `--restart=always` | | 資料 Volume | `antmedia_volume` → `/usr/local/antmedia/` | ### 操作腳本(/opt/antmediaserver) ```bash ./build_antmedia_image.sh # 建構 Docker image ./run.sh # 停舊容器 → 啟動新容器(掛載 antmedia_volume) ./stop.sh # docker stop antmedia ./shell.sh # docker exec -it antmedia bash ./enable_ssl.sh [DOMAIN] # 一鍵更新 SSL 憑證 ./backup_antmedia_data.sh # 備份 antmedia_volume 到當前目錄 ``` ### build_antmedia_image.sh ```bash docker build --network=host -t antmediaserver \ --build-arg AntMediaServer=ant-media-server-enterprise-2.13.2-20250207_1708.zip . ``` ### run.sh ```bash docker stop antmedia && docker rm antmedia docker run -d --network host --privileged \ --restart=always \ -e TZ=Asia/Taipei \ -v /etc/localtime:/etc/localtime:ro \ --mount source=antmedia_volume,target=/usr/local/antmedia/ \ --name antmedia antmediaserver:2.13.2 ``` ### backup_antmedia_data.sh ```bash docker run --rm \ -v antmedia_volume:/data \ -v "$(pwd)":/backup \ busybox \ sh -c "cd /data && tar czf /backup/antmedia_backup_$(date +%Y%m%d_%H%M%S).tar.gz ." ``` ## AMS SSL 憑證 ### 目前憑證資訊 | 項目 | 值 | |------|-----| | 網域 | `tel-server.tpech.gov.tw` | | 簽發者 | 中華電信 HiPKI OV TLS CA - G1 | | 有效期 | 2025-04-23 ~ 2026-04-23 | | 憑證位置(容器內) | `/usr/local/antmedia/conf/fullchain.pem`、`privkey.pem`、`chain.pem` | | Keystore 密碼 | 網域名稱 `tel-server.tpech.gov.tw`(由容器內 `enable_ssl.sh` 的 `generate_password` 決定) | ### 更新 AMS SSL 憑證 #### 方法一:使用 /opt/antmediaserver/enable_ssl.sh(推薦) 將新的 fullchain.pem + key 放入憑證資料夾,然後一行搞定: ```bash # 把憑證檔案放到對應資料夾(資料夾內需有 fullchain.pem 和 tel_server_tpech_gov_tw.key) cd /opt/antmediaserver ./enable_ssl.sh ssl_tel_server_tpech_gov_tw_2025 # 或指定網域 ./enable_ssl.sh ssl_tel_server_tpech_gov_tw_2025 tel-server.tpech.gov.tw ``` 此腳本會自動:`docker cp` 憑證進容器 → 在容器內執行 `enable_ssl.sh` 生成 keystore/truststore 並重啟 AMS。 #### 方法二:手動操作 1. 準備 PEM 檔:`fullchain.pem`(伺服器憑證 + 中繼 CA)、`privkey.pem`、`chain.pem`(中繼 CA) 如果拿到的是 `.cer`(DER 格式),先轉換: ```bash openssl x509 -inform der -in certificate.cer -out certificate.pem cat server.pem intermediate_ca.pem > fullchain.pem cp intermediate_ca.pem chain.pem ``` 2. 複製進容器並執行: ```bash docker cp fullchain.pem antmedia:/usr/local/antmedia/ docker cp privkey.pem antmedia:/usr/local/antmedia/ docker cp chain.pem antmedia:/usr/local/antmedia/ docker exec -it antmedia bash -c "cd /usr/local/antmedia && ./enable_ssl.sh \ -d tel-server.tpech.gov.tw \ -f /usr/local/antmedia/fullchain.pem \ -p /usr/local/antmedia/privkey.pem \ -c /usr/local/antmedia/chain.pem" ``` #### 驗證 ```bash openssl s_client -connect tel-server.tpech.gov.tw:5443 -servername tel-server.tpech.gov.tw < /dev/null 2>/dev/null | openssl x509 -noout -dates ``` ## 連接埠 | 協定 | Port | |------|------| | HTTP | 5080 | | HTTPS | 5443 | | RTMP | 1935 | | RTMPS | 8443 | | TURN/STUN | 3478 | | WebRTC UDP | 50000-60000 | ## Web 應用 | 應用 | 路徑 | 說明 | |------|------|------| | LiveApp | `/LiveApp` | 直播應用(主要使用),WebRTC 20fps,HLS 啟用 | | WebRTCAppEE | `/WebRTCAppEE` | WebRTC 企業版,30fps,目前無串流 | | root | `/` | AMS 管理後台(Angular SPA) | - 轉碼設定:720p (1.5Mbps) + 480p (1Mbps) - TURN/STUN 指向 `106.105.181.40:3478`(帳密為預設 `testuser`/`testpassword`,建議更換) - LiveApp 的 `remoteAllowedCIDR` 有格式錯誤:`106.105.181.40.106.105.181.70`,中間句點應為逗號 ## 系統維護 ### SSL 憑證到期時間 兩張憑證皆為中華電信簽發,每年需手動更新: | 網域 | 到期日 | 使用於 | |------|--------|--------| | `tel.tpech.gov.tw` | 2026-04-23 | Caddy 反向代理 | | `tel-server.tpech.gov.tw` | 2026-04-23 | Ant Media Server | ### 年度 SSL 更新 checklist #### 步驟一:網域驗證(DCV) 中華電信 HiPKI 簽發憑證前,會要求透過 HTTP 驗證網域所有權。驗證檔案放在: ``` /opt/caddy/tel-server/.well-known/pki-validation/ ├── DN_CHECK_FILE.htm # HiPKI DCV 驗證檔(JSON 格式,含 randomNumber + expireTime) └── whois.txt # 域名所有權驗證 ``` Caddy 中 `tel-server.tpech.gov.tw:80` 設定為靜態檔案服務,就是為了讓 CA 能存取: `http://tel-server.tpech.gov.tw/.well-known/pki-validation/DN_CHECK_FILE.htm` 流程: 1. 向中華電信提交 CSR 申請憑證 2. 中華電信會提供新的驗證檔案內容 3. 更新 `/opt/caddy/tel-server/.well-known/pki-validation/` 下的檔案 4. 等待 CA 驗證通過後取得新憑證 #### 步驟二:安裝新憑證 1. 更新 Caddy 憑證:覆蓋 `/opt/caddy/fullchain.pem` + `privkey.pem` → `./restart.sh` 2. 更新 AMS 憑證:`cd /opt/antmediaserver && ./enable_ssl.sh ssl_tel_server_tpech_gov_tw_<年份>` 3. 備份新憑證到 `/opt/caddy/hospital/` 和 `/opt/antmediaserver/ssl_tel_server_tpech_gov_tw_<年份>/` 4. 備份 AMS 資料:`cd /opt/antmediaserver && ./backup_antmedia_data.sh` ### 備份 | 項目 | 方式 | 說明 | |------|------|------| | AMS 資料卷備份 | `/opt/antmediaserver/backup_antmedia_data.sh` | 從 `antmedia_volume` 備份到當前目錄 | | AMS 歷史完整備份 | `/opt/antmedia_*.tar.gz` | 手動 tar 備份(最新:2025-05-12,3.4GB) | | 憑證備份 | `/opt/caddy/hospital/`、`/opt/antmediaserver/ssl_*/` | 各時期憑證 | ### 注意事項 - **AMS 使用 Docker volume**(`antmedia_volume`):容器刪除後資料仍保留,但刪除 volume 則遺失 - **AMS 特權模式**: 容器以 `--privileged` 運行 - **Caddy 使用 bind mount**: Caddyfile 和憑證直接掛載主機檔案 - **host 網路**: `caddy` 和 `antmedia` 皆使用 host 網路模式,直接共用主機所有 port - **TURN/STUN 帳密為預設值** `testuser`/`testpassword`,建議更換 - **LiveApp 的 `remoteAllowedCIDR` 有格式錯誤**:`106.105.181.40.106.105.181.70`,中間句點應為逗號 --- ## NFS 備份掛載(hdsnas02 / TEL_BACKUP_NFS) 將院內 NAS 的備份空間掛載到本機 `/mnt/tel_backup_nfs`。 | 項目 | 值 | |------|-----| | NAS 主機 | `hdsnas02.tpech.gov.tw`(`10.200.30.149`) | | Export 路徑 | `/TEL_BACKUP_NFS`(**大寫,小寫會被 server 回 "No such file or directory"**) | | 掛載點 | `/mnt/tel_backup_nfs` | | 容量 | 54G(掛載時已用 2.3G) | | NAS 支援版本 | **僅 NFSv2/v3,無 NFSv4**(mountd 在 4048,外觀像 Synology/QNAP) | | Export ACL | 限 `10.200.251.40`、`10.200.251.70`(本機符合) | ### fstab(開機自動掛載) ``` hdsnas02.tpech.gov.tw:/TEL_BACKUP_NFS /mnt/tel_backup_nfs nfs vers=3,soft,timeo=100,retrans=2,_netdev,nofail 0 0 ``` - `nofail` + `soft`:NAS 未上線時不卡開機。手動掛載用 `sudo mount /mnt/tel_backup_nfs`。 ### 防火牆需求(重要) NFSv3 掛載除了 `2049`(nfsd)、`111`(rpcbind)外,**必須**能連 NAS 的: | 服務 | Port | 協定 | |------|------|------| | mountd | 4048 | TCP+UDP | | nlockmgr (lockd) | 4045 | TCP+UDP | | status (statd) | 4050 | TCP+UDP | > 初次掛載時僅 2049/111 通,4048/4045/4050 被擋導致 `mount` 卡在向 mountd 取 filehandle 而 timeout,請網管開放後才成功。 ### nfs-common 離線安裝 本機**無對外網路**,`apt` 無法下載。改在有網路的機器下載 amd64 deb → `scp` → `dpkg -i`: - `keyutils`、`rpcbind`、`libnfsidmap1`、`nfs-common`(已安裝完成,`/sbin/mount.nfs` 就位,`rpcbind` service 已啟用) - 套件來源:`security.ubuntu.com` / `archive.ubuntu.com` 的 `pool/main`