aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.adoc10
-rw-r--r--README.adoc71
-rw-r--r--cmd/rescached/config.go149
-rw-r--r--cmd/rescached/main.go30
-rw-r--r--cmd/rescached/rescached.cfg157
-rw-r--r--doc/rescached.cfg.adoc201
-rw-r--r--go.mod5
-rw-r--r--go.sum6
-rw-r--r--options.go22
-rw-r--r--options_test.go57
-rw-r--r--rescached.go6
-rw-r--r--testdata/rescached.cfg39
12 files changed, 336 insertions, 417 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 0736ba8..9870d2b 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -12,9 +12,15 @@ and watching changes from system resolv.conf.
== Breaking Changes
-There are also some major changes on configuration file,
+There are also some major changes on configuration file.
+All configuration now break into two section '[rescached]' and
+'[dns "server"]'.
+For more information see new rescached.cfg manual page or an example in
+`cmd/rescached/rescached.cfg`.
-* "server.parent" option now use URI format instead of IP:PORT.
+Some detailed changes are,
+
+* "parent" option now use URI format instead of IP:PORT.
This will allow parent name servers to be UDP, TCP, and/or DoH
simultaneously.
diff --git a/README.adoc b/README.adoc
index 673e5c7..ad1e10e 100644
--- a/README.adoc
+++ b/README.adoc
@@ -42,27 +42,27 @@ List of current features,
- Enable to handle request from UDP and TCP connections
- Enable to forward request using UDP or TCP
- Load and serve addresses and hostnames in +/etc/hosts+
-- Load and serve hosts formated files inside directory
+- Load and serve hosts formatted files inside directory
+/etc/rescached/hosts.d/+
- Blocking ads and/or malicious websites through host list in
+/etc/rescached/hosts.d/hosts.block+
- Support loading and serving master (zone) file format from
+/etc/rescached/master.d+
- Integration with openresolv
-- Support DNS over HTTPS (DoH) (draft 14)
+- Support DNS over HTTPS (DoH) (RFC 8484)
=== BEHIND THE DNS
When you open a website, let say 'kilabit.info', in a browser, the first thing
that browser do is to translate name address 'kilabit.info' into an internet
-address (e.g.: 103.200.4.162) so browser can make a connection to
+address (for example to 35.240.172.103) so browser can make a connection to
'kilabit.info' server.
How browser do that?
First, it will send query to one of DNS server listed in your system
-configuration (i.e. +/etc/resolv.conf+ in Linux).
+configuration (in example, +/etc/resolv.conf+ in Linux).
Then, if your DNS server also "caching" the name that you requested, it will
reply the answer (internet address) directly, if it is not then it will ask
their parent DNS server.
@@ -76,7 +76,7 @@ their parent DNS server.
If you browsing frequently on the same site, hitting the refresh button,
opening another page on the same website, etc; this procedures will always
repeated every times, not including all external links like ads, social media
-button, or javascripts from an other server.
+button, or JavaScript from an other server.
To make this repetitive procedures less occurred, you can run +rescached+ in
your personal computer.
@@ -100,7 +100,7 @@ The only request that will be send to your DNS server is the one that does not
already exist in +rescached+ cache.
-=== HOW CACHE WORKS IN +RESCACHED+
+=== HOW CACHE WORKS
This section explain the simplified version of how internal program works.
@@ -125,8 +125,8 @@ The following table illustrate list of caches in memory,
+---------------------+------------------+
----
-Every +cache.prune_delay+ (e.g. 5 minutes), rescached will try to pruning old
-records from cache.
+Every +cache.prune_delay+ (let say every 5 minutes), rescached will try to
+pruning old records from cache.
If the accessed-at value of record in cache is less than,
----
@@ -179,12 +179,12 @@ We use directory "/etc/rescached" as configuration directory.
+
If you want your program running each time the system is starting up you can
create a system startup script (or system service).
-For system using systemd, uou can see an example for +systemd+ service in
+For OS using systemd, you can see an example for +systemd+ service in
+scripts/rescached.service+.
For system using launchd (macOS), you can see an example in
+scripts/info.kilabit.rescached.plist+.
+
-This step is really different between each system, consult your distribution
+This step could be different between systems, consult your distribution
wiki, forum, or mailing-list on how to create system startup script.
==== AUTOMATIC INSTALLATION ON LINUX
@@ -216,7 +216,7 @@ You can then load the rescached service using launchd,
* Set your parent DNS server.
+
Edit rescached configuration, +/etc/rescached/rescached.cfg+, change the value
-of +server.parent+ based on your preferred DNS server.
+of +parent+ based on your preferred DNS server.
* Set the cache prune delay and threshold
+
@@ -251,8 +251,8 @@ Rescached support loading master file format.
Unlike hosts file format, where each domain name is only mapped to type A
(IPv4 address), in master file, one can define other type that known to
rescached.
-All files defined `dir.master` configuration are considered as master file and
-will be loaded by rescached only if the config is not empty.
+All files defined +dir.master+ configuration are considered as master file and
+will be loaded by rescached only if the configuration is not empty.
Example of master file,
@@ -275,10 +275,10 @@ my-site.com A 10.8.0.1
Here we defined the variable origin for root domain "my-site.vm." with minimum
time-to-live (TTL) to 3600 seconds.
-If no "$origin" variable is defined, rescached will use the file name as
-origin.
+If no "$ORIGIN" variable is defined, rescached will use the file name as
+$ORIGIN's value.
-The "@" character will be replaced with the value of origin.
+The "@" character will be replaced with the value of $ORIGIN.
The first resource record (RR) is defining an IPv4 address for "my-site.vm."
to "192.168.56.10".
@@ -299,7 +299,7 @@ For more information about format of master file see RFC 1035 section 5.
=== INTEGRATION WITH OPENRESOLV
-rescached can detect change on file generated by resolvconf.
+Rescached can detect change on file generated by resolvconf.
To use this feature unset the "file.resolvconf" in configuration file and set
either "dnsmasq_resolv", "pdnsd_resolv", or "unbound_conf" in
"/etc/resolvconf.conf" to point to file referenced in "file.resolvconf".
@@ -310,25 +310,28 @@ For more information see *rescached.cfg*(5).
=== INTEGRATION WITH DNS OVER HTTPS
DNS over HTTPS (DoH) is the new protocol to query DNS through HTTPS layer.
-To enable this feature rescached must run as DoH server using the provided
-self-signed certificate or your own certificate.
+Rescached support serving DNS over HTTPS or as client to parent DoH
+nameservers.
+To enable this feature rescached provided TLS certificate and private key.
Example configuration in *rescached.cfg*,
----
- server.doh.parent = https://cloudflare-dns.com/dns-query
- server.doh.certificate = /etc/rescached/localhost.cert.pem
- server.doh.certificate.key = /etc/rescached/localhost.key.pem
+ [rescached]
+ tls.certificate = /etc/rescached/localhost.cert.pem
+ tls.private_key = /etc/rescached/localhost.key.pem
+
+ [dns "server"]
+ parent = https://kilabit.info/dns-query
+ tls.allow_insecure = false
----
-If the "server.doh.parent" is using self-signed certificate, you can set
-"server.doh.allow_insecure" to true.
+If the parent nameserver is using self-signed certificate, you can set
+"tls.allow_insecure" to true.
Using the above configuration, rescached will serve DoH queries on
-*https://localhost/dns-query*.
-Only query to port 443 will be forwarded to "+server.doh.parent+".
-Queries to port 53, either with UDP or TCP, will be forwarded to
-"+server.parent+" name servers as usual.
+*https://localhost/dns-query* on port 443 and UDP queries on port 53.
+All queries to both locations will be forwarded to parent nameserver.
This feature can be tested using Firefox Nightly by updating the configuration
in "about:config" into,
@@ -342,7 +345,7 @@ in "about:config" into,
Since we are using `mode=3`, the `network.trr.bootstrapAddress` is required so
Firefox Nightly can resolve "localhost" to "127.0.0.1".
If you use the provided self-signed certificate, you must import and/or enable
-an exception for it manually in Firefox Nightly (e.g. by opening
+an exception for it manually in Firefox Nightly (for example. by opening
`https://localhost/dns-query` in new tab and accept security risk).
To check if DoH works, first, set the `debug` option to `1`, and
@@ -352,9 +355,9 @@ Run Firefox Nightly and open any random website.
At the terminal you will see output from rescached which looks like these,
----
-... rescached[10742]: < request: 4 - &{Name:cs2...
-... rescached[10742]: - expired: 413 1548503139 &{Name:cs2...
-... rescached[10742]: + update : - 1548503139 &{Name:cs2...
+... rescached[808]: dns: ^ DoH https://kilabit.info/dns-query 41269:&{Name:id.wikipedia.org Type:A}
+... rescached[808]: dns: < UDP 45873:&{Name:id.wikipedia.org Type:AAAA}
+... rescached[808]: dns: + UDP 41269:&{Name:id.wikipedia.org Type:A}
----
If you see number "4" in request line, "< request: 4", thats indicated that
@@ -390,7 +393,7 @@ This program developed with references to,
'RFC1035':: Domain Names - Implementation and Specification.
'RFC1886':: DNS Extensions to support IP version 6.
'RFC2782':: A DNS RR for specifying the location of services (DNS SRV)
-'draft-ietf-doh-dns-over-https-14':: DNS Queries over HTTPS (DoH)
+'RFC8484':: DNS Queries over HTTPS (DoH)
== BUGS
@@ -413,7 +416,7 @@ AAAA:: A host address in IPv6
SRV:: Service locator
OPT:: This is a "pseudo DNS record type" needed to support EDNS
-+rescached+ only run and tested in Linux system.
++rescached+ only run and tested in Linux and macOS system.
Technically, if it can compiled, it will run in any operating system.
For request of features and/or bugs report please submitted through web at
diff --git a/cmd/rescached/config.go b/cmd/rescached/config.go
deleted file mode 100644
index 56831bf..0000000
--- a/cmd/rescached/config.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "crypto/tls"
- "log"
- "strconv"
- "strings"
- "time"
-
- "github.com/shuLhan/share/lib/debug"
- "github.com/shuLhan/share/lib/dns"
- "github.com/shuLhan/share/lib/ini"
- libnet "github.com/shuLhan/share/lib/net"
-
- rescached "github.com/shuLhan/rescached-go/v3"
-)
-
-// List of config sections.
-const (
- cfgSecRescached = "rescached"
-)
-
-func parseConfig(file string) (opts *rescached.Options) {
- opts = rescached.NewOptions()
-
- cfg, err := ini.Open(file)
- if err != nil {
- return opts
- }
-
- opts.FileResolvConf, _ = cfg.Get(cfgSecRescached, "", "file.resolvconf", "")
-
- dohCertFile, _ := cfg.Get(cfgSecRescached, "", "server.doh.certificate", "")
- dohPrivateKey, _ := cfg.Get(cfgSecRescached, "", "server.doh.certificate.key", "")
- opts.DoHAllowInsecure = cfg.GetBool(cfgSecRescached, "",
- "server.doh.allow_insecure", false)
-
- parseNSParent(cfg, opts)
- parseListen(cfg, opts)
-
- opts.DirHosts, _ = cfg.Get(cfgSecRescached, "", "dir.hosts", "")
- opts.DirMaster, _ = cfg.Get(cfgSecRescached, "", "dir.master", "")
- parseDoHPort(cfg, opts)
- parseTimeout(cfg, opts)
- parseCachePruneDelay(cfg, opts)
- parseCacheThreshold(cfg, opts)
- parseDebugLevel(cfg)
-
- if len(dohCertFile) > 0 && len(dohPrivateKey) > 0 {
- cert, err := tls.LoadX509KeyPair(dohCertFile, dohPrivateKey)
- if err != nil {
- log.Println("rescached: error loading certificate: " + err.Error())
- } else {
- opts.DoHCertificate = &cert
- }
- }
-
- return opts
-}
-
-func parseNSParent(cfg *ini.Ini, opts *rescached.Options) {
- parents := cfg.Gets(cfgSecRescached, "", "server.parent")
-
- for _, ns := range parents {
- ns = strings.TrimSpace(ns)
- if len(ns) > 0 {
- opts.NameServers = append(opts.NameServers, ns)
- }
- }
-}
-
-func parseListen(cfg *ini.Ini, opts *rescached.Options) {
- listen, _ := cfg.Get(cfgSecRescached, "", "server.listen", "127.0.0.1")
-
- _, ip, port := libnet.ParseIPPort(listen, dns.DefaultPort)
- if ip == nil {
- log.Printf("Invalid server.listen: '%s', using default\n",
- listen)
- return
- }
-
- opts.IPAddress = ip.String()
- opts.Port = port
-}
-
-func parseDoHPort(cfg *ini.Ini, opts *rescached.Options) {
- v, _ := cfg.Get(cfgSecRescached, "", "server.doh.listen.port", "443")
- port, err := strconv.Atoi(v)
- if err != nil {
- port = int(dns.DefaultDoHPort)
- }
-
- opts.DoHPort = uint16(port)
-}
-
-func parseTimeout(cfg *ini.Ini, opts *rescached.Options) {
- v, _ := cfg.Get(cfgSecRescached, "", "server.timeout", "6")
- timeout, err := strconv.Atoi(v)
- if err != nil {
- return
- }
-
- opts.Timeout = time.Duration(timeout) * time.Second
-}
-
-func parseCachePruneDelay(cfg *ini.Ini, opts *rescached.Options) {
- v, ok := cfg.Get(cfgSecRescached, "", "cache.prune_delay", "")
- if !ok {
- return
- }
-
- v = strings.TrimSpace(v)
-
- var err error
-
- opts.PruneDelay, err = time.ParseDuration(v)
- if err != nil {
- return
- }
-}
-
-func parseCacheThreshold(cfg *ini.Ini, opts *rescached.Options) {
- v, ok := cfg.Get(cfgSecRescached, "", "cache.prune_threshold", "")
- if !ok {
- return
- }
-
- v = strings.TrimSpace(v)
-
- var err error
-
- opts.PruneThreshold, err = time.ParseDuration(v)
- if err != nil {
- return
- }
-}
-
-func parseDebugLevel(cfg *ini.Ini) {
- v, ok := cfg.Get(cfgSecRescached, "", "debug", "")
- if !ok {
- return
- }
-
- debug.Value, _ = strconv.Atoi(v)
-}
diff --git a/cmd/rescached/main.go b/cmd/rescached/main.go
index b79c240..b0b780b 100644
--- a/cmd/rescached/main.go
+++ b/cmd/rescached/main.go
@@ -5,8 +5,10 @@
package main
import (
+ "crypto/tls"
"flag"
"fmt"
+ "io/ioutil"
"log"
"os"
"os/signal"
@@ -14,10 +16,38 @@ import (
"time"
"github.com/shuLhan/share/lib/debug"
+ "github.com/shuLhan/share/lib/ini"
rescached "github.com/shuLhan/rescached-go/v3"
)
+func parseConfig(file string) (opts *rescached.Options) {
+ opts = rescached.NewOptions()
+
+ cfg, err := ioutil.ReadFile(file)
+ if err != nil {
+ return opts
+ }
+
+ err = ini.Unmarshal(cfg, opts)
+ if err != nil {
+ return opts
+ }
+
+ if len(opts.TLSCertFile) > 0 && len(opts.TLSPrivateKey) > 0 {
+ cert, err := tls.LoadX509KeyPair(opts.TLSCertFile, opts.TLSPrivateKey)
+ if err != nil {
+ log.Println("rescached: error loading certificate: " + err.Error())
+ } else {
+ opts.TLSCertificate = &cert
+ }
+ }
+
+ debug.Value = opts.Debug
+
+ return opts
+}
+
func createRescachedServer(fileConfig string) *rescached.Server {
opts := parseConfig(fileConfig)
diff --git a/cmd/rescached/rescached.cfg b/cmd/rescached/rescached.cfg
index 8474e4e..de8d747 100644
--- a/cmd/rescached/rescached.cfg
+++ b/cmd/rescached/rescached.cfg
@@ -1,96 +1,19 @@
-[RESCACHED]
+[rescached]
##
-## server.parent:: List of parent DNS servers, separated by commas.
-##
-## Format::
-##
-## nameservers = [ scheme "://"] ( ip-address / domain-name ) [ ":" port ]
-## scheme = ( "tcp" / "udp" / "https")
-##
-## Default scheme:: udp
-## Default address:: (None)
-## Default port:: 53
-##
-
-server.parent=udp://1.1.1.1
-server.parent=udp://1.0.0.1:53
-server.parent=https://cloudflare-dns.com/dns-query
-
-##
-## server.listen:: Local IP address that rescached will listening for client
-## request.
-##
-## Format:: <IP-ADDRESS>:<PORT>
-## Default:: 127.0.0.1:53
-##
-
-server.listen=127.0.0.1:53
-
-## Uncomment line below if you want to serve rescached to other computers.
-#server.listen = 0.0.0.0:53
-
-##
-## server.doh.listen.port:: port to serve DNS over HTTPS.
-## Default:: 443
-##
-
-#server.doh.listen.port = 443
-
-##
-## server.doh.certificate:: path to certificate file to serve DNS over HTTPS.
+## tls.certificate:: path to certificate file to serve DNS over HTTPS.
## Default:: "" (empty)
##
-#server.doh.certificate = /etc/rescached/localhost.cert.pem
+#tls.certificate = /etc/rescached/localhost.cert.pem
##
-## server.doh.certificate.key:: path to certificate private key file to serve
+## tls.private_key:: path to certificate's private key file to serve
## DNS over HTTPS.
## Default:: "" (empty)
##
-#server.doh.certificate.key = /etc/rescached/localhost.key.pem
-
-##
-## server.doh.allow_insecure:: If its true, allow serving self signed
-## certificate on DoH connection.
-##
-## Format:: true | false
-## Default:: false
-##
-
-#server.doh.allow_insecure = false
-
-##
-## server.timeout:: Timeout value, in seconds, for sending and waiting
-## packet from client or parent server.
-## Format:: any number from 3 to 6.
-## Default:: 6
-##
-
-#server.timeout=6
-
-##
-## cache.prune_delay:: Delay for pruning worker.
-## Every N seconds/minutes/hours, rescached will traverse all caches and
-## remove response that has not been accessed less than "cache.threshold".
-##
-## Format:: Duration with time unit. Valid time units are "s", "m", "h".
-## Default:: 1h
-##
-
-#cache.prune_delay = 1h
-
-##
-## cache.prune_threshold:: The duration when the cache will be considered
-## expired.
-##
-## Format:: Duration. Valid time units are "s", "m", "h".
-## Default:: -1h
-##
-
-#cache.prune_threshold = -1h
+#tls.private_key = /etc/rescached/localhost.key.pem
##
## dir.hosts:: If its set, rescached will load all (host) files in path.
@@ -137,3 +60,73 @@ server.listen=127.0.0.1:53
##
#debug=0
+
+[dns "server"]
+
+##
+## parent:: List of parent DNS servers.
+##
+## Format::
+##
+## nameservers = [ scheme "://"] ( ip-address / domain-name ) [ ":" port ]
+## scheme = ( "tcp" / "udp" / "https")
+##
+## Default scheme:: udp
+## Default address:: (None)
+## Default port:: 53
+##
+
+parent=udp://35.240.172.103
+parent=tcp://35.240.172.103:53
+parent=https://kilabit.info/dns-query
+
+##
+## listen:: Local IP address that rescached will listening for client
+## request.
+##
+## Format:: <IP-ADDRESS>:<PORT>
+## Default:: 127.0.0.1:53
+##
+
+listen=127.0.0.1:53
+
+## Uncomment line below if you want to serve DNS to other computers.
+#listen = 0.0.0.0:53
+
+##
+## http.port:: port to serve DNS over HTTPS.
+## Default:: 443
+##
+
+#http.port = 443
+
+##
+## tls.allow_insecure:: If its true, allow serving self signed
+## certificate on DoH connection.
+##
+## Format:: true | false
+## Default:: false
+##
+
+#tls.allow_insecure = false
+
+##
+## cache.prune_delay:: Delay for pruning worker.
+## Every N seconds/minutes/hours, DNS server will traverse all caches and
+## remove response that has not been accessed less than "cache.threshold".
+##
+## Format:: Duration with time unit. Valid time units are "s", "m", "h".
+## Default:: 1h
+##
+
+#cache.prune_delay = 1h
+
+##
+## cache.prune_threshold:: The duration when the cache will be considered
+## expired.
+##
+## Format:: Duration. Valid time units are "s", "m", "h".
+## Default:: -1h
+##
+
+#cache.prune_threshold = -1h
diff --git a/doc/rescached.cfg.adoc b/doc/rescached.cfg.adoc
index 6c7ef67..8a2af0a 100644
--- a/doc/rescached.cfg.adoc
+++ b/doc/rescached.cfg.adoc
@@ -27,37 +27,113 @@ The configuration is using INI format where each options is grouped by header
in square bracket:
* +[rescached]+
+* +[dns "server"]+
== OPTIONS
=== +[rescached]+
-This group of options contain the main configuration.
+This group of options contain the main configuration that related to
+rescached.
-[[server.parent]]
-==== +server.parent+
+[[tls.certificate]]
+==== +tls.certificate+
+
+Format:: /path/to/file
+Default:: (empty)
+Description:: Path to certificate file to serve DNS over HTTPS.
+
+
+[[tls.private_key]]
+==== +tls.private_key+
+
+Format:: /path/to/file
+Default:: (empty)
+Description:: Path to certificate private key file to serve DNS over HTTPS.
+
+[[dir.hosts]]
+==== +dir.hosts+
+
+Format:: string
+Default:: /etc/rescached/hosts.d
+Description:: Path to hosts directory.
+If set, rescached will load all hosts formatted files inside the directory.
+If its empty or unset, it will not loading hosts files even in default
+location.
+
+[[dir.master]]
+==== +dir.master+
+
+Format:: string
+Default:: /etc/rescached/master.d
+Description:: Path to master directory.
+If set, rescached will load all master files inside directory.
+If its empty or unset, it will not loading master file even in default
+location.
+
+[[file.resolvconf]]
+==== +file.resolvconf+
+
+Format:: /any/path/to/file
+Default:: /etc/rescached/resolv.conf
+Description:: A path to dynamically generated *resolv.conf*(5) by
+*resolvconf*(8). If set, the nameserver values in referenced file will
+replace "parent" value and "parent" will become a fallback in
+case the referenced file being deleted or can't be parsed.
+
+To use this config, you must set either "dnsmasq_resolv", "pdnsd_resolv", or
+"unbound_conf" in "/etc/resolvconf.conf" to point to
+"/etc/rescached/resolv.conf".
+
+For example,
+----
+resolv_conf=/etc/resolv.conf
+name_servers=127.0.0.1
+dnsmasq_resolv=/etc/rescached/resolv.conf
+#pdnsd_resolv=/etc/rescached/resolv.conf
+#unbound_conf=/etc/rescached/resolv.conf
+----
+
+[[debug]]
+==== +debug+
+
+Value::
+0::: log nothing.
+1::: log startup, request, response, caches, and exit status.
+Format:: Number (0 or 1).
+Default:: 0
+Description:: This option only used by developer for debugging program or if
+user want to monitor what kind of traffic goes out, set this option to 1.
+
+[[dns_server]]
+=== DNS Server options
+
+This group of options related to DNS server using `[dns "server"]` as section
+header.
+
+[[parent]]
+==== +parent+
Format::
----
-nameservers = nameserver *( "," nameserver )
-nameserver = [ scheme "://"] ( ip-address / domain-name ) [ ":" port ]
-scheme = ( "tcp" / "udp" / "https")
+parent = "parent = " [ scheme "://"] ( ip-address / domain-name ) [ ":" port ]
+scheme = ( "tcp" / "udp" / "https")
----
Default::
-* Address: udp://1.1.1.1 , udp://1.0.0.1
+* Address: udp://35.240.172.103
* Port: 53
Description:: List of parent DNS servers, separated by commas.
+
When +rescached+ receive a query from client and when it does
not have a cached address of query, it will pass the query to those parent
server.
-+rescached+ use Cloudflare DNS public servers as a default parent name servers
++rescached+ use its own public servers as a default parent name servers
if not set.
-The reason for this is that Cloudflare DNS public server use a simple and
-small size of response/answer.
+The reason for this is that its public server use a simple and
+small size of response/answer without logging client requests.
+
Please, do not use OpenDNS server.
If certain host-name not found (i.e. typo in host-name), OpenDNS will reply
@@ -70,17 +146,17 @@ To check if your parent server reply the unknown host-name with no answer, use
Example::
----
## Using UDP connection to forward request to parent name server.
- server.parent = udp://1.1.1.1
+ parent = udp://35.240.172.103
## Using TCP connection to forward request to parent name server.
- server.parent = tcp://1.0.0.1
+ parent = tcp://35.240.172.103
## Using DNS over HTTPS to forward request to parent name server.
- server.parent = https://cloudflare-dns.com/dns-query
+ parent = https://kilabit.info/dns-query
----
-[[server.listen]]
-==== +server.listen+
+[[listen]]
+==== +listen+
Format:: <IP-ADDRESS>:<PORT>
Default:: 127.0.0.1:53
@@ -90,45 +166,22 @@ If you want rescached to serve a query from another host in your local
network, change this value to +0.0.0.0:53+.
-[[server.doh.certificate]]
-==== +server.doh.certificate+
-
-Format:: /path/to/file
-Default:: (empty)
-Description:: Path to certificate file to serve DNS over HTTPS.
-
-
-[[server.doh.certificate.key]]
-==== +server.doh.certificate.key+
-
-Format:: /path/to/file
-Default:: (empty)
-Description:: Path to certificate private key file to serve DNS over HTTPS.
-
-
-[[server.doh.allow_insecure]]
-==== +server.doh.allow_insecure+
+[[tls.allow_insecure]]
+==== +tls.allow_insecure+
Format:: true | false
Default:: false
Description:: If its true, the certificate is self-signed.
-[[server.doh.listen.port]]
-==== +server.doh.listen.port+
+[[http.port]]
+==== +http.port+
Format:: Number
Default:: 443
Description:: Port to serve DNS over HTTPS.
-[[server.timeout]]
-==== +server.timeout+
-
-Format:: Number
-Default:: 6
-Description:: This option set the server read and write timeout value.
-
[[cache.prune_delay]]
==== +cache.prune_delay+
@@ -146,62 +199,6 @@ Default:: -1h
Description:: The duration when the cache will be considered expired.
Its value must negative and less than -1 minute.
-[[dir.hosts]]
-==== +dir.hosts+
-
-Format:: string
-Default:: /etc/rescached/hosts.d
-Description:: Path to hosts directory.
-If set, rescached will load all hosts formatted files inside the directory.
-If its empty or unset, it will not loading hosts files even in default
-location.
-
-[[dir.master]]
-==== +dir.master+
-
-Format:: string
-Default:: /etc/rescached/master.d
-Description:: Path to master directory.
-If set, rescached will load all master files inside directory.
-If its empty or unset, it will not loading master file even in default
-location.
-
-[[file.resolvconf]]
-==== +file.resolvconf+
-
-Format:: /any/path/to/file
-Default:: /etc/rescached/resolv.conf
-Description:: A path to dynamically generated *resolv.conf*(5) by
-*resolvconf*(8). If set, the nameserver values in referenced file will
-replace "server.parent" value and "server.parent" will become a fallback in
-case the referenced file being deleted or can't be parsed.
-
-To use this config, you must set either "dnsmasq_resolv", "pdnsd_resolv", or
-"unbound_conf" in "/etc/resolvconf.conf" to point to
-"/etc/rescached/resolv.conf".
-
-For example,
-----
-resolv_conf=/etc/resolv.conf
-name_servers=127.0.0.1
-dnsmasq_resolv=/etc/rescached/resolv.conf
-#pdnsd_resolv=/etc/rescached/resolv.conf
-#unbound_conf=/etc/rescached/resolv.conf
-----
-
-
-[[debug]]
-==== +debug+
-
-Value::
-0::: log nothing.
-1::: log startup, request, response, caches, and exit status.
-Format:: Number (0 or 1).
-Default:: 0
-Description:: This option only used by developer for debugging program or if
-user want to monitor what kind of traffic goes out, set this option to 1.
-
-
== EXAMPLE
Simple rescached configuration using dnscrypt-proxy that listen on port 54 as
@@ -209,8 +206,8 @@ parent resolver, with prune delay set to 60 seconds and threshold also to 60
seconds.
..............................................................................
-[rescached]
-server.parent=udp://127.0.0.1:54
+[dns "server"]
+parent=udp://127.0.0.1:54
cache.prune_delay=60s
cache.prune_threshold=60s
..............................................................................
@@ -222,12 +219,12 @@ Save the above script into +rescached.cfg+ and run it,
== AUTHOR
-+rescached+ is developed by M. Shulhan (ms@kilabit.info).
++rescached+ is developed by M. Shulhan (m.shulhan@gmail.com).
== LICENSE
-Copyright 2018, M. Shulhan (ms@kilabit.info).
+Copyright 2018, M. Shulhan (m.shulhan@gmail.com).
All rights reserved.
Use of this source code is governed by a BSD-style license that can be found
diff --git a/go.mod b/go.mod
index 65b8ec6..e50c035 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,7 @@ module github.com/shuLhan/rescached-go/v3
go 1.11
-require github.com/shuLhan/share v0.8.3-0.20190928194720-61dcfc67b113
+require (
+ github.com/shuLhan/share v0.9.1-0.20191016132846-c698f9750a2a
+ golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 // indirect
+)
diff --git a/go.sum b/go.sum
index 0d6b9b2..c75213c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,10 +1,12 @@
-github.com/shuLhan/share v0.8.3-0.20190928194720-61dcfc67b113 h1:RTCqj1aGMN+BDvzVx2gqtgKjlCRJedmylN/F9G5s03E=
-github.com/shuLhan/share v0.8.3-0.20190928194720-61dcfc67b113/go.mod h1:1+SBspKy8sF3BkQ83Jov/CDul+2e4Y3nr+izWC3hDhI=
+github.com/shuLhan/share v0.9.1-0.20191016132846-c698f9750a2a h1:KEpcbL7cEpR7Tsk87TKp5Uov7rgB79dMm4rnxP6k15A=
+github.com/shuLhan/share v0.9.1-0.20191016132846-c698f9750a2a/go.mod h1:1+SBspKy8sF3BkQ83Jov/CDul+2e4Y3nr+izWC3hDhI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190926114937-fa1a29108794/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 h1:qPnAdmjNA41t3QBTx2mFGf/SD1IoslhYu7AmdsVzCcs=
golang.org/x/net v0.0.0-20190926025831-c00fd9afed17/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
+golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/options.go b/options.go
index 7294b02..4a421a2 100644
--- a/options.go
+++ b/options.go
@@ -6,7 +6,6 @@ package rescached
import (
"fmt"
- "time"
"github.com/shuLhan/share/lib/debug"
"github.com/shuLhan/share/lib/dns"
@@ -19,10 +18,12 @@ import (
//
type Options struct {
dns.ServerOptions
- Timeout time.Duration
- FileResolvConf string
- DirHosts string
- DirMaster string
+ TLSCertFile string `ini:"rescached::tls.certificate"`
+ TLSPrivateKey string `ini:"rescached::tls.private_key"`
+ DirHosts string `ini:"rescached::dir.hosts"`
+ DirMaster string `ini:"rescached::dir.master"`
+ FileResolvConf string `ini:"rescached::file.resolvconf"`
+ Debug int `ini:"rescached::debug"`
}
//
@@ -31,10 +32,8 @@ type Options struct {
func NewOptions() *Options {
return &Options{
ServerOptions: dns.ServerOptions{
- IPAddress: "127.0.0.1",
+ ListenAddress: "127.0.0.1:53",
},
-
- Timeout: 6 * time.Second,
}
}
@@ -42,11 +41,8 @@ func NewOptions() *Options {
// init check and initialize the Options instance with default values.
//
func (opts *Options) init() {
- if len(opts.IPAddress) == 0 {
- opts.IPAddress = "127.0.0.1"
- }
- if opts.Timeout <= 0 || opts.Timeout > (6*time.Second) {
- opts.Timeout = 6 * time.Second
+ if len(opts.ListenAddress) == 0 {
+ opts.ListenAddress = "127.0.0.1:53"
}
if len(opts.FileResolvConf) > 0 {
_, _ = opts.loadResolvConf()
diff --git a/options_test.go b/options_test.go
new file mode 100644
index 0000000..0cd78d5
--- /dev/null
+++ b/options_test.go
@@ -0,0 +1,57 @@
+// Copyright 2019, Shulhan <m.shulhan@gmail.com>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rescached
+
+import (
+ "testing"
+
+ "github.com/shuLhan/share/lib/dns"
+ "github.com/shuLhan/share/lib/ini"
+ "github.com/shuLhan/share/lib/test"
+)
+
+func TestOptions(t *testing.T) {
+ cases := []struct {
+ desc string
+ content string
+ exp *Options
+ expError string
+ }{{
+ desc: "With empty content",
+ exp: &Options{},
+ }, {
+ desc: "With multiple parents",
+ content: `[dns "server"]
+listen = 127.0.0.1:53
+parent = udp://35.240.172.103
+parent = https://kilabit.info/dns-query
+`,
+ exp: &Options{
+ ServerOptions: dns.ServerOptions{
+ ListenAddress: "127.0.0.1:53",
+ NameServers: []string{
+ "udp://35.240.172.103",
+ "https://kilabit.info/dns-query",
+ },
+ },
+ },
+ }}
+
+ for _, c := range cases {
+ t.Log(c.desc)
+
+ got := &Options{
+ ServerOptions: dns.ServerOptions{},
+ }
+
+ err := ini.Unmarshal([]byte(c.content), got)
+ if err != nil {
+ test.Assert(t, "error", c.expError, err.Error(), true)
+ continue
+ }
+
+ test.Assert(t, "Options", c.exp, got, true)
+ }
+}
diff --git a/rescached.go b/rescached.go
index 954f24c..cc08173 100644
--- a/rescached.go
+++ b/rescached.go
@@ -57,10 +57,8 @@ func New(opts *Options) (srv *Server, err error) {
// it.
//
func (srv *Server) Start() (err error) {
- fmt.Printf("= Listening on UDP and TCP at '%s:%d'\n",
- srv.opts.IPAddress, srv.opts.Port)
- fmt.Printf("= Listening on DoH at '%s:%d'\n", srv.opts.IPAddress,
- srv.opts.DoHPort)
+ fmt.Printf("= Listening on %q (UDP and TCP) and port %d for HTTP(S)\n",
+ srv.opts.ListenAddress, srv.opts.HTTPPort)
if len(srv.opts.FileResolvConf) > 0 {
_, err = libio.NewWatcher(srv.opts.FileResolvConf, 0, srv.watchResolvConf)
diff --git a/testdata/rescached.cfg b/testdata/rescached.cfg
index 83676a4..41a786b 100644
--- a/testdata/rescached.cfg
+++ b/testdata/rescached.cfg
@@ -1,46 +1,29 @@
-[RESCACHED]
+[rescached]
+
+[dns "server"]
##
-## server.parent:: List of parent DNS servers, separated by commas.
+## parent:: List of parent DNS servers, separated by commas.
##
## Format:: <IP-ADDRESS:PORT> , ...
-## Default address:: 1.1.1.1, 1.0.0.1
+## Default address:: 35.240.172.103
## Default port:: 53
##
-#server.parent=1.1.1.1, 1.0.0.1:53
-
-##
-## server.parent.connection:: Type of connection to parent server.
-##
-## Format:: tcp | udp
-## Default:: udp
-##
-
-server.parent.connection=udp
-#server.parent.connection=tcp
+#parent=35.240.172.103
##
-## server.listen:: Local IP address that rescached will listening for client
+## listen:: Local IP address that rescached will listening for client
## request.
##
## Format:: <IP-ADDRESS>:<PORT>
## Default:: 127.0.0.1:53
##
-server.listen=127.0.0.1:5353
+listen=127.0.0.1:5353
## Uncomment line below if you want to serve rescached to other computers.
-#server.listen=0.0.0.0:53
-
-##
-## server.timeout:: Timeout value, in seconds, for sending and waiting
-## packet from client or parent server.
-## Format:: any number from 300 to 2147483647.
-## Default:: 6
-##
-
-#server.timeout=6
+#listen=0.0.0.0:53
##
## cache.prune_delay:: Delay for pruning worker.
@@ -63,14 +46,14 @@ server.listen=127.0.0.1:5353
#cache.threshold = -1h
##
-## hosts_d.path:: If its set, rescached will load all (host) files in path.
+## dir.hosts:: If its set, rescached will load all (host) files in path.
## if its empty, it will skip loading hosts files event in default location.
##
## Format : string.
## Default : /etc/rescached/hosts.d
##
-#hosts_d.path=/etc/rescached/hosts.d
+#dir.hosts=/etc/rescached/hosts.d
##
## debug:: If its not zero, rescached will print debugging information to