feat: add skip-auth-prefixes
This commit is contained in:
parent
7ed25ddc74
commit
6bcd91a801
13 changed files with 110 additions and 61 deletions
|
@ -38,9 +38,27 @@ func WithSpecialProxy(specialProxy string) Addition {
|
||||||
|
|
||||||
func WithSrcAddr(addr net.Addr) Addition {
|
func WithSrcAddr(addr net.Addr) Addition {
|
||||||
return func(metadata *C.Metadata) {
|
return func(metadata *C.Metadata) {
|
||||||
if ip, port, err := parseAddr(addr); err == nil {
|
if addrPort, err := parseAddr(addr); err == nil {
|
||||||
metadata.SrcIP = ip
|
metadata.SrcIP = addrPort.Addr()
|
||||||
metadata.SrcPort = port
|
metadata.SrcPort = addrPort.Port()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithDstAddr(addr net.Addr) Addition {
|
||||||
|
return func(metadata *C.Metadata) {
|
||||||
|
if addrPort, err := parseAddr(addr); err == nil {
|
||||||
|
metadata.DstIP = addrPort.Addr()
|
||||||
|
metadata.DstPort = addrPort.Port()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithInAddr(addr net.Addr) Addition {
|
||||||
|
return func(metadata *C.Metadata) {
|
||||||
|
if addrPort, err := parseAddr(addr); err == nil {
|
||||||
|
metadata.InIP = addrPort.Addr()
|
||||||
|
metadata.InPort = addrPort.Port()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
adapter/inbound/auth.go
Normal file
27
adapter/inbound/auth.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package inbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
)
|
||||||
|
|
||||||
|
var skipAuthPrefixes []netip.Prefix
|
||||||
|
|
||||||
|
func SetSkipAuthPrefixes(prefixes []netip.Prefix) {
|
||||||
|
skipAuthPrefixes = prefixes
|
||||||
|
}
|
||||||
|
|
||||||
|
func SkipAuthPrefixes() []netip.Prefix {
|
||||||
|
return skipAuthPrefixes
|
||||||
|
}
|
||||||
|
|
||||||
|
func SkipAuthRemoteAddr(addr net.Addr) bool {
|
||||||
|
if addrPort, err := parseAddr(addr); err == nil {
|
||||||
|
for _, prefix := range skipAuthPrefixes {
|
||||||
|
if prefix.Contains(addrPort.Addr()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -13,16 +13,9 @@ func NewHTTP(target socks5.Addr, source net.Addr, conn net.Conn, additions ...Ad
|
||||||
metadata := parseSocksAddr(target)
|
metadata := parseSocksAddr(target)
|
||||||
metadata.NetWork = C.TCP
|
metadata.NetWork = C.TCP
|
||||||
metadata.Type = C.HTTP
|
metadata.Type = C.HTTP
|
||||||
|
additions = append(additions, WithSrcAddr(source), WithInAddr(conn.LocalAddr()))
|
||||||
for _, addition := range additions {
|
for _, addition := range additions {
|
||||||
addition.Apply(metadata)
|
addition.Apply(metadata)
|
||||||
}
|
}
|
||||||
if ip, port, err := parseAddr(source); err == nil {
|
|
||||||
metadata.SrcIP = ip
|
|
||||||
metadata.SrcPort = port
|
|
||||||
}
|
|
||||||
if ip, port, err := parseAddr(conn.LocalAddr()); err == nil {
|
|
||||||
metadata.InIP = ip
|
|
||||||
metadata.InPort = port
|
|
||||||
}
|
|
||||||
return context.NewConnContext(conn, metadata)
|
return context.NewConnContext(conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,9 @@ import (
|
||||||
func NewHTTPS(request *http.Request, conn net.Conn, additions ...Addition) *context.ConnContext {
|
func NewHTTPS(request *http.Request, conn net.Conn, additions ...Addition) *context.ConnContext {
|
||||||
metadata := parseHTTPAddr(request)
|
metadata := parseHTTPAddr(request)
|
||||||
metadata.Type = C.HTTPS
|
metadata.Type = C.HTTPS
|
||||||
|
additions = append(additions, WithSrcAddr(conn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
|
||||||
for _, addition := range additions {
|
for _, addition := range additions {
|
||||||
addition.Apply(metadata)
|
addition.Apply(metadata)
|
||||||
}
|
}
|
||||||
if ip, port, err := parseAddr(conn.RemoteAddr()); err == nil {
|
|
||||||
metadata.SrcIP = ip
|
|
||||||
metadata.SrcPort = port
|
|
||||||
}
|
|
||||||
if ip, port, err := parseAddr(conn.LocalAddr()); err == nil {
|
|
||||||
metadata.InIP = ip
|
|
||||||
metadata.InPort = port
|
|
||||||
}
|
|
||||||
return context.NewConnContext(conn, metadata)
|
return context.NewConnContext(conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,13 @@ func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type, additions
|
||||||
metadata := parseSocksAddr(target)
|
metadata := parseSocksAddr(target)
|
||||||
metadata.NetWork = C.UDP
|
metadata.NetWork = C.UDP
|
||||||
metadata.Type = source
|
metadata.Type = source
|
||||||
|
additions = append(additions, WithSrcAddr(packet.LocalAddr()))
|
||||||
|
if p, ok := packet.(C.UDPPacketInAddr); ok {
|
||||||
|
additions = append(additions, WithInAddr(p.InAddr()))
|
||||||
|
}
|
||||||
for _, addition := range additions {
|
for _, addition := range additions {
|
||||||
addition.Apply(metadata)
|
addition.Apply(metadata)
|
||||||
}
|
}
|
||||||
if ip, port, err := parseAddr(packet.LocalAddr()); err == nil {
|
|
||||||
metadata.SrcIP = ip
|
|
||||||
metadata.SrcPort = port
|
|
||||||
}
|
|
||||||
if p, ok := packet.(C.UDPPacketInAddr); ok {
|
|
||||||
if ip, port, err := parseAddr(p.InAddr()); err == nil {
|
|
||||||
metadata.InIP = ip
|
|
||||||
metadata.InPort = port
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PacketAdapter{
|
return &PacketAdapter{
|
||||||
packet,
|
packet,
|
||||||
|
|
|
@ -15,19 +15,11 @@ func NewSocket(target socks5.Addr, conn net.Conn, source C.Type, additions ...Ad
|
||||||
metadata := parseSocksAddr(target)
|
metadata := parseSocksAddr(target)
|
||||||
metadata.NetWork = C.TCP
|
metadata.NetWork = C.TCP
|
||||||
metadata.Type = source
|
metadata.Type = source
|
||||||
|
additions = append(additions, WithSrcAddr(conn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
|
||||||
for _, addition := range additions {
|
for _, addition := range additions {
|
||||||
addition.Apply(metadata)
|
addition.Apply(metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ip, port, err := parseAddr(conn.RemoteAddr()); err == nil {
|
|
||||||
metadata.SrcIP = ip
|
|
||||||
metadata.SrcPort = port
|
|
||||||
}
|
|
||||||
if ip, port, err := parseAddr(conn.LocalAddr()); err == nil {
|
|
||||||
metadata.InIP = ip
|
|
||||||
metadata.InPort = port
|
|
||||||
}
|
|
||||||
|
|
||||||
return context.NewConnContext(conn, metadata)
|
return context.NewConnContext(conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,21 +63,25 @@ func parseHTTPAddr(request *http.Request) *C.Metadata {
|
||||||
return metadata
|
return metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAddr(addr net.Addr) (netip.Addr, uint16, error) {
|
func parseAddr(addr net.Addr) (netip.AddrPort, error) {
|
||||||
// Filter when net.Addr interface is nil
|
// Filter when net.Addr interface is nil
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return netip.Addr{}, 0, errors.New("nil addr")
|
return netip.AddrPort{}, errors.New("nil addr")
|
||||||
}
|
}
|
||||||
if rawAddr, ok := addr.(interface{ RawAddr() net.Addr }); ok {
|
if rawAddr, ok := addr.(interface{ RawAddr() net.Addr }); ok {
|
||||||
ip, port, err := parseAddr(rawAddr.RawAddr())
|
if addrPort, err := parseAddr(rawAddr.RawAddr()); err == nil {
|
||||||
if err == nil {
|
return addrPort, nil
|
||||||
return ip, port, err
|
}
|
||||||
|
}
|
||||||
|
if addr, ok := addr.(interface{ AddrPort() netip.AddrPort }); ok {
|
||||||
|
if addrPort := addr.AddrPort(); addrPort.IsValid() {
|
||||||
|
return addrPort, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addrStr := addr.String()
|
addrStr := addr.String()
|
||||||
host, port, err := net.SplitHostPort(addrStr)
|
host, port, err := net.SplitHostPort(addrStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netip.Addr{}, 0, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var uint16Port uint16
|
var uint16Port uint16
|
||||||
|
@ -86,5 +90,5 @@ func parseAddr(addr net.Addr) (netip.Addr, uint16, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := netip.ParseAddr(host)
|
ip, err := netip.ParseAddr(host)
|
||||||
return ip, uint16Port, err
|
return netip.AddrPortFrom(ip, uint16Port), err
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,20 +66,21 @@ type General struct {
|
||||||
|
|
||||||
// Inbound config
|
// Inbound config
|
||||||
type Inbound struct {
|
type Inbound struct {
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
SocksPort int `json:"socks-port"`
|
SocksPort int `json:"socks-port"`
|
||||||
RedirPort int `json:"redir-port"`
|
RedirPort int `json:"redir-port"`
|
||||||
TProxyPort int `json:"tproxy-port"`
|
TProxyPort int `json:"tproxy-port"`
|
||||||
MixedPort int `json:"mixed-port"`
|
MixedPort int `json:"mixed-port"`
|
||||||
Tun LC.Tun `json:"tun"`
|
Tun LC.Tun `json:"tun"`
|
||||||
TuicServer LC.TuicServer `json:"tuic-server"`
|
TuicServer LC.TuicServer `json:"tuic-server"`
|
||||||
ShadowSocksConfig string `json:"ss-config"`
|
ShadowSocksConfig string `json:"ss-config"`
|
||||||
VmessConfig string `json:"vmess-config"`
|
VmessConfig string `json:"vmess-config"`
|
||||||
Authentication []string `json:"authentication"`
|
Authentication []string `json:"authentication"`
|
||||||
AllowLan bool `json:"allow-lan"`
|
SkipAuthPrefixes []netip.Prefix `json:"skip-auth-prefixes"`
|
||||||
BindAddress string `json:"bind-address"`
|
AllowLan bool `json:"allow-lan"`
|
||||||
InboundTfo bool `json:"inbound-tfo"`
|
BindAddress string `json:"bind-address"`
|
||||||
InboundMPTCP bool `json:"inbound-mptcp"`
|
InboundTfo bool `json:"inbound-tfo"`
|
||||||
|
InboundMPTCP bool `json:"inbound-mptcp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controller config
|
// Controller config
|
||||||
|
@ -271,6 +272,7 @@ type RawConfig struct {
|
||||||
InboundTfo bool `yaml:"inbound-tfo"`
|
InboundTfo bool `yaml:"inbound-tfo"`
|
||||||
InboundMPTCP bool `yaml:"inbound-mptcp"`
|
InboundMPTCP bool `yaml:"inbound-mptcp"`
|
||||||
Authentication []string `yaml:"authentication"`
|
Authentication []string `yaml:"authentication"`
|
||||||
|
SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes"`
|
||||||
AllowLan bool `yaml:"allow-lan"`
|
AllowLan bool `yaml:"allow-lan"`
|
||||||
BindAddress string `yaml:"bind-address"`
|
BindAddress string `yaml:"bind-address"`
|
||||||
Mode T.TunnelMode `yaml:"mode"`
|
Mode T.TunnelMode `yaml:"mode"`
|
||||||
|
@ -620,6 +622,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
||||||
ShadowSocksConfig: cfg.ShadowSocksConfig,
|
ShadowSocksConfig: cfg.ShadowSocksConfig,
|
||||||
VmessConfig: cfg.VmessConfig,
|
VmessConfig: cfg.VmessConfig,
|
||||||
AllowLan: cfg.AllowLan,
|
AllowLan: cfg.AllowLan,
|
||||||
|
SkipAuthPrefixes: cfg.SkipAuthPrefixes,
|
||||||
BindAddress: cfg.BindAddress,
|
BindAddress: cfg.BindAddress,
|
||||||
InboundTfo: cfg.InboundTfo,
|
InboundTfo: cfg.InboundTfo,
|
||||||
InboundMPTCP: cfg.InboundMPTCP,
|
InboundMPTCP: cfg.InboundMPTCP,
|
||||||
|
|
|
@ -8,6 +8,11 @@ mixed-port: 10801 # HTTP(S) 和 SOCKS 代理混合端口
|
||||||
|
|
||||||
allow-lan: true # 允许局域网连接
|
allow-lan: true # 允许局域网连接
|
||||||
bind-address: "*" # 绑定 IP 地址,仅作用于 allow-lan 为 true,'*'表示所有地址
|
bind-address: "*" # 绑定 IP 地址,仅作用于 allow-lan 为 true,'*'表示所有地址
|
||||||
|
authentication: # http,socks入口的验证用户名,密码
|
||||||
|
- "username:password"
|
||||||
|
skip-auth-prefixes: # 设置跳过验证的IP段
|
||||||
|
- 127.0.0.1/8
|
||||||
|
- ::1/128
|
||||||
|
|
||||||
# find-process-mode has 3 values:always, strict, off
|
# find-process-mode has 3 values:always, strict, off
|
||||||
# - always, 开启,强制匹配所有进程
|
# - always, 开启,强制匹配所有进程
|
||||||
|
|
|
@ -140,6 +140,7 @@ func GetGeneral() *config.General {
|
||||||
ShadowSocksConfig: ports.ShadowSocksConfig,
|
ShadowSocksConfig: ports.ShadowSocksConfig,
|
||||||
VmessConfig: ports.VmessConfig,
|
VmessConfig: ports.VmessConfig,
|
||||||
Authentication: authenticator,
|
Authentication: authenticator,
|
||||||
|
SkipAuthPrefixes: inbound.SkipAuthPrefixes(),
|
||||||
AllowLan: listener.AllowLan(),
|
AllowLan: listener.AllowLan(),
|
||||||
BindAddress: listener.BindAddress(),
|
BindAddress: listener.BindAddress(),
|
||||||
},
|
},
|
||||||
|
@ -164,6 +165,7 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList
|
||||||
|
|
||||||
allowLan := general.AllowLan
|
allowLan := general.AllowLan
|
||||||
listener.SetAllowLan(allowLan)
|
listener.SetAllowLan(allowLan)
|
||||||
|
inbound.SetSkipAuthPrefixes(general.SkipAuthPrefixes)
|
||||||
|
|
||||||
bindAddress := general.BindAddress
|
bindAddress := general.BindAddress
|
||||||
listener.SetBindAddress(bindAddress)
|
listener.SetBindAddress(bindAddress)
|
||||||
|
|
|
@ -2,9 +2,11 @@ package route
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/adapter/inbound"
|
||||||
"github.com/Dreamacro/clash/component/dialer"
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
"github.com/Dreamacro/clash/config"
|
"github.com/Dreamacro/clash/config"
|
||||||
|
@ -47,6 +49,7 @@ type configSchema struct {
|
||||||
TcptunConfig *string `json:"tcptun-config"`
|
TcptunConfig *string `json:"tcptun-config"`
|
||||||
UdptunConfig *string `json:"udptun-config"`
|
UdptunConfig *string `json:"udptun-config"`
|
||||||
AllowLan *bool `json:"allow-lan"`
|
AllowLan *bool `json:"allow-lan"`
|
||||||
|
SkipAuthPrefixes *[]netip.Prefix `json:"skip-auth-prefixes"`
|
||||||
BindAddress *string `json:"bind-address"`
|
BindAddress *string `json:"bind-address"`
|
||||||
Mode *tunnel.TunnelMode `json:"mode"`
|
Mode *tunnel.TunnelMode `json:"mode"`
|
||||||
LogLevel *log.LogLevel `json:"log-level"`
|
LogLevel *log.LogLevel `json:"log-level"`
|
||||||
|
@ -231,6 +234,10 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) {
|
||||||
P.SetAllowLan(*general.AllowLan)
|
P.SetAllowLan(*general.AllowLan)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if general.SkipAuthPrefixes != nil {
|
||||||
|
inbound.SetSkipAuthPrefixes(*general.SkipAuthPrefixes)
|
||||||
|
}
|
||||||
|
|
||||||
if general.BindAddress != nil {
|
if general.BindAddress != nil {
|
||||||
P.SetBindAddress(*general.BindAddress)
|
P.SetBindAddress(*general.BindAddress)
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,9 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *cache.LruCache[string, bool]
|
||||||
|
|
||||||
func authenticate(request *http.Request, cache *cache.LruCache[string, bool]) *http.Response {
|
func authenticate(request *http.Request, cache *cache.LruCache[string, bool]) *http.Response {
|
||||||
authenticator := authStore.Authenticator()
|
authenticator := authStore.Authenticator()
|
||||||
|
if inbound.SkipAuthRemoteAddr(N.NewCustomAddr("", request.RemoteAddr, nil)) {
|
||||||
|
authenticator = nil
|
||||||
|
}
|
||||||
if authenticator != nil {
|
if authenticator != nil {
|
||||||
credential := parseBasicProxyAuthorization(request)
|
credential := parseBasicProxyAuthorization(request)
|
||||||
if credential == "" {
|
if credential == "" {
|
||||||
|
|
|
@ -86,7 +86,11 @@ func handleSocks(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleSocks4(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
|
func HandleSocks4(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
|
||||||
addr, _, err := socks4.ServerHandshake(conn, authStore.Authenticator())
|
authenticator := authStore.Authenticator()
|
||||||
|
if inbound.SkipAuthRemoteAddr(conn.RemoteAddr()) {
|
||||||
|
authenticator = nil
|
||||||
|
}
|
||||||
|
addr, _, err := socks4.ServerHandshake(conn, authenticator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return
|
return
|
||||||
|
@ -95,7 +99,11 @@ func HandleSocks4(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleSocks5(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
|
func HandleSocks5(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
|
||||||
target, command, err := socks5.ServerHandshake(conn, authStore.Authenticator())
|
authenticator := authStore.Authenticator()
|
||||||
|
if inbound.SkipAuthRemoteAddr(conn.RemoteAddr()) {
|
||||||
|
authenticator = nil
|
||||||
|
}
|
||||||
|
target, command, err := socks5.ServerHandshake(conn, authenticator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue