Skip to content

Commit

Permalink
feat: support listen on multi ip
Browse files Browse the repository at this point in the history
  • Loading branch information
wweir committed May 14, 2024
1 parent 0c83462 commit 45c9eea
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 33 deletions.
67 changes: 40 additions & 27 deletions cmd/sower/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"
"time"

"github.com/bobg/go-generics/v3/slices"
"github.com/cristalhq/aconfig"
"github.com/cristalhq/aconfig/aconfighcl"
"github.com/cristalhq/aconfig/aconfigtoml"
Expand All @@ -34,9 +35,11 @@ var (
}

DNS struct {
Disable bool `default:"false" usage:"disable DNS proxy"`
Serve string `default:"127.0.0.1" required:"true" usage:"dns server ip"`
Fallback string `default:"223.5.5.5" required:"true" usage:"fallback dns server"`
Disable bool `default:"false" usage:"disable DNS proxy"`
Serve string `default:"127.0.0.1" usage:"Deprecated, use 'serve_ips' instead"`
ServeIps []string `usage:"dns server ip, eg: 127.0.0.1,::1"`
ServeIface string `usage:"dns server interface, eg: eth0"`
Fallback string `default:"223.5.5.5" required:"true" usage:"fallback dns server"`
}
Socks5 struct {
Disable bool `default:"false" usage:"disable sock5 proxy"`
Expand Down Expand Up @@ -86,6 +89,25 @@ func init() {
Msg("Load config")
}

if !slices.Contains(conf.DNS.ServeIps, conf.DNS.Serve) {
conf.DNS.ServeIps = append(conf.DNS.ServeIps, conf.DNS.Serve)
}
if conf.DNS.ServeIface != "" {
iface, err := net.InterfaceByName(conf.DNS.ServeIface)
log.DebugFatal(err).Str("iface", conf.DNS.ServeIface).Msg("get iface")
addrs, err := iface.Addrs()
log.InfoFatal(err).Str("iface", conf.DNS.ServeIface).Msg("get iface addrs")
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
log.InfoFatal(err).Str("iface", conf.DNS.ServeIface).
Msg("parse iface addr: " + addr.String())

if !slices.Contains(conf.DNS.ServeIps, ip.String()) {
conf.DNS.ServeIps = append(conf.DNS.ServeIps, ip.String())
}
}
}

