Commit 61b5cdb3 authored by Mohammad Yosefpor's avatar Mohammad Yosefpor Committed by GitHub

plugin/bind: Bind by interface name (#4522)

* auto make -f Makefile.doc
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* Bind by interface name
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* README.md: Interface with multiple address
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* auto make -f Makefile.doc
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* auto make -f Makefile.doc
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* Elaborate more on the behaviour in README.md, revert man/*, fix tests
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* auto make -f Makefile.doc
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* --sign-off

Revert man/* to fix DCO check
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>

* auto make -f Makefile.doc

* Revert man/* to fix DCO check
Signed-off-by: default avatarMohammad Yosefpor <myusefpur@gmail.com>
Co-authored-by: default avatarcoredns-auto-go-mod-tidy[bot] <coredns-auto-go-mod-tidy[bot]@users.noreply.github.com>
parent 5457cdcd
...@@ -11,7 +11,9 @@ another IP instead. ...@@ -11,7 +11,9 @@ another IP instead.
If several addresses are provided, a listener will be open on each of the IP provided. If several addresses are provided, a listener will be open on each of the IP provided.
Each address has to be an IP of one of the interfaces of the host. Each address has to be an IP or name of one of the interfaces of the host. Bind by interface name, binds to the IPs on that interface at the time of startup or reload (reload will happen with a SIGHUP or if the config file changes).
If the given argument is an interface name, and that interface has serveral IP addresses, CoreDNS will listen on all of the interface IP addresses (including IPv4 and IPv6).
## Syntax ## Syntax
...@@ -50,6 +52,14 @@ The following sample is equivalent to the preceding: ...@@ -50,6 +52,14 @@ The following sample is equivalent to the preceding:
} }
~~~ ~~~
The following server block, binds on localhost with its interface name (both "127.0.0.1" and "::1"):
~~~ corefile
. {
bind lo
}
~~~
## Bugs ## Bugs
When defining more than one server block, take care not to bind more than one server to the same When defining more than one server block, take care not to bind more than one server to the same
......
...@@ -15,16 +15,40 @@ func setup(c *caddy.Controller) error { ...@@ -15,16 +15,40 @@ func setup(c *caddy.Controller) error {
// addresses will be consolidated over all BIND directives available in that BlocServer // addresses will be consolidated over all BIND directives available in that BlocServer
all := []string{} all := []string{}
for c.Next() { for c.Next() {
addrs := c.RemainingArgs() args := c.RemainingArgs()
if len(addrs) == 0 { if len(args) == 0 {
return plugin.Error("bind", fmt.Errorf("at least one address is expected")) return plugin.Error("bind", fmt.Errorf("at least one address or interface name is expected"))
} }
for _, addr := range addrs {
if net.ParseIP(addr) == nil { ifaces, err := net.Interfaces()
return plugin.Error("bind", fmt.Errorf("not a valid IP address: %s", addr)) if err != nil {
return plugin.Error("bind", fmt.Errorf("failed to get interfaces list"))
}
var isIface bool
for _, arg := range args {
isIface = false
for _, iface := range ifaces {
if arg == iface.Name {
isIface = true
addrs, err := iface.Addrs()
if err != nil {
return plugin.Error("bind", fmt.Errorf("failed to get the IP(s) of the interface: %s", arg))
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok {
all = append(all, ipnet.IP.String())
}
}
}
}
if !isIface {
if net.ParseIP(arg) == nil {
return plugin.Error("bind", fmt.Errorf("not a valid IP address: %s", arg))
}
all = append(all, arg)
} }
} }
all = append(all, addrs...)
} }
config.ListenHosts = all config.ListenHosts = all
return nil return nil
......
...@@ -19,6 +19,7 @@ func TestSetup(t *testing.T) { ...@@ -19,6 +19,7 @@ func TestSetup(t *testing.T) {
{`bind 1.2.3.4 ::5`, []string{"1.2.3.4", "::5"}, false}, {`bind 1.2.3.4 ::5`, []string{"1.2.3.4", "::5"}, false},
{`bind ::1 1.2.3.4 ::5 127.9.9.0`, []string{"::1", "1.2.3.4", "::5", "127.9.9.0"}, false}, {`bind ::1 1.2.3.4 ::5 127.9.9.0`, []string{"::1", "1.2.3.4", "::5", "127.9.9.0"}, false},
{`bind ::1 1.2.3.4 ::5 127.9.9.0 noone`, nil, true}, {`bind ::1 1.2.3.4 ::5 127.9.9.0 noone`, nil, true},
{`bind 1.2.3.4 lo`, []string{"1.2.3.4", "127.0.0.1", "::1"}, false},
} { } {
c := caddy.NewTestController("dns", test.config) c := caddy.NewTestController("dns", test.config)
err := setup(c) err := setup(c)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment