Meow
2026-11-04 08:34:58 +00:00
committed by GitHub
parent ab88e0118f
commit 63ca2e0c1d
12 changed files with 132 additions and 64 deletions
+34 -20
View File
@@ -8,6 +8,7 @@ package freedom
import (
geodata "github.com/xtls/xray-core/common/geodata"
log "github.com/xtls/xray-core/common/log"
net "github.com/xtls/xray-core/common/net"
protocol "github.com/xtls/xray-core/common/protocol"
internet "github.com/xtls/xray-core/transport/internet"
@@ -357,7 +358,8 @@ type FinalRuleConfig struct {
Networks []net.Network `protobuf:"varint,2,rep,packed,name=networks,proto3,enum=xray.common.net.Network" json:"networks,omitempty"`
PortList *net.PortList `protobuf:"bytes,3,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"`
Ip []*geodata.IPRule `protobuf:"bytes,4,rep,name=ip,proto3" json:"ip,omitempty"`
BlockDelay *Range `protobuf:"bytes,5,opt,name=block_delay,json=blockDelay,proto3" json:"block_delay,omitempty"`
Delay *Range `protobuf:"bytes,5,opt,name=delay,proto3" json:"delay,omitempty"`
LogLevel *log.Severity `protobuf:"varint,6,opt,name=log_level,json=logLevel,proto3,enum=xray.common.log.Severity,oneof" json:"log_level,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -420,13 +422,20 @@ func (x *FinalRuleConfig) GetIp() []*geodata.IPRule {
return nil
}
func (x *FinalRuleConfig) GetBlockDelay() *Range {
func (x *FinalRuleConfig) GetDelay() *Range {
if x != nil {
return x.BlockDelay
return x.Delay
}
return nil
}
func (x *FinalRuleConfig) GetLogLevel() log.Severity {
if x != nil && x.LogLevel != nil {
return *x.LogLevel
}
return log.Severity(0)
}
type Config struct {
state protoimpl.MessageState `protogen:"open.v1"`
DomainStrategy internet.DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=xray.transport.internet.DomainStrategy" json:"domain_strategy,omitempty"`
@@ -523,7 +532,7 @@ var File_proxy_freedom_config_proto protoreflect.FileDescriptor
const file_proxy_freedom_config_proto_rawDesc = "" +
"\n" +
"\x1aproxy/freedom/config.proto\x12\x12xray.proxy.freedom\x1a!common/protocol/server_spec.proto\x1a\x1ftransport/internet/config.proto\x1a\x15common/net/port.proto\x1a\x18common/net/network.proto\x1a\x1bcommon/geodata/geodat.proto\"S\n" +
"\x1aproxy/freedom/config.proto\x12\x12xray.proxy.freedom\x1a!common/protocol/server_spec.proto\x1a\x1ftransport/internet/config.proto\x1a\x15common/net/port.proto\x1a\x18common/net/network.proto\x1a\x1bcommon/geodata/geodat.proto\x1a\x14common/log/log.proto\"S\n" +
"\x13DestinationOverride\x12<\n" +
"\x06server\x18\x01 \x01(\v2$.xray.common.protocol.ServerEndpointR\x06server\"\x98\x02\n" +
"\bFragment\x12!\n" +
@@ -549,14 +558,16 @@ const file_proxy_freedom_config_proto_rawDesc = "" +
"\bapply_to\x18\x06 \x01(\tR\aapplyTo\"+\n" +
"\x05Range\x12\x10\n" +
"\x03min\x18\x01 \x01(\x04R\x03min\x12\x10\n" +
"\x03max\x18\x02 \x01(\x04R\x03max\"\xa0\x02\n" +
"\x03max\x18\x02 \x01(\x04R\x03max\"\xe0\x02\n" +
"\x0fFinalRuleConfig\x126\n" +
"\x06action\x18\x01 \x01(\x0e2\x1e.xray.proxy.freedom.RuleActionR\x06action\x124\n" +
"\bnetworks\x18\x02 \x03(\x0e2\x18.xray.common.net.NetworkR\bnetworks\x126\n" +
"\tport_list\x18\x03 \x01(\v2\x19.xray.common.net.PortListR\bportList\x12+\n" +
"\x02ip\x18\x04 \x03(\v2\x1b.xray.common.geodata.IPRuleR\x02ip\x12:\n" +
"\vblock_delay\x18\x05 \x01(\v2\x19.xray.proxy.freedom.RangeR\n" +
"blockDelay\"\xaf\x03\n" +
"\x02ip\x18\x04 \x03(\v2\x1b.xray.common.geodata.IPRuleR\x02ip\x12/\n" +
"\x05delay\x18\x05 \x01(\v2\x19.xray.proxy.freedom.RangeR\x05delay\x12;\n" +
"\tlog_level\x18\x06 \x01(\x0e2\x19.xray.common.log.SeverityH\x00R\blogLevel\x88\x01\x01B\f\n" +
"\n" +
"_log_level\"\xaf\x03\n" +
"\x06Config\x12P\n" +
"\x0fdomain_strategy\x18\x01 \x01(\x0e2'.xray.transport.internet.DomainStrategyR\x0edomainStrategy\x12Z\n" +
"\x14destination_override\x18\x03 \x01(\v2'.xray.proxy.freedom.DestinationOverrideR\x13destinationOverride\x12\x1d\n" +
@@ -599,7 +610,8 @@ var file_proxy_freedom_config_proto_goTypes = []any{
(net.Network)(0), // 8: xray.common.net.Network
(*net.PortList)(nil), // 9: xray.common.net.PortList
(*geodata.IPRule)(nil), // 10: xray.common.geodata.IPRule
(internet.DomainStrategy)(0), // 11: xray.transport.internet.DomainStrategy
(log.Severity)(0), // 11: xray.common.log.Severity
(internet.DomainStrategy)(0), // 12: xray.transport.internet.DomainStrategy
}
var file_proxy_freedom_config_proto_depIdxs = []int32{
7, // 0: xray.proxy.freedom.DestinationOverride.server:type_name -> xray.common.protocol.ServerEndpoint
@@ -607,17 +619,18 @@ var file_proxy_freedom_config_proto_depIdxs = []int32{
8, // 2: xray.proxy.freedom.FinalRuleConfig.networks:type_name -> xray.common.net.Network
9, // 3: xray.proxy.freedom.FinalRuleConfig.port_list:type_name -> xray.common.net.PortList
10, // 4: xray.proxy.freedom.FinalRuleConfig.ip:type_name -> xray.common.geodata.IPRule
4, // 5: xray.proxy.freedom.FinalRuleConfig.block_delay:type_name -> xray.proxy.freedom.Range
11, // 6: xray.proxy.freedom.Config.domain_strategy:type_name -> xray.transport.internet.DomainStrategy
1, // 7: xray.proxy.freedom.Config.destination_override:type_name -> xray.proxy.freedom.DestinationOverride
2, // 8: xray.proxy.freedom.Config.fragment:type_name -> xray.proxy.freedom.Fragment
3, // 9: xray.proxy.freedom.Config.noises:type_name -> xray.proxy.freedom.Noise
5, // 10: xray.proxy.freedom.Config.final_rules:type_name -> xray.proxy.freedom.FinalRuleConfig
11, // [11:11] is the sub-list for method output_type
11, // [11:11] is the sub-list for method input_type
11, // [11:11] is the sub-list for extension type_name
11, // [11:11] is the sub-list for extension extendee
0, // [0:11] is the sub-list for field type_name
4, // 5: xray.proxy.freedom.FinalRuleConfig.delay:type_name -> xray.proxy.freedom.Range
11, // 6: xray.proxy.freedom.FinalRuleConfig.log_level:type_name -> xray.common.log.Severity
12, // 7: xray.proxy.freedom.Config.domain_strategy:type_name -> xray.transport.internet.DomainStrategy
1, // 8: xray.proxy.freedom.Config.destination_override:type_name -> xray.proxy.freedom.DestinationOverride
2, // 9: xray.proxy.freedom.Config.fragment:type_name -> xray.proxy.freedom.Fragment
3, // 10: xray.proxy.freedom.Config.noises:type_name -> xray.proxy.freedom.Noise
5, // 11: xray.proxy.freedom.Config.final_rules:type_name -> xray.proxy.freedom.FinalRuleConfig
12, // [12:12] is the sub-list for method output_type
12, // [12:12] is the sub-list for method input_type
12, // [12:12] is the sub-list for extension type_name
12, // [12:12] is the sub-list for extension extendee
0, // [0:12] is the sub-list for field type_name
}
func init() { file_proxy_freedom_config_proto_init() }
@@ -625,6 +638,7 @@ func file_proxy_freedom_config_proto_init() {
if File_proxy_freedom_config_proto != nil {
return
}
file_proxy_freedom_config_proto_msgTypes[4].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
+3 -1
View File
@@ -11,6 +11,7 @@ import "transport/internet/config.proto";
import "common/net/port.proto";
import "common/net/network.proto";
import "common/geodata/geodat.proto";
import "common/log/log.proto";
message DestinationOverride {
xray.common.protocol.ServerEndpoint server = 1;
@@ -51,7 +52,8 @@ message FinalRuleConfig {
repeated xray.common.net.Network networks = 2;
xray.common.net.PortList port_list = 3;
repeated xray.common.geodata.IPRule ip = 4;
Range block_delay = 5;
Range delay = 5;
optional xray.common.log.Severity log_level = 6;
}
message Config {
+42 -20
View File
@@ -15,6 +15,7 @@ import (
"github.com/xtls/xray-core/common/dice"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/geodata"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/platform"
"github.com/xtls/xray-core/common/retry"
@@ -72,23 +73,26 @@ func init() {
}
defaultBlockPrivateRule = &FinalRule{
action: RuleAction_Block,
network: allNetworks,
ip: geodata.GetPrivateIPMatcher(),
action: RuleAction_Block,
network: allNetworks,
ip: geodata.GetPrivateIPMatcher(),
logLevel: log.Severity_Warning.Enum(),
}
defaultBlockAllRule = &FinalRule{
action: RuleAction_Block,
network: allNetworks,
action: RuleAction_Block,
network: allNetworks,
logLevel: log.Severity_Warning.Enum(),
}
}
type FinalRule struct {
action RuleAction
network [8]bool
port net.MemoryPortList
ip geodata.IPMatcher
blockDelay *Range
action RuleAction
network [8]bool
port net.MemoryPortList
ip geodata.IPMatcher
delay *Range
logLevel *log.Severity
}
// Handler handles Freedom connections.
@@ -102,8 +106,9 @@ type Handler struct {
func buildFinalRule(config *FinalRuleConfig) (*FinalRule, error) {
rule := &FinalRule{
action: config.GetAction(),
blockDelay: config.GetBlockDelay(),
action: config.GetAction(),
delay: config.GetDelay(),
logLevel: config.LogLevel,
}
if len(config.Networks) == 0 {
@@ -164,7 +169,7 @@ func getDefaultFinalRule(inbound *session.Inbound) *FinalRule {
switch inbound.Name {
case "vless-reverse":
return defaultBlockAllRule
case "vless", "vmess", "trojan", "hysteria", "wireguard":
case "vless", "vmess", "trojan", "hysteria", "wireguard", "masque":
return defaultBlockPrivateRule
default:
if strings.HasPrefix(inbound.Name, "shadowsocks") {
@@ -212,12 +217,12 @@ func (h *Handler) policy() policy.Session {
return p
}
func (h *Handler) blockDelay(rule *FinalRule) time.Duration {
func (r *FinalRule) blockDuration() time.Duration {
min := uint64(30)
max := uint64(90)
if rule.blockDelay != nil {
min = rule.blockDelay.Min
max = rule.blockDelay.Max
if r.delay != nil {
min = r.delay.Min
max = r.delay.Max
}
span := max - min
if max < min {
@@ -226,9 +231,26 @@ func (h *Handler) blockDelay(rule *FinalRule) time.Duration {
return time.Duration(min+uint64(dice.Roll(int(span+1)))) * time.Second
}
func (r *FinalRule) log(ctx context.Context, msg ...interface{}) {
level := log.Severity_Info
if r.logLevel != nil {
level = *r.logLevel
}
switch level {
case log.Severity_Debug:
errors.LogDebug(ctx, msg...)
case log.Severity_Info:
errors.LogInfo(ctx, msg...)
case log.Severity_Warning:
errors.LogWarning(ctx, msg...)
case log.Severity_Error:
errors.LogError(ctx, msg...)
}
}
func (h *Handler) blackhole(ctx context.Context, input buf.Reader, output buf.Writer, rule *FinalRule, dest *net.Destination) error {
delay := h.blockDelay(rule)
errors.LogInfo(ctx, "blocked target: ", *dest, ", blackholing connection for ", delay)
delay := rule.blockDuration()
rule.log(ctx, "target blocked by a finalrule: ", *dest, ", blackholing connection for ", delay)
defer common.Close(output)
done := make(chan struct{})
go func() { // a DispatchLink inbound's reader ignores Interrupt, so don't wait for this copy
@@ -240,7 +262,7 @@ func (h *Handler) blackhole(ctx context.Context, input buf.Reader, output buf.Wr
case <-time.After(delay):
common.Interrupt(input)
common.Interrupt(output)
errors.LogInfo(ctx, "closed blackholed connection to blocked target: ", *dest)
rule.log(ctx, "closed blackholed connection to blocked target: ", *dest)
}
return nil
}