conf.Router.Direct.Rules = append(conf.Router.Direct.Rules,
conf.Remote.Addr, "**.in-addr.arpa", "**.ip6.arpa")
log.Info().
Expand All @@ -103,31 +125,25 @@ func main() {
r.ProxyRule = suffixtree.NewNodeFromRules(conf.Router.Proxy.Rules...)
r.AddCountryCIDRs(conf.Router.Country.Rules...)

go func() {
if conf.DNS.Disable {
log.Info().Msg("DNS proxy disabled")
return
}
if conf.DNS.Disable {
log.Info().Msg("DNS proxy disabled")
return
}

lnHTTP, err := net.Listen("tcp", net.JoinHostPort(conf.DNS.Serve, "80"))
if err != nil {
log.Fatal().Err(err).Msg("listen port")
}
for _, ip := range conf.DNS.ServeIps {
lnHTTP, err := net.Listen("tcp", net.JoinHostPort(ip, "80"))
log.DebugFatal(err).Str("listen_on", ip).Msg("listen port 80")
go ServeHTTP(lnHTTP, r)

lnHTTPS, err := net.Listen("tcp", net.JoinHostPort(conf.DNS.Serve, "443"))
if err != nil {
log.Fatal().Err(err).Msg("listen port")
}
lnHTTPS, err := net.Listen("tcp", net.JoinHostPort(ip, "443"))
log.DebugFatal(err).Str("listen_on", ip).Msg("listen port 443")
go ServeHTTPS(lnHTTPS, r)

log.Info().
Str("listen_on", conf.DNS.Serve).
Msg("DNS proxy started")
if err := dns.ListenAndServe(net.JoinHostPort(conf.DNS.Serve, "53"), "udp", r); err != nil {
log.Fatal().Err(err).Msg("serve dns")
}
}()
go func(ip string) {
err := dns.ListenAndServe(net.JoinHostPort(ip, "53"), "udp", r)
log.InfoFatal(err).Str("listen_on", ip).Msg("serve dns")
}(ip)
}

go func() {
if conf.Socks5.Disable {
Expand All @@ -136,10 +152,7 @@ func main() {
}

ln, err := net.Listen("tcp", conf.Socks5.Addr)
if err != nil {
log.Fatal().Err(err).Msg("listen port")
}
log.Info().Msgf("SOCKS5 proxy listening on %s", conf.Socks5.Addr)
log.InfoFatal(err).Str("listen_on", conf.Socks5.Addr).Msg("listen SOCKS5 proxy")
go ServeSocks5(ln, r)
}()

Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
module github.com/wweir/sower

go 1.18
go 1.22

toolchain go1.22.3

require (
github.com/bobg/go-generics/v3 v3.4.0
github.com/cristalhq/aconfig v0.18.5
github.com/cristalhq/aconfig/aconfighcl v0.17.1
github.com/cristalhq/aconfig/aconfigtoml v0.17.1
Expand All @@ -13,7 +16,7 @@ require (
github.com/oschwald/geoip2-golang v1.9.0
github.com/pkg/errors v0.9.1
github.com/sower-proxy/conns v0.0.3
github.com/sower-proxy/deferlog v1.0.6
github.com/sower-proxy/deferlog v1.0.7
github.com/sower-proxy/mem v0.0.3
golang.org/x/crypto v0.23.0
)
Expand Down
13 changes: 11 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/bobg/go-generics/v3 v3.4.0 h1:XxTJxH843OknMgw//HGQXklJCZ0eacdt5EABfNcKFr8=
github.com/bobg/go-generics/v3 v3.4.0/go.mod h1:gCsHnnRz88zpXpdsWPyDmjg1tYQPmpbUQbM4MW8z9Jc=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cristalhq/aconfig v0.17.0/go.mod h1:NXaRp+1e6bkO4dJn+wZ71xyaihMDYPtCSvEhMTm/H3E=
github.com/cristalhq/aconfig v0.18.5 h1:QqXH/Gy2c4QUQJTV2BN8UAuL/rqZ3IwhvxeC8OgzquA=
Expand All @@ -13,6 +15,8 @@ github.com/cristalhq/aconfig/aconfigyaml v0.17.1/go.mod h1:5DTsjHkvQ6hfbyxfG32ro
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771 h1:t2c2B9g1ZVhMYduqmANSEGVD3/1WlsrEYNPtVoFlENk=
Expand All @@ -24,6 +28,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
Expand All @@ -33,23 +39,26 @@ github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfgl
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sower-proxy/conns v0.0.3 h1:3jbkvPhDwC+ph/NZi7Gywks9WakHK4ept7CkjTiNUJ8=
github.com/sower-proxy/conns v0.0.3/go.mod h1:p3ZM/8MolzW4TN0LaiPJnwnhhif3y9sBi2vQEWHvwhg=
github.com/sower-proxy/deferlog v1.0.6 h1:itJcycT6Z0IEZCakCYrAPEeiHr1R8rL850E/sC1jqZQ=
github.com/sower-proxy/deferlog v1.0.6/go.mod h1:TVXk/Pm7TAs1ZqayZfrxSbwCl+SSm7+p1xcEPkKHWvQ=
github.com/sower-proxy/deferlog v1.0.7 h1:2gRkdTeSHPhnAj6uwBJ74ufqEmn1spT5o1Y3jGXY9zU=
github.com/sower-proxy/deferlog v1.0.7/go.mod h1:TVXk/Pm7TAs1ZqayZfrxSbwCl+SSm7+p1xcEPkKHWvQ=
github.com/sower-proxy/mem v0.0.3 h1:JK86etQ2QxRUXhs9JhoKYz5p3pFBSrI3UXVhwm44OzM=
github.com/sower-proxy/mem v0.0.3/go.mod h1:tM3P+gCAZMVBnOixGVAHS34si9Iwj2HU6M4IVEv4rK0=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
6 changes: 4 additions & 2 deletions router/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ func (r *Router) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
case r.DirectRule.Match(domain):

case r.ProxyRule.Match(domain):
_ = w.WriteMsg(r.dnsProxyA(domain, r.dns.serveIP, req))
host, _, err := net.SplitHostPort(w.LocalAddr().String())
log.DebugWarn(err).Str("host", host).Msg("proxy dns")
_ = w.WriteMsg(r.dnsProxyA(domain, net.ParseIP(host), req))
return
}

Expand All @@ -40,7 +42,7 @@ func (r *Router) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {

func (r *Router) dnsFail(req *dns.Msg, rcode int) *dns.Msg {
m := new(dns.Msg)
m.SetRcode(req, dns.RcodeServerFailure)
m.SetRcode(req, rcode)
return m
}

Expand Down

0 comments on commit 45c9eea

Please sign in to comment.