diff --git a/cmd/serve/main.go b/cmd/serve/main.go index ea87b37a..965859e1 100644 --- a/cmd/serve/main.go +++ b/cmd/serve/main.go @@ -74,16 +74,6 @@ func (cmd *servecmd) Name() string { func (cmd *servecmd) Run() { conf := cmd.ReadConfig() - if conf.VPN.CIDR == "0" { - conf.VPN.CIDR = "" - } - if conf.VPN.CIDRv6 == "0" { - conf.VPN.CIDRv6 = "" - } - if conf.DNS.Domain == "0" { - conf.DNS.Domain = "" - } - // Get the server's IP addresses within the VPN var vpnip, vpnipv6 *net.IPNet var err error @@ -284,6 +274,7 @@ func (cmd *servecmd) Run() { } } +// ReadConfig reads the config file from disk if specified and overrides any env vars or cmdline options func (cmd *servecmd) ReadConfig() *config.AppConfig { if cmd.ConfigFilePath != "" { if b, err := ioutil.ReadFile(cmd.ConfigFilePath); err == nil { @@ -335,6 +326,24 @@ func (cmd *servecmd) ReadConfig() *config.AppConfig { cmd.AppConfig.WireGuard.PrivateKey = key.String() } + // The empty string can be hard to pass through an env var, so we accept '0' too + if cmd.AppConfig.VPN.CIDR == "0" { + cmd.AppConfig.VPN.CIDR = "" + } + if cmd.AppConfig.VPN.CIDRv6 == "0" { + cmd.AppConfig.VPN.CIDRv6 = "" + } + if cmd.AppConfig.DNS.Domain == "0" { + cmd.AppConfig.DNS.Domain = "" + } + // kingpin only splits env vars by \n, let's split at commas as well + if len(cmd.AppConfig.VPN.AllowedIPs) == 1 { + cmd.AppConfig.VPN.AllowedIPs = strings.Split(cmd.AppConfig.VPN.AllowedIPs[0], ",") + } + if len(cmd.AppConfig.DNS.Upstream) == 1 { + cmd.AppConfig.DNS.Upstream = strings.Split(cmd.AppConfig.DNS.Upstream[0], ",") + } + return &cmd.AppConfig } diff --git a/docs/2-configuration.md b/docs/2-configuration.md index c3d63b88..400d37d1 100644 --- a/docs/2-configuration.md +++ b/docs/2-configuration.md @@ -16,6 +16,15 @@ wg genkey The config file format is `yaml` and an example is provided [below](#the-config-file-configyaml). +The format for specifying multiple values for options that allow it is: +* as commandline flags: + * repeat the flag (e.g. `--dns-upstream 2001:db8::1 --dns-upstream 192.0.2.1`) + * separate the values with a comma (e.g. `--dns-upstream 2001:db8::1,192.0.2.1`) +* as environment variables: + * separate with a comma (e.g. `WG_DNS_UPSTREAM="2001:db8::1,192.0.2.1"`) + * separate with a new line char (e.g. `WG_DNS_UPSTREAM=$'2001:db8::1\n192.0.2.1'`) +* in the config file as YAML list. + Here's what you can configure: | Environment Variable | CLI Flag | Config File Path | Required | Default (docker) | Description | @@ -40,7 +49,7 @@ Here's what you can configure: | `WG_VPN_GATEWAY_INTERFACE` | `--vpn-gateway-interface` | `vpn.gatewayInterface` | | _default gateway interface (e.g. eth0)_ | The VPN gateway interface. VPN client traffic will be forwarded to this interface. | | `WG_VPN_ALLOWED_IPS` | `--vpn-allowed-ips` | `vpn.allowedIPs` | | `0.0.0.0/0, ::/0` | Allowed IPs that clients may route through this VPN. This will be set in the client's WireGuard connection file and routing is also enforced by the server using iptables. | | `WG_DNS_ENABLED` | `--[no-]dns-enabled` | `dns.enabled` | | `true` | Enable/disable the embedded DNS proxy server. This is enabled by default and allows VPN clients to avoid DNS leaks by sending all DNS requests to wg-access-server itself. | -| `WG_DNS_UPSTREAM` | `--dns-upstream` | `dns.upstream` | | _resolvconf autodetection or Cloudflare DNS_ | The upstream DNS server to proxy DNS requests to. By default the host machine's resolveconf configuration is used to find it's upstream DNS server, with a fallback to Cloudflare. | +| `WG_DNS_UPSTREAM` | `--dns-upstream` | `dns.upstream` | | _resolvconf autodetection or Cloudflare DNS_ | The upstream DNS servers to proxy DNS requests to. By default the host machine's resolveconf configuration is used to find its upstream DNS server, with a fallback to Cloudflare. | | `WG_DNS_DOMAIN` | `--dns-domain` | `dns.domain` | | | A domain to serve configured devices authoritatively. Queries for names in the format .. will be answered with the device's IP addresses. | ## The Config File (config.yaml)