mirror of
https://github.com/wweir/sower.git
synced 2024-04-21 12:42:15 +00:00
Fix #2, add dhcp dynamic setting upstream dns, ipv4 only
This commit is contained in:
@@ -41,7 +41,7 @@ If you wanna uninstall sower, change `install` into `uninstall` and rerun the co
|
||||
### Docker deploy
|
||||
The auto build docker images are [wweir/sower](https://hub.docker.com/r/wweir/sower).
|
||||
|
||||
It is very simple to use it on the server side. Map the port and run it directly.
|
||||
It is very simple to use it on the server side. Export the port(5533) and run it directly.
|
||||
|
||||
But the client is more troublesome and needs some understanding of the working mechanism of the sower.
|
||||
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@ password="12345678"
|
||||
server_port="5533"
|
||||
# server_addr="remote-server:5533" # replce it to remote server
|
||||
http_proxy=":8080" # eg: 192.168.0.2:8080
|
||||
dns_server="223.5.5.5" # Alibaba public dns
|
||||
dns_server="" # Keep empty for dynamic setting from net env
|
||||
client_ip="127.0.0.1" # listen the IP, dns target is the IP
|
||||
# clear_dns_cache="killall -HUP mDNSResponder"
|
||||
blocklist=[
|
||||
@@ -22,6 +22,7 @@ blocklist=[
|
||||
"**.twimg.com",
|
||||
"**.blogspot.com", # blogspot
|
||||
"**.wikipedia.org", # wikipeida
|
||||
"*.cloudfront.net",
|
||||
]
|
||||
whitelist=[
|
||||
"iamp.*.*.*",
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/wweir/netboot/dhcp4"
|
||||
)
|
||||
|
||||
func GetDefaultDNSServer() string {
|
||||
xid := make([]byte, 4)
|
||||
rand.Read(xid)
|
||||
|
||||
pack := &dhcp4.Packet{
|
||||
Type: dhcp4.MsgDiscover,
|
||||
TransactionID: xid,
|
||||
Broadcast: true,
|
||||
}
|
||||
options := map[dhcp4.Option][]byte{
|
||||
dhcp4.OptRequestedOptions: []byte{byte(dhcp4.OptDNSServers)},
|
||||
}
|
||||
|
||||
ifaces := mustGetInterfaces()
|
||||
for _, iface := range ifaces {
|
||||
conn, err := dhcp4.NewConn(iface.IP.String() + ":68")
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
continue
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
pack.HardwareAddr = iface.Interface.HardwareAddr
|
||||
options[dhcp4.OptClientIdentifier] = iface.Interface.HardwareAddr
|
||||
pack.Options = dhcp4.Options(options)
|
||||
|
||||
if err := conn.SendDHCP(pack, iface.Interface); err != nil {
|
||||
glog.Errorln(err)
|
||||
continue
|
||||
}
|
||||
|
||||
pack, _, err = conn.RecvDHCP()
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
continue
|
||||
}
|
||||
|
||||
ip, err := pack.Options.IP(dhcp4.OptDNSServers)
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
continue
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type netIface struct {
|
||||
*net.Interface
|
||||
net.Addr
|
||||
net.IP
|
||||
}
|
||||
|
||||
func mustGetInterfaces() []*netIface {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
glog.Fatalln(err)
|
||||
}
|
||||
|
||||
v4Iface := make([]*netIface, 0, len(ifaces))
|
||||
for i := range ifaces {
|
||||
if len(ifaces[i].HardwareAddr) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, _ := ifaces[i].Addrs()
|
||||
for _, addr := range addrs {
|
||||
if ip := addr.(*net.IPNet).IP.To4(); ip != nil {
|
||||
v4Iface = append(v4Iface, &netIface{&ifaces[i], addr, ip})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return v4Iface
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dns
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGetDefaultDNSServer(t *testing.T) {
|
||||
t.Skip("for net env")
|
||||
tests := []struct {
|
||||
name string
|
||||
want string
|
||||
}{{
|
||||
"",
|
||||
"192.168.1.1",
|
||||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := GetDefaultDNSServer(); got != tt.want {
|
||||
t.Errorf("GetDefaultDNSServer() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+20
-6
@@ -18,7 +18,9 @@ func StartDNS(dnsServer, listenIP string) {
|
||||
ip := net.ParseIP(listenIP)
|
||||
suggest := &intelliSuggest{listenIP, 2 * time.Second, []string{"80", "443"}}
|
||||
mem.DefaultCache = mem.New(time.Hour)
|
||||
dnsServer = net.JoinHostPort(dnsServer, "53")
|
||||
if dnsServer != "" {
|
||||
dnsServer = net.JoinHostPort(dnsServer, "53")
|
||||
}
|
||||
|
||||
dns.HandleFunc(".", func(w dns.ResponseWriter, r *dns.Msg) {
|
||||
// *Msg r has an TSIG record and it was validated
|
||||
@@ -37,15 +39,15 @@ func StartDNS(dnsServer, listenIP string) {
|
||||
domain = domain[:idx]
|
||||
}
|
||||
|
||||
matchAndServe(w, r, domain, listenIP, dnsServer, ip, suggest)
|
||||
matchAndServe(w, r, domain, listenIP, &dnsServer, ip, suggest)
|
||||
})
|
||||
|
||||
server := &dns.Server{Addr: net.JoinHostPort(listenIP, "53"), Net: "udp"}
|
||||
glog.Fatalln(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func matchAndServe(w dns.ResponseWriter, r *dns.Msg, domain, listenIP,
|
||||
dnsServer string, ipNet net.IP, suggest *intelliSuggest) {
|
||||
func matchAndServe(w dns.ResponseWriter, r *dns.Msg, domain, listenIP string,
|
||||
dnsServer *string, ipNet net.IP, suggest *intelliSuggest) {
|
||||
|
||||
inWriteList := whiteList.Match(domain)
|
||||
|
||||
@@ -59,7 +61,19 @@ func matchAndServe(w dns.ResponseWriter, r *dns.Msg, domain, listenIP,
|
||||
go mem.Remember(suggest, domain)
|
||||
}
|
||||
|
||||
msg, err := dns.Exchange(r, dnsServer)
|
||||
if *dnsServer == "" {
|
||||
host := GetDefaultDNSServer()
|
||||
if host == "" {
|
||||
return
|
||||
}
|
||||
*dnsServer = net.JoinHostPort(host, "53")
|
||||
glog.Infoln("set dns server to", host)
|
||||
}
|
||||
|
||||
msg, err := dns.Exchange(r, *dnsServer)
|
||||
if err != nil {
|
||||
*dnsServer = ""
|
||||
}
|
||||
if msg == nil { // expose any response except nil
|
||||
glog.V(1).Infof("get dns of %s fail: %s", domain, err)
|
||||
return
|
||||
@@ -84,7 +98,7 @@ func (i *intelliSuggest) GetOne(domain interface{}) (iface interface{}, e error)
|
||||
|
||||
for _, port := range i.ports {
|
||||
// give local dial a hand, make it not so easy to be added into suggestions
|
||||
<-util.HTTPPing(addr+port, addr, i.timeout/5)
|
||||
<-util.HTTPPing(addr+port, addr, i.timeout/10)
|
||||
localCh := util.HTTPPing(addr+port, addr, i.timeout)
|
||||
remoteCh := util.HTTPPing(i.listenIP+port, addr, i.timeout)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ require (
|
||||
github.com/ulule/deepcopier v0.0.0-20171107155558-ca99b135e50f // indirect
|
||||
github.com/wweir/fsnotify v1.4.8
|
||||
github.com/wweir/mem-go v0.0.0-20190109100331-8673ab596296
|
||||
github.com/wweir/netboot v0.0.2
|
||||
github.com/xtaci/kcp-go v5.0.7+incompatible
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
|
||||
|
||||
@@ -34,6 +34,8 @@ github.com/wweir/fsnotify v1.4.8 h1:zxOoqwE5p91F3rmcYLQheoSeTlIVqwi2b5T7UlpElWE=
|
||||
github.com/wweir/fsnotify v1.4.8/go.mod h1:4GuxIc23DXfJI1/LhBXG5eE/wJ4CzL+kk5M7woxVprc=
|
||||
github.com/wweir/mem-go v0.0.0-20190109100331-8673ab596296 h1:/HkUfg+ZMx/tNdnyJdVlhyv+xO3A7ZlpfL9nFLWLYcc=
|
||||
github.com/wweir/mem-go v0.0.0-20190109100331-8673ab596296/go.mod h1:k7rjBGWoJ+JKwvfe8juAX0zgybjo/Yo3JGkca5f/06s=
|
||||
github.com/wweir/netboot v0.0.2 h1:DFuNd97kxzgblExEKn4Nqf1du0m9qUnaTQ70rFgIjLU=
|
||||
github.com/wweir/netboot v0.0.2/go.mod h1:p/WOnPHdqwgAI6YLEfdmwjwutbc/zDZ7EojAHlXLi4s=
|
||||
github.com/xtaci/kcp-go v5.0.7+incompatible h1:zs9tc8XRID0m+aetu3qPWZFyRt2UIMqbXIBgw+vcnlE=
|
||||
github.com/xtaci/kcp-go v5.0.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE=
|
||||
|
||||
Reference in New Issue
Block a user