feat: expose transparent web device forwarders

This commit is contained in:
Yoilun
2026-05-15 11:25:18 +08:00
parent 2f458b1691
commit 7b32b21f07
4 changed files with 24 additions and 10 deletions

View File

@@ -20,6 +20,8 @@ services:
MANAGED_PORTAL_HOST_SCAN_IMAGE: "managed-portal:${IMAGE_VERSION:-dev}" MANAGED_PORTAL_HOST_SCAN_IMAGE: "managed-portal:${IMAGE_VERSION:-dev}"
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
ports:
- "${MANAGED_PORTAL_FORWARD_PORT_RANGE:-31000-31255}:31000-31255"
networks: networks:
- managed-portal - managed-portal

View File

@@ -128,13 +128,22 @@ func (s *Service) Scan(r *http.Request) (*ScanResult, error) {
} }
s.allowIP(device.IP) s.allowIP(device.IP)
forwardPort, forwardErr := s.EnsureForwarder(device.IP)
if forwardErr != nil {
result.Errors = append(result.Errors, fmt.Sprintf("%s: 启动%s透明转发失败: %v", iface.Name, device.IP, forwardErr))
continue
}
scheme, host := requestBase(r)
deviceInfo := DeviceInfo{ deviceInfo := DeviceInfo{
IP: device.IP, IP: device.IP,
Interface: iface.Name, Interface: iface.Name,
Port: device.Port, Port: device.Port,
TargetURL: fmt.Sprintf("http://%s/", device.IP), TargetURL: fmt.Sprintf("http://%s/", device.IP),
ProxyURL: fmt.Sprintf("/proxy/web/%s/", device.IP), ProxyURL: fmt.Sprintf("/proxy/web/%s/", device.IP),
DirectURL: buildDirectURL(scheme, host, forwardPort),
ForwardPort: forwardPort,
} }
result.Devices = append(result.Devices, deviceInfo) result.Devices = append(result.Devices, deviceInfo)
} }

View File

@@ -71,8 +71,11 @@ func TestScanBuildsProxyURLAndAllowList(t *testing.T) {
if result.Devices[0].ProxyURL != "/proxy/web/192.168.1.124/" { if result.Devices[0].ProxyURL != "/proxy/web/192.168.1.124/" {
t.Fatalf("ProxyURL = %q", result.Devices[0].ProxyURL) t.Fatalf("ProxyURL = %q", result.Devices[0].ProxyURL)
} }
if result.Devices[0].DirectURL != "" { if result.Devices[0].DirectURL != "http://10.8.0.14:31124/" {
t.Fatalf("DirectURL = %q, want empty", result.Devices[0].DirectURL) t.Fatalf("DirectURL = %q", result.Devices[0].DirectURL)
}
if result.Devices[0].ForwardPort != 31124 {
t.Fatalf("ForwardPort = %d, want 31124", result.Devices[0].ForwardPort)
} }
} }

View File

@@ -37,8 +37,8 @@
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column <el-table-column
prop="proxy_url" prop="direct_url"
label="代理地址" label="透明转发地址"
min-width="220" min-width="220"
show-overflow-tooltip show-overflow-tooltip
/> />
@@ -99,7 +99,7 @@ async function handleScan() {
} }
function openDevice(row) { function openDevice(row) {
const url = row?.proxy_url || row?.direct_url; const url = row?.direct_url || row?.proxy_url;
if (!url) { if (!url) {
ElMessage.error("设备打开地址无效"); ElMessage.error("设备打开地址无效");
return; return;