249 lines
7.2 KiB
Go
249 lines
7.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/xtls/xray-core/app/proxyman/command"
|
|
cnet "github.com/xtls/xray-core/common/net"
|
|
"github.com/xtls/xray-core/common/protocol"
|
|
"github.com/xtls/xray-core/common/serial"
|
|
"github.com/xtls/xray-core/proxy/dns"
|
|
"github.com/xtls/xray-core/proxy/dokodemo"
|
|
"github.com/xtls/xray-core/proxy/http"
|
|
"github.com/xtls/xray-core/proxy/loopback"
|
|
"github.com/xtls/xray-core/proxy/shadowsocks"
|
|
ss2022 "github.com/xtls/xray-core/proxy/shadowsocks_2022"
|
|
"github.com/xtls/xray-core/proxy/socks"
|
|
"github.com/xtls/xray-core/proxy/trojan"
|
|
"github.com/xtls/xray-core/proxy/vless"
|
|
vlessin "github.com/xtls/xray-core/proxy/vless/inbound"
|
|
"github.com/xtls/xray-core/proxy/vmess"
|
|
vmessin "github.com/xtls/xray-core/proxy/vmess/inbound"
|
|
)
|
|
|
|
// AddVMessInbound demonstrates HandlerServiceClient.AddInbound for VMess inbound.
|
|
func AddVMessInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, true),
|
|
serial.ToTypedMessage(&vmessin.Config{
|
|
User: []*protocol.User{
|
|
{
|
|
Level: 0,
|
|
Email: "demo@vmess.local",
|
|
Account: serial.ToTypedMessage(&vmess.Account{
|
|
Id: randomUUID(),
|
|
SecuritySettings: &protocol.SecurityConfig{
|
|
Type: protocol.SecurityType_AUTO,
|
|
},
|
|
}),
|
|
},
|
|
},
|
|
Default: &vmessin.DefaultConfig{Level: 0},
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddVLESSInbound adds a VLESS inbound with Vision style fallbacks.
|
|
func AddVLESSInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, true),
|
|
serial.ToTypedMessage(&vlessin.Config{
|
|
Clients: []*protocol.User{
|
|
{
|
|
Level: 1,
|
|
Email: "client@vless.local",
|
|
Account: serial.ToTypedMessage(&vless.Account{
|
|
Id: randomUUID(),
|
|
Encryption: "none",
|
|
}),
|
|
},
|
|
},
|
|
Fallbacks: []*vlessin.Fallback{
|
|
{
|
|
Name: "websocket",
|
|
Alpn: "h2",
|
|
Path: "/ws",
|
|
Type: "http",
|
|
Dest: "127.0.0.1:8080",
|
|
Xver: 1,
|
|
},
|
|
},
|
|
Decryption: "none",
|
|
Padding: "enable",
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddTrojanInbound registers a Trojan inbound with two users and ALPN fallback.
|
|
func AddTrojanInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, true),
|
|
serial.ToTypedMessage(&trojan.ServerConfig{
|
|
Users: []*protocol.User{
|
|
{
|
|
Level: 0,
|
|
Email: "alice@trojan.local",
|
|
Account: serial.ToTypedMessage(&trojan.Account{
|
|
Password: randomUUID(),
|
|
}),
|
|
},
|
|
{
|
|
Level: 0,
|
|
Email: "bob@trojan.local",
|
|
Account: serial.ToTypedMessage(&trojan.Account{
|
|
Password: randomUUID(),
|
|
}),
|
|
},
|
|
},
|
|
Fallbacks: []*trojan.Fallback{
|
|
{
|
|
Name: "http",
|
|
Alpn: "http/1.1",
|
|
Dest: "127.0.0.1:8081",
|
|
},
|
|
},
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddShadowsocksInbound adds an AEAD Shadowsocks inbound supporting both TCP and UDP.
|
|
func AddShadowsocksInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(&shadowsocks.ServerConfig{
|
|
Users: []*protocol.User{
|
|
{
|
|
Level: 0,
|
|
Email: "ss@demo.local",
|
|
Account: serial.ToTypedMessage(&shadowsocks.Account{
|
|
Password: "s3cret-pass",
|
|
CipherType: shadowsocks.CipherType_AES_128_GCM,
|
|
}),
|
|
},
|
|
},
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddShadowsocks2022Inbound covers both single user and multi-user deployment.
|
|
func AddShadowsocks2022Inbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
server := &ss2022.MultiUserServerConfig{
|
|
Method: "2022-blake3-aes-128-gcm",
|
|
Key: "0123456789abcdef0123456789abcdef",
|
|
Users: []*protocol.User{
|
|
{
|
|
Level: 0,
|
|
Email: "user1@ss2022.local",
|
|
Account: serial.ToTypedMessage(&ss2022.Account{
|
|
Key: randomUUID(),
|
|
}),
|
|
},
|
|
{
|
|
Level: 0,
|
|
Email: "user2@ss2022.local",
|
|
Account: serial.ToTypedMessage(&ss2022.Account{
|
|
Key: randomUUID(),
|
|
}),
|
|
},
|
|
},
|
|
}
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(server),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddSocksInbound exposes a SOCKS5 server with username/password authentication.
|
|
func AddSocksInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(&socks.ServerConfig{
|
|
AuthType: socks.AuthType_PASSWORD,
|
|
Accounts: map[string]string{"demo": "passw0rd"},
|
|
UdpEnabled: true,
|
|
UserLevel: 0,
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddHTTPInbound adds an HTTP proxy inbound with basic auth.
|
|
func AddHTTPInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(&http.ServerConfig{
|
|
Accounts: map[string]string{"demo": "http-pass"},
|
|
AllowTransparent: true,
|
|
UserLevel: 0,
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddDokodemoInbound configures a dokodemo-door mirror port.
|
|
func AddDokodemoInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32, targetPort uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(&dokodemo.Config{
|
|
Address: cnetOrDomain("example.com"),
|
|
Port: targetPort,
|
|
Networks: []cnet.Network{cnet.Network_TCP, cnet.Network_UDP},
|
|
FollowRedirect: false,
|
|
UserLevel: 0,
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddDNSInbound exposes the built-in DNS server on an API port.
|
|
func AddDNSInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(&dns.Config{
|
|
Server: &cnet.Endpoint{
|
|
Network: cnet.Network_UDP,
|
|
Address: cnetOrDomain("1.1.1.1"),
|
|
Port: 53,
|
|
},
|
|
Non_IPQuery: "drop",
|
|
BlockTypes: []int32{65, 28},
|
|
}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|
|
// AddLoopbackInbound ties an inbound to an existing outbound chain.
|
|
func AddLoopbackInbound(ctx context.Context, client command.HandlerServiceClient, tag string, port uint32, targetInbound string) error {
|
|
inbound := inboundConfig(
|
|
tag,
|
|
receiverSettings(port, false),
|
|
serial.ToTypedMessage(&loopback.Config{InboundTag: targetInbound}),
|
|
)
|
|
_, err := client.AddInbound(ctx, &command.AddInboundRequest{Inbound: inbound})
|
|
return err
|
|
}
|
|
|