Simplify config and refactoring
This commit is contained in:
parent
00bd9a5486
commit
5c5e938742
10
README.md
10
README.md
@ -39,18 +39,14 @@ Look for `meshnamed.service` in the source directory for a systemd unit file.
|
|||||||
In this example, meshnamed is configured as authoritative for two domain zones:
|
In this example, meshnamed is configured as authoritative for two domain zones:
|
||||||
|
|
||||||
{
|
{
|
||||||
"Domain":"aiag7sesed2aaxgcgbnevruwpy",
|
"aiag7sesed2aaxgcgbnevruwpy": [
|
||||||
"Records": [
|
|
||||||
"aiag7sesed2aaxgcgbnevruwpy.meshname. AAAA 200:6fc8:9220:f400:5cc2:305a:4ac6:967e",
|
"aiag7sesed2aaxgcgbnevruwpy.meshname. AAAA 200:6fc8:9220:f400:5cc2:305a:4ac6:967e",
|
||||||
"_xmpp-client._tcp.aiag7sesed2aaxgcgbnevruwpy.meshname. SRV 5 0 5222 xmpp.aiag7sesed2aaxgcgbnevruwpy.meshname",
|
"_xmpp-client._tcp.aiag7sesed2aaxgcgbnevruwpy.meshname. SRV 5 0 5222 xmpp.aiag7sesed2aaxgcgbnevruwpy.meshname",
|
||||||
"_xmpp-server._tcp.aiag7sesed2aaxgcgbnevruwpy.meshname. SRV 5 0 5269 xmpp.aiag7sesed2aaxgcgbnevruwpy.meshname",
|
"_xmpp-server._tcp.aiag7sesed2aaxgcgbnevruwpy.meshname. SRV 5 0 5269 xmpp.aiag7sesed2aaxgcgbnevruwpy.meshname",
|
||||||
"xmpp.aiag7sesed2aaxgcgbnevruwpy.meshname. AAAA 300:6fc8:9220:f400::1",
|
"xmpp.aiag7sesed2aaxgcgbnevruwpy.meshname. AAAA 300:6fc8:9220:f400::1",
|
||||||
"forum.aiag7sesed2aaxgcgbnevruwpy.meshname. CNAME amag7sesed2aaaaaaaaaaaaaau.meshname."
|
"forum.aiag7sesed2aaxgcgbnevruwpy.meshname. CNAME amag7sesed2aaaaaaaaaaaaaau.meshname."
|
||||||
]
|
],
|
||||||
}
|
"amag7sesed2aaaaaaaaaaaaaau": [
|
||||||
{
|
|
||||||
"Domain":"amag7sesed2aaaaaaaaaaaaaau",
|
|
||||||
"Records":[
|
|
||||||
"amag7sesed2aaaaaaaaaaaaaau.meshname. AAAA 300:6fc8:9220:f400::5"
|
"amag7sesed2aaaaaaaaaaaaaau.meshname. AAAA 300:6fc8:9220:f400::5"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/gologme/log"
|
"github.com/gologme/log"
|
||||||
@ -13,6 +14,20 @@ import (
|
|||||||
"github.com/zhoreeq/meshname/src/meshname"
|
"github.com/zhoreeq/meshname/src/meshname"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func parseNetworks(networksconf string) (map[string]*net.IPNet, error) {
|
||||||
|
networks := make(map[string]*net.IPNet)
|
||||||
|
for _, item := range strings.Split(networksconf, ",") {
|
||||||
|
if tokens := strings.SplitN(item, "=", 2); len(tokens) == 2 {
|
||||||
|
if _, validSubnet, err := net.ParseCIDR(tokens[1]); err == nil {
|
||||||
|
networks[tokens[0]] = validSubnet
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return networks, nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
genconf := flag.String("genconf", "", "generate a new config for IP address")
|
genconf := flag.String("genconf", "", "generate a new config for IP address")
|
||||||
subdomain := flag.String("subdomain", "meshname.", "subdomain used to generate config")
|
subdomain := flag.String("subdomain", "meshname.", "subdomain used to generate config")
|
||||||
@ -33,24 +48,28 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *genconf != "" {
|
if *genconf != "" {
|
||||||
confString, err := meshname.GenConf(*genconf, *subdomain)
|
if conf, err := meshname.GenConf(*genconf, *subdomain); err == nil {
|
||||||
if err != nil {
|
fmt.Println(conf)
|
||||||
logger.Errorln(err)
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(confString)
|
logger.Errorln(err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
networks := make(map[string]string)
|
|
||||||
for _, item := range strings.Split(*networksconf, ",") {
|
|
||||||
if tokens := strings.SplitN(item, "=", 2); len(tokens) == 2 {
|
|
||||||
networks[tokens[0]] = tokens[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s := new(meshname.MeshnameServer)
|
s := new(meshname.MeshnameServer)
|
||||||
s.Init(logger, *listenAddr, *useconffile, networks)
|
s.Init(logger, *listenAddr)
|
||||||
|
|
||||||
|
if networks, err := parseNetworks(*networksconf); err == nil {
|
||||||
|
s.SetNetworks(networks)
|
||||||
|
} else {
|
||||||
|
logger.Errorln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *useconffile != "" {
|
||||||
|
s.LoadConfig(*useconffile)
|
||||||
|
}
|
||||||
|
|
||||||
s.Start()
|
s.Start()
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
@ -63,7 +82,11 @@ func main() {
|
|||||||
case _ = <-c:
|
case _ = <-c:
|
||||||
return
|
return
|
||||||
case _ = <-r:
|
case _ = <-r:
|
||||||
s.UpdateConfig()
|
if *useconffile != "" {
|
||||||
|
s.Stop()
|
||||||
|
s.LoadConfig(*useconffile)
|
||||||
|
s.Start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gologme/log"
|
"github.com/gologme/log"
|
||||||
@ -43,79 +42,58 @@ func GenConf(target, zone string) (string, error) {
|
|||||||
}
|
}
|
||||||
subDomain := DomainFromIP(&ip)
|
subDomain := DomainFromIP(&ip)
|
||||||
selfRecord := fmt.Sprintf("\t\t\"%s.%s AAAA %s\"\n", subDomain, zone, target)
|
selfRecord := fmt.Sprintf("\t\t\"%s.%s AAAA %s\"\n", subDomain, zone, target)
|
||||||
confString := fmt.Sprintf("{\n\t\"Domain\":\"%s\",\n\t\"Records\":[\n%s\t]\n}", subDomain, selfRecord)
|
confString := fmt.Sprintf("{\n\t\"%s\":[\n%s\t]\n}", subDomain, selfRecord)
|
||||||
|
|
||||||
return confString, nil
|
return confString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MeshnameServer struct {
|
// Load zoneConfig from a JSON file
|
||||||
log *log.Logger
|
func ParseConfigFile(configPath string) (map[string][]dns.RR, error) {
|
||||||
listenAddr, zoneConfigPath string
|
conf, err := ioutil.ReadFile(configPath)
|
||||||
zoneConfig map[string][]dns.RR
|
if err != nil {
|
||||||
dnsClient *dns.Client
|
return nil, err
|
||||||
dnsServer *dns.Server
|
}
|
||||||
networks map[string]*net.IPNet
|
var dat map[string][]string
|
||||||
|
if err := json.Unmarshal(conf, &dat); err == nil {
|
||||||
|
return ParseZoneConfigMap(dat)
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MeshnameServer) Init(log *log.Logger, listenAddr string, zoneConfigPath string, networks map[string]string) {
|
func ParseZoneConfigMap(zoneConfigMap map[string][]string) (map[string][]dns.RR, error) {
|
||||||
|
var zoneConfig = make(map[string][]dns.RR)
|
||||||
|
for subDomain, records := range zoneConfigMap {
|
||||||
|
for _, r := range records {
|
||||||
|
if rr, err := dns.NewRR(r); err == nil {
|
||||||
|
zoneConfig[subDomain] = append(zoneConfig[subDomain], rr)
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return zoneConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type MeshnameServer struct {
|
||||||
|
log *log.Logger
|
||||||
|
listenAddr string
|
||||||
|
zoneConfig map[string][]dns.RR
|
||||||
|
dnsClient *dns.Client
|
||||||
|
dnsServer *dns.Server
|
||||||
|
networks map[string]*net.IPNet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MeshnameServer) Init(log *log.Logger, listenAddr string) {
|
||||||
s.log = log
|
s.log = log
|
||||||
s.listenAddr = listenAddr
|
s.listenAddr = listenAddr
|
||||||
s.networks = make(map[string]*net.IPNet)
|
|
||||||
for domain, subnet := range networks {
|
|
||||||
_, validSubnet, err := net.ParseCIDR(subnet)
|
|
||||||
if err != nil {
|
|
||||||
s.log.Errorln(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.networks[domain] = validSubnet
|
|
||||||
}
|
|
||||||
s.zoneConfigPath = zoneConfigPath
|
|
||||||
s.zoneConfig = make(map[string][]dns.RR)
|
s.zoneConfig = make(map[string][]dns.RR)
|
||||||
|
s.networks = make(map[string]*net.IPNet)
|
||||||
|
|
||||||
if s.dnsClient == nil {
|
if s.dnsClient == nil {
|
||||||
s.dnsClient = new(dns.Client)
|
s.dnsClient = new(dns.Client)
|
||||||
s.dnsClient.Timeout = 5000000000 // increased 5 seconds timeout
|
s.dnsClient.Timeout = 5000000000 // increased 5 seconds timeout
|
||||||
}
|
}
|
||||||
s.LoadConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *MeshnameServer) LoadConfig() {
|
|
||||||
if s.zoneConfigPath == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for k := range s.zoneConfig {
|
|
||||||
delete(s.zoneConfig, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
reader, err := os.Open(s.zoneConfigPath)
|
|
||||||
if err != nil {
|
|
||||||
s.log.Errorln("Can't open config:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Zone struct {
|
|
||||||
Domain string
|
|
||||||
Records []string
|
|
||||||
}
|
|
||||||
|
|
||||||
dec := json.NewDecoder(reader)
|
|
||||||
for {
|
|
||||||
var m Zone
|
|
||||||
if err := dec.Decode(&m); err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
s.log.Errorln("Syntax error in config:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, v := range m.Records {
|
|
||||||
rr, err := dns.NewRR(v)
|
|
||||||
if err != nil {
|
|
||||||
s.log.Errorln("Invalid DNS record:", v)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.zoneConfig[m.Domain] = append(s.zoneConfig[m.Domain], rr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.log.Infoln("Meshname config loaded:", s.zoneConfigPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MeshnameServer) Stop() error {
|
func (s *MeshnameServer) Stop() error {
|
||||||
@ -127,15 +105,31 @@ func (s *MeshnameServer) Stop() error {
|
|||||||
|
|
||||||
func (s *MeshnameServer) Start() error {
|
func (s *MeshnameServer) Start() error {
|
||||||
s.dnsServer = &dns.Server{Addr: s.listenAddr, Net: "udp"}
|
s.dnsServer = &dns.Server{Addr: s.listenAddr, Net: "udp"}
|
||||||
for domain := range s.networks {
|
for tld, subnet := range s.networks {
|
||||||
dns.HandleFunc(domain, s.handleRequest)
|
dns.HandleFunc(tld, s.handleRequest)
|
||||||
s.log.Debugln("Handling:", domain)
|
s.log.Debugln("Handling:", tld, subnet)
|
||||||
}
|
}
|
||||||
go s.dnsServer.ListenAndServe()
|
go s.dnsServer.ListenAndServe()
|
||||||
s.log.Infoln("Started meshnamed on:", s.listenAddr)
|
s.log.Infoln("Started meshnamed on:", s.listenAddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *MeshnameServer) LoadConfig(confPath string) {
|
||||||
|
if zoneConf, err := ParseConfigFile(confPath); err == nil {
|
||||||
|
s.zoneConfig = zoneConf
|
||||||
|
} else {
|
||||||
|
s.log.Errorln("Can't parse config file:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MeshnameServer) SetZoneConfig(zoneConfig map[string][]dns.RR) {
|
||||||
|
s.zoneConfig = zoneConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MeshnameServer) SetNetworks(networks map[string]*net.IPNet) {
|
||||||
|
s.networks = networks
|
||||||
|
}
|
||||||
|
|
||||||
func (s *MeshnameServer) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
func (s *MeshnameServer) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
var remoteLookups = make(map[string][]dns.Question)
|
var remoteLookups = make(map[string][]dns.Question)
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
@ -192,9 +186,3 @@ func (s *MeshnameServer) isRemoteLookupAllowed(addr net.Addr) bool {
|
|||||||
return strings.HasPrefix(ra, "[::1]:") || strings.HasPrefix(ra, "127.0.0.1:")
|
return strings.HasPrefix(ra, "[::1]:") || strings.HasPrefix(ra, "127.0.0.1:")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MeshnameServer) UpdateConfig() error {
|
|
||||||
s.Stop()
|
|
||||||
s.LoadConfig()
|
|
||||||
s.Start()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user