Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20411b650f | ||
|
|
3bb130d055 | ||
|
|
1d85bf75b0 | ||
|
|
c2c5c5cd70 | ||
|
|
a09073da12 | ||
|
|
4bb5e265ab | ||
|
|
b452d504c8 | ||
|
|
f76790426d | ||
|
|
f650e47fe5 | ||
|
|
dc0dd43017 | ||
|
|
c827ee4801 | ||
|
|
db2a6bc288 |
+2
-1
@@ -1,10 +1,11 @@
|
|||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.9
|
- 1.9
|
||||||
|
- 1.11
|
||||||
env:
|
env:
|
||||||
- "PATH=/home/travis/gopath/bin:$PATH"
|
- "PATH=/home/travis/gopath/bin:$PATH"
|
||||||
before_install:
|
before_install:
|
||||||
- go get github.com/golang/lint/golint
|
- go get golang.org/x/lint/golint
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
script:
|
script:
|
||||||
- go vet
|
- go vet
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ See the INSTALL section for information on how to do this.
|
|||||||
|
|
||||||
2) Install acme-dns: `go get github.com/joohoi/acme-dns/...`. This will install acme-dns to `~/go/bin/acme-dns`.
|
2) Install acme-dns: `go get github.com/joohoi/acme-dns/...`. This will install acme-dns to `~/go/bin/acme-dns`.
|
||||||
|
|
||||||
3) Edit config.cfg to suit your needs (see [configuration](#configuration)). `acme-dns` will read the configuration file from `/etc/acme-dns/config.cfg` or `./config.cfg`.
|
3) Edit config.cfg to suit your needs (see [configuration](#configuration)). `acme-dns` will read the configuration file from `/etc/acme-dns/config.cfg` or `./config.cfg`, or a location specified with the `-c` flag.
|
||||||
|
|
||||||
4) If your system has systemd, you can optionally install acme-dns as a service so that it will start on boot and be tracked by systemd. This also allows us to add the `CAP_NET_BIND_SERVICE` capability so that acme-dns can be run by a user other than root.
|
4) If your system has systemd, you can optionally install acme-dns as a service so that it will start on boot and be tracked by systemd. This also allows us to add the `CAP_NET_BIND_SERVICE` capability so that acme-dns can be run by a user other than root.
|
||||||
|
|
||||||
@@ -168,15 +168,15 @@ docker run --rm --name acmedns \
|
|||||||
## DNS Records
|
## DNS Records
|
||||||
|
|
||||||
Note: In this documentation:
|
Note: In this documentation:
|
||||||
- `example.com` is your domain name
|
- `auth.example.org` is the hostname of the acme-dns server
|
||||||
- `auth.example.com` is the subdomain you want to use for acme-dns
|
- acme-dns will serve `*.auth.example.org` records
|
||||||
- `198.51.100.1` is the **public** IP address of the system running acme-dns
|
- `198.51.100.1` is the **public** IP address of the system running acme-dns
|
||||||
|
|
||||||
These values should be changed based on your environment.
|
These values should be changed based on your environment.
|
||||||
|
|
||||||
You will need to add some DNS records on your domain's regular DNS server:
|
You will need to add some DNS records on your domain's regular DNS server:
|
||||||
- `NS` record for `auth.example.com` pointing to `ns.auth.example.com`
|
- `NS` record for `auth.example.org` pointing to `auth.example.org` (this means, that `auth.example.org` is responsible for any `*.auth.example.org` records)
|
||||||
- `A` record for `ns.auth.example.com` pointing to `198.51.100.1`
|
- `A` record for `auth.example.org` pointing to `198.51.100.1`
|
||||||
- If using IPv6, an `AAAA` record pointing to the IPv6 address.
|
- If using IPv6, an `AAAA` record pointing to the IPv6 address.
|
||||||
- Each domain you will be authenticating will need a `_acme-challenge` `CNAME` subdomain added. The [client](README.md#clients) you use will explain how to do this.
|
- Each domain you will be authenticating will need a `_acme-challenge` `CNAME` subdomain added. The [client](README.md#clients) you use will explain how to do this.
|
||||||
|
|
||||||
@@ -184,12 +184,12 @@ You will need to add some DNS records on your domain's regular DNS server:
|
|||||||
|
|
||||||
You may want to test that acme-dns is working before using it for real queries.
|
You may want to test that acme-dns is working before using it for real queries.
|
||||||
|
|
||||||
1) Confirm that DNS lookups for the acme-dns subdomain works as expected: `dig auth.example.com`.
|
1) Confirm that DNS lookups for the acme-dns subdomain works as expected: `dig auth.example.org`.
|
||||||
|
|
||||||
2) Call the `/register` API endpoint to register a test domain:
|
2) Call the `/register` API endpoint to register a test domain:
|
||||||
```
|
```
|
||||||
$ curl -X POST http://auth.example.com/register
|
$ curl -X POST http://auth.example.org/register
|
||||||
{"username":"eabcdb41-d89f-4580-826f-3e62e9755ef2","password":"pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0","fulldomain":"d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com","subdomain":"d420c923-bbd7-4056-ab64-c3ca54c9b3cf","allowfrom":[]}
|
{"username":"eabcdb41-d89f-4580-826f-3e62e9755ef2","password":"pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0","fulldomain":"d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.org","subdomain":"d420c923-bbd7-4056-ab64-c3ca54c9b3cf","allowfrom":[]}
|
||||||
```
|
```
|
||||||
|
|
||||||
3) Call the `/update` API endpoint to set a test TXT record. Pass the `username`, `password` and `subdomain` received from the `register` call performed above:
|
3) Call the `/update` API endpoint to set a test TXT record. Pass the `username`, `password` and `subdomain` received from the `register` call performed above:
|
||||||
@@ -198,40 +198,38 @@ $ curl -X POST \
|
|||||||
-H "X-Api-User: eabcdb41-d89f-4580-826f-3e62e9755ef2" \
|
-H "X-Api-User: eabcdb41-d89f-4580-826f-3e62e9755ef2" \
|
||||||
-H "X-Api-Key: pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0" \
|
-H "X-Api-Key: pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0" \
|
||||||
-d '{"subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", "txt": "___validation_token_received_from_the_ca___"}' \
|
-d '{"subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", "txt": "___validation_token_received_from_the_ca___"}' \
|
||||||
http://auth.example.com/update
|
http://auth.example.org/update
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: The `txt` field must be exactly 43 characters long, otherwise acme-dns will reject it
|
Note: The `txt` field must be exactly 43 characters long, otherwise acme-dns will reject it
|
||||||
|
|
||||||
4) Perform a DNS lookup to the test subdomain to confirm that everything is working properly:
|
4) Perform a DNS lookup to the test subdomain to confirm that everything is working properly:
|
||||||
```
|
```
|
||||||
$ dig @ns.auth.example.com d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com
|
$ dig @auth.example.org d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.org
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[general]
|
[general]
|
||||||
# dns interface
|
# DNS interface. Note that systemd-resolved may reserve port 53 on 127.0.0.53
|
||||||
|
# In this case acme-dns will error out and you will need to define the listening interface
|
||||||
|
# for example: listen = "127.0.0.1:53"
|
||||||
listen = ":53"
|
listen = ":53"
|
||||||
# protocol, "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6"
|
# protocol, "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6"
|
||||||
protocol = "udp"
|
protocol = "udp"
|
||||||
# domain name to serve the requests off of
|
# domain name to serve the requests off of
|
||||||
domain = "auth.example.org"
|
domain = "auth.example.org"
|
||||||
# zone name server
|
# zone name server
|
||||||
nsname = "ns1.auth.example.org"
|
nsname = "auth.example.org"
|
||||||
# admin email address, where @ is substituted with .
|
# admin email address, where @ is substituted with .
|
||||||
nsadmin = "admin.example.org"
|
nsadmin = "admin.example.org"
|
||||||
# predefined records served in addition to the TXT
|
# predefined records served in addition to the TXT
|
||||||
records = [
|
records = [
|
||||||
# default A
|
# domain pointing to the public IP of your acme-dns server
|
||||||
"auth.example.org. A 192.168.1.100",
|
"auth.example.org. A 198.51.100.1",
|
||||||
# A
|
# specify that auth.example.org will resolve any *.auth.example.org records
|
||||||
"ns1.auth.example.org. A 192.168.1.100",
|
"auth.example.org. NS auth.example.org.",
|
||||||
"ns2.auth.example.org. A 192.168.1.100",
|
|
||||||
# NS
|
|
||||||
"auth.example.org. NS ns1.auth.example.org.",
|
|
||||||
"auth.example.org. NS ns2.auth.example.org.",
|
|
||||||
]
|
]
|
||||||
# debug messages from CORS etc
|
# debug messages from CORS etc
|
||||||
debug = false
|
debug = false
|
||||||
@@ -240,7 +238,7 @@ debug = false
|
|||||||
# Database engine to use, sqlite3 or postgres
|
# Database engine to use, sqlite3 or postgres
|
||||||
engine = "sqlite3"
|
engine = "sqlite3"
|
||||||
# Connection string, filename for sqlite3 and postgres://$username:$password@$host/$db_name for postgres
|
# Connection string, filename for sqlite3 and postgres://$username:$password@$host/$db_name for postgres
|
||||||
connection = "acme-dns.db"
|
connection = "/var/lib/acme-dns/acme-dns.db"
|
||||||
# connection = "postgres://user:password@localhost/acmedns_db"
|
# connection = "postgres://user:password@localhost/acmedns_db"
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
@@ -265,6 +263,10 @@ acme_cache_dir = "api-certs"
|
|||||||
corsorigins = [
|
corsorigins = [
|
||||||
"*"
|
"*"
|
||||||
]
|
]
|
||||||
|
# use HTTP header to get the client ip
|
||||||
|
use_header = false
|
||||||
|
# header name to pull the ip address / list of ip addresses from
|
||||||
|
header_name = "X-Forwarded-For"
|
||||||
|
|
||||||
[logconfig]
|
[logconfig]
|
||||||
# logging level: "error", "warning", "info" or "debug"
|
# logging level: "error", "warning", "info" or "debug"
|
||||||
@@ -275,18 +277,16 @@ logtype = "stdout"
|
|||||||
# logfile = "./acme-dns.log"
|
# logfile = "./acme-dns.log"
|
||||||
# format, either "json" or "text"
|
# format, either "json" or "text"
|
||||||
logformat = "text"
|
logformat = "text"
|
||||||
# use HTTP header to get the client ip
|
|
||||||
use_header = false
|
|
||||||
# header name to pull the ip address / list of ip addresses from
|
|
||||||
header_name = "X-Forwarded-For"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Clients
|
## Clients
|
||||||
|
|
||||||
- acme.sh: [https://github.com/Neilpang/acme.sh](https://github.com/Neilpang/acme.sh)
|
- acme.sh: [https://github.com/Neilpang/acme.sh](https://github.com/Neilpang/acme.sh)
|
||||||
|
- cert-manager: [https://github.com/jetstack/cert-manager](https://github.com/jetstack/cert-manager)
|
||||||
- Lego: [https://github.com/xenolf/lego](https://github.com/xenolf/lego)
|
- Lego: [https://github.com/xenolf/lego](https://github.com/xenolf/lego)
|
||||||
- Posh-ACME: [https://github.com/rmbolger/Posh-ACME](https://github.com/rmbolger/Posh-ACME)
|
- Posh-ACME: [https://github.com/rmbolger/Posh-ACME](https://github.com/rmbolger/Posh-ACME)
|
||||||
- Sewer: [https://github.com/komuw/sewer](https://github.com/komuw/sewer)
|
- Sewer: [https://github.com/komuw/sewer](https://github.com/komuw/sewer)
|
||||||
|
- Traefik: [https://github.com/containous/traefik](https://github.com/containous/traefik)
|
||||||
|
|
||||||
### Authentication hooks
|
### Authentication hooks
|
||||||
|
|
||||||
@@ -300,6 +300,13 @@ header_name = "X-Forwarded-For"
|
|||||||
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
- v0.6
|
||||||
|
- New
|
||||||
|
- Command line flag `-c` to specify location of config file.
|
||||||
|
- Proper refusal of dynamic update requests.
|
||||||
|
- Release signing
|
||||||
|
- Changed
|
||||||
|
- Better error messages for goroutines
|
||||||
- v0.5
|
- v0.5
|
||||||
- New
|
- New
|
||||||
- Configurable certificate cache directory
|
- Configurable certificate cache directory
|
||||||
|
|||||||
+8
-10
@@ -1,24 +1,22 @@
|
|||||||
[general]
|
[general]
|
||||||
# dns interface
|
# DNS interface. Note that systemd-resolved may reserve port 53 on 127.0.0.53
|
||||||
|
# In this case acme-dns will error out and you will need to define the listening interface
|
||||||
|
# for example: listen = "127.0.0.1:53"
|
||||||
listen = ":53"
|
listen = ":53"
|
||||||
# protocol, "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6"
|
# protocol, "udp", "udp4", "udp6" or "tcp", "tcp4", "tcp6"
|
||||||
protocol = "udp"
|
protocol = "udp"
|
||||||
# domain name to serve the requests off of
|
# domain name to serve the requests off of
|
||||||
domain = "auth.example.org"
|
domain = "auth.example.org"
|
||||||
# zone name server
|
# zone name server
|
||||||
nsname = "ns1.auth.example.org"
|
nsname = "auth.example.org"
|
||||||
# admin email address, where @ is substituted with .
|
# admin email address, where @ is substituted with .
|
||||||
nsadmin = "admin.example.org"
|
nsadmin = "admin.example.org"
|
||||||
# predefined records served in addition to the TXT
|
# predefined records served in addition to the TXT
|
||||||
records = [
|
records = [
|
||||||
# default A
|
# domain pointing to the public IP of your acme-dns server
|
||||||
"auth.example.org. A 192.168.1.100",
|
"auth.example.org. A 198.51.100.1",
|
||||||
# A
|
# specify that auth.example.org will resolve any *.auth.example.org records
|
||||||
"ns1.auth.example.org. A 192.168.1.100",
|
"auth.example.org. NS auth.example.org.",
|
||||||
"ns2.auth.example.org. A 192.168.1.100",
|
|
||||||
# NS
|
|
||||||
"auth.example.org. NS ns1.auth.example.org.",
|
|
||||||
"auth.example.org. NS ns2.auth.example.org.",
|
|
||||||
]
|
]
|
||||||
# debug messages from CORS etc
|
# debug messages from CORS etc
|
||||||
debug = false
|
debug = false
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ func answer(q dns.Question) ([]dns.RR, int, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
rcode = dns.RcodeNameError
|
rcode = dns.RcodeNameError
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
log.WithFields(log.Fields{"qtype": dns.TypeToString[rtype], "domain": domain, "rcode": dns.RcodeToString[rcode]}).Debug("Answering question for domain")
|
log.WithFields(log.Fields{"qtype": dns.TypeToString[rtype], "domain": domain, "rcode": dns.RcodeToString[rcode]}).Debug("Answering question for domain")
|
||||||
return r, rcode, nil
|
return r, rcode, nil
|
||||||
@@ -68,6 +67,9 @@ func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
|||||||
|
|
||||||
if r.Opcode == dns.OpcodeQuery {
|
if r.Opcode == dns.OpcodeQuery {
|
||||||
readQuery(m)
|
readQuery(m)
|
||||||
|
} else if r.Opcode == dns.OpcodeUpdate {
|
||||||
|
log.Debug("Refusing DNS Dynamic update request")
|
||||||
|
m.MsgHdr.Rcode = dns.RcodeRefused
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteMsg(m)
|
w.WriteMsg(m)
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"flag"
|
||||||
stdlog "log"
|
stdlog "log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
|
"github.com/miekg/dns"
|
||||||
"github.com/rs/cors"
|
"github.com/rs/cors"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/crypto/acme/autocert"
|
"golang.org/x/crypto/acme/autocert"
|
||||||
@@ -18,11 +20,13 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
// Created files are not world writable
|
// Created files are not world writable
|
||||||
syscall.Umask(0077)
|
syscall.Umask(0077)
|
||||||
|
configPtr := flag.String("c", "/etc/acme-dns/config.cfg", "config file location")
|
||||||
|
flag.Parse()
|
||||||
// Read global config
|
// Read global config
|
||||||
var err error
|
var err error
|
||||||
if fileIsAccessible("/etc/acme-dns/config.cfg") {
|
if fileIsAccessible(*configPtr) {
|
||||||
log.WithFields(log.Fields{"file": "/etc/acme-dns/config.cfg"}).Info("Using config file")
|
log.WithFields(log.Fields{"file": *configPtr}).Info("Using config file")
|
||||||
Config, err = readConfig("/etc/acme-dns/config.cfg")
|
Config, err = readConfig(*configPtr)
|
||||||
} else if fileIsAccessible("./config.cfg") {
|
} else if fileIsAccessible("./config.cfg") {
|
||||||
log.WithFields(log.Fields{"file": "./config.cfg"}).Info("Using config file")
|
log.WithFields(log.Fields{"file": "./config.cfg"}).Info("Using config file")
|
||||||
Config, err = readConfig("./config.cfg")
|
Config, err = readConfig("./config.cfg")
|
||||||
@@ -52,16 +56,41 @@ func main() {
|
|||||||
DB = newDB
|
DB = newDB
|
||||||
defer DB.Close()
|
defer DB.Close()
|
||||||
|
|
||||||
|
// Error channel for servers
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
// DNS server
|
// DNS server
|
||||||
startDNS(Config.General.Listen, Config.General.Proto)
|
dnsServer := setupDNSServer()
|
||||||
|
go startDNS(dnsServer, errChan)
|
||||||
|
|
||||||
// HTTP API
|
// HTTP API
|
||||||
startHTTPAPI()
|
go startHTTPAPI(errChan)
|
||||||
|
|
||||||
|
// block waiting for error
|
||||||
|
select {
|
||||||
|
case err = <-errChan:
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
log.Debugf("Shutting down...")
|
log.Debugf("Shutting down...")
|
||||||
}
|
}
|
||||||
|
|
||||||
func startHTTPAPI() {
|
func startDNS(server *dns.Server, errChan chan error) {
|
||||||
|
// DNS server part
|
||||||
|
dns.HandleFunc(".", handleRequest)
|
||||||
|
log.WithFields(log.Fields{"addr": Config.General.Listen}).Info("Listening DNS")
|
||||||
|
err := server.ListenAndServe()
|
||||||
|
if err != nil {
|
||||||
|
errChan <- err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupDNSServer() *dns.Server {
|
||||||
|
return &dns.Server{Addr: Config.General.Listen, Net: Config.General.Proto}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startHTTPAPI(errChan chan error) {
|
||||||
// Setup http logger
|
// Setup http logger
|
||||||
logger := log.New()
|
logger := log.New()
|
||||||
logwriter := logger.Writer()
|
logwriter := logger.Writer()
|
||||||
@@ -87,7 +116,7 @@ func startHTTPAPI() {
|
|||||||
cfg := &tls.Config{
|
cfg := &tls.Config{
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
switch Config.API.TLS {
|
switch Config.API.TLS {
|
||||||
case "letsencrypt":
|
case "letsencrypt":
|
||||||
m := autocert.Manager{
|
m := autocert.Manager{
|
||||||
@@ -106,7 +135,7 @@ func startHTTPAPI() {
|
|||||||
ErrorLog: stdlog.New(logwriter, "", 0),
|
ErrorLog: stdlog.New(logwriter, "", 0),
|
||||||
}
|
}
|
||||||
log.WithFields(log.Fields{"host": host, "domain": Config.API.Domain}).Info("Listening HTTPS, using certificate from autocert")
|
log.WithFields(log.Fields{"host": host, "domain": Config.API.Domain}).Info("Listening HTTPS, using certificate from autocert")
|
||||||
log.Fatal(srv.ListenAndServeTLS("", ""))
|
err = srv.ListenAndServeTLS("", "")
|
||||||
case "cert":
|
case "cert":
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: host,
|
Addr: host,
|
||||||
@@ -115,9 +144,12 @@ func startHTTPAPI() {
|
|||||||
ErrorLog: stdlog.New(logwriter, "", 0),
|
ErrorLog: stdlog.New(logwriter, "", 0),
|
||||||
}
|
}
|
||||||
log.WithFields(log.Fields{"host": host}).Info("Listening HTTPS")
|
log.WithFields(log.Fields{"host": host}).Info("Listening HTTPS")
|
||||||
log.Fatal(srv.ListenAndServeTLS(Config.API.TLSCertFullchain, Config.API.TLSCertPrivkey))
|
err = srv.ListenAndServeTLS(Config.API.TLSCertFullchain, Config.API.TLSCertPrivkey)
|
||||||
default:
|
default:
|
||||||
log.WithFields(log.Fields{"host": host}).Info("Listening HTTP")
|
log.WithFields(log.Fields{"host": host}).Info("Listening HTTP")
|
||||||
log.Fatal(http.ListenAndServe(host, c.Handler(api)))
|
err = http.ListenAndServe(host, c.Handler(api))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
errChan <- err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -7,6 +7,7 @@ import (
|
|||||||
logrustest "github.com/sirupsen/logrus/hooks/test"
|
logrustest "github.com/sirupsen/logrus/hooks/test"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,7 +43,15 @@ func TestMain(m *testing.M) {
|
|||||||
_ = newDb.Init("sqlite3", ":memory:")
|
_ = newDb.Init("sqlite3", ":memory:")
|
||||||
}
|
}
|
||||||
DB = newDb
|
DB = newDb
|
||||||
server := startDNS("0.0.0.0:15353", "udp")
|
server := setupDNSServer()
|
||||||
|
// Make sure that we're not creating a race condition in tests
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
server.NotifyStartedFunc = func() {
|
||||||
|
wg.Done()
|
||||||
|
}
|
||||||
|
go startDNS(server, make(chan error, 1))
|
||||||
|
wg.Wait()
|
||||||
exitval := m.Run()
|
exitval := m.Run()
|
||||||
server.Shutdown()
|
server.Shutdown()
|
||||||
DB.Close()
|
DB.Close()
|
||||||
@@ -57,6 +66,8 @@ func setupConfig() {
|
|||||||
|
|
||||||
var generalcfg = general{
|
var generalcfg = general{
|
||||||
Domain: "auth.example.org",
|
Domain: "auth.example.org",
|
||||||
|
Listen: "127.0.0.1:15353",
|
||||||
|
Proto: "udp",
|
||||||
Nsname: "ns1.auth.example.org",
|
Nsname: "ns1.auth.example.org",
|
||||||
Nsadmin: "admin.example.org",
|
Nsadmin: "admin.example.org",
|
||||||
StaticRecords: records,
|
StaticRecords: records,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/miekg/dns"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -108,14 +107,6 @@ func setupLogging(format string, level string) {
|
|||||||
// TODO: file logging
|
// TODO: file logging
|
||||||
}
|
}
|
||||||
|
|
||||||
func startDNS(listen string, proto string) *dns.Server {
|
|
||||||
// DNS server part
|
|
||||||
dns.HandleFunc(".", handleRequest)
|
|
||||||
server := &dns.Server{Addr: listen, Net: proto}
|
|
||||||
go server.ListenAndServe()
|
|
||||||
return server
|
|
||||||
}
|
|
||||||
|
|
||||||
func getIPListFromHeader(header string) []string {
|
func getIPListFromHeader(header string) []string {
|
||||||
iplist := []string{}
|
iplist := []string{}
|
||||||
for _, v := range strings.Split(header, ",") {
|
for _, v := range strings.Split(header, ",") {
|
||||||
|
|||||||
Reference in New Issue
Block a user