Skip to content

Commit

Permalink
Client network config (Place1#25)
Browse files Browse the repository at this point in the history
* allowedips support + dns enable/disable

* bug fix: upstream dns now checks resolvconf if left unconfigured

* dns proxy no longer starts when dns is disabled

* updated changelog
  • Loading branch information
Place1 authored Apr 12, 2020
1 parent 89ab8fa commit 48f842f
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 30 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [master]

### Added

- The VPN DNS proxy feature can now be disabled using config: `dns.enabled = false`
- When disabled the `DNS` wireguard config value will be omitted from client wg config files
- When disabled the DNS proxy will not be started server-side (i.e. port 53 won't be used)

### Changes

- The admin UI will now show the device owner's name or email if available.
- The admin UI will now show the auth provider for a given device if more than 1 auth provider is in use.
- Bug fix: upstream dns now correctly configured using resolvconf if not set in config file, flag or envvar.

## [0.1.1]

Expand Down
12 changes: 11 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ type AppConfig struct {
Rules *network.NetworkRules `yaml:"rules"`
}
DNS struct {
// Enabled allows you to turn on/off
// the VPN DNS proxy feature.
// DNS Proxying is enabled by default.
Enabled *bool `yaml:"enabled"`
Upstream []string `yaml:"upstream"`
} `yaml:"dns"`
// Auth configures optional authentication backends
Expand Down Expand Up @@ -104,6 +108,12 @@ func Read() *AppConfig {
config.DisableMetadata = *disableMetadata
config.Storage.Directory = *storagePath
config.WireGuard.PrivateKey = *privateKey

if config.DNS.Enabled == nil {
on := true
config.DNS.Enabled = &on
}

if adminPassword != nil {
config.AdminPassword = *adminPassword
config.AdminSubject = *adminUsername
Expand All @@ -112,7 +122,7 @@ func Read() *AppConfig {
}
}

if upstreamDNS != nil {
if upstreamDNS != nil && *upstreamDNS != "" {
config.DNS.Upstream = []string{*upstreamDNS}
}

Expand Down
42 changes: 38 additions & 4 deletions internal/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,43 @@ type NetworkRules struct {
AllowedNetworks []string `yaml:"allowedNetworks"`
}

// https://simple.wikipedia.org/wiki/Private_network
var ServerLANSubnets = []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}

// Public IPv4 blocks
var PublicInternetSubnets = []string{
"200.0.0.0/5",
"172.64.0.0/10",
"172.128.0.0/9",
"12.0.0.0/6",
"16.0.0.0/4",
"11.0.0.0/8",
"32.0.0.0/3",
"128.0.0.0/3",
"196.0.0.0/6",
"64.0.0.0/2",
"172.0.0.0/12",
"194.0.0.0/7",
"192.160.0.0/13",
"192.0.0.0/9",
"192.170.0.0/15",
"160.0.0.0/5",
"192.128.0.0/11",
"193.0.0.0/8",
"208.0.0.0/4",
"192.172.0.0/14",
"176.0.0.0/4",
"192.169.0.0/16",
"0.0.0.0/5",
"174.0.0.0/7",
"192.176.0.0/12",
"192.192.0.0/10",
"8.0.0.0/7",
"172.32.0.0/11",
"173.0.0.0/8",
"168.0.0.0/6",
}

func ConfigureForwarding(wgIface string, gatewayIface string, cidr string, rules NetworkRules) error {
// Networking configuration (iptables) configuration
// to ensure that traffic from clients the wireguard interface
Expand All @@ -88,9 +125,6 @@ func ConfigureForwarding(wgIface string, gatewayIface string, cidr string, rules
logrus.Error(errors.Wrap(err, "failed to configure interface"))
}

// https://simple.wikipedia.org/wiki/Private_network
privateCIDRs := []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}

// White listed networks
if len(rules.AllowedNetworks) != 0 {
for _, subnet := range rules.AllowedNetworks {
Expand All @@ -112,7 +146,7 @@ func ConfigureForwarding(wgIface string, gatewayIface string, cidr string, rules
}

// Server LAN
for _, privateCIDR := range privateCIDRs {
for _, privateCIDR := range ServerLANSubnets {
if err := ipt.AppendUnique("filter", "WG_ACCESS_SERVER_FORWARD", "-s", cidr, "-d", privateCIDR, "-j", boolToRule(rules.AllowServerLAN)); err != nil {
return errors.Wrap(err, "failed to set ip tables rule")
}
Expand Down
30 changes: 29 additions & 1 deletion internal/services/server_service.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package services

import (
"github.com/place1/wg-access-server/internal/network"
"context"
"strings"

"github.com/place1/wg-access-server/internal/network"

"github.com/place1/wg-access-server/internal/config"
"github.com/place1/wg-access-server/pkg/authnz/authsession"
Expand Down Expand Up @@ -36,5 +38,31 @@ func (s *ServerService) Info(ctx context.Context, req *proto.InfoReq) (*proto.In
HostVpnIp: network.ServerVPNIP(s.Config.VPN.CIDR).IP.String(),
MetadataEnabled: !s.Config.DisableMetadata,
IsAdmin: user.Claims.Contains("admin"),
AllowedIps: allowedIPs(s.Config),
DnsEnabled: *s.Config.DNS.Enabled,
}, nil
}

func allowedIPs(config *config.AppConfig) string {
if config.VPN.Rules == nil {
return "0.0.0.0/1, 128.0.0.0/1, ::/0"
}

allowed := []string{}

if config.VPN.Rules.AllowVPNLAN {
allowed = append(allowed, config.VPN.CIDR)
}

if config.VPN.Rules.AllowServerLAN {
allowed = append(allowed, network.ServerLANSubnets...)
}

if config.VPN.Rules.AllowInternet {
allowed = append(allowed, network.PublicInternetSubnets...)
}

allowed = append(allowed, config.VPN.Rules.AllowedNetworks...)

return strings.Join(allowed, ", ")
}
10 changes: 6 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ func main() {
}

// DNS Server
dns, err := dnsproxy.New(conf.DNS.Upstream)
if err != nil {
logrus.Fatal(errors.Wrap(err, "failed to start dns server"))
if *conf.DNS.Enabled {
dns, err := dnsproxy.New(conf.DNS.Upstream)
if err != nil {
logrus.Fatal(errors.Wrap(err, "failed to start dns server"))
}
defer dns.Close()
}
defer dns.Close()

// Storage
var storageDriver storage.Storage
Expand Down
54 changes: 36 additions & 18 deletions proto/proto/server.pb.go

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

2 changes: 2 additions & 0 deletions proto/server.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ message InfoRes {
string host_vpn_ip = 4;
bool metadata_enabled = 5;
bool is_admin = 6;
string allowed_ips = 7;
bool dns_enabled = 8;
}
4 changes: 2 additions & 2 deletions website/src/components/AddDevice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ export class AddDevice extends React.Component<Props> {
[Interface]
PrivateKey = ${privateKey}
Address = ${device.address}
DNS = ${info.hostVpnIp}
${info.dnsEnabled && `DNS = ${info.hostVpnIp}`}
[Peer]
PublicKey = ${info.publicKey}
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1, ::/0
AllowedIPs = ${info.allowedIps}
Endpoint = ${`${info.host?.value || window.location.hostname}:${info.port || '51820'}`}
`;

Expand Down
38 changes: 38 additions & 0 deletions website/src/sdk/server_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export declare namespace InfoRes {
hostVpnIp: string,
metadataEnabled: boolean,
isAdmin: boolean,
allowedIps: string,
dnsEnabled: boolean,
}
}

Expand Down Expand Up @@ -173,6 +175,22 @@ export class InfoRes extends jspb.Message {
(jspb.Message as any).setProto3BooleanField(this, 6, value);
}

getAllowedIps(): string {
return jspb.Message.getFieldWithDefault(this, 7, "");
}

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

getDnsEnabled(): boolean {
return jspb.Message.getFieldWithDefault(this, 8, false);
}

setDnsEnabled(value: boolean): void {
(jspb.Message as any).setProto3BooleanField(this, 8, value);
}

serializeBinary(): Uint8Array {
const writer = new jspb.BinaryWriter();
InfoRes.serializeBinaryToWriter(this, writer);
Expand All @@ -187,6 +205,8 @@ export class InfoRes extends jspb.Message {
hostVpnIp: this.getHostVpnIp(),
metadataEnabled: this.getMetadataEnabled(),
isAdmin: this.getIsAdmin(),
allowedIps: this.getAllowedIps(),
dnsEnabled: this.getDnsEnabled(),

};
}
Expand Down Expand Up @@ -216,6 +236,14 @@ export class InfoRes extends jspb.Message {
if (field6 != false) {
writer.writeBool(6, field6);
}
const field7 = message.getAllowedIps();
if (field7.length > 0) {
writer.writeString(7, field7);
}
const field8 = message.getDnsEnabled();
if (field8 != false) {
writer.writeBool(8, field8);
}
}

static deserializeBinary(bytes: Uint8Array): InfoRes {
Expand Down Expand Up @@ -256,6 +284,14 @@ export class InfoRes extends jspb.Message {
const field6 = reader.readBool()
message.setIsAdmin(field6);
break;
case 7:
const field7 = reader.readString()
message.setAllowedIps(field7);
break;
case 8:
const field8 = reader.readBool()
message.setDnsEnabled(field8);
break;
default:
reader.skipField();
break;
Expand Down Expand Up @@ -286,6 +322,8 @@ function InfoResFromObject(obj: InfoRes.AsObject | undefined): InfoRes | undefin
message.setHostVpnIp(obj.hostVpnIp);
message.setMetadataEnabled(obj.metadataEnabled);
message.setIsAdmin(obj.isAdmin);
message.setAllowedIps(obj.allowedIps);
message.setDnsEnabled(obj.dnsEnabled);
return message;
}

Expand Down

0 comments on commit 48f842f

Please sign in to comment.