2020-05-26 16:24:45 -07:00
2020-05-26 15:37:38 -07:00
2020-05-26 12:14:32 -07:00
2020-05-26 12:14:32 -07:00
2020-05-20 21:50:48 -07:00
2020-05-26 14:29:42 -07:00
2020-05-26 16:24:45 -07:00

wgsd

wgsd is a CoreDNS plugin that provides WireGuard peer information via DNS-SD (RFC6763) semantics. This enables dynamic discovery of WireGuard Endpoint addressing (both IP address and port number) with the added of benefit of NAT-to-NAT WireGuard connectivity where UDP hole punching is supported.

See this blog post for a deep dive on the underlying techniques and development thought.

Installation

External CoreDNS plugins can be enabled in one of two ways:

  1. Build with compile-time configuration file
  2. Build with external golang source code

For method #2 you can simply go build the contents of cmd/coredns. The resulting binary is CoreDNS server with all the "internal" plugins + wgsd.

% go build
% ./coredns -plugins | grep wgsd
  dns.wgsd

A basic client is available under cmd/wgsd-client.

Configuration

.:53 {
  wgsd <zone> <wg device>
}

For example:

$ cat Corefile
.:53 {
  wgsd example.com. wg0
}

Querying wgsd

wgsd provides a listing of peers via PTR records at the namespace _wireguard._udp.<zone>. The target for the PTR records is <base32PubKey>._wireguard._udp.<zone> which correspond to SRV and A or AAAA records. When querying the SRV record for a peer, wgsd will return the A/AAAA in the "additional" section.

$ sudo wg show
interface: wg0
  public key: JeZlz14G8tg1Bqh6apteFCwVhNhpexJ19FDPfuxQtUY=
  private key: (hidden)
  listening port: 51820

peer: xScVkH3fUGUv4RrJFfmcqm8rs3SEHr41km6+yffAHw4=
  endpoint: 203.0.113.1:7777
  allowed ips: 10.0.0.1/32
  latest handshake: 14 hours, 24 minutes, 40 seconds ago
  transfer: 840.64 KiB received, 85.54 KiB sent

peer: syKB97XhGnvC+kynh2KqQJPXoOoOpx/HmpMRTc+r4js=
  endpoint: 198.51.100.1:8888
  allowed ips: 10.0.0.2/32
  latest handshake: 4 days, 15 hours, 8 minutes, 12 seconds ago
  transfer: 1.38 MiB received, 139.42 KiB sent
$
$ cat Corefile
.:5353 {
  wgsd example.com. wg0
}
$ sudo ./coredns &
[1] 49165
$ .:5353
CoreDNS-1.6.9
linux/amd64, go1.14.2,

$
$ dig @127.0.0.1 -p 5353 _wireguard._udp.example.com. PTR +noall +answer +additional
_wireguard._udp.example.com. 0	IN	PTR	YUTRLED535IGKL7BDLERL6M4VJXSXM3UQQPL4NMSN27MT56AD4HA====._wireguard._udp.example.com.
_wireguard._udp.example.com. 0	IN	PTR	WMRID55V4ENHXQX2JSTYOYVKICJ5PIHKB2TR7R42SMIU3T5L4I5Q====._wireguard._udp.example.com.
$
$ dig @127.0.0.1 -p 5353 YUTRLED535IGKL7BDLERL6M4VJXSXM3UQQPL4NMSN27MT56AD4HA====._wireguard._udp.example.com. SRV +noall +answer +additional
yutrled535igkl7bdlerl6m4vjxsxm3uqqpl4nmsn27mt56ad4ha====._wireguard._udp.example.com. 0	IN SRV 0 0 7777 YUTRLED535IGKL7BDLERL6M4VJXSXM3UQQPL4NMSN27MT56AD4HA====.example.com.
YUTRLED535IGKL7BDLERL6M4VJXSXM3UQQPL4NMSN27MT56AD4HA====.example.com. 0	IN A 203.0.113.1
$
$ dig @127.0.0.1 -p 5353 WMRID55V4ENHXQX2JSTYOYVKICJ5PIHKB2TR7R42SMIU3T5L4I5Q====._wireguard._udp.example.com. SRV +noall +answer +additional
wmrid55v4enhxqx2jstyoyvkicj5pihkb2tr7r42smiu3t5l4i5q====._wireguard._udp.example.com. 0	IN SRV 0 0 8888 WMRID55V4ENHXQX2JSTYOYVKICJ5PIHKB2TR7R42SMIU3T5L4I5Q====.example.com.
WMRID55V4ENHXQX2JSTYOYVKICJ5PIHKB2TR7R42SMIU3T5L4I5Q====.example.com. 0	IN A 198.51.100.1
$
$ echo YUTRLED535IGKL7BDLERL6M4VJXSXM3UQQPL4NMSN27MT56AD4HA==== | base32 -d | base64
xScVkH3fUGUv4RrJFfmcqm8rs3SEHr41km6+yffAHw4=
$ echo WMRID55V4ENHXQX2JSTYOYVKICJ5PIHKB2TR7R42SMIU3T5L4I5Q==== | base32 -d | base64
syKB97XhGnvC+kynh2KqQJPXoOoOpx/HmpMRTc+r4js=

Why Base32 for public keys?

Base64 is case-sensitive. While slightly longer, Base32 allows us to store public keys as part of node names in the DNS tree, which are treated as case-insensitive.

TODOs

  • unit tests
  • SOA record support
  • CI & release binaries
Description
A CoreDNS plugin that provides WireGuard peer information via DNS-SD semantics
Readme MIT 292 KiB
Languages
Go 100%