diff --git a/cmd/config.go b/cmd/config.go index 5231bdeeb..da17231f8 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -1,12 +1,10 @@ package cmd -import "golang.zx2c4.com/wireguard/wgctrl/wgtypes" - type Config struct { // Wireguard private key of local peer - PrivateKey wgtypes.Key + PrivateKey string // configured remote peers (Wireguard public keys) - Peers []string + Peers string StunURL string TurnURL string TurnUser string diff --git a/cmd/up.go b/cmd/up.go index e19d44f4b..1eea73f5f 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -7,9 +7,11 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/wiretrustee/wiretrustee/engine" - "github.com/wiretrustee/wiretrustee/signal" - "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + sig "github.com/wiretrustee/wiretrustee/signal" "os" + "os/signal" + "strings" + "syscall" ) const ( @@ -19,6 +21,8 @@ const ( var ( cfgFile string + config = &Config{} + upCmd = &cobra.Command{ Use: "up", Short: "start wiretrustee", @@ -29,51 +33,69 @@ var ( os.Exit(ExitSetupFailed) }*/ - c := defaultConfig() + //c := defaultConfig() //todo print config //todo connect to signal ctx := context.Background() - signalClient, err := signal.NewClient(c.SignalAddr, ctx) + signalClient, err := sig.NewClient(config.SignalAddr, ctx) if err != nil { - log.Errorf("error while connecting to the Signal Exchange Service %s: %s", c.SignalAddr, err) + log.Errorf("error while connecting to the Signal Exchange Service %s: %s", config.SignalAddr, err) os.Exit(ExitSetupFailed) } //todo proper close handling defer func() { signalClient.Close() }() - stunURL, _ := ice.ParseURL(fmt.Sprintf("stun:%s", c.StunURL)) - turnURL, _ := ice.ParseURL(fmt.Sprintf("turn:%s", c.StunURL)) - turnURL.Password = c.TurnPwd - turnURL.Username = c.TurnUser + stunURL, _ := ice.ParseURL(config.StunURL) + turnURL, _ := ice.ParseURL(config.TurnURL) + turnURL.Password = config.TurnPwd + turnURL.Username = config.TurnUser urls := []*ice.URL{turnURL, stunURL} - s := c.PrivateKey.PublicKey().String() + engine := engine.NewEngine(signalClient, urls, config.WgIface, config.WgAddr) - engine := engine.NewEngine(signalClient, urls, c.WgIface, c.WgAddr) - err = engine.Start(s, c.Peers) + err = engine.Start(config.PrivateKey, strings.Split(config.Peers, ",")) - signalClient.WaitConnected() + //signalClient.WaitConnected() - select {} + SetupCloseHandler(signalClient) }, } ) +func SetupCloseHandler(signalClient *sig.Client) { + c := make(chan os.Signal) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + <-c + fmt.Println("\r- Ctrl+C pressed in Terminal") + signalClient.Close() + os.Exit(0) +} + func init() { - upCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.wiretrustee.yaml)") + //upCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.wiretrustee.yaml)") + upCmd.PersistentFlags().StringVar(&config.WgAddr, "address", "", "IP address of a peer in CIDR notation (e.g. 10.30.30.1/24)") + upCmd.PersistentFlags().StringVar(&config.PrivateKey, "key", "", "Peers Wireguard private key") + upCmd.PersistentFlags().StringVar(&config.Peers, "peers", "", "A comma separated list of peers (Wireguard public keys) to connect to") + upCmd.MarkPersistentFlagRequired("key") + upCmd.MarkPersistentFlagRequired("ip") + upCmd.MarkPersistentFlagRequired("peers") + upCmd.PersistentFlags().StringVar(&config.WgIface, "interface", "wiretrustee0", "Wireguard interface name") + upCmd.PersistentFlags().StringVar(&config.StunURL, "stun", "stun:stun.wiretrustee.com:3468", "A comma separated list of STUN servers including protocol (e.g. stun:stun.wiretrustee.com:3468") + upCmd.PersistentFlags().StringVar(&config.TurnURL, "turn", "turn:stun.wiretrustee.com:3468", "A comma separated list of TURN servers including protocol (e.g. stun:stun.wiretrustee.com:3468") + upCmd.PersistentFlags().StringVar(&config.TurnPwd, "turnUser", "wiretrustee", "A comma separated list of TURN servers including protocol (e.g. stun:stun.wiretrustee.com:3468") + upCmd.PersistentFlags().StringVar(&config.TurnUser, "turnPwd", "wt2021hello@", "A comma separated list of TURN servers including protocol (e.g. stun:stun.wiretrustee.com:3468") + upCmd.PersistentFlags().StringVar(&config.SignalAddr, "signal", "signal.wiretrustee.com:10000", "Signal server URL (e.g. signal.wiretrustee.com:10000") //upCmd.MarkPersistentFlagRequired("config") fmt.Printf("") } func defaultConfig() *Config { - key, _ := wgtypes.ParseKey("OCVgR9VJT4y4tBscRQ6SYHWocQlykUMCDI6APjp3ilY=") - return &Config{ - PrivateKey: key, - Peers: []string{"uRoZAk1g90WXXvazH0SS6URZ2/Kmhx+hbVhUt2ipzlU="}, + PrivateKey: "OCVgR9VJT4y4tBscRQ6SYHWocQlykUMCDI6APjp3ilY=", + Peers: "uRoZAk1g90WXXvazH0SS6URZ2/Kmhx+hbVhUt2ipzlU=", SignalAddr: "signal.wiretrustee.com:10000", StunURL: "stun.wiretrustee.com:3468", TurnURL: "stun.wiretrustee.com:3468", diff --git a/engine/agent.go b/engine/agent.go index 5f30c1c7e..b2b27ae1a 100644 --- a/engine/agent.go +++ b/engine/agent.go @@ -21,7 +21,7 @@ type PeerAgent struct { // Actual peer-to-peer connection conn *ice.Conn // a signal.Client to negotiate initial connection - signal signal.Client + signal *signal.Client // a connection to a local Wireguard instance to proxy data wgConn net.Conn // an address of local Wireguard instance @@ -29,7 +29,7 @@ type PeerAgent struct { } // NewPeerAgent creates a new PeerAgent with give local and remote Wireguard public keys and initializes an ICE Agent -func NewPeerAgent(localKey string, remoteKey string, stunTurnURLS []*ice.URL, wgAddr string) (*PeerAgent, error) { +func NewPeerAgent(localKey string, remoteKey string, stunTurnURLS []*ice.URL, wgAddr string, signal *signal.Client) (*PeerAgent, error) { // init ICE Agent iceAgent, err := ice.NewAgent(&ice.AgentConfig{ @@ -47,6 +47,7 @@ func NewPeerAgent(localKey string, remoteKey string, stunTurnURLS []*ice.URL, wg wgAddr: wgAddr, conn: nil, wgConn: nil, + signal: signal, } err = peerAgent.onConnectionStateChange() @@ -217,6 +218,24 @@ func (pa *PeerAgent) onConnectionStateChange() error { }) } +func (pa *PeerAgent) Start() error { + localUFrag, localPwd, err := pa.iceAgent.GetLocalUserCredentials() + if err != nil { + return err + } + + offer := signal.MarshalCredential(pa.LocalKey, pa.RemoteKey, &signal.Credential{ + UFrag: localUFrag, + Pwd: localPwd}, sProto.Message_OFFER) + + err = pa.signal.Send(offer) + if err != nil { + return err + } + + return nil +} + // authenticate sets the signal.Credential of the remote peer // and returns local Credentials func (pa *PeerAgent) Authenticate(credential *signal.Credential) (*signal.Credential, error) { diff --git a/engine/engine.go b/engine/engine.go index abae0613c..e7acb7b60 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -34,12 +34,13 @@ func NewEngine(signal *signal.Client, stunsTurns []*ice.URL, wgIface string, wgA } } -func (e *Engine) Start(localKey string, peers []string) error { +func (e *Engine) Start(privateKey string, peers []string) error { // setup wireguard - myKey, err := wgtypes.ParseKey(localKey) + myKey, err := wgtypes.ParseKey(privateKey) + myPubKey := myKey.PublicKey().String() if err != nil { - log.Errorf("error parsing Wireguard key %s: [%s]", localKey, err.Error()) + log.Errorf("error parsing Wireguard key %s: [%s]", privateKey, err.Error()) return err } @@ -63,17 +64,23 @@ func (e *Engine) Start(localKey string, peers []string) error { // initialize peer agents for _, peer := range peers { - peerAgent, err := NewPeerAgent(localKey, peer, e.stunsTurns, fmt.Sprintf("127.0.0.1:%d", *wgPort)) + peerAgent, err := NewPeerAgent(myPubKey, peer, e.stunsTurns, fmt.Sprintf("127.0.0.1:%d", *wgPort), e.signal) if err != nil { - log.Fatalf("failed creating peer agent for pair %s - %s", localKey, peer) + log.Fatalf("failed creating peer agent for pair %s - %s", myPubKey, peer) return err } - e.agents[localKey] = peerAgent + e.agents[myPubKey] = peerAgent } - e.receiveSignal(localKey) + e.receiveSignal(myPubKey) - // todo send offer to each peer + for _, pa := range e.agents { + err := pa.Start() + if err != nil { + log.Fatalf("failed starting agent %s %s", myPubKey, err) + return err + } + } return nil }