From 03b7a84f55a31f407570f7d19ef5581101434bf3 Mon Sep 17 00:00:00 2001 From: ForgQi <34411314+ForgQi@users.noreply.github.com> Date: Mon, 24 Aug 2026 01:13:29 +0800 Subject: [PATCH] Allow remote Web UI bootstrap with auth This change updates the server default bind to 127.0.0.1 for safer local-only access while documenting how to expose the Web UI via --bind 0.0.0.0 --auth for remote or Docker use. It also removes the previous restriction that blocked first-time admin bootstrap on non-loopback addresses, allowing authenticated remote initialization and bumping the workspace version to 1.2.4. --- Cargo.lock | 8 +++--- Cargo.toml | 2 +- Dockerfile | 3 +++ README.md | 51 +++++++++++++++++++++++++++++++----- crates/biliup-cli/src/lib.rs | 33 ++++++----------------- docker-compose.yml | 3 ++- 6 files changed, 63 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef38be5..3ad29b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,7 +387,7 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "biliup" -version = "1.2.3" +version = "1.2.4" dependencies = [ "async-trait", "base64", @@ -426,7 +426,7 @@ dependencies = [ [[package]] name = "biliup-cli" -version = "1.2.3" +version = "1.2.4" dependencies = [ "async-channel", "async-trait", @@ -1015,7 +1015,7 @@ dependencies = [ [[package]] name = "danmaku" -version = "1.2.3" +version = "1.2.4" dependencies = [ "async-trait", "base64", @@ -4109,7 +4109,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stream-gears" -version = "1.2.3" +version = "1.2.4" dependencies = [ "async-channel", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 8019f13..87cd3f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ resolver = "3" [workspace.package] -version = "1.2.3" +version = "1.2.4" [workspace.dependencies] serde = { version = "1.0", features = ["derive"] } diff --git a/Dockerfile b/Dockerfile index d46ed22..32e296d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -129,3 +129,6 @@ RUN set -eux; \ WORKDIR /opt ENTRYPOINT ["biliup"] +# 容器内必须监听 0.0.0.0,否则宿主机的端口映射无法转发进容器。 +# CLI 默认的 127.0.0.1 只适用于直接在本机运行的场景。 +CMD ["server", "--bind", "0.0.0.0", "--auth"] diff --git a/README.md b/README.md index 93f0da5..8e1cb12 100644 --- a/README.md +++ b/README.md @@ -79,13 +79,18 @@ Options: Usage: biliup server [OPTIONS] Options: - -b, --bind Specify bind address [default: 0.0.0.0] - -p, --port Port to use [default: 19159] - --auth 开启登录密码认证 - -c, --config 使用 biliup 1.0.7 风格配置文件启动录制 - -h, --help Print help + -b, --bind Specify bind address [default: 127.0.0.1] + -p, --port Port to use [default: 19159] + --auth 开启登录密码认证 + --secure-session-cookie 为会话 Cookie 附加 Secure 属性。仅当通过 HTTPS 反向代理访问 Web UI 时开启; 直接通过 HTTP 远程访问时开启会导致浏览器丢弃登录态 + -c, --config 使用 biliup 1.0.7 风格配置文件启动录制 + -h, --help Print help ``` +> [!IMPORTANT] +> 自 [#1660](https://github.com/biliup/biliup/pull/1660) 起,`--bind` 的默认值由 `0.0.0.0` 改为 `127.0.0.1`,即**默认只监听本机**,局域网/公网无法直接访问。 +> 如需从其他设备访问,请加上 `--bind 0.0.0.0 --auth`,详见下方「🔓 远程访问」一节。Docker 镜像已内置该参数,不受影响。 + - [使用文档 »](https://docs.biliup.rs) ## 🚀 快速开始 @@ -97,13 +102,47 @@ Options: 1. 安装 [uv](https://docs.astral.sh/uv/getting-started/installation/) 2. 安装:`uv tool install biliup` 3. 启动:`biliup server --auth` -4. 访问 WebUI:`http://your-ip:19159` +4. 访问 WebUI:`http://127.0.0.1:19159`(默认只监听本机,远程访问见下方说明) * 后台运行 1. `nohup biliup server --auth &` 2. [请查看参考](https://biliup.github.io/biliup/docs/guide/introduction/#linuxxia-pei-zhi-kai-ji-zi-qi) ### Termux - 详见[Wiki](https://github.com/biliup/biliup/wiki/Termux-%E4%B8%AD%E4%BD%BF%E7%94%A8-biliup) +### 🔓 远程访问(监听 0.0.0.0) + +默认的 `127.0.0.1` 只允许本机访问。需要从其他设备访问时,显式指定 `--bind 0.0.0.0` 并开启 `--auth`: + +```shell +biliup server --bind 0.0.0.0 --auth +``` + +首次打开 `http://your-ip:19159` 会引导设置管理员密码(用户名固定为 `biliup`),之后即可正常登录使用。 + +> [!NOTE] +> 绑定非回环地址时必须同时开启 `--auth`,否则会拒绝启动,避免无认证的 Web API 被暴露: +> +> ``` +> refusing to expose the unauthenticated Web API on 0.0.0.0:19159; use a loopback bind address or enable --auth +> ``` + +> [!WARNING] +> 将 Web UI 暴露到公网存在风险,建议仅在可信局域网内使用,或置于反向代理之后。 +> 若通过 **HTTPS** 反向代理访问,请加上 `--secure-session-cookie`;直接以 HTTP 远程访问时**不要**加,否则浏览器会丢弃登录态(见 [#1669](https://github.com/biliup/biliup/pull/1669))。 + +#### Docker + +镜像已内置 `--bind 0.0.0.0 --auth`,开箱即用,无需额外配置: + +```shell +docker compose up -d +``` + +打开 `http://your-ip:19159` 设置管理员密码即可。 + +> [!IMPORTANT] +> 若要自定义 `command`,必须带上 `--bind 0.0.0.0`。容器内若监听 `127.0.0.1`,宿主机的端口映射无法转发进容器,Web UI 将完全无法访问。 + --- ## 🧑‍💻开发 diff --git a/crates/biliup-cli/src/lib.rs b/crates/biliup-cli/src/lib.rs index 60d3c71..91f6636 100644 --- a/crates/biliup-cli/src/lib.rs +++ b/crates/biliup-cli/src/lib.rs @@ -16,7 +16,6 @@ use crate::server::infrastructure::models::upload_streamer::{ }; use crate::server::infrastructure::repositories; use crate::server::infrastructure::service_register::ServiceRegister; -use crate::server::infrastructure::users::Backend; use clap::ValueEnum; use error_stack::{Report, ResultExt, bail}; use std::net::{SocketAddr, ToSocketAddrs}; @@ -73,7 +72,6 @@ pub async fn run_with_cookie( let conn_pool = ConnectionManager::new_pool("data/data.sqlite3") .await .attach("could not initialize the database connection pool")?; - validate_remote_auth_bootstrap(addr, auth, Backend::new(conn_pool.clone()).exists().await?)?; if let Some(configuration) = repositories::register_bilibili_cookie(&conn_pool, &user_cookie).await? @@ -128,20 +126,6 @@ fn validate_server_exposure(addr: SocketAddr, auth: bool) -> AppResult<()> { Ok(()) } -fn validate_remote_auth_bootstrap( - addr: SocketAddr, - auth: bool, - administrator_exists: bool, -) -> AppResult<()> { - if auth && !addr.ip().is_loopback() && !administrator_exists { - bail!(AppError::Custom( - "refusing remote first-user bootstrap; initialize the Web administrator on a loopback bind before exposing the authenticated server" - .into(), - )); - } - Ok(()) -} - async fn import_config_streamers(path: &Path, service_register: &ServiceRegister) -> AppResult<()> { let streamers: Vec<_> = { let config = service_register.config.read().unwrap(); @@ -380,7 +364,7 @@ pub enum UploadLine { #[cfg(test)] mod server_exposure_tests { - use super::{validate_remote_auth_bootstrap, validate_server_exposure}; + use super::validate_server_exposure; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; #[test] @@ -400,17 +384,16 @@ mod server_exposure_tests { ); } + /// The Web administrator is bootstrapped over the network on first visit, so + /// an authenticated server must start on a non-loopback bind even when no + /// administrator exists yet — a container or headless host has no way to + /// reach a loopback-only bind to initialize one. #[test] - fn authenticated_server_can_bind_non_loopback_after_local_bootstrap() { - let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 19159); - assert!(validate_server_exposure(addr, true).is_ok()); - assert!(validate_remote_auth_bootstrap(addr, true, false).is_err()); - assert!(validate_remote_auth_bootstrap(addr, true, true).is_ok()); + fn authenticated_server_can_bind_non_loopback_before_bootstrap() { assert!( - validate_remote_auth_bootstrap( - SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 19159), + validate_server_exposure( + SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 19159), true, - false, ) .is_ok() ); diff --git a/docker-compose.yml b/docker-compose.yml index 1fb68c5..c0b9ab7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,4 +8,5 @@ services: - "::19159" volumes: - /path/to/save_folder:/opt - command: server --auth \ No newline at end of file + # 容器内必须监听 0.0.0.0,否则上面的端口映射无法转发进容器 + command: server --bind 0.0.0.0 --auth \ No newline at end of file