feat: 新增 GRE 隧道协议,管理端口调整为 18080
- backend: 新增 GRE 隧道实现(ip tunnel 点对点互联),binmgr 支持 iproute2 - backend: api/identity 调整,各协议 service(gre/ikev2/ipsec/l2tp/openvpn)统一改动 - backend: OpenVPN 认证辅助与用户口令同步逻辑完善 - frontend: 协议图标/向导/编辑器支持 GRE,VPN 用户页重构(234 行) - frontend: 新增 RouteListInput 路由列表输入组件,Dashboard/Layout 优化 - i18n: 中英文文案同步更新 - test: 新增 binmgr/common/gre 单测,openvpn 测试补充 - docs: README 补充 GRE 说明,默认监听端口 8080 → 18080 - chore: .gitignore 增加 opsx-vpn.previous(构建备份二进制)
This commit is contained in:
1 parent
c7f59f2cbf
commit
ef7eb378d2
28 files changed
+1363
-439
No files matched your search
@@ -5,6 +5,7 @@ package gre
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"vpn-platform/backend/internal/core"
|
||||
@@ -15,6 +16,8 @@ import (
|
||||
|
||||
type Service struct{}
|
||||
|
||||
var interfaceNamePattern = regexp.MustCompile(`^[a-zA-Z0-9_.-]{1,15}$`)
|
||||
|
||||
func New() *Service { return &Service{} }
|
||||
|
||||
func (s *Service) Name() string { return "gre" }
|
||||
@@ -38,18 +41,34 @@ func (s *Service) Validate(cfg map[string]interface{}) (map[string]interface{},
|
||||
out := service.CloneConfig(cfg)
|
||||
|
||||
// Validate IPs
|
||||
if _, err := netip.ParseAddr(service.Str(out, "local_endpoint")); err != nil {
|
||||
localEndpoint, err := netip.ParseAddr(service.Str(out, "local_endpoint"))
|
||||
if err != nil || !localEndpoint.Is4() {
|
||||
return nil, fmt.Errorf("local_endpoint 必须是有效的 IP 地址")
|
||||
}
|
||||
if _, err := netip.ParseAddr(service.Str(out, "remote_endpoint")); err != nil {
|
||||
remoteEndpoint, err := netip.ParseAddr(service.Str(out, "remote_endpoint"))
|
||||
if err != nil || !remoteEndpoint.Is4() {
|
||||
return nil, fmt.Errorf("remote_endpoint 必须是有效的 IP 地址")
|
||||
}
|
||||
if _, err := netip.ParsePrefix(service.Str(out, "local_tunnel_ip")); err != nil {
|
||||
localTunnel, err := netip.ParsePrefix(service.Str(out, "local_tunnel_ip"))
|
||||
if err != nil || !localTunnel.Addr().Is4() {
|
||||
return nil, fmt.Errorf("local_tunnel_ip 必须是 CIDR 格式(如 10.10.0.1/30)")
|
||||
}
|
||||
if _, err := netip.ParsePrefix(service.Str(out, "remote_tunnel_ip")); err != nil {
|
||||
remoteTunnel, err := netip.ParsePrefix(service.Str(out, "remote_tunnel_ip"))
|
||||
if err != nil || !remoteTunnel.Addr().Is4() {
|
||||
return nil, fmt.Errorf("remote_tunnel_ip 必须是 CIDR 格式(如 10.10.0.2/30)")
|
||||
}
|
||||
if localTunnel == remoteTunnel || localTunnel.Masked() != remoteTunnel.Masked() || localTunnel.Bits() != remoteTunnel.Bits() {
|
||||
return nil, fmt.Errorf("local_tunnel_ip 与 remote_tunnel_ip 必须位于同一隧道子网")
|
||||
}
|
||||
if remoteSubnet := service.Str(out, "remote_subnet"); remoteSubnet != "" {
|
||||
prefix, err := netip.ParsePrefix(remoteSubnet)
|
||||
if err != nil || !prefix.Addr().Is4() {
|
||||
return nil, fmt.Errorf("remote_subnet 必须是 IPv4 CIDR")
|
||||
}
|
||||
}
|
||||
if outbound := service.Str(out, "outbound_interface"); outbound != "" && !interfaceNamePattern.MatchString(outbound) {
|
||||
return nil, fmt.Errorf("outbound_interface 包含非法字符")
|
||||
}
|
||||
|
||||
// Defaults
|
||||
if service.Num(out, "ttl", 0) == 0 {
|
||||
@@ -58,6 +77,12 @@ func (s *Service) Validate(cfg map[string]interface{}) (map[string]interface{},
|
||||
if service.Num(out, "mtu", 0) == 0 {
|
||||
out["mtu"] = 1476
|
||||
}
|
||||
if ttl := int(service.Num(out, "ttl", 255)); ttl < 1 || ttl > 255 {
|
||||
return nil, fmt.Errorf("ttl 必须在 1-255")
|
||||
}
|
||||
if mtu := int(service.Num(out, "mtu", 1476)); mtu < 576 || mtu > 9000 {
|
||||
return nil, fmt.Errorf("mtu 必须在 576-9000")
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user