fix: flow order - wireguard proxy goes first

This commit is contained in:
braginini 2021-04-15 16:25:25 +02:00
parent 2cfafe9392
commit d3454eb0f9
6 changed files with 64 additions and 52 deletions

View File

@ -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)")
}

View File

@ -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("")

View File

@ -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 ??

View File

@ -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

View File

@ -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

View File

@ -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??
}
}