Add DefaultGateway

This commit is contained in:
Shtorm
2026-08-08 10:33:31 +03:00
parent 3310474137
commit 97c981764d
8 changed files with 202 additions and 39 deletions

View File

@@ -0,0 +1,53 @@
{
"log": {
"level": "error"
},
"dns": {
"servers": [
{
"type": "local",
"tag": "default"
}
]
},
"endpoints": [
{
"type": "vpn-client",
"tag": "vpn",
"address": "10.0.0.2",
"key": "1c9b2ccf-b0c0-4c26-868d-a55a4edad3fe",
"outbound": {
"type": "vless",
"tag": "vless-out",
"server": "0.0.0.0",
"server_port": 8000,
"uuid": "9b65b7e1-04c8-4717-8f45-2aa61fd25937",
"network": "tcp"
}
}
],
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen_port": 7897
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
}
],
"route": {
"rules": [
{
"domain_suffix": ".internal",
"outbound": "vpn",
"override_gateway": "10.0.0.3"
}
],
"final": "direct-out",
"auto_detect_interface": true
}
}

View File

@@ -0,0 +1,40 @@
{
"log": {
"level": "error"
},
"dns": {
"servers": [
{
"type": "local",
"tag": "default"
}
]
},
"endpoints": [
{
"type": "vpn-client",
"tag": "vpn",
"address": "10.0.0.3",
"key": "3d74d616-2502-4c17-9cc3-92c366550f4f",
"outbound": {
"type": "vless",
"tag": "vless-out",
"server": "0.0.0.0",
"server_port": 8000,
"uuid": "9b65b7e1-04c8-4717-8f45-2aa61fd25937",
"network": "tcp"
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
}
],
"route": {
"final": "direct-out",
"default_domain_resolver": "default",
"auto_detect_interface": true
}
}

View File

@@ -0,0 +1,61 @@
{
"log": {
"level": "error"
},
"dns": {
"servers": [
{
"type": "local",
"tag": "default"
}
]
},
"endpoints": [
{
"type": "vpn-server",
"tag": "vpn",
"address": "10.0.0.1",
"users": [
{
"address": "10.0.0.2",
"key": "1c9b2ccf-b0c0-4c26-868d-a55a4edad3fe"
},
{
"address": "10.0.0.3",
"key": "3d74d616-2502-4c17-9cc3-92c366550f4f"
}
],
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "0.0.0.0",
"listen_port": 8000,
"users": [
{
"name": "vless",
"uuid": "9b65b7e1-04c8-4717-8f45-2aa61fd25937"
}
]
}
]
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
}
],
"route": {
"rules": [
{
"source_ip_cidr": "10.0.0.0/24",
"outbound": "vpn"
}
],
"final": "direct-out",
"default_domain_resolver": "default",
"auto_detect_interface": true
}
}

View File

@@ -16,6 +16,7 @@
"tag": "vpn",
"address": "10.0.0.2",
"key": "1c9b2ccf-b0c0-4c26-868d-a55a4edad3fe",
"default_gateway": "10.0.0.3",
"outbound": {
"type": "vless",
"tag": "vless-out",
@@ -40,13 +41,7 @@
}
],
"route": {
"rules": [
{
"outbound": "vpn",
"override_gateway": "10.0.0.3"
}
],
"final": "direct-out",
"final": "vpn",
"auto_detect_interface": true
}
}

View File

