Compare commits

..

4 Commits

Author SHA1 Message Date
Akizon77
b1c863bacd fix: https://github.com/komari-monitor/komari/issues/446 去重同一物理设备的挂载点 2026-03-10 17:56:03 +08:00
Akizon77
bb1e01459b fix: https://github.com/komari-monitor/komari/issues/402 2026-03-10 15:55:04 +08:00
Akizon
c829958d59 Merge pull request #72 from Yuuuuu0/main
feat: 所有出站连接支持 HTTP 代理
2026-02-21 11:21:10 +08:00
Yuuuuu0
3be21757f6 feat: 所有出站连接支持 HTTP 代理
在无法直接访问外网的环境下(如内网服务器需要通过代理访问互联网),
agent 的 websocket 上报、IP 地址获取、autodiscovery 注册等请求
无法走代理导致连接失败。

现在统一添加 http.ProxyFromEnvironment,
配置 http_proxy/https_proxy 环境变量即可生效,未配置时行为不变。

systemd 配置示例:

[Service]
Environment="http_proxy=http://your-proxy-ip:port"
Environment="https_proxy=http://your-proxy-ip:port"
Environment="HTTP_PROXY=http://your-proxy-ip:port"
Environment="HTTPS_PROXY=http://your-proxy-ip:port"
Environment="no_proxy=localhost,127.0.0.1,::1,172.16.0.0/12"
Environment="NO_PROXY=localhost,127.0.0.1,::1,172.16.0.0/12"
2026-02-10 19:59:54 +08:00
4 changed files with 36 additions and 10 deletions

View File

@@ -10,7 +10,9 @@ import (
"net/url"
"os"
"path/filepath"
"time"
"github.com/komari-monitor/komari-agent/dnsresolver"
"github.com/komari-monitor/komari-agent/utils"
)
@@ -136,7 +138,7 @@ func registerWithAutoDiscovery() error {
}
// 发送请求
client := &http.Client{}
client := dnsresolver.GetHTTPClient(30 * time.Second)
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to send register request: %v", err)

View File

@@ -83,26 +83,21 @@ func isPhysicalDisk(part disk.PartitionStat) bool {
}
mountpoint := strings.ToLower(part.Mountpoint)
// 排除挂载点
var mountpointsToExclude = []string{
var mountpointsToExcludePerfix = []string{
"/tmp",
"/var/tmp",
"/dev/shm",
"/dev",
"/run",
"/run/lock",
"/run/user",
"/var/lib/containers",
"/var/lib/docker",
"/proc",
"/dev/pts",
"/sys",
"/sys/fs/cgroup",
"/dev/mqueue",
"/etc/resolv.conf",
"/etc/host", // /etc/hosts,/etc/hostname
"/dev/hugepages",
"/nix/store",
}
for _, mp := range mountpointsToExclude {
for _, mp := range mountpointsToExcludePerfix {
if mountpoint == mp || strings.HasPrefix(mountpoint, mp) {
return false
}
@@ -123,6 +118,7 @@ func isPhysicalDisk(part disk.PartitionStat) bool {
var fstypeToExclude = []string{
"tmpfs",
"devtmpfs",
"udev",
"nfs",
"cifs",
"smb",
@@ -136,6 +132,9 @@ func isPhysicalDisk(part disk.PartitionStat) bool {
"cgroup",
"mqueue",
"hugetlbfs",
"debugfs",
"binfmt_misc",
"securityfs",
}
for _, fs := range fstypeToExclude {
if fstype == fs || strings.HasPrefix(fstype, fs) {
@@ -172,11 +171,33 @@ func DiskList() ([]string, error) {
if err != nil {
return nil, err
}
// 同一物理设备只保留路径最短的根挂载点
deviceMap := make(map[string]disk.PartitionStat)
for _, part := range usage {
if isPhysicalDisk(part) {
diskList = append(diskList, fmt.Sprintf("%s (%s)", part.Mountpoint, part.Fstype))
deviceID := part.Device
// ZFS去重: 基于 pool 名称
if strings.ToLower(part.Fstype) == "zfs" {
if idx := strings.Index(deviceID, "/"); idx != -1 {
deviceID = deviceID[:idx]
}
}
if existing, ok := deviceMap[deviceID]; ok {
// 优先保留路径更短的挂载点 (e.g., /volume1 优于 /volume1/@appdata/...)
if len(part.Mountpoint) < len(existing.Mountpoint) {
deviceMap[deviceID] = part
}
} else {
deviceMap[deviceID] = part
}
}
}
for _, part := range deviceMap {
diskList = append(diskList, fmt.Sprintf("%s (%s)", part.Mountpoint, part.Fstype))
}
}
return diskList, nil
}

View File

@@ -16,6 +16,7 @@ var (
// 创建适用于IPv4和IPv6的HTTP客户端
ipv4HTTPClient = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := dnsresolver.GetNetDialer(15 * time.Second)
return dialer.DialContext(ctx, "tcp4", addr) // 锁v4防止出现问题
@@ -29,6 +30,7 @@ var (
}
ipv6HTTPClient = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := dnsresolver.GetNetDialer(15 * time.Second)
return dialer.DialContext(ctx, "tcp6", addr) // 锁v6防止出现问题

View File

@@ -192,6 +192,7 @@ func newWSDialer() *websocket.Dialer {
d := &websocket.Dialer{
HandshakeTimeout: 15 * time.Second,
NetDialContext: dnsresolver.GetDialContext(15 * time.Second),
Proxy: http.ProxyFromEnvironment,
}
if flags.IgnoreUnsafeCert {
d.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}