README ¶
Wireguard Topology
Table of Contents
What is Wireguard Topology
Wireguard Topology is a tool that create all the necessary files for systemd-networkd
to run a full-secured wireguard VPNs with optionnaly some others network services like vxlan
s.
Use Case
If you have 10 linux servers, and you want to create a mesh VPN between them with Wireguard, then you have to :
- generate 10 private keys
- generate 45 Pre Shared Keys
- write 20 files and 10 of theses files must list 10 combinaisons of 9 pair of public keys and IP Addresses
If you want to use only 1 vxlan
to have a layer 2 VPN then you will 20 others files and again 10 of theses files must list 10 combinaison of 9 IP Addresses
It's a lot of files, and Wireguard Topology can generate them from only 1 single JSON.
Usage
Installation
go install -u github.com/nathanaelle/wireguard-topology/cmd/wg-topology
command line options
-dont-generate-cryptographic-keys
this option is useful for tests or when the crypto part is delegated to another process-in <JSON source>
this mandatory option specify the JSON source file. "-" means stdin.-out <destination>
this option specify the destination directory or tar file. the default output destination is the current directory-tmpl <templates>
this mandatory option specify the templates directory. The template use the officialtext/template
grammar.
JSON configuration
config-name
specify the name of the destination where all the configuration will be createdprefix-ipv6/cidr
mandatory option in case of DNS resolutionhosts
is a list of unique hostsclusters
is a list of clustercluster
is a mandatory non unique field wich describe a dense sub networkmembers
is the list of FQDN which each peer is connected to every others.
You can read the type declaration in config.go to find all the available options.
Example
the following configuration will produce a VPN where each peer is connected to the 3 others :
{
"config-name" : "1-network",
"iface": "wg",
"prefix-ipv6/cidr": "fd00::/16",
"hosts": [
{ "host": "n1", "ipv6": "fd00:dead:1dea::1/96" },
{ "host": "n2", "ipv6": "fd00:dead:1dea::2/96" },
{ "host": "n3", "ipv6": "fd00:dead:1dea::3/96" },
{ "host": "n4", "ipv6": "fd00:dead:1dea::4/96" }
],
"clusters": [
{
"cluster": "network",
"templates": [ "wg.netdev", "wg.network" ],
"members": [ "n1", "n2", "n3", "n4" ]
}
]
}
There is others examples in examples/
Main Goals
-
systemd-networkd
compliant - secure Wireguard mesh with unique PSK per edge
- can configure
vxlan
s - use templating for config files
- use a linear description for a combinatorial situation
- Coping with custom
AllowedIP
Security Statements
- this code was audited 0 time
License & credits
License
2-Clause BSD
Credits
Thanks to Bruno Bellamy to allow me to use one of his draw as an illustration.
To do
- Coping with custom
AllowedIP
- cleanup some historical weird stuff in the configuration
- Improve code comments
- Improve documentations
Documentation ¶
Index ¶
- Constants
- func GenKeyPair() (priv string, pub string, err error)
- func GenPSK() (psk string, err error)
- func Render(output Output, t Template, clusters map[string]*NetCluster) error
- func ValidateConf(config *Config, noKey bool) error
- type Cluster
- type Config
- type EdgeFunc
- type Forest
- func (f *Forest) AddDenseSubGraph(graphName string, nodes []string, applyOnPair EdgeFunc) error
- func (f *Forest) AddNodes(nodes []string)
- func (f *Forest) ForNodes(nodeFunc func(node string) error) error
- func (f *Forest) GetEdge(graphName string, nodeA, nodeB string) (string, bool)
- func (f *Forest) GetEdges(graphName string, node string) ([]string, bool)
- func (f *Forest) Len(graphName string) int
- type Graph
- type Host
- type NetCluster
- type Output
- type Template
- type WGInterface
- type WGPeer
Constants ¶
const WGKeyLen int = 32
WGKeyLen is the length of a Curve25519 key
Variables ¶
This section is empty.
Functions ¶
func GenKeyPair ¶
GenKeyPair generates a pair of base64 encoded Curve25519 keys
func Render ¶
func Render(output Output, t Template, clusters map[string]*NetCluster) error
Render applys templates on the data and export the result in output
func ValidateConf ¶
ValidateConf takes the json Config, validates some input and propagate parameters
Types ¶
type Config ¶
type Config struct { ConfigName string `json:"config-name"` IPv6Prefix string `json:"prefix-ipv6/cidr"` PersistentKeepalive *uint16 `json:"persistent-keepalive"` Iface string `json:"iface"` ListenPort uint16 `json:"port"` Hosts []*Host `json:"hosts"` HostsMap map[string]*Host `json:"-"` Clusters []*Cluster `json:"clusters"` Misc map[string]interface{} `json:"Misc"` }
type Forest ¶
Forest is a set of graph
func (*Forest) AddDenseSubGraph ¶
AddDenseSubGraph connects a subset of nodes a dense subgraph
type Host ¶
type Host struct { Name string `json:"host"` Templates []string `json:"templates"` Iface string `json:"iface"` PersistentKeepalive *uint16 `json:"persistent-keepalive"` ListenPort uint16 `json:"port"` PrivateIPv6 string `json:"-"` AllowedIPv6 []string `json:"-"` PrivateIPv6CIDR string `json:"ipv6"` PrivateKey string `json:"-"` PublicKey string `json:"public-key"` Misc map[string]interface{} `json:"Misc"` }
type NetCluster ¶
type NetCluster struct {
Ifaces map[string]*WGInterface
}
type Output ¶
type Output interface { AddFolder(name ...string) error AddEntry(name ...string) (io.WriteCloser, error) }
func NewDirOutput ¶
type Template ¶
func LoadTemplates ¶
LoadTemplates compiles all the available templates in a folder (not the subfolders) a template is a file with the extension .tmpl