@@ -15,6 +15,7 @@
"type": "vpn-server",
"tag": "vpn",
"address": "10.0.0.1",
"default_gateway": "10.0.0.2",
"users": [
{
"address": "10.0.0.2",
@@ -47,8 +48,7 @@
"rules": [
{
"inbound": "vless-in",
"outbound": "vpn",
"override_gateway": "10.0.0.2"
"outbound": "vpn"
}
],
"final": "direct-out",

View File

@@ -15,6 +15,7 @@
"type": "vpn-server",
"tag": "vpn",
"address": "10.0.0.1",
"default_gateway": "10.0.0.2",
"users": [
{
"address": "10.0.0.2",
@@ -51,13 +52,7 @@
}
],
"route": {
"rules": [
{
"outbound": "vpn",
"override_gateway": "10.0.0.2"
}
],
"final": "direct-out",
"final": "vpn",
"default_domain_resolver": "default",
"auto_detect_interface": true
}

View File

@@ -29,13 +29,14 @@ func RegisterClientEndpoint(registry *endpoint.Registry) {
type ClientEndpoint struct {
outbound.Adapter
ctx context.Context
outbound adapter.Outbound
router adapter.ConnectionRouterEx
logger logger.ContextLogger
address IPv4
key uuid.UUID
uotClient *uot.Client
ctx context.Context
outbound adapter.Outbound
router adapter.ConnectionRouterEx
logger logger.ContextLogger
address IPv4
key uuid.UUID
defaultGateway IPv4
uotClient *uot.Client
}
func NewClientEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VPNClientEndpointOptions) (adapter.Endpoint, error) {
@@ -47,13 +48,21 @@ func NewClientEndpoint(ctx context.Context, router adapter.Router, logger log.Co
if err != nil {
return nil, err
}
defaultGateway := Loopback.As4()
if options.DefaultGateway.IsValid() {
if !options.DefaultGateway.Is4() {
return nil, E.New("invalid default_gateway: ", options.DefaultGateway)
}
defaultGateway = options.DefaultGateway.As4()
}
client := &ClientEndpoint{
Adapter: outbound.NewAdapter(C.TypeVPNClient, tag, []string{N.NetworkTCP, N.NetworkUDP}, []string{}),
ctx: ctx,
router: sbUot.NewRouter(router, logger),
logger: logger,
address: address.As4(),
key: key,
Adapter: outbound.NewAdapter(C.TypeVPNClient, tag, []string{N.NetworkTCP, N.NetworkUDP}, []string{}),
ctx: ctx,
router: sbUot.NewRouter(router, logger),
logger: logger,
address: address.As4(),
key: key,
defaultGateway: defaultGateway,
}
outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
outbound, err := outboundRegistry.CreateOutbound(ctx, router, logger, options.Outbound.Tag, options.Outbound.Type, options.Outbound.Options)
@@ -102,7 +111,7 @@ func (c *ClientEndpoint) DialContext(ctx context.Context, network string, destin
if err != nil {
return nil, err
}
gateway := Loopback.As4()
gateway := c.defaultGateway
if metadata := adapter.ContextFrom(ctx); metadata != nil {
if metadata.Gateway != nil {
gateway = metadata.Gateway.As4()

View File

@@ -29,15 +29,16 @@ func RegisterServerEndpoint(registry *endpoint.Registry) {
type ServerEndpoint struct {
outbound.Adapter
logger logger.ContextLogger
inbounds []adapter.Inbound
router adapter.ConnectionRouterEx
address IPv4
addresses map[uuid.UUID]IPv4
keys map[IPv4]uuid.UUID
conns map[IPv4]chan net.Conn
timeout time.Duration
uotClient *uot.Client
logger logger.ContextLogger
inbounds []adapter.Inbound
router adapter.ConnectionRouterEx
address IPv4
addresses map[uuid.UUID]IPv4
keys map[IPv4]uuid.UUID
conns map[IPv4]chan net.Conn
timeout time.Duration
defaultGateway *netip.Addr
uotClient *uot.Client
}
func NewServerEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VPNServerEndpointOptions) (adapter.Endpoint, error) {
@@ -51,6 +52,13 @@ func NewServerEndpoint(ctx context.Context, router adapter.Router, logger log.Co
router: sbUot.NewRouter(router, logger),
address: address.As4(),
}
if options.DefaultGateway.IsValid() {
if !options.DefaultGateway.Is4() {
return nil, E.New("invalid default_gateway: ", options.DefaultGateway)
}
defaultGateway := options.DefaultGateway
server.defaultGateway = &defaultGateway
}
router = NewRouter(router, logger, server.connHandler)
inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
inbounds := make([]adapter.Inbound, len(options.Inbounds))
@@ -124,6 +132,8 @@ func (s *ServerEndpoint) DialContext(ctx context.Context, network string, destin
Addr: Loopback,
Port: destination.Port,
}
} else if s.defaultGateway != nil {
gateway = s.defaultGateway
} else {
return nil, E.New("missing gateway")
}