chore(release): 发布 v1.9.2
CI / verify (push) Canceled after 0s
Docker Release / build-and-push (amd64, linux/amd64) (push) Canceled after 0s
Docker Release / build-and-push (arm64, linux/arm64) (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
Docker Release / create-manifest (push) Canceled after 0s

- 「公网服务端」新增 Nginx 启停控制(Agent 0.15.2,停止带二次确认)
- frps 启动失败不再误报成功,并增强启动诊断
- frps vhost 端口禁止 80/443,避免与 VPS 上 Nginx 冲突
- 旧服务端配置的 tcp_mux / login_fail_exit 默认值补齐
- 新增安全审查、页面布局方案与场景操作文档
This commit is contained in:
2026-10-07 19:26:02 +08:00
parent a7d71752e3
commit 2a0740a60f
55 changed files with 5065 additions and 467 deletions
+10
View File
@@ -12,6 +12,8 @@ import (
type Config struct {
ListenAddr string
GatewaySocket string
GatewayPrefix string
DataDir string
SessionSecret string
NginxBin string
@@ -33,6 +35,8 @@ func Load() Config {
}
return Config{
ListenAddr: envOr("HAVLINE_LISTEN", ":6893"),
GatewaySocket: envOr("HAVLINE_GATEWAY_SOCKET", ""),
GatewayPrefix: envOr("HAVLINE_GATEWAY_PREFIX", ""),
DataDir: dataDir,
SessionSecret: envOr("HAVLINE_SESSION_SECRET", ""),
NginxBin: envOr("HAVLINE_NGINX_BIN", "nginx"),
@@ -108,6 +112,12 @@ func (c Config) SSHKnownHostsPath() string {
return filepath.Join(c.DataDir, "ssh_known_hosts")
}
// SSHKnownHostsPathForServer 为每台 FRP 服务端提供独立的 known_hosts,
// 避免一台 VPS 的主机密钥记录影响另一台服务器的 SSH 连接。
func (c Config) SSHKnownHostsPathForServer(serverID int64) string {
return filepath.Join(c.DataDir, "ssh_known_hosts", fmt.Sprintf("server-%d", serverID))
}
func (c Config) ErrorsDir() string {
return c.NginxDir() + "/errors"
}
+9
View File
@@ -2,6 +2,7 @@ package config
import (
"os"
"path/filepath"
"testing"
)
@@ -42,3 +43,11 @@ func TestLoadUpdaterTokenFile(t *testing.T) {
t.Fatalf("updater token file %q", cfg.UpdaterTokenFile)
}
}
func TestSSHKnownHostsPathForServer(t *testing.T) {
cfg := Config{DataDir: "/data"}
want := filepath.Join("/data", "ssh_known_hosts", "server-3")
if got := cfg.SSHKnownHostsPathForServer(3); got != want {
t.Fatalf("per-server known_hosts path %q", got)
}
}
+16
View File
@@ -0,0 +1,16 @@
package config
import "testing"
func TestNativeGatewayConfig(t *testing.T) {
t.Setenv("HAVLINE_GATEWAY_SOCKET", "/tmp/havline-test.sock")
t.Setenv("HAVLINE_GATEWAY_PREFIX", "/app/havline")
t.Setenv("HAVLINE_UPDATER_SOCKET", "")
cfg := Load()
if cfg.GatewaySocket != "/tmp/havline-test.sock" || cfg.GatewayPrefix != "/app/havline" {
t.Fatal("原生网关配置未生效")
}
if cfg.UpdaterSocket != "" {
t.Fatal("原生应用显式空值应禁用 Docker 升级")
}
}