diff --git a/src/cmd/configure.go b/src/cmd/configure.go index 415175d..5446e09 100644 --- a/src/cmd/configure.go +++ b/src/cmd/configure.go @@ -38,6 +38,7 @@ type configureCmdConfig struct { mtu int disableV6 bool localhostIP string + generatePSK bool } // Defaults for configure command. @@ -66,6 +67,7 @@ var configureCmdArgs = configureCmdConfig{ mtu: MTU, disableV6: false, localhostIP: "", + generatePSK: false, } // configureCmd represents the configure command. @@ -89,6 +91,7 @@ func init() { configureCmd.Flags().IntVarP(&configureCmdArgs.sport, "sport", "S", configureCmdArgs.sport, "listener port for server wireguard relay. Default is to copy the --outbound-endpoint port, or fallback to 51820") configureCmd.Flags().StringVarP(&configureCmdArgs.nickname, "nickname", "n", configureCmdArgs.nickname, "Server nickname to display in 'status' command") configureCmd.Flags().StringVarP(&configureCmdArgs.localhostIP, "localhost-ip", "i", configureCmdArgs.localhostIP, "[EXPERIMENTAL] Redirect wiretap packets destined for this IPv4 address to server's localhost") + configureCmd.Flags().BoolVarP(&configureCmdArgs.generatePSK, "PSK", "K", configureCmdArgs.generatePSK, "generates a preshared key") configureCmd.Flags().StringVarP(&configureCmdArgs.configFileRelay, "relay-output", "", configureCmdArgs.configFileRelay, "wireguard relay config output filename") configureCmd.Flags().StringVarP(&configureCmdArgs.configFileE2EE, "e2ee-output", "", configureCmdArgs.configFileE2EE, "wireguard E2EE config output filename") @@ -223,6 +226,15 @@ func (c configureCmdConfig) Run() { Peers: []peer.PeerConfigArgs{ { PublicKey: serverConfigRelay.GetPublicKey(), + PresharedKey: func() string { + if c.generatePSK { + err = serverConfigRelay.GenPresharedKey() + check("failed to generate preshared key", err) + return serverConfigRelay.GetPresharedKey() + } else { + return "" + } + }(), AllowedIPs: func() []string { if c.simple { return c.allowedIPs diff --git a/src/cmd/serve.go b/src/cmd/serve.go index f9ffc36..b116c1b 100644 --- a/src/cmd/serve.go +++ b/src/cmd/serve.go @@ -165,6 +165,7 @@ func init() { // Deprecated flags, kept for backwards compatibility. cmd.Flags().StringP("private-relay", "", "", "wireguard private key for relay interface") cmd.Flags().StringP("public-relay", "", "", "wireguard public key of remote peer for relay interface") + cmd.Flags().StringP("preshared-relay", "", "", "wireguard preshared key of remote peer for relay interface") cmd.Flags().StringP("private-e2ee", "", "", "wireguard private key for E2EE interface") cmd.Flags().StringP("public-e2ee", "", "", "wireguard public key of remote peer for E2EE interface") cmd.Flags().StringP("endpoint-relay", "", wiretapDefault.endpointRelay, "socket address of remote peer that server will connect to (example \"1.2.3.4:51820\")") @@ -189,6 +190,8 @@ func init() { err = viper.BindPFlag("Relay.Peer.publickey", cmd.Flags().Lookup("public-relay")) check("error binding flag to viper", err) + err = viper.BindPFlag("Relay.Peer.presharedkey", cmd.Flags().Lookup("preshared-relay")) + check("error binding flag to viper", err) err = viper.BindPFlag("Relay.Peer.endpoint", cmd.Flags().Lookup("endpoint-relay")) check("error binding flag to viper", err) err = viper.BindPFlag("Relay.Peer.allowed", cmd.Flags().Lookup("allowed")) @@ -239,6 +242,7 @@ func init() { "ipv6-e2ee-client", "private-relay", "public-relay", + "preshared-relay", "private-e2ee", "public-e2ee", "endpoint-relay", @@ -370,6 +374,13 @@ func (c serveCmdConfig) Run() { return 0 } }(), + PresharedKey: func() string { + if len(viper.GetString("Relay.Peer.presharedkey")) > 0 { + return viper.GetString("Relay.Peer.presharedkey") + } else { + return "" + } + }(), AllowedIPs: aips, }, }, diff --git a/src/peer/config.go b/src/peer/config.go index d9c100a..9493b03 100644 --- a/src/peer/config.go +++ b/src/peer/config.go @@ -19,6 +19,7 @@ type Config struct { peers []PeerConfig addresses []net.IPNet localhostIP string + presharedKey *wgtypes.Key } type configJSON struct { @@ -27,6 +28,7 @@ type configJSON struct { Peers []PeerConfig Addresses []net.IPNet LocalhostIP string + PresharedKey *wgtypes.Key } type ConfigArgs struct { @@ -38,6 +40,7 @@ type ConfigArgs struct { Peers []PeerConfigArgs Addresses []string LocalhostIP string + PresharedKey string } type Shell uint @@ -193,6 +196,8 @@ func ParseConfig(filename string) (c Config, err error) { err = newPeer.SetAllowedIPs(strings.Split(value, ",")) case "publickey": err = newPeer.SetPublicKey(value) + case "presharedkey": + err = newPeer.SetPresharedKey(value) case "persistentkeepalive": keepalive, e := strconv.Atoi(value) if e != nil { @@ -233,6 +238,7 @@ func (c *Config) MarshalJSON() ([]byte, error) { c.peers, c.addresses, c.localhostIP, + c.presharedKey, }) } @@ -248,6 +254,7 @@ func (c *Config) UnmarshalJSON(b []byte) error { c.peers = tmp.Peers c.addresses = tmp.Addresses c.localhostIP = tmp.LocalhostIP + c.presharedKey = tmp.PresharedKey return nil } @@ -266,6 +273,23 @@ func (c *Config) GetPrivateKey() string { return c.config.PrivateKey.String() } +func (c* Config) GenPresharedKey() error { + key, err := wgtypes.GenerateKey() + if err != nil { + return err + } + c.presharedKey = &key + return nil +} + +func (c* Config) GetPresharedKey() string { + if c.presharedKey != nil { + return c.presharedKey.String() + } else { + return "" + } +} + func (c *Config) SetPort(port int) error { if port < 1 || port > 65535 { return errors.New("invalid port") @@ -440,6 +464,9 @@ func (c *Config) AsShareableFile() string { s.WriteString("[Peer]\n") s.WriteString(fmt.Sprintf("PublicKey = %s\n", c.config.PrivateKey.PublicKey().String())) + if c.presharedKey != nil { + s.WriteString(fmt.Sprintf("PresharedKey = %s\n", c.presharedKey.String())) + } s.WriteString("AllowedIPs = 0.0.0.0/32\n") return s.String() @@ -488,6 +515,11 @@ func CreateServerCommand(relayConfig Config, e2eeConfig Config, shell Shell, sim // Relay Peer. keys = append(keys, "WIRETAP_RELAY_PEER_PUBLICKEY") vals = append(vals, relayConfig.GetPeerPublicKey(0)) + + if relayConfig.presharedKey != nil { + keys = append(keys, "WIRETAP_RELAY_PEER_PRESHAREDKEY") + vals = append(vals, relayConfig.GetPresharedKey()) + } if len(relayConfig.peers) > 0 && len(relayConfig.peers[0].config.AllowedIPs) > 0 { keys = append(keys, "WIRETAP_RELAY_PEER_ALLOWED") @@ -588,6 +620,9 @@ func CreateServerFile(relayConfig Config, e2eeConfig Config, simple bool) string } s.WriteString(fmt.Sprintf("PublicKey = %s\n", relayConfig.GetPeerPublicKey(0))) + if relayConfig.presharedKey != nil { + s.WriteString(fmt.Sprintf("PresharedKey = %s\n", relayConfig.GetPresharedKey())) + } if len(relayConfig.GetPeerEndpoint(0)) > 0 { s.WriteString(fmt.Sprintf("Endpoint = %s\n", relayConfig.GetPeerEndpoint(0))) } diff --git a/src/peer/peer_config.go b/src/peer/peer_config.go index 0b20e6a..5f785e9 100644 --- a/src/peer/peer_config.go +++ b/src/peer/peer_config.go @@ -277,6 +277,10 @@ func (p *PeerConfig) AsFile() string { s.WriteString(fmt.Sprintf("PublicKey = %s\n", p.config.PublicKey.String())) + if p.config.PresharedKey != nil { + s.WriteString(fmt.Sprintf("PresharedKey = %s\n", p.config.PresharedKey.String())) + } + ips := []string{} for _, a := range p.config.AllowedIPs { ips = append(ips, a.String()) @@ -301,6 +305,9 @@ func (p *PeerConfig) AsIPC() string { var s strings.Builder s.WriteString(fmt.Sprintf("public_key=%s\n", hex.EncodeToString(p.config.PublicKey[:]))) + if p.config.PresharedKey != nil { + s.WriteString(fmt.Sprintf("preshared_key=%s\n", hex.EncodeToString(p.config.PresharedKey[:]))) + } if p.config.Endpoint != nil { s.WriteString(fmt.Sprintf("endpoint=%s\n", p.config.Endpoint.String())) }