Install takes over a pivpn WireGuard server
On a server running pivpn's WireGuard, a new install offers to take it over: the server key, port, MTU, tunnel networks, endpoint, DNS, AllowedIPs and keepalive, and every client with its public key, preshared key and addresses. Devices keep their configs. Clients pivpn switched off are imported switched off, with the note "Imported from pivpn". Client private keys in /etc/wireguard/configs are not read. - Install notes which peers are connected, stops wg-quick@wg0, starts GHOSTWIRE on the same wg0 and waits up to 30 s for those peers. The wait only reports; idle devices reconnect when they next send. - If the service does not stay running, install removes what it set up, including config.json, and starts pivpn's WireGuard again. - Without a terminal the takeover needs -import-pivpn; install refuses to run next to pivpn otherwise, and the flag is refused on an existing install. - Names GHOSTWIRE does not accept are renamed and listed in the summary. An IPv6 address that differs from the mapped one is kept on the peer until its config is issued again. - uninstall without a config of its own (e.g. after a takeover was undone) leaves the WireGuard interface alone and removes only the firewall table. - README: "Coming from pivpn?" under the intro, a Features entry and a "Moving from pivpn" section. Tested end to end on Ubuntu 24.04 with pivpn aa96de7.
This commit is contained in:
@@ -172,16 +172,20 @@ type ClientDefaults struct {
|
||||
// Peer is one client. Its private key is never stored: it is shown once when
|
||||
// the config is issued.
|
||||
type Peer struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Note string `json:"note"`
|
||||
Enabled bool `json:"enabled"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
PresharedKey string `json:"presharedKey,omitempty"`
|
||||
IPv4 string `json:"ipv4"`
|
||||
DNS []string `json:"dns,omitempty"` // nil = server default
|
||||
AllowedIPs []string `json:"allowedIPs,omitempty"` // nil = server default
|
||||
Keepalive *int `json:"keepalive,omitempty"` // nil = server default
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Note string `json:"note"`
|
||||
Enabled bool `json:"enabled"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
PresharedKey string `json:"presharedKey,omitempty"`
|
||||
IPv4 string `json:"ipv4"`
|
||||
// IPv6 is set only for a peer imported from pivpn, which numbers IPv6
|
||||
// differently: its device keeps the address until the config is issued
|
||||
// here. Empty means the address mapped from IPv4 (see mapIPv6).
|
||||
IPv6 string `json:"ipv6,omitempty"`
|
||||
DNS []string `json:"dns,omitempty"` // nil = server default
|
||||
AllowedIPs []string `json:"allowedIPs,omitempty"` // nil = server default
|
||||
Keepalive *int `json:"keepalive,omitempty"` // nil = server default
|
||||
// LatencyCheck says when the server pings the peer through the tunnel:
|
||||
// "" (off), "active" (while the device sends traffic) or "always".
|
||||
LatencyCheck string `json:"latencyCheck,omitempty"`
|
||||
@@ -473,6 +477,7 @@ func (c *Config) validate() error {
|
||||
|
||||
names := map[string]bool{}
|
||||
ips := map[netip.Addr]bool{}
|
||||
ips6 := map[netip.Addr]bool{}
|
||||
keys := map[string]bool{}
|
||||
for _, p := range c.Peers {
|
||||
if err := validatePeerName(p.Name); err != nil {
|
||||
@@ -493,6 +498,17 @@ func (c *Config) validate() error {
|
||||
return fmt.Errorf("address %s is used twice", ip)
|
||||
}
|
||||
ips[ip] = true
|
||||
if p.IPv6 != "" {
|
||||
a, err := netip.ParseAddr(p.IPv6)
|
||||
if err != nil || !a.Is6() || !v6.Contains(a) || a == v6.Addr() {
|
||||
return fmt.Errorf("peer %q: IPv6 address %s is outside %s", p.Name, p.IPv6, v6)
|
||||
}
|
||||
}
|
||||
if a := peerIPv6(c, &p); ips6[a] {
|
||||
return fmt.Errorf("IPv6 address %s is used twice", a)
|
||||
} else {
|
||||
ips6[a] = true
|
||||
}
|
||||
if p.hasKey() && keys[p.PublicKey] {
|
||||
return fmt.Errorf("peer %q: public key is used by another peer", p.Name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user