diff --git a/cmd/signal.go b/cmd/signal.go index fad093ba0..db1582c1c 100644 --- a/cmd/signal.go +++ b/cmd/signal.go @@ -42,6 +42,5 @@ var ( ) func init() { - //upCmd.PersistentFlags().IntVar(&port, "port", 10000, "Server port to listen on (e.g. 10000)") upCmd.PersistentFlags().IntVar(&port, "port", 10000, "Server port to listen on (e.g. 10000)") } diff --git a/cmd/up.go b/cmd/up.go index ae41c428c..768af7225 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -25,17 +25,8 @@ var ( Use: "up", Short: "start wiretrustee", Run: func(cmd *cobra.Command, args []string) { - /*config, err := ReadConfig("config.yml") - if err != nil { - log.Fatal("failed to load config") - os.Exit(ExitSetupFailed) - }*/ + log.SetLevel(log.DebugLevel) - //c := defaultConfig() - - //todo print config - - //todo connect to signal ctx := context.Background() signalClient, err := sig.NewClient(config.SignalAddr, ctx) if err != nil { @@ -73,8 +64,8 @@ func init() { 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.TurnUser, "turnUser", "wiretrustee", "A comma separated list of TURN servers including protocol (e.g. stun:stun.wiretrustee.com:3468") + upCmd.PersistentFlags().StringVar(&config.TurnPwd, "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("") diff --git a/engine/agent.go b/engine/agent.go index b2b27ae1a..4708f72f6 100644 --- a/engine/agent.go +++ b/engine/agent.go @@ -4,9 +4,11 @@ import ( "context" "github.com/pion/ice/v2" log "github.com/sirupsen/logrus" + "github.com/wiretrustee/wiretrustee/iface" "github.com/wiretrustee/wiretrustee/signal" sProto "github.com/wiretrustee/wiretrustee/signal/proto" "net" + "time" ) // PeerAgent is responsible for establishing and maintaining of the connection between two peers (local and remote) @@ -26,10 +28,13 @@ type PeerAgent struct { wgConn net.Conn // an address of local Wireguard instance wgAddr string + // + wgIface string } // 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, signal *signal.Client) (*PeerAgent, error) { +func NewPeerAgent(localKey string, remoteKey string, stunTurnURLS []*ice.URL, wgAddr string, signal *signal.Client, + wgIface string) (*PeerAgent, error) { // init ICE Agent iceAgent, err := ice.NewAgent(&ice.AgentConfig{ @@ -48,6 +53,7 @@ func NewPeerAgent(localKey string, remoteKey string, stunTurnURLS []*ice.URL, wg conn: nil, wgConn: nil, signal: signal, + wgIface: wgIface, } err = peerAgent.onConnectionStateChange() @@ -112,19 +118,33 @@ func (pa *PeerAgent) proxyToLocalWireguard() { // 4. after connection has been established peer starts to: // - proxy all local Wireguard's packets to the remote peer // - proxy all incoming data from the remote peer to local Wireguard -// The returned connection address can be used to be set as Wireguard's remote peer endpoint -func (pa *PeerAgent) OpenConnection(initiator bool) (net.Conn, error) { - // start gathering candidates - err := pa.iceAgent.GatherCandidates() +func (pa *PeerAgent) OpenConnection(initiator bool) error { + + // connect to local Wireguard instance + wgConn, err := net.Dial("udp", pa.wgAddr) if err != nil { - return nil, err + log.Fatalf("failed dialing to local Wireguard port %s", err) + return err + } + pa.wgConn = wgConn + + // add local proxy connection as a Wireguard peer + err = iface.UpdatePeer(pa.wgIface, pa.RemoteKey, "0.0.0.0/0", 15*time.Second, wgConn.LocalAddr().String()) + if err != nil { + log.Errorf("error while configuring Wireguard peer [%s] %s", pa.RemoteKey, err.Error()) + } + + // start gathering candidates + err = pa.iceAgent.GatherCandidates() + if err != nil { + return err } // by that time it should be already set frag, pwd, err := pa.iceAgent.GetRemoteUserCredentials() if err != nil { log.Errorf("remote credentials are not set for remote peer %s", pa.RemoteKey) - return nil, err + return err } // initiate remote connection @@ -138,21 +158,13 @@ func (pa *PeerAgent) OpenConnection(initiator bool) (net.Conn, error) { if err != nil { log.Fatalf("failed listening on local port %s", err) - return nil, err + return err } log.Infof("Local addr %s, remote addr %s", conn.LocalAddr(), conn.RemoteAddr()) pa.conn = conn - // connect to local Wireguard instance - wgConn, err := net.Dial("udp", pa.wgAddr) - if err != nil { - log.Fatalf("failed dialing to local Wireguard port %s", err) - return nil, err - } - pa.wgConn = wgConn - - return wgConn, nil + return nil } func (pa *PeerAgent) OnAnswer(msg *sProto.Message) error { @@ -160,21 +172,21 @@ func (pa *PeerAgent) OnAnswer(msg *sProto.Message) error { } func (pa *PeerAgent) OnRemoteCandidate(msg *sProto.Message) error { - return nil -} -// signalCandidate sends a message with a local ice.Candidate details to the remote peer via signal server -func (pa *PeerAgent) signalCandidate(c ice.Candidate) error { - err := pa.signal.Send(&sProto.Message{ - Type: sProto.Message_CANDIDATE, - Key: pa.LocalKey, - RemoteKey: pa.RemoteKey, - Body: c.Marshal(), - }) + log.Debugf("received remote candidate %s", msg.Body) + candidate, err := ice.UnmarshalCandidate(msg.Body) if err != nil { + log.Errorf("failed on parsing remote candidate %s -> %s", candidate, err) return err } + + err = pa.iceAgent.AddRemoteCandidate(candidate) + if err != nil { + log.Errorf("failed on adding remote candidate %s -> %s", candidate, err) + return err + } + return nil } @@ -182,7 +194,15 @@ func (pa *PeerAgent) signalCandidate(c ice.Candidate) error { func (pa *PeerAgent) onCandidate() error { return pa.iceAgent.OnCandidate(func(candidate ice.Candidate) { if candidate != nil { - err := pa.signalCandidate(candidate) + + log.Debugf("discovered local candidate %s", candidate.String()) + + err := pa.signal.Send(&sProto.Message{ + Type: sProto.Message_CANDIDATE, + Key: pa.LocalKey, + RemoteKey: pa.RemoteKey, + Body: candidate.Marshal(), + }) if err != nil { log.Errorf("failed signaling candidate to the remote peer %s %s", pa.RemoteKey, err) //todo ?? diff --git a/engine/engine.go b/engine/engine.go index e7acb7b60..16bd99a6b 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -8,7 +8,6 @@ import ( signal "github.com/wiretrustee/wiretrustee/signal" sProto "github.com/wiretrustee/wiretrustee/signal/proto" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" - "time" ) type Engine struct { @@ -64,7 +63,7 @@ func (e *Engine) Start(privateKey string, peers []string) error { // initialize peer agents for _, peer := range peers { - peerAgent, err := NewPeerAgent(myPubKey, peer, e.stunsTurns, fmt.Sprintf("127.0.0.1:%d", *wgPort), e.signal) + peerAgent, err := NewPeerAgent(myPubKey, peer, e.stunsTurns, fmt.Sprintf("127.0.0.1:%d", *wgPort), e.signal, e.wgIface) if err != nil { log.Fatalf("failed creating peer agent for pair %s - %s", myPubKey, peer) return err @@ -89,9 +88,12 @@ func (e *Engine) receiveSignal(localKey string) { // connect to a stream of messages coming from the signal server e.signal.Receive(localKey, func(msg *sProto.Message) error { - // check if this is our "buddy" peer - peerAgent := e.agents[msg.Key] + peerAgent := e.agents[msg.RemoteKey] if peerAgent == nil { + return fmt.Errorf("wrongly addressed message %s", msg.Key) + } + + if peerAgent.RemoteKey != msg.Key { return fmt.Errorf("unknown peer %s", msg.Key) } @@ -152,15 +154,10 @@ func (e *Engine) handle(msg *sProto.Message, peerAgent *PeerAgent, initiator boo go func() { - conn, err := peerAgent.OpenConnection(initiator) + err := peerAgent.OpenConnection(initiator) if err != nil { log.Errorf("error opening connection ot remote peer %s", msg.Key) } - - err = iface.UpdatePeer(e.wgIface, peerAgent.RemoteKey, "0.0.0.0/0", 15*time.Second, conn.LocalAddr().String()) - if err != nil { - log.Errorf("error while configuring Wireguard peer [%s] %s", peerAgent.RemoteKey, err.Error()) - } }() return cred, nil diff --git a/iface/iface.go b/iface/iface.go index 8a6dee41f..85b93e967 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -159,6 +159,9 @@ func ifname(n string) []byte { // Updates existing Wireguard Peer or creates a new one if doesn't exist // Endpoint is optional func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error { + + log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint) + wg, err := wgctrl.New() if err != nil { return err @@ -208,6 +211,8 @@ func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time. // Used when NAT hole punching was successful and an update of the remote peer endpoint is required func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error { + log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint) + wg, err := wgctrl.New() if err != nil { return err diff --git a/signal/client.go b/signal/client.go index 6d9725fa7..9fd17d3cc 100644 --- a/signal/client.go +++ b/signal/client.go @@ -147,7 +147,7 @@ func (client *Client) receive(stream proto.SignalExchange_ConnectStreamClient, err = msgHandler(msg) if err != nil { - log.Errorf("error while handling message of Peer [fingerprint: %s] error: [%s]", msg.Key, err.Error()) + log.Errorf("error while handling message of Peer [key: %s] error: [%s]", msg.Key, err.Error()) //todo send something?? } }