Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions infra/conf/xray.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,70 @@ func (c *OutboundDetourConfig) checkChainProxyConfig() error {
return nil
}

func isInternalOrInvalidAddress(address *Address) bool {
if address == nil {
return true
}
ip := address.IP()
if ip == nil {
return true
}
return ip.IsPrivate() || ip.IsLoopback() || ip.IsMulticast() || ip.IsLinkLocalUnicast()
}

func (c *OutboundDetourConfig) checkOutboundTLSConflict(rawConfig interface{}, senderSettings *proxyman.SenderConfig) error {
if senderSettings.StreamSettings != nil && senderSettings.StreamSettings.GetSecurityType() != "" {
return nil
}
// VMess
if vmCfg, ok := rawConfig.(*VMessOutboundConfig); ok {
return c.checkVMessTLSConflict(vmCfg)
}

// VLESS should always with encryption
if vlessCfg, ok := rawConfig.(*VLessOutboundConfig); ok {
if !isInternalOrInvalidAddress(vlessCfg.Address) {
// When the encryption present, GetSecurityType() => should not be empty
return errors.New("vless without TLS or other encryption is prohibited")
}
}

// Trojan,unlikely
if tjCfg, ok := rawConfig.(*TrojanClientConfig); ok {
if !isInternalOrInvalidAddress(tjCfg.Address) {
return errors.New("trojan without TLS is prohibited")
}
}

// Hysteria, unlikely
// if _, ok := rawConfig.(*HysteriaClientConfig); ok {
// return errors.New("hysteria2 without TLS is prohibited")
// }

return nil
}
func (c *OutboundDetourConfig) checkVMessTLSConflict(vmCfg *VMessOutboundConfig) error {
sec := ""
if vmCfg.Address != nil {
sec = vmCfg.Security
} else if len(vmCfg.Receivers) > 0 {
rec := vmCfg.Receivers[0]
if len(rec.Users) > 0 {
acct := new(VMessAccount)
if err := json.Unmarshal(rec.Users[0], acct); err == nil {
sec = strings.ToLower(acct.Security)
}
}
}

if sec == "none" || sec == "auto" || sec == "" || sec == "zero" {
if !isInternalOrInvalidAddress(vmCfg.Address) {
return errors.New("vmess with 'none' or 'zero' security is conflicted without TLS in streamSettings, alternatively, you can use the socks5 protocol.")
}
}
return nil
}

// Build implements Buildable.
func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
senderSettings := &proxyman.SenderConfig{}
Expand Down Expand Up @@ -319,6 +383,9 @@ func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
if err != nil {
return nil, errors.New("failed to load outbound detour config for protocol ", c.Protocol).Base(err)
}
if err := c.checkOutboundTLSConflict(rawConfig, senderSettings); err != nil {
return nil, err
}
ts, err := rawConfig.(Buildable).Build()
if err != nil {
return nil, errors.New("failed to build outbound handler for protocol ", c.Protocol).Base(err)
Expand Down