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.
This commit is contained in:
1 parent
c351c39771
commit
03b7a84f55
6 files changed
+63
-37
No files matched your search
Generated
+4
-4
@@ -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",
|
||||
|
||||
+1
-1
@@ -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"] }
|
||||
|
||||
@@ -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"]
|
||||
@@ -79,13 +79,18 @@ Options:
|
||||
Usage: biliup server [OPTIONS]
|
||||
|
||||
Options:
|
||||
-b, --bind <BIND> Specify bind address [default: 0.0.0.0]
|
||||
-p, --port <PORT> Port to use [default: 19159]
|
||||
--auth 开启登录密码认证
|
||||
-c, --config <FILE> 使用 biliup 1.0.7 风格配置文件启动录制
|
||||
-h, --help Print help
|
||||
-b, --bind <BIND> Specify bind address [default: 127.0.0.1]
|
||||
-p, --port <PORT> Port to use [default: 19159]
|
||||
--auth 开启登录密码认证
|
||||
--secure-session-cookie 为会话 Cookie 附加 Secure 属性。仅当通过 HTTPS 反向代理访问 Web UI 时开启; 直接通过 HTTP 远程访问时开启会导致浏览器丢弃登录态
|
||||
-c, --config <FILE> 使用 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 将完全无法访问。
|
||||
|
||||
---
|
||||
|
||||
## 🧑💻开发
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
|
||||
+2
-1
@@ -8,4 +8,5 @@ services:
|
||||
- "<HOST_ADDRESS>:<HOST_PORT>:19159"
|
||||
volumes:
|
||||
- /path/to/save_folder:/opt
|
||||
command: server --auth
|
||||
# 容器内必须监听 0.0.0.0,否则上面的端口映射无法转发进容器
|
||||
command: server --bind 0.0.0.0 --auth
|
||||
Reference in new issue
Block a user