Skip to content

Commit

Permalink
support ExternalHostname which has precedence over IPs
Browse files Browse the repository at this point in the history
  • Loading branch information
naggie committed Nov 29, 2020
1 parent 6ca3614 commit 45b61f8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 19 deletions.
20 changes: 17 additions & 3 deletions CONFIG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
Explanation of each field:

{
"ExternalHostname": "",

The `ExternalHostname` is used for the client config server `Endpoint` if
defined. It has precedence over `ExternalIP` and `ExternalIP6`.


"ExternalIP": "198.51.100.2",
"ExternalIP6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",

This is the external IP that will be the value of Endpoint for the server peer
in client configs. It is automatically detected by opening a socket or using an
external IP discovery service -- the first to give a valid public IP will win.
This is the external IPv4 and IPv6 that will be the value of Endpoint for the
server peer in client configs. It is automatically detected by opening a socket
or using an external IP discovery service -- the first to give a valid public
IP will win.

When generating configs, the `ExternalHostname` has precendence for the server
`Endpoint`, followed by `ExternalIP` (IPv4) and `ExternalIP6` (IPv6) The IPs are
discovered automatically on init. Define an `ExternalHostname` if you're using
dynamic DNS, want to change IPs without updating configs, or want wireguard to
be able to choose between IPv4/IPv6. It is only possible to specify one
Endpoint per peer entry in wireguard.


"ListenPort": 51820,
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Main (automatically generated) configuration example:


{
"ExternalHostname": "",
"ExternalIP": "198.51.100.2",
"ExternalIP6": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
"ListenPort": 51820,
Expand Down
28 changes: 17 additions & 11 deletions add.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ DNS={{ .DsnetConfig.DNS }}
[Peer]
PublicKey={{ .DsnetConfig.PrivateKey.PublicKey.Key }}
PresharedKey={{ .Peer.PresharedKey.Key }}
{{ if gt (.DsnetConfig.ExternalIP | len) 0 -}}
Endpoint={{ .DsnetConfig.ExternalIP }}:{{ .DsnetConfig.ListenPort }}
{{ else -}}
Endpoint={{ .DsnetConfig.ExternalIP6 }}:{{ .DsnetConfig.ListenPort }}
{{ end -}}
Endpoint={{ .Endpoint }}:{{ .DsnetConfig.ListenPort }}
PersistentKeepalive={{ .Keepalive }}
{{ if gt (.DsnetConfig.Network.IPNet.IP | len) 0 -}}
AllowedIPs={{ .DsnetConfig.Network }}
Expand Down Expand Up @@ -54,11 +50,7 @@ set interfaces wireguard {{ .Wgif }} description {{ .DsnetConfig.InterfaceName }
#set service dns forwarding name-server {{ .DsnetConfig.DNS }}
{{ end }}
{{ if gt (.DsnetConfig.ExternalIP | len) 0 -}}
set interfaces wireguard {{ .Wgif }} peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} endpoint {{ .DsnetConfig.ExternalIP }}:{{ .DsnetConfig.ListenPort }}
{{ else -}}
set interfaces wireguard {{ .Wgif }} peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} endpoint {{ .DsnetConfig.ExternalIP6 }}:{{ .DsnetConfig.ListenPort }}
{{ end -}}
set interfaces wireguard {{ .Wgif }} peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} endpoint {{ .Endpoint }}:{{ .DsnetConfig.ListenPort }}
set interfaces wireguard {{ .Wgif }} peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} persistent-keepalive {{ .Keepalive }}
set interfaces wireguard {{ .Wgif }} peer {{ .DsnetConfig.PrivateKey.PublicKey.Key }} preshared-key {{ .Peer.PresharedKey.Key }}
{{ if gt (.DsnetConfig.Network.IPNet.IP | len) 0 -}}
Expand Down Expand Up @@ -151,6 +143,19 @@ func PrintPeerCfg(peer PeerConfig, conf *DsnetConfig) {
wgifSeed += int(b)
}

// See DsnetConfig type for explanation
var endpoint string

if conf.ExternalHostname != "" {
endpoint = conf.ExternalHostname
} else if len(conf.ExternalIP) > 0 {
endpoint = conf.ExternalIP.String()
} else if len(conf.ExternalIP6) > 0 {
endpoint = conf.ExternalIP6.String()
} else {
ExitFail("Config does not contain ExternalIP, ExternalIP6 or ExternalHostname")
}

t := template.Must(template.New("peerConf").Parse(peerConf))
err := t.Execute(os.Stdout, map[string]interface{}{
"Peer": peer,
Expand All @@ -161,7 +166,8 @@ func PrintPeerCfg(peer PeerConfig, conf *DsnetConfig) {
// vyatta requires an interface in range/format wg0-wg999
// deterministically choosing one in this range will probably allow use
// of the config without a colliding interface name
"Wgif": fmt.Sprintf("wg%d", wgifSeed%999),
"Wgif": fmt.Sprintf("wg%d", wgifSeed%999),
"Endpoint": endpoint,
})
check(err)
}
17 changes: 12 additions & 5 deletions configtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@ type PeerConfig struct {
}

type DsnetConfig struct {
// When generating configs, the ExternalHostname has precendence for the
// server Endpoint, followed by ExternalIP (IPv4) and ExternalIP6 (IPv6)
// The IPs are discovered automatically on init. Define an ExternalHostname
// if you're using dynamic DNS, want to change IPs without updating
// configs, or want wireguard to be able to choose between IPv4/IPv6. It is
// only possible to specify one Endpoint per peer entry in wireguard.
ExternalHostname string
ExternalIP net.IP
ExternalIP6 net.IP
ListenPort int `validate:"gte=1024,lte=65535"`
// domain to append to hostnames. Relies on separate DNS server for
// resolution. Informational only.
ExternalIP net.IP
ExternalIP6 net.IP
ListenPort int `validate:"gte=1024,lte=65535"`
Domain string `validate:"required,gte=1,lte=255"`
InterfaceName string `validate:"required,gte=1,lte=255"`
// IP network from which to allocate automatic sequential addresses
Expand Down Expand Up @@ -76,8 +83,8 @@ func MustLoadDsnetConfig() *DsnetConfig {
err = validator.New().Struct(conf)
check(err)

if len(conf.ExternalIP) == 0 && len(conf.ExternalIP6) == 0 {
ExitFail("Config does not contain ExternalIP or ExternalIP6")
if conf.ExternalHostname == "" && len(conf.ExternalIP) == 0 && len(conf.ExternalIP6) == 0 {
ExitFail("Config does not contain ExternalIP, ExternalIP6 or ExternalHostname")
}

return &conf
Expand Down

0 comments on commit 45b61f8

Please sign in to comment.