mirror of
https://github.com/openziti/zrok.git
synced 2024-11-22 16:13:47 +01:00
allow overriding default VPN address
This commit is contained in:
parent
0775847fa5
commit
fdea51210e
@ -3,12 +3,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/endpoints/vpn"
|
||||||
"github.com/openziti/zrok/environment"
|
"github.com/openziti/zrok/environment"
|
||||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
"github.com/openziti/zrok/tui"
|
"github.com/openziti/zrok/tui"
|
||||||
"github.com/openziti/zrok/util"
|
"github.com/openziti/zrok/util"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"net"
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -115,7 +117,15 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "vpn":
|
case "vpn":
|
||||||
target = "vpn"
|
if len(args) == 2 {
|
||||||
|
_, _, err := net.ParseCIDR(args[1])
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("the 'vpn' backend expect valid CIDR <target>", err)
|
||||||
|
}
|
||||||
|
target = args[1]
|
||||||
|
} else {
|
||||||
|
target = vpn.DefaultTarget()
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; "+
|
tui.Error(fmt.Sprintf("invalid backend mode '%v'; "+
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/openziti/zrok/tui"
|
"github.com/openziti/zrok/tui"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -107,7 +108,15 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
|||||||
target = "socks"
|
target = "socks"
|
||||||
|
|
||||||
case "vpn":
|
case "vpn":
|
||||||
target = "vpn"
|
if len(args) == 1 {
|
||||||
|
_, _, err := net.ParseCIDR(args[0])
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("the 'vpn' backend expect valid CIDR <target>", err)
|
||||||
|
}
|
||||||
|
target = args[0]
|
||||||
|
} else {
|
||||||
|
target = vpn.DefaultTarget()
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive}", cmd.backendMode), nil)
|
tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive}", cmd.backendMode), nil)
|
||||||
|
@ -2,6 +2,7 @@ package vpn
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/net-byte/vtun/common/config"
|
"github.com/net-byte/vtun/common/config"
|
||||||
"github.com/net-byte/vtun/tun"
|
"github.com/net-byte/vtun/tun"
|
||||||
_ "github.com/net-byte/vtun/tun"
|
_ "github.com/net-byte/vtun/tun"
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/songgao/water/waterutil"
|
"github.com/songgao/water/waterutil"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -34,7 +36,10 @@ type Backend struct {
|
|||||||
cfg *BackendConfig
|
cfg *BackendConfig
|
||||||
listener edge.Listener
|
listener edge.Listener
|
||||||
|
|
||||||
cidr net.IPAddr
|
addr net.IP
|
||||||
|
addr6 net.IP
|
||||||
|
subnet *net.IPNet
|
||||||
|
subnet6 *net.IPNet
|
||||||
tun *water.Interface
|
tun *water.Interface
|
||||||
mtu int
|
mtu int
|
||||||
|
|
||||||
@ -60,6 +65,19 @@ func NewBackend(cfg *BackendConfig) (*Backend, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error listening")
|
return nil, errors.Wrap(err, "error listening")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr6 := zrokIPv6Addr
|
||||||
|
addr4 := zrokIPv4Addr
|
||||||
|
sub4 := zrokIPv4
|
||||||
|
sub6 := zrokIPv6
|
||||||
|
|
||||||
|
if cfg.EndpointAddress != "" {
|
||||||
|
addr4, sub4, err = net.ParseCIDR(cfg.EndpointAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to parse VPN subnet config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
b := &Backend{
|
b := &Backend{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
listener: listener,
|
listener: listener,
|
||||||
@ -67,6 +85,10 @@ func NewBackend(cfg *BackendConfig) (*Backend, error) {
|
|||||||
clients: cmap.NewWithCustomShardingFunction[dest, *client](func(key dest) uint32 {
|
clients: cmap.NewWithCustomShardingFunction[dest, *client](func(key dest) uint32 {
|
||||||
return key.toInt32()
|
return key.toInt32()
|
||||||
}),
|
}),
|
||||||
|
addr: addr4,
|
||||||
|
addr6: addr6,
|
||||||
|
subnet: sub4,
|
||||||
|
subnet6: sub6,
|
||||||
}
|
}
|
||||||
b.counter.Store(1)
|
b.counter.Store(1)
|
||||||
return b, nil
|
return b, nil
|
||||||
@ -112,15 +134,18 @@ func (b *Backend) Run() error {
|
|||||||
logrus.Info("started")
|
logrus.Info("started")
|
||||||
defer logrus.Info("exited")
|
defer logrus.Info("exited")
|
||||||
|
|
||||||
|
bits, _ := b.subnet.Mask.Size()
|
||||||
|
bits6, _ := b.subnet6.Mask.Size()
|
||||||
|
|
||||||
tunCfg := config.Config{
|
tunCfg := config.Config{
|
||||||
ServerIP: "192.168.127.1",
|
ServerIP: b.addr.String(),
|
||||||
ServerIPv6: "fced::ffff:c0a8:7f01",
|
ServerIPv6: b.addr6.String(),
|
||||||
CIDR: "192.168.127.1/24",
|
CIDR: b.addr.String() + "/" + strconv.Itoa(bits),
|
||||||
CIDRv6: "fced::ffff:c0a8:7f01/64",
|
CIDRv6: b.addr6.String() + "/" + strconv.Itoa(bits6),
|
||||||
MTU: ZROK_VPN_MTU,
|
MTU: ZROK_VPN_MTU,
|
||||||
Verbose: true,
|
Verbose: true,
|
||||||
}
|
}
|
||||||
|
logrus.Infof("%+v", tunCfg)
|
||||||
b.tun = tun.CreateTun(tunCfg)
|
b.tun = tun.CreateTun(tunCfg)
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = b.tun.Close()
|
_ = b.tun.Close()
|
||||||
@ -142,20 +167,18 @@ func (b *Backend) handle(conn net.Conn) {
|
|||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
}(conn)
|
}(conn)
|
||||||
|
|
||||||
num := uint32(0)
|
ipv4, ipv6 := b.nextIP()
|
||||||
for num == 0 || num == 1 {
|
|
||||||
num = b.counter.Add(1)
|
|
||||||
num = num % 256
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv4 := net.IPv4(192, 168, 127, byte(num))
|
|
||||||
ip := ipToDest(ipv4)
|
ip := ipToDest(ipv4)
|
||||||
|
|
||||||
|
bits, _ := b.subnet.Mask.Size()
|
||||||
|
bits6, _ := b.subnet6.Mask.Size()
|
||||||
|
|
||||||
cfg := &ClientConfig{
|
cfg := &ClientConfig{
|
||||||
Greeting: "Welcome to zrok VPN",
|
Greeting: "Welcome to zrok VPN",
|
||||||
IP: ipv4.String(),
|
ServerIP: b.addr.String(),
|
||||||
ServerIP: "192.168.127.1",
|
ServerIPv6: b.addr6.String(),
|
||||||
CIDR: ipv4.String() + "/24",
|
CIDR: ipv4.String() + "/" + strconv.Itoa(bits),
|
||||||
|
CIDR6: ipv6.String() + "/" + strconv.Itoa(bits6),
|
||||||
MTU: b.mtu,
|
MTU: b.mtu,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,3 +226,40 @@ func (b *Backend) handle(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Backend) nextIP() (net.IP, net.IP) {
|
||||||
|
ip4 := make([]byte, len(b.subnet.IP))
|
||||||
|
for {
|
||||||
|
copy(ip4, b.subnet.IP)
|
||||||
|
n := b.counter.Add(1)
|
||||||
|
if n == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(ip4); i++ {
|
||||||
|
b := (n >> (i * 8)) % 0xff
|
||||||
|
ip4[len(ip4)-1-i] ^= byte(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// subnet overflow
|
||||||
|
if !b.subnet.Contains(ip4) {
|
||||||
|
b.counter.Store(1)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmp.Equal(b.addr, ip4) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.clients.Has(ipToDest(ip4)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
ip6 := append([]byte{}, b.subnet6.IP...)
|
||||||
|
copy(ip6[net.IPv6len-net.IPv4len:], ip4)
|
||||||
|
|
||||||
|
return ip4, ip6
|
||||||
|
}
|
||||||
|
@ -82,8 +82,8 @@ func (f *Frontend) Run() error {
|
|||||||
cfg := config.Config{
|
cfg := config.Config{
|
||||||
ServerIP: cltCfg.ServerIP,
|
ServerIP: cltCfg.ServerIP,
|
||||||
CIDR: cltCfg.CIDR,
|
CIDR: cltCfg.CIDR,
|
||||||
ServerIPv6: "fced::ffff:c0a8:7f01",
|
ServerIPv6: cltCfg.ServerIPv6,
|
||||||
CIDRv6: "fced::ffff:c0a8:7f16/64",
|
CIDRv6: cltCfg.CIDR6,
|
||||||
MTU: cltCfg.MTU,
|
MTU: cltCfg.MTU,
|
||||||
Verbose: false,
|
Verbose: false,
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,42 @@ import (
|
|||||||
|
|
||||||
const ZROK_VPN_MTU = 16 * 1024
|
const ZROK_VPN_MTU = 16 * 1024
|
||||||
|
|
||||||
|
var (
|
||||||
|
zrokIPv4Addr = net.IPv4(10, 'z', 0, 0)
|
||||||
|
zrokIPv4 = &net.IPNet{
|
||||||
|
IP: net.IPv4(10, 'z', 0, 0),
|
||||||
|
Mask: net.CIDRMask(16, 8*net.IPv4len),
|
||||||
|
}
|
||||||
|
|
||||||
|
zrokIPv6Addr = net.IP{0xfd, 0, 'z', 'r', 'o', 'k', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
||||||
|
zrokIPv6 = &net.IPNet{
|
||||||
|
IP: net.IP{0xfd, 0, 'z', 'r', 'o', 'k', // prefix + global ID
|
||||||
|
0, 0, // subnet id
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
},
|
||||||
|
Mask: net.CIDRMask(64, 8*net.IPv6len),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func DefaultTarget() string {
|
||||||
|
l := len(zrokIPv4Addr)
|
||||||
|
subnet := net.IPNet{
|
||||||
|
IP: make([]byte, l),
|
||||||
|
Mask: zrokIPv4.Mask,
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(subnet.IP, zrokIPv4Addr)
|
||||||
|
subnet.IP[l-1] = 1
|
||||||
|
return subnet.String()
|
||||||
|
}
|
||||||
|
|
||||||
type ClientConfig struct {
|
type ClientConfig struct {
|
||||||
Greeting string
|
Greeting string
|
||||||
IP string
|
|
||||||
CIDR string
|
CIDR string
|
||||||
|
CIDR6 string
|
||||||
ServerIP string
|
ServerIP string
|
||||||
|
ServerIPv6 string
|
||||||
Routes []string
|
Routes []string
|
||||||
MTU int
|
MTU int
|
||||||
}
|
}
|
||||||
|
1
go.mod
1
go.mod
@ -17,6 +17,7 @@ require (
|
|||||||
github.com/go-openapi/validate v0.23.0
|
github.com/go-openapi/validate v0.23.0
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||||
|
github.com/google/go-cmp v0.6.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/websocket v1.5.1
|
github.com/gorilla/websocket v1.5.1
|
||||||
github.com/iancoleman/strcase v0.2.0
|
github.com/iancoleman/strcase v0.2.0
|
||||||
|
Loading…
Reference in New Issue
Block a user