pull/38/head
James Batt 4 years ago committed by GitHub
parent 48f842fcbd
commit f93daa5dff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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"
@ -49,7 +66,7 @@ wireguard:
# Optional
externalHost: ""
# The WireGuard ListenPort
# Optional
# Optional, defaults to 51820
port: 51820
vpn:
# CIDR configures a network address space
@ -93,6 +110,9 @@ 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
@ -100,6 +120,9 @@ dns:
# 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

@ -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
@ -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
@ -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()
@ -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

@ -15,6 +15,11 @@ import (
"github.com/sirupsen/logrus"
)
type DNSServerOpts struct {
Port int
Upstream []string
}
type DNSServer struct {
server *dns.Server
client *dns.Client
@ -22,7 +27,9 @@ type DNSServer struct {
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 {
@ -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{

@ -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")

@ -2,6 +2,7 @@ package services
import (
"context"
"fmt"
"strings"
"github.com/place1/wg-access-server/internal/network"
@ -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
}

@ -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,
@ -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"))
}
@ -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"))
}

@ -65,6 +65,7 @@ type InfoRes struct {
IsAdmin bool `protobuf:"varint,6,opt,name=is_admin,json=isAdmin,proto3" json:"is_admin,omitempty"`
AllowedIps string `protobuf:"bytes,7,opt,name=allowed_ips,json=allowedIps,proto3" json:"allowed_ips,omitempty"`
DnsEnabled bool `protobuf:"varint,8,opt,name=dns_enabled,json=dnsEnabled,proto3" json:"dns_enabled,omitempty"`
DnsAddress string `protobuf:"bytes,9,opt,name=dns_address,json=dnsAddress,proto3" json:"dns_address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -151,6 +152,13 @@ func (m *InfoRes) GetDnsEnabled() bool {
return false
}
func (m *InfoRes) GetDnsAddress() string {
if m != nil {
return m.DnsAddress
}
return ""
}
func init() {
proto.RegisterType((*InfoReq)(nil), "proto.InfoReq")
proto.RegisterType((*InfoRes)(nil), "proto.InfoRes")
@ -159,26 +167,27 @@ func init() {
func init() { proto.RegisterFile("server.proto", fileDescriptor_ad098daeda4239f7) }
var fileDescriptor_ad098daeda4239f7 = []byte{
// 293 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xcd, 0x4e, 0x02, 0x31,
0x14, 0x85, 0x1d, 0x1c, 0xfe, 0x2e, 0x46, 0x4d, 0x57, 0x95, 0x28, 0x4e, 0x58, 0x8d, 0x9b, 0xc1,
0xe0, 0x13, 0xb8, 0x70, 0x41, 0xdc, 0x0d, 0x09, 0xdb, 0xa6, 0x63, 0x2f, 0xd8, 0x58, 0xda, 0xda,
0x16, 0x08, 0x2f, 0xe2, 0xf3, 0x9a, 0x69, 0xc1, 0xc4, 0x55, 0xef, 0xf9, 0x7a, 0xda, 0x93, 0x7b,
0xe0, 0xca, 0xa3, 0xdb, 0xa3, 0xab, 0xac, 0x33, 0xc1, 0x90, 0x6e, 0x3c, 0xc6, 0x93, 0x8d, 0x31,
0x1b, 0x85, 0xb3, 0xa8, 0x9a, 0xdd, 0x7a, 0x76, 0x70, 0xdc, 0x5a, 0x74, 0x3e, 0xd9, 0xa6, 0x43,
0xe8, 0x2f, 0xf4, 0xda, 0xd4, 0xf8, 0x3d, 0xfd, 0xe9, 0x9c, 0x67, 0x4f, 0x1e, 0x00, 0xec, 0xae,
0x51, 0xf2, 0x83, 0x7d, 0xe1, 0x91, 0x66, 0x45, 0x56, 0x0e, 0xeb, 0x61, 0x22, 0xef, 0x78, 0x24,
0xcf, 0x90, 0x7f, 0x1a, 0x1f, 0x68, 0xa7, 0xc8, 0xca, 0xd1, 0xfc, 0xbe, 0x4a, 0x21, 0xd5, 0x39,
0xa4, 0x5a, 0x06, 0x27, 0xf5, 0x66, 0xc5, 0xd5, 0x0e, 0xeb, 0xe8, 0x24, 0x04, 0x72, 0x6b, 0x5c,
0xa0, 0x97, 0x45, 0x56, 0x76, 0xeb, 0x38, 0x93, 0x09, 0x8c, 0xda, 0x3b, 0xb6, 0xb7, 0x9a, 0x49,
0x4b, 0xf3, 0x94, 0xd2, 0xa2, 0x95, 0xd5, 0x0b, 0x4b, 0x9e, 0xe0, 0x76, 0x8b, 0x81, 0x0b, 0x1e,
0x38, 0x43, 0xcd, 0x1b, 0x85, 0x82, 0x76, 0x8b, 0xac, 0x1c, 0xd4, 0x37, 0x67, 0xfe, 0x96, 0x30,
0xb9, 0x83, 0x81, 0xf4, 0x8c, 0x8b, 0xad, 0xd4, 0xb4, 0x17, 0x2d, 0x7d, 0xe9, 0x5f, 0x5b, 0x49,
0x1e, 0x61, 0xc4, 0x95, 0x32, 0x07, 0x14, 0x4c, 0x5a, 0x4f, 0xfb, 0x31, 0x05, 0x4e, 0x68, 0x61,
0x7d, 0x6b, 0x10, 0xda, 0xff, 0x25, 0x0c, 0xe2, 0x73, 0x10, 0xda, 0x9f, 0x3e, 0x9f, 0xcf, 0xa1,
0xb7, 0x8c, 0xd5, 0x92, 0x12, 0xf2, 0xb6, 0x21, 0x72, 0x9d, 0x56, 0xad, 0x4e, 0xd5, 0x8d, 0xff,
0x6b, 0x3f, 0xbd, 0x68, 0x7a, 0x11, 0xbc, 0xfc, 0x06, 0x00, 0x00, 0xff, 0xff, 0xca, 0x15, 0xd9,
0x84, 0x95, 0x01, 0x00, 0x00,
// 308 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xcf, 0x4e, 0xf3, 0x30,
0x10, 0xc4, 0xbf, 0xf4, 0x4b, 0xff, 0x64, 0x8b, 0x00, 0xf9, 0x64, 0x2a, 0x28, 0x51, 0x4f, 0xe1,
0x92, 0xa2, 0xf2, 0x04, 0x3d, 0x70, 0xa8, 0xb8, 0xa5, 0x52, 0xaf, 0x91, 0x83, 0xb7, 0xc5, 0x22,
0xb5, 0x8d, 0x37, 0x6d, 0xd5, 0x27, 0xe3, 0xf5, 0x50, 0xec, 0x06, 0x89, 0x93, 0x77, 0x7e, 0x9e,
0xdd, 0x91, 0x06, 0xae, 0x08, 0xdd, 0x11, 0x5d, 0x6e, 0x9d, 0x69, 0x0c, 0xeb, 0xfb, 0x67, 0x32,
0xdd, 0x19, 0xb3, 0xab, 0x71, 0xee, 0x55, 0x75, 0xd8, 0xce, 0x4f, 0x4e, 0x58, 0x8b, 0x8e, 0x82,
0x6d, 0x96, 0xc0, 0x70, 0xa5, 0xb7, 0xa6, 0xc0, 0xaf, 0xd9, 0x77, 0xaf, 0x9b, 0x89, 0x3d, 0x00,
0xd8, 0x43, 0x55, 0xab, 0xf7, 0xf2, 0x13, 0xcf, 0x3c, 0x4a, 0xa3, 0x2c, 0x29, 0x92, 0x40, 0xde,
0xf0, 0xcc, 0x9e, 0x21, 0xfe, 0x30, 0xd4, 0xf0, 0x5e, 0x1a, 0x65, 0xe3, 0xc5, 0x7d, 0x1e, 0x42,
0xf2, 0x2e, 0x24, 0x5f, 0x37, 0x4e, 0xe9, 0xdd, 0x46, 0xd4, 0x07, 0x2c, 0xbc, 0x93, 0x31, 0x88,
0xad, 0x71, 0x0d, 0xff, 0x9f, 0x46, 0x59, 0xbf, 0xf0, 0x33, 0x9b, 0xc2, 0xb8, 0xfd, 0x2b, 0x8f,
0x56, 0x97, 0xca, 0xf2, 0x38, 0xa4, 0xb4, 0x68, 0x63, 0xf5, 0xca, 0xb2, 0x27, 0xb8, 0xdd, 0x63,
0x23, 0xa4, 0x68, 0x44, 0x89, 0x5a, 0x54, 0x35, 0x4a, 0xde, 0x4f, 0xa3, 0x6c, 0x54, 0xdc, 0x74,
0xfc, 0x35, 0x60, 0x76, 0x07, 0x23, 0x45, 0xa5, 0x90, 0x7b, 0xa5, 0xf9, 0xc0, 0x5b, 0x86, 0x8a,
0x96, 0xad, 0x64, 0x8f, 0x30, 0x16, 0x75, 0x6d, 0x4e, 0x28, 0x4b, 0x65, 0x89, 0x0f, 0x7d, 0x0a,
0x5c, 0xd0, 0xca, 0x52, 0x6b, 0x90, 0x9a, 0x7e, 0x13, 0x46, 0x7e, 0x1d, 0xa4, 0xa6, 0xee, 0xf8,
0xc5, 0x20, 0xa4, 0x74, 0x48, 0xc4, 0x93, 0x70, 0x41, 0x6a, 0x5a, 0x06, 0xb2, 0x58, 0xc0, 0x60,
0xed, 0xbb, 0x67, 0x19, 0xc4, 0x6d, 0x85, 0xec, 0x3a, 0x74, 0x91, 0x5f, 0xba, 0x9d, 0xfc, 0xd5,
0x34, 0xfb, 0x57, 0x0d, 0x3c, 0x78, 0xf9, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x30, 0xb0, 0x21,
0xb6, 0x01, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -21,4 +21,5 @@ message InfoRes {
bool is_admin = 6;
string allowed_ips = 7;
bool dns_enabled = 8;
string dns_address = 9;
}

@ -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}

@ -112,6 +112,7 @@ export declare namespace InfoRes {
isAdmin: boolean,
allowedIps: string,
dnsEnabled: boolean,
dnsAddress: string,
}
}
@ -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);
@ -207,6 +216,7 @@ export class InfoRes extends jspb.Message {
isAdmin: this.getIsAdmin(),
allowedIps: this.getAllowedIps(),
dnsEnabled: this.getDnsEnabled(),
dnsAddress: this.getDnsAddress(),
};
}
@ -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 {
@ -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;
@ -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;
}

Loading…
Cancel
Save