mirror of
https://github.com/whyvl/wireproxy.git
synced 2025-04-29 19:01:42 +02:00
Allow multiple peers, tunnels, and proxies
This commit is contained in:
parent
e686381fa9
commit
aef9da0bdf
4 changed files with 110 additions and 52 deletions
74
config.go
74
config.go
|
@ -12,15 +12,20 @@ import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PeerConfig struct {
|
||||||
|
PublicKey string
|
||||||
|
PreSharedKey string
|
||||||
|
Endpoint string
|
||||||
|
KeepAlive int
|
||||||
|
AllowedIPs []netip.Prefix
|
||||||
|
}
|
||||||
|
|
||||||
// DeviceConfig contains the information to initiate a wireguard connection
|
// DeviceConfig contains the information to initiate a wireguard connection
|
||||||
type DeviceConfig struct {
|
type DeviceConfig struct {
|
||||||
SelfSecretKey string
|
SecretKey string
|
||||||
SelfEndpoint []netip.Addr
|
Endpoint []netip.Addr
|
||||||
PeerPublicKey string
|
Peers []PeerConfig
|
||||||
PeerEndpoint string
|
|
||||||
DNS []netip.Addr
|
DNS []netip.Addr
|
||||||
KeepAlive int
|
|
||||||
PreSharedKey string
|
|
||||||
MTU int
|
MTU int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +149,24 @@ func parseCIDRNetIP(section *ini.Section, keyName string) ([]netip.Addr, error)
|
||||||
return ips, nil
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseAllowedIPs(section *ini.Section) ([]netip.Prefix, error) {
|
||||||
|
key := section.Key("AllowedIPs")
|
||||||
|
if key == nil {
|
||||||
|
return []netip.Prefix{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var ips []netip.Prefix
|
||||||
|
for _, str := range key.StringsWithShadows(",") {
|
||||||
|
prefix, err := netip.ParsePrefix(str)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ips = append(ips, prefix)
|
||||||
|
}
|
||||||
|
return ips, nil
|
||||||
|
}
|
||||||
|
|
||||||
func resolveIP(ip string) (*net.IPAddr, error) {
|
func resolveIP(ip string) (*net.IPAddr, error) {
|
||||||
return net.ResolveIPAddr("ip", ip)
|
return net.ResolveIPAddr("ip", ip)
|
||||||
}
|
}
|
||||||
|
@ -174,13 +197,13 @@ func ParseInterface(cfg *ini.File, device *DeviceConfig) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
device.SelfEndpoint = address
|
device.Endpoint = address
|
||||||
|
|
||||||
privKey, err := parseBase64KeyToHex(section, "PrivateKey")
|
privKey, err := parseBase64KeyToHex(section, "PrivateKey")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
device.SelfSecretKey = privKey
|
device.SecretKey = privKey
|
||||||
|
|
||||||
dns, err := parseNetIP(section, "DNS")
|
dns, err := parseNetIP(section, "DNS")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -199,26 +222,31 @@ func ParseInterface(cfg *ini.File, device *DeviceConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsePeer parses the [Peer] section and extract the information into `device`
|
// ParsePeer parses the [Peer] section and extract the information into `peers`
|
||||||
func ParsePeer(cfg *ini.File, device *DeviceConfig) error {
|
func ParsePeers(cfg *ini.File, peers *[]PeerConfig) error {
|
||||||
sections, err := cfg.SectionsByName("Peer")
|
sections, err := cfg.SectionsByName("Peer")
|
||||||
if len(sections) != 1 || err != nil {
|
if len(sections) < 1 || err != nil {
|
||||||
return errors.New("one and only one [Peer] is expected")
|
return errors.New("at least one [Peer] is expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, section := range sections {
|
||||||
|
peer := PeerConfig{
|
||||||
|
PreSharedKey: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
KeepAlive: 0,
|
||||||
}
|
}
|
||||||
section := sections[0]
|
|
||||||
|
|
||||||
decoded, err := parseBase64KeyToHex(section, "PublicKey")
|
decoded, err := parseBase64KeyToHex(section, "PublicKey")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
device.PeerPublicKey = decoded
|
peer.PublicKey = decoded
|
||||||
|
|
||||||
if sectionKey, err := section.GetKey("PreSharedKey"); err == nil {
|
if sectionKey, err := section.GetKey("PreSharedKey"); err == nil {
|
||||||
value, err := encodeBase64ToHex(sectionKey.String())
|
value, err := encodeBase64ToHex(sectionKey.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
device.PreSharedKey = value
|
peer.PreSharedKey = value
|
||||||
}
|
}
|
||||||
|
|
||||||
decoded, err = parseString(section, "Endpoint")
|
decoded, err = parseString(section, "Endpoint")
|
||||||
|
@ -229,16 +257,23 @@ func ParsePeer(cfg *ini.File, device *DeviceConfig) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
device.PeerEndpoint = decoded
|
peer.Endpoint = decoded
|
||||||
|
|
||||||
if sectionKey, err := section.GetKey("PersistentKeepalive"); err == nil {
|
if sectionKey, err := section.GetKey("PersistentKeepalive"); err == nil {
|
||||||
value, err := sectionKey.Int()
|
value, err := sectionKey.Int()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
device.KeepAlive = value
|
peer.KeepAlive = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer.AllowedIPs, err = parseAllowedIPs(section)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*peers = append(*peers, peer)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +355,7 @@ func ParseConfig(path string) (*Configuration, error) {
|
||||||
iniOpt := ini.LoadOptions{
|
iniOpt := ini.LoadOptions{
|
||||||
Insensitive: true,
|
Insensitive: true,
|
||||||
AllowShadows: true,
|
AllowShadows: true,
|
||||||
|
AllowNonUniqueSections: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := ini.LoadSources(iniOpt, path)
|
cfg, err := ini.LoadSources(iniOpt, path)
|
||||||
|
@ -328,8 +364,6 @@ func ParseConfig(path string) (*Configuration, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
device := &DeviceConfig{
|
device := &DeviceConfig{
|
||||||
PreSharedKey: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
KeepAlive: 0,
|
|
||||||
MTU: 1420,
|
MTU: 1420,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +382,7 @@ func ParseConfig(path string) (*Configuration, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ParsePeer(wgCfg, device)
|
err = ParsePeers(wgCfg, &device.Peers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/octeep/wireproxy
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||||
github.com/akamensky/argparse v1.3.1
|
github.com/akamensky/argparse v1.3.1
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||||
github.com/go-ini/ini v1.66.4
|
github.com/go-ini/ini v1.66.4
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -56,6 +56,8 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
|
||||||
|
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||||
|
|
39
wireguard.go
39
wireguard.go
|
@ -1,12 +1,15 @@
|
||||||
package wireproxy
|
package wireproxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/MakeNowJust/heredoc/v2"
|
||||||
"golang.zx2c4.com/wireguard/conn"
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
"golang.zx2c4.com/wireguard/tun/netstack"
|
||||||
"net/netip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeviceSetting contains the parameters for setting up a tun interface
|
// DeviceSetting contains the parameters for setting up a tun interface
|
||||||
|
@ -19,15 +22,33 @@ type DeviceSetting struct {
|
||||||
|
|
||||||
// serialize the config into an IPC request and DeviceSetting
|
// serialize the config into an IPC request and DeviceSetting
|
||||||
func createIPCRequest(conf *DeviceConfig) (*DeviceSetting, error) {
|
func createIPCRequest(conf *DeviceConfig) (*DeviceSetting, error) {
|
||||||
request := fmt.Sprintf(`private_key=%s
|
var request bytes.Buffer
|
||||||
public_key=%s
|
|
||||||
endpoint=%s
|
|
||||||
persistent_keepalive_interval=%d
|
|
||||||
preshared_key=%s
|
|
||||||
allowed_ip=0.0.0.0/0
|
|
||||||
allowed_ip=::0/0`, conf.SelfSecretKey, conf.PeerPublicKey, conf.PeerEndpoint, conf.KeepAlive, conf.PreSharedKey)
|
|
||||||
|
|
||||||
setting := &DeviceSetting{ipcRequest: request, dns: conf.DNS, deviceAddr: conf.SelfEndpoint, mtu: conf.MTU}
|
request.WriteString(fmt.Sprintf("private_key=%s\n", conf.SecretKey))
|
||||||
|
|
||||||
|
for _, peer := range conf.Peers {
|
||||||
|
request.WriteString(fmt.Sprintf(heredoc.Doc(`
|
||||||
|
public_key=%s
|
||||||
|
endpoint=%s
|
||||||
|
persistent_keepalive_interval=%d
|
||||||
|
preshared_key=%s
|
||||||
|
`),
|
||||||
|
peer.PublicKey, peer.Endpoint, peer.KeepAlive, peer.PreSharedKey,
|
||||||
|
))
|
||||||
|
|
||||||
|
if len(peer.AllowedIPs) > 0 {
|
||||||
|
for _, ip := range peer.AllowedIPs {
|
||||||
|
request.WriteString(fmt.Sprintf("allowed_ip=%s\n", ip.String()))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
request.WriteString(heredoc.Doc(`
|
||||||
|
allowed_ip=0.0.0.0/0
|
||||||
|
allowed_ip=::0/0
|
||||||
|
`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setting := &DeviceSetting{ipcRequest: request.String(), dns: conf.DNS, deviceAddr: conf.Endpoint, mtu: conf.MTU}
|
||||||
return setting, nil
|
return setting, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue