mirror of
https://github.com/openziti/zrok.git
synced 2024-11-28 19:14:07 +01:00
132 lines
3.0 KiB
Go
132 lines
3.0 KiB
Go
package vpn
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/net-byte/vtun/common/config"
|
|
"github.com/net-byte/vtun/tun"
|
|
"github.com/openziti/sdk-golang/ziti"
|
|
"github.com/openziti/zrok/endpoints"
|
|
"github.com/openziti/zrok/environment"
|
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
type FrontendConfig struct {
|
|
IdentityName string
|
|
ShrToken string
|
|
RequestsChan chan *endpoints.Request
|
|
}
|
|
|
|
type Frontend struct {
|
|
cfg *FrontendConfig
|
|
ztx ziti.Context
|
|
conn net.Conn
|
|
}
|
|
|
|
func NewFrontend(cfg *FrontendConfig) (*Frontend, error) {
|
|
env, err := environment.LoadRoot()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "error loading environment root")
|
|
}
|
|
zCfgPath, err := env.ZitiIdentityNamed(cfg.IdentityName)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "error getting ziti identity '%v' from environment", cfg.IdentityName)
|
|
}
|
|
zCfg, err := ziti.NewConfigFromFile(zCfgPath)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "error loading config")
|
|
}
|
|
zCfg.ConfigTypes = []string{sdk.ZrokProxyConfig}
|
|
zCtx, err := ziti.NewContext(zCfg)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "error loading ziti context")
|
|
}
|
|
|
|
zConn, err := zCtx.DialWithOptions(cfg.ShrToken, &ziti.DialOptions{ConnectTimeout: 30 * time.Second})
|
|
if err != nil {
|
|
zCtx.Close()
|
|
return nil, errors.Wrap(err, "error connecting to ziti")
|
|
}
|
|
return &Frontend{
|
|
cfg: cfg,
|
|
ztx: zCtx,
|
|
conn: zConn,
|
|
}, nil
|
|
}
|
|
|
|
func (f *Frontend) Run() error {
|
|
var cltCfg ClientConfig
|
|
d := json.NewDecoder(f.conn)
|
|
if err := d.Decode(&cltCfg); err != nil {
|
|
return errors.Wrap(err, "error decoding vpn config")
|
|
}
|
|
f.cfg.RequestsChan <- &endpoints.Request{
|
|
Stamp: time.Now(),
|
|
RemoteAddr: cltCfg.ServerIP,
|
|
Method: "CONNECTED",
|
|
Path: cltCfg.Greeting,
|
|
}
|
|
logrus.Info("connected:", cltCfg.Greeting)
|
|
|
|
defer func() {
|
|
f.cfg.RequestsChan <- &endpoints.Request{
|
|
Stamp: time.Now(),
|
|
RemoteAddr: cltCfg.ServerIP,
|
|
Method: "Disconnected",
|
|
}
|
|
}()
|
|
|
|
cfg := config.Config{
|
|
ServerIP: cltCfg.ServerIP,
|
|
CIDR: cltCfg.CIDR,
|
|
ServerIPv6: cltCfg.ServerIPv6,
|
|
CIDRv6: cltCfg.CIDR6,
|
|
MTU: cltCfg.MTU,
|
|
Verbose: false,
|
|
}
|
|
iface := tun.CreateTun(cfg)
|
|
|
|
logrus.Infof("created tun device: %s", iface.Name())
|
|
|
|
go func() {
|
|
defer func() {
|
|
_ = f.conn.Close()
|
|
_ = iface.Close()
|
|
}()
|
|
|
|
b := make([]byte, cltCfg.MTU)
|
|
for {
|
|
n, err := f.conn.Read(b)
|
|
if err != nil {
|
|
logrus.WithError(err).Error("error reading from ziti")
|
|
return
|
|
}
|
|
p := packet(b[:n])
|
|
logrus.WithField("packet", p).Trace("received packet from peer")
|
|
_, err = iface.Write(p)
|
|
if err != nil {
|
|
logrus.WithError(err).Error("error writing to device")
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
buf := make([]byte, cltCfg.MTU)
|
|
for {
|
|
n, err := iface.Read(buf)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error reading packet")
|
|
}
|
|
pkt := packet(buf[:n])
|
|
logrus.WithField("packet", pkt).Trace("read packet from tun device")
|
|
_, err = f.conn.Write(pkt)
|
|
|
|
if err != nil {
|
|
return errors.Wrap(err, "error sending packet to ziti")
|
|
}
|
|
}
|
|
}
|