Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Place1 authored Apr 13, 2020
1 parent 48f842f commit f93daa5
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 35 deletions.
31 changes: 27 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,34 @@ For example you can configure `STORAGE_DIRECTORY` by passing `--storage-director
Here's an annotated config file example:

```yaml
loglevel: debug
# The application's log level.
# Can be debug, info, error
# Optional, defaults to info
loglevel: info
# Disable device metadata storage.
# Device metadata includes the last handshake time,
# total sent/received bytes count, their endpoint IP.
# This metadata is captured from wireguard itself.
# Disabling this flag will not stop wireguard from capturing
# this data.
# See stored data here: https://github.com/Place1/wg-access-server/blob/master/internal/storage/contracts.go#L14
# Optional, defaults to false.
disableMetadata: false
# The port that the web ui server (http) will listen on.
# Optional, defaults to 8000
port: 8000
storage:
# Directory that VPN devices (WireGuard peers)
# should be saved under.
# If this value is empty then an InMemory storage
# backend will be used (not recommended).
# Defaults to "/data" inside the docker container
# Optional
# Defaults to in-memory
# The docker container sets this value to /data automatically
directory: /data
wireguard:
# The network interface name for wireguard
# Optional
# Optional, defaults to wg0
interfaceName: wg0
# The WireGuard PrivateKey
# You can generate this value using "$ wg genkey"
Expand All @@ -49,7 +66,7 @@ wireguard:
# Optional
externalHost: ""
# The WireGuard ListenPort
# Optional
# Optional, defaults to 51820
port: 51820
vpn:
# CIDR configures a network address space
Expand Down Expand Up @@ -93,13 +110,19 @@ vpn:
# Optional
allowedNetworks: []
dns:
# Enable a DNS proxy for VPN clients.
# Optional, Defaults to true
enabled: true
# upstream DNS servers.
# that the server-side DNS proxy will forward requests to.
# By default /etc/resolv.conf will be used to find upstream
# DNS servers.
# Optional
upstream:
- "1.1.1.1"
# Port sets the port that the DNS proxy will listen on
# Optional, defaults to 53
port: 53
# Auth configures optional authentication backends
# to controll access to the web ui.
# Devices will be managed on a per-user basis if any
Expand Down
22 changes: 19 additions & 3 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ type AppConfig struct {
DisableMetadata bool `yaml:"disableMetadata"`
AdminSubject string `yaml:"adminSubject"`
AdminPassword string `yaml:"adminPassword"`
Storage struct {
// Port sets the port that the web UI will listen on.
// Defaults to 8000
Port int `yaml:"port"`
Storage struct {
// Directory that VPN devices (WireGuard peers)
// should be saved under.
// If this value is empty then an InMemory storage
Expand Down Expand Up @@ -73,7 +76,15 @@ type AppConfig struct {
// Enabled allows you to turn on/off
// the VPN DNS proxy feature.
// DNS Proxying is enabled by default.
Enabled *bool `yaml:"enabled"`
Enabled *bool `yaml:"enabled"`
// Port sets the port for the DNS proxy server.
// Defaults to 53
Port int `yaml:"port"`
// Upstream configures the addresses of upstream
// DNS servers to which client DNS requests will be sent to.
// Defaults the host's upstream DNS servers (via resolveconf)
// or 1.1.1.1 if resolveconf cannot be used.
// NOTE: currently wg-access-server will only use the first upstream.
Upstream []string `yaml:"upstream"`
} `yaml:"dns"`
// Auth configures optional authentication backends
Expand All @@ -89,6 +100,9 @@ var (
app = kingpin.New("wg-access-server", "An all-in-one WireGuard Access Server & VPN solution")
configPath = app.Flag("config", "Path to a config file").Envar("CONFIG").String()
logLevel = app.Flag("log-level", "Log level (debug, info, error)").Envar("LOG_LEVEL").Default("info").String()
webPort = app.Flag("web-port", "The port that the web ui server will listen on").Envar("WEB_PORT").Default("8000").Int()
wireguardPort = app.Flag("wireguard-port", "The port that the Wireguard server will listen on").Envar("WIREGUARD_PORT").Default("51820").Int()
dnsPort = app.Flag("dns-port", "The port that the DNS proxy server will listen on").Envar("DNS_PORT").Default("53").Int()
storagePath = app.Flag("storage-directory", "Path to a storage directory").Envar("STORAGE_DIRECTORY").String()
privateKey = app.Flag("wireguard-private-key", "Wireguard private key").Envar("WIREGUARD_PRIVATE_KEY").String()
disableMetadata = app.Flag("disable-metadata", "Disable metadata collection (i.e. metrics)").Envar("DISABLE_METADATA").Default("false").Bool()
Expand All @@ -102,12 +116,14 @@ func Read() *AppConfig {

config := AppConfig{}
config.LogLevel = *logLevel
config.Port = *webPort
config.WireGuard.InterfaceName = "wg0"
config.WireGuard.Port = 51820
config.WireGuard.Port = *wireguardPort
config.VPN.CIDR = "10.44.0.0/24"
config.DisableMetadata = *disableMetadata
config.Storage.Directory = *storagePath
config.WireGuard.PrivateKey = *privateKey
config.DNS.Port = *dnsPort

if config.DNS.Enabled == nil {
on := true
Expand Down
15 changes: 12 additions & 3 deletions internal/dnsproxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@ import (
"github.com/sirupsen/logrus"
)

type DNSServerOpts struct {
Port int
Upstream []string
}

type DNSServer struct {
server *dns.Server
client *dns.Client
cache *cache.Cache
upstream []string
}

func New(upstream []string) (*DNSServer, error) {
func New(opts DNSServerOpts) (*DNSServer, error) {

upstream := opts.Upstream

if len(upstream) == 0 {
if r, err := resolvconf.Get(); err == nil {
Expand All @@ -35,11 +42,13 @@ func New(upstream []string) (*DNSServer, error) {
upstream = append(upstream, "1.1.1.1")
}

logrus.Infof("starting dns server with upstreams: %s", strings.Join(upstream, ", "))
addr := fmt.Sprintf("0.0.0.0:%d", opts.Port)

logrus.Infof("starting dns server on %s with upstreams: %s", addr, strings.Join(upstream, ", "))

dnsServer := &DNSServer{
server: &dns.Server{
Addr: "0.0.0.0:53",
Addr: addr,
Net: "udp",
},
client: &dns.Client{
Expand Down
1 change: 0 additions & 1 deletion internal/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ func ConfigureRouting(wgIface string, cidr string) error {
return errors.Wrap(err, "failed to find wireguard interface")
}
vpnip := ServerVPNIP(cidr)
logrus.Infof("server VPN subnet IP is %s", vpnip.String())
addr, err := netlink.ParseAddr(vpnip.String())
if err != nil {
return errors.Wrap(err, "failed to parse subnet address")
Expand Down
2 changes: 2 additions & 0 deletions internal/services/server_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package services

import (
"context"
"fmt"
"strings"

"github.com/place1/wg-access-server/internal/network"
Expand Down Expand Up @@ -40,6 +41,7 @@ func (s *ServerService) Info(ctx context.Context, req *proto.InfoReq) (*proto.In
IsAdmin: user.Claims.Contains("admin"),
AllowedIps: allowedIPs(s.Config),
DnsEnabled: *s.Config.DNS.Enabled,
DnsAddress: fmt.Sprintf("%s:%d", network.ServerVPNIP(s.Config.VPN.CIDR).IP.String(), s.Config.DNS.Port),
}, nil
}

Expand Down
13 changes: 10 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func main() {
}
defer wg.Close()

logrus.Infof("starting wireguard server on 0.0.0.0:%d", conf.WireGuard.Port)

wg.LoadConfig(&wgembed.ConfigFile{
Interface: wgembed.IfaceConfig{
PrivateKey: conf.WireGuard.PrivateKey,
Expand All @@ -55,13 +57,18 @@ func main() {
},
})

logrus.Infof("wireguard VPN network is %s", conf.VPN.CIDR)

if err := network.ConfigureForwarding(conf.WireGuard.InterfaceName, conf.VPN.GatewayInterface, conf.VPN.CIDR, *conf.VPN.Rules); err != nil {
logrus.Fatal(err)
}

// DNS Server
if *conf.DNS.Enabled {
dns, err := dnsproxy.New(conf.DNS.Upstream)
dns, err := dnsproxy.New(dnsproxy.DNSServerOpts{
Port: conf.DNS.Port,
Upstream: conf.DNS.Upstream,
})
if err != nil {
logrus.Fatal(errors.Wrap(err, "failed to start dns server"))
}
Expand Down Expand Up @@ -154,14 +161,14 @@ func main() {
publicRouter.NotFoundHandler = handler

// Listen
address := "0.0.0.0:8000"
address := fmt.Sprintf("0.0.0.0:%d", conf.Port)
srv := &http.Server{
Addr: address,
Handler: publicRouter,
}

// Start Web server
logrus.Infof("listening on %v", address)
logrus.Infof("web ui listening on %v", address)
if err := srv.ListenAndServe(); err != nil {
logrus.Fatal(errors.Wrap(err, "unable to start http server"))
}
Expand Down
49 changes: 29 additions & 20 deletions proto/proto/server.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions proto/server.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ message InfoRes {
bool is_admin = 6;
string allowed_ips = 7;
bool dns_enabled = 8;
string dns_address = 9;
}
2 changes: 1 addition & 1 deletion website/src/components/AddDevice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class AddDevice extends React.Component<Props> {
[Interface]
PrivateKey = ${privateKey}
Address = ${device.address}
${info.dnsEnabled && `DNS = ${info.hostVpnIp}`}
${info.dnsEnabled && `DNS = ${info.dnsAddress}`}
[Peer]
PublicKey = ${info.publicKey}
Expand Down
19 changes: 19 additions & 0 deletions website/src/sdk/server_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export declare namespace InfoRes {
isAdmin: boolean,
allowedIps: string,
dnsEnabled: boolean,
dnsAddress: string,
}
}

Expand Down Expand Up @@ -191,6 +192,14 @@ export class InfoRes extends jspb.Message {
(jspb.Message as any).setProto3BooleanField(this, 8, value);
}

getDnsAddress(): string {
return jspb.Message.getFieldWithDefault(this, 9, "");
}

setDnsAddress(value: string): void {
(jspb.Message as any).setProto3StringField(this, 9, value);
}

serializeBinary(): Uint8Array {
const writer = new jspb.BinaryWriter();
InfoRes.serializeBinaryToWriter(this, writer);
Expand All @@ -207,6 +216,7 @@ export class InfoRes extends jspb.Message {
isAdmin: this.getIsAdmin(),
allowedIps: this.getAllowedIps(),
dnsEnabled: this.getDnsEnabled(),
dnsAddress: this.getDnsAddress(),

};
}
Expand Down Expand Up @@ -244,6 +254,10 @@ export class InfoRes extends jspb.Message {
if (field8 != false) {
writer.writeBool(8, field8);
}
const field9 = message.getDnsAddress();
if (field9.length > 0) {
writer.writeString(9, field9);
}
}

static deserializeBinary(bytes: Uint8Array): InfoRes {
Expand Down Expand Up @@ -292,6 +306,10 @@ export class InfoRes extends jspb.Message {
const field8 = reader.readBool()
message.setDnsEnabled(field8);
break;
case 9:
const field9 = reader.readString()
message.setDnsAddress(field9);
break;
default:
reader.skipField();
break;
Expand Down Expand Up @@ -324,6 +342,7 @@ function InfoResFromObject(obj: InfoRes.AsObject | undefined): InfoRes | undefin
message.setIsAdmin(obj.isAdmin);
message.setAllowedIps(obj.allowedIps);
message.setDnsEnabled(obj.dnsEnabled);
message.setDnsAddress(obj.dnsAddress);
return message;
}

Expand Down

0 comments on commit f93daa5

Please sign in to comment.