Files
port-manager/internal/service/identifier.go
2025-09-23 01:47:48 +08:00

181 lines
7.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"fmt"
"net/http"
"time"
"github.com/miaomint/port-manager/pkg/types"
)
// ServiceIdentifier 服务识别器
type ServiceIdentifier struct {
wellKnownPorts map[int]types.ServiceMapping
}
// NewServiceIdentifier 创建新的服务识别器
func NewServiceIdentifier() *ServiceIdentifier {
return &ServiceIdentifier{
wellKnownPorts: initWellKnownPorts(),
}
}
// IdentifyService 识别端口对应的服务
func (si *ServiceIdentifier) IdentifyService(port *types.PortInfo) *types.PortInfo {
// 复制端口信息
result := *port
// 查找已知服务
if mapping, exists := si.wellKnownPorts[port.Port]; exists {
result.ServiceName = mapping.ServiceName
// 如果是HTTP/HTTPS服务尝试构建访问URL
if mapping.IsHTTP || mapping.IsHTTPS {
protocol := "http"
if mapping.IsHTTPS {
protocol = "https"
}
result.ServiceURL = fmt.Sprintf("%s://localhost:%d", protocol, port.Port)
// 验证HTTP服务是否可访问
if si.isHTTPServiceActive(result.ServiceURL) {
result.ServiceName = fmt.Sprintf("%s (可访问)", result.ServiceName)
}
}
} else {
// 尝试探测HTTP服务
if si.probeHTTPService(port.Port) {
result.ServiceName = "HTTP服务"
result.ServiceURL = fmt.Sprintf("http://localhost:%d", port.Port)
} else if si.probeHTTPSService(port.Port) {
result.ServiceName = "HTTPS服务"
result.ServiceURL = fmt.Sprintf("https://localhost:%d", port.Port)
} else {
result.ServiceName = "未知服务"
}
}
return &result
}
// probeHTTPService 探测HTTP服务
func (si *ServiceIdentifier) probeHTTPService(port int) bool {
url := fmt.Sprintf("http://localhost:%d", port)
return si.isHTTPServiceActive(url)
}
// probeHTTPSService 探测HTTPS服务
func (si *ServiceIdentifier) probeHTTPSService(port int) bool {
url := fmt.Sprintf("https://localhost:%d", port)
return si.isHTTPServiceActive(url)
}
// isHTTPServiceActive 检查HTTP服务是否活跃
func (si *ServiceIdentifier) isHTTPServiceActive(url string) bool {
client := &http.Client{
Timeout: 2 * time.Second,
}
resp, err := client.Get(url)
if err != nil {
return false
}
defer resp.Body.Close()
// 任何HTTP响应都认为是活跃的HTTP服务
return true
}
// initWellKnownPorts 初始化已知端口映射
func initWellKnownPorts() map[int]types.ServiceMapping {
return map[int]types.ServiceMapping{
// Web服务
80: {Port: 80, ServiceName: "HTTP", Description: "超文本传输协议", IsHTTP: true},
443: {Port: 443, ServiceName: "HTTPS", Description: "安全超文本传输协议", IsHTTPS: true},
8080: {Port: 8080, ServiceName: "HTTP代理", Description: "HTTP代理服务", IsHTTP: true},
8443: {Port: 8443, ServiceName: "HTTPS代理", Description: "HTTPS代理服务", IsHTTPS: true},
3000: {Port: 3000, ServiceName: "开发服务器", Description: "React/Node.js开发服务器", IsHTTP: true},
3001: {Port: 3001, ServiceName: "开发服务器", Description: "开发服务器", IsHTTP: true},
4000: {Port: 4000, ServiceName: "开发服务器", Description: "Jekyll/Hugo开发服务器", IsHTTP: true},
8000: {Port: 8000, ServiceName: "HTTP服务", Description: "Python HTTP服务器", IsHTTP: true},
9000: {Port: 9000, ServiceName: "PHP-FPM", Description: "PHP FastCGI Process Manager", IsHTTP: true},
// 数据库
3306: {Port: 3306, ServiceName: "MySQL", Description: "MySQL数据库服务器"},
5432: {Port: 5432, ServiceName: "PostgreSQL", Description: "PostgreSQL数据库服务器"},
27017: {Port: 27017, ServiceName: "MongoDB", Description: "MongoDB数据库服务器"},
6379: {Port: 6379, ServiceName: "Redis", Description: "Redis内存数据库"},
11211: {Port: 11211, ServiceName: "Memcached", Description: "Memcached缓存服务器"},
// 远程访问
22: {Port: 22, ServiceName: "SSH", Description: "安全外壳协议"},
23: {Port: 23, ServiceName: "Telnet", Description: "远程登录协议"},
3389: {Port: 3389, ServiceName: "RDP", Description: "远程桌面协议"},
5900: {Port: 5900, ServiceName: "VNC", Description: "虚拟网络计算"},
// 邮件服务
25: {Port: 25, ServiceName: "SMTP", Description: "简单邮件传输协议"},
110: {Port: 110, ServiceName: "POP3", Description: "邮局协议版本3"},
143: {Port: 143, ServiceName: "IMAP", Description: "互联网消息访问协议"},
465: {Port: 465, ServiceName: "SMTPS", Description: "安全SMTP"},
587: {Port: 587, ServiceName: "SMTP-Submission", Description: "邮件提交"},
993: {Port: 993, ServiceName: "IMAPS", Description: "安全IMAP"},
995: {Port: 995, ServiceName: "POP3S", Description: "安全POP3"},
// FTP
20: {Port: 20, ServiceName: "FTP-Data", Description: "文件传输协议数据"},
21: {Port: 21, ServiceName: "FTP", Description: "文件传输协议"},
// DNS
53: {Port: 53, ServiceName: "DNS", Description: "域名系统"},
// DHCP
67: {Port: 67, ServiceName: "DHCP-Server", Description: "动态主机配置协议服务器"},
68: {Port: 68, ServiceName: "DHCP-Client", Description: "动态主机配置协议客户端"},
// NTP
123: {Port: 123, ServiceName: "NTP", Description: "网络时间协议"},
// SNMP
161: {Port: 161, ServiceName: "SNMP", Description: "简单网络管理协议"},
162: {Port: 162, ServiceName: "SNMP-Trap", Description: "SNMP陷阱"},
// LDAP
389: {Port: 389, ServiceName: "LDAP", Description: "轻量目录访问协议"},
636: {Port: 636, ServiceName: "LDAPS", Description: "安全LDAP"},
// NAS相关服务
139: {Port: 139, ServiceName: "NetBIOS-SSN", Description: "NetBIOS会话服务"},
445: {Port: 445, ServiceName: "SMB", Description: "服务器消息块"},
548: {Port: 548, ServiceName: "AFP", Description: "Apple文件协议"},
2049: {Port: 2049, ServiceName: "NFS", Description: "网络文件系统"},
// 开发工具
9090: {Port: 9090, ServiceName: "Prometheus", Description: "Prometheus监控系统", IsHTTP: true},
5601: {Port: 5601, ServiceName: "Kibana", Description: "Kibana可视化平台", IsHTTP: true},
9200: {Port: 9200, ServiceName: "Elasticsearch", Description: "Elasticsearch搜索引擎", IsHTTP: true},
8888: {Port: 8888, ServiceName: "Jupyter", Description: "Jupyter Notebook", IsHTTP: true},
4040: {Port: 4040, ServiceName: "Spark UI", Description: "Apache Spark Web UI", IsHTTP: true},
// 消息队列
5672: {Port: 5672, ServiceName: "RabbitMQ", Description: "RabbitMQ消息队列"},
15672: {Port: 15672, ServiceName: "RabbitMQ管理", Description: "RabbitMQ管理界面", IsHTTP: true},
9092: {Port: 9092, ServiceName: "Kafka", Description: "Apache Kafka"},
// 容器和编排
2375: {Port: 2375, ServiceName: "Docker", Description: "Docker守护进程(非安全)"},
2376: {Port: 2376, ServiceName: "Docker", Description: "Docker守护进程(TLS)"},
6443: {Port: 6443, ServiceName: "Kubernetes API", Description: "Kubernetes API服务器"},
10250: {Port: 10250, ServiceName: "kubelet", Description: "Kubernetes kubelet"},
// Synology NAS特定端口
5000: {Port: 5000, ServiceName: "DSM", Description: "Synology DiskStation Manager", IsHTTP: true},
5001: {Port: 5001, ServiceName: "DSM (HTTPS)", Description: "Synology DiskStation Manager", IsHTTPS: true},
6690: {Port: 6690, ServiceName: "Cloud Station", Description: "Synology Cloud Station"},
9117: {Port: 9117, ServiceName: "Jackett", Description: "Jackett种子搜索", IsHTTP: true},
8989: {Port: 8989, ServiceName: "Sonarr", Description: "Sonarr自动下载", IsHTTP: true},
7878: {Port: 7878, ServiceName: "Radarr", Description: "Radarr电影下载", IsHTTP: true},
8686: {Port: 8686, ServiceName: "Lidarr", Description: "Lidarr音乐下载", IsHTTP: true},
}
}