mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 03:33:15 +08:00
feat: Add LAN allowed and disallowed IP configurations (#861)
This commit is contained in:
parent
3cf865e5f0
commit
7ee6809257
57
adapter/inbound/ipfilter.go
Normal file
57
adapter/inbound/ipfilter.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package inbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
C "github.com/metacubex/mihomo/constant"
|
||||||
|
)
|
||||||
|
|
||||||
|
var lanAllowedIPs []netip.Prefix
|
||||||
|
var lanDisAllowedIPs []netip.Prefix
|
||||||
|
|
||||||
|
func SetAllowedIPs(prefixes []netip.Prefix) {
|
||||||
|
lanAllowedIPs = prefixes
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDisAllowedIPs(prefixes []netip.Prefix) {
|
||||||
|
lanDisAllowedIPs = prefixes
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllowedIPs() []netip.Prefix {
|
||||||
|
return lanAllowedIPs
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisAllowedIPs() []netip.Prefix {
|
||||||
|
return lanDisAllowedIPs
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsRemoteAddrDisAllowed(addr net.Addr) bool {
|
||||||
|
m := C.Metadata{}
|
||||||
|
if err := m.SetRemoteAddr(addr); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isAllowed(m.AddrPort().Addr().Unmap()) && !isDisAllowed(m.AddrPort().Addr().Unmap())
|
||||||
|
}
|
||||||
|
|
||||||
|
func isAllowed(addr netip.Addr) bool {
|
||||||
|
if addr.IsValid() {
|
||||||
|
for _, prefix := range lanAllowedIPs {
|
||||||
|
if prefix.Contains(addr) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isDisAllowed(addr netip.Addr) bool {
|
||||||
|
if addr.IsValid() {
|
||||||
|
for _, prefix := range lanDisAllowedIPs {
|
||||||
|
if prefix.Contains(addr) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
@ -80,6 +80,8 @@ type Inbound struct {
|
|||||||
VmessConfig string `json:"vmess-config"`
|
VmessConfig string `json:"vmess-config"`
|
||||||
Authentication []string `json:"authentication"`
|
Authentication []string `json:"authentication"`
|
||||||
SkipAuthPrefixes []netip.Prefix `json:"skip-auth-prefixes"`
|
SkipAuthPrefixes []netip.Prefix `json:"skip-auth-prefixes"`
|
||||||
|
LanAllowedIPs []netip.Prefix `json:"lan-allowed-ips"`
|
||||||
|
LanDisAllowedIPs []netip.Prefix `json:"lan-disallowed-ips"`
|
||||||
AllowLan bool `json:"allow-lan"`
|
AllowLan bool `json:"allow-lan"`
|
||||||
BindAddress string `json:"bind-address"`
|
BindAddress string `json:"bind-address"`
|
||||||
InboundTfo bool `json:"inbound-tfo"`
|
InboundTfo bool `json:"inbound-tfo"`
|
||||||
@ -289,6 +291,8 @@ type RawConfig struct {
|
|||||||
InboundMPTCP bool `yaml:"inbound-mptcp"`
|
InboundMPTCP bool `yaml:"inbound-mptcp"`
|
||||||
Authentication []string `yaml:"authentication" json:"authentication"`
|
Authentication []string `yaml:"authentication" json:"authentication"`
|
||||||
SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes"`
|
SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes"`
|
||||||
|
LanAllowedIPs []netip.Prefix `yaml:"lan-allowed-ips"`
|
||||||
|
LanDisAllowedIPs []netip.Prefix `yaml:"lan-disallowed-ips"`
|
||||||
AllowLan bool `yaml:"allow-lan" json:"allow-lan"`
|
AllowLan bool `yaml:"allow-lan" json:"allow-lan"`
|
||||||
BindAddress string `yaml:"bind-address" json:"bind-address"`
|
BindAddress string `yaml:"bind-address" json:"bind-address"`
|
||||||
Mode T.TunnelMode `yaml:"mode" json:"mode"`
|
Mode T.TunnelMode `yaml:"mode" json:"mode"`
|
||||||
@ -387,6 +391,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
|||||||
rawCfg := &RawConfig{
|
rawCfg := &RawConfig{
|
||||||
AllowLan: false,
|
AllowLan: false,
|
||||||
BindAddress: "*",
|
BindAddress: "*",
|
||||||
|
LanAllowedIPs: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0"), netip.MustParsePrefix("::/0")},
|
||||||
IPv6: true,
|
IPv6: true,
|
||||||
Mode: T.Rule,
|
Mode: T.Rule,
|
||||||
GeoAutoUpdate: false,
|
GeoAutoUpdate: false,
|
||||||
@ -647,6 +652,8 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
|||||||
VmessConfig: cfg.VmessConfig,
|
VmessConfig: cfg.VmessConfig,
|
||||||
AllowLan: cfg.AllowLan,
|
AllowLan: cfg.AllowLan,
|
||||||
SkipAuthPrefixes: cfg.SkipAuthPrefixes,
|
SkipAuthPrefixes: cfg.SkipAuthPrefixes,
|
||||||
|
LanAllowedIPs: cfg.LanAllowedIPs,
|
||||||
|
LanDisAllowedIPs: cfg.LanDisAllowedIPs,
|
||||||
BindAddress: cfg.BindAddress,
|
BindAddress: cfg.BindAddress,
|
||||||
InboundTfo: cfg.InboundTfo,
|
InboundTfo: cfg.InboundTfo,
|
||||||
InboundMPTCP: cfg.InboundMPTCP,
|
InboundMPTCP: cfg.InboundMPTCP,
|
||||||
|
@ -13,6 +13,11 @@ authentication: # http,socks入口的验证用户名,密码
|
|||||||
skip-auth-prefixes: # 设置跳过验证的IP段
|
skip-auth-prefixes: # 设置跳过验证的IP段
|
||||||
- 127.0.0.1/8
|
- 127.0.0.1/8
|
||||||
- ::1/128
|
- ::1/128
|
||||||
|
lan-allowed-ips: # 允许连接的 IP 地址段,仅作用于 allow-lan 为 true, 默认值为0.0.0.0/0和::/0
|
||||||
|
- 0.0.0.0/0
|
||||||
|
- ::/0
|
||||||
|
lan-disallowed-ips: # 禁止连接的 IP 地址段, 黑名单优先级高于白名单, 默认值为空
|
||||||
|
- 192.168.0.3/32
|
||||||
|
|
||||||
# find-process-mode has 3 values:always, strict, off
|
# find-process-mode has 3 values:always, strict, off
|
||||||
# - always, 开启,强制匹配所有进程
|
# - always, 开启,强制匹配所有进程
|
||||||
|
@ -141,6 +141,8 @@ func GetGeneral() *config.General {
|
|||||||
VmessConfig: ports.VmessConfig,
|
VmessConfig: ports.VmessConfig,
|
||||||
Authentication: authenticator,
|
Authentication: authenticator,
|
||||||
SkipAuthPrefixes: inbound.SkipAuthPrefixes(),
|
SkipAuthPrefixes: inbound.SkipAuthPrefixes(),
|
||||||
|
LanAllowedIPs: inbound.AllowedIPs(),
|
||||||
|
LanDisAllowedIPs: inbound.DisAllowedIPs(),
|
||||||
AllowLan: listener.AllowLan(),
|
AllowLan: listener.AllowLan(),
|
||||||
BindAddress: listener.BindAddress(),
|
BindAddress: listener.BindAddress(),
|
||||||
},
|
},
|
||||||
@ -166,6 +168,8 @@ 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)
|
inbound.SetSkipAuthPrefixes(general.SkipAuthPrefixes)
|
||||||
|
inbound.SetAllowedIPs(general.LanAllowedIPs)
|
||||||
|
inbound.SetDisAllowedIPs(general.LanDisAllowedIPs)
|
||||||
|
|
||||||
bindAddress := general.BindAddress
|
bindAddress := general.BindAddress
|
||||||
listener.SetBindAddress(bindAddress)
|
listener.SetBindAddress(bindAddress)
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/metacubex/mihomo/component/dialer"
|
"github.com/metacubex/mihomo/component/dialer"
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
"github.com/metacubex/mihomo/config"
|
"github.com/metacubex/mihomo/config"
|
||||||
"github.com/metacubex/mihomo/constant"
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/hub/executor"
|
"github.com/metacubex/mihomo/hub/executor"
|
||||||
P "github.com/metacubex/mihomo/listener"
|
P "github.com/metacubex/mihomo/listener"
|
||||||
@ -50,6 +49,8 @@ type configSchema struct {
|
|||||||
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"`
|
SkipAuthPrefixes *[]netip.Prefix `json:"skip-auth-prefixes"`
|
||||||
|
LanAllowedIPs *[]netip.Prefix `json:"lan-allowed-ips"`
|
||||||
|
LanDisAllowedIPs *[]netip.Prefix `json:"lan-disallowed-ips"`
|
||||||
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"`
|
||||||
@ -268,6 +269,14 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) {
|
|||||||
inbound.SetSkipAuthPrefixes(*general.SkipAuthPrefixes)
|
inbound.SetSkipAuthPrefixes(*general.SkipAuthPrefixes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if general.LanAllowedIPs != nil {
|
||||||
|
inbound.SetAllowedIPs(*general.LanAllowedIPs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if general.LanDisAllowedIPs != nil {
|
||||||
|
inbound.SetDisAllowedIPs(*general.LanDisAllowedIPs)
|
||||||
|
}
|
||||||
|
|
||||||
if general.BindAddress != nil {
|
if general.BindAddress != nil {
|
||||||
P.SetBindAddress(*general.BindAddress)
|
P.SetBindAddress(*general.BindAddress)
|
||||||
}
|
}
|
||||||
@ -335,7 +344,7 @@ func updateConfigs(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if req.Path == "" {
|
if req.Path == "" {
|
||||||
req.Path = constant.Path.Config()
|
req.Path = C.Path.Config()
|
||||||
}
|
}
|
||||||
if !filepath.IsAbs(req.Path) {
|
if !filepath.IsAbs(req.Path) {
|
||||||
render.Status(r, http.StatusBadRequest)
|
render.Status(r, http.StatusBadRequest)
|
||||||
@ -380,7 +389,7 @@ func updateGeoDatabases(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := executor.ParseWithPath(constant.Path.Config())
|
cfg, err := executor.ParseWithPath(C.Path.Config())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("[REST-API] update GEO databases failed: %v", err)
|
log.Errorln("[REST-API] update GEO databases failed: %v", err)
|
||||||
return
|
return
|
||||||
|
@ -71,6 +71,12 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
|
|||||||
t.SetKeepAlive(false)
|
t.SetKeepAlive(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(additions) == 0 { // only apply on default listener
|
||||||
|
if inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) {
|
||||||
|
_ = conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
go HandleConn(conn, tunnel, c, additions...)
|
go HandleConn(conn, tunnel, c, additions...)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -62,6 +62,12 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if len(additions) == 0 { // only apply on default listener
|
||||||
|
if inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) {
|
||||||
|
_ = c.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
go handleConn(c, tunnel, ml.cache, additions...)
|
go handleConn(c, tunnel, ml.cache, additions...)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -59,6 +59,12 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if len(additions) == 0 { // only apply on default listener
|
||||||
|
if inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) {
|
||||||
|
_ = c.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
go handleSocks(c, tunnel, additions...)
|
go handleSocks(c, tunnel, additions...)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
Loading…
Reference in New Issue
Block a user