mirror of
https://github.com/fosrl/newt.git
synced 2025-05-12 21:20:39 +01:00
Basic relay working!
This commit is contained in:
parent
f6429b6eee
commit
b68502de9e
4 changed files with 44 additions and 72 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
newt
|
||||
.DS_Store
|
||||
bin/
|
||||
bin/
|
||||
nohup.out
|
14
main.go
14
main.go
|
@ -258,7 +258,6 @@ func main() {
|
|||
logLevel string
|
||||
interfaceName string
|
||||
generateAndSaveKeyTo string
|
||||
reachableAt string
|
||||
)
|
||||
|
||||
// if PANGOLIN_ENDPOINT, NEWT_ID, and NEWT_SECRET are set as environment variables, they will be used as default values
|
||||
|
@ -270,7 +269,6 @@ func main() {
|
|||
logLevel = os.Getenv("LOG_LEVEL")
|
||||
interfaceName = os.Getenv("INTERFACE")
|
||||
generateAndSaveKeyTo = os.Getenv("GENERATE_AND_SAVE_KEY_TO")
|
||||
reachableAt = os.Getenv("REACHABLE_AT")
|
||||
|
||||
if endpoint == "" {
|
||||
flag.StringVar(&endpoint, "endpoint", "", "Endpoint of your pangolin server")
|
||||
|
@ -296,9 +294,6 @@ func main() {
|
|||
if generateAndSaveKeyTo == "" {
|
||||
flag.StringVar(&generateAndSaveKeyTo, "generateAndSaveKeyTo", "", "Path to save generated private key")
|
||||
}
|
||||
if reachableAt == "" {
|
||||
flag.StringVar(&reachableAt, "reachableAt", "", "Endpoint of the http server to tell remote config about")
|
||||
}
|
||||
|
||||
// do a --version check
|
||||
version := flag.Bool("version", false, "Print the version")
|
||||
|
@ -353,7 +348,7 @@ func main() {
|
|||
}
|
||||
|
||||
// Create WireGuard service
|
||||
wgService, err = wg.NewWireGuardService(interfaceName, mtuInt, reachableAt, generateAndSaveKeyTo, host, id, client)
|
||||
wgService, err = wg.NewWireGuardService(interfaceName, mtuInt, generateAndSaveKeyTo, host, id, client)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to create WireGuard service: %v", err)
|
||||
}
|
||||
|
@ -469,6 +464,13 @@ persistent_keepalive_interval=5`, fixKey(fmt.Sprintf("%s", privateKey)), fixKey(
|
|||
updateTargets(pm, "add", wgData.TunnelIP, "udp", TargetData{Targets: wgData.Targets.UDP})
|
||||
}
|
||||
|
||||
// first make sure the wpgService has a port
|
||||
if wgService != nil {
|
||||
// add a udp proxy for localost and the wgService port
|
||||
// TODO: make sure this port is not used in a target
|
||||
pm.AddTarget("udp", wgData.TunnelIP, int(wgService.Port), fmt.Sprintf("localhost:%d", wgService.Port))
|
||||
}
|
||||
|
||||
err = pm.Start()
|
||||
if err != nil {
|
||||
logger.Error("Failed to start proxy manager: %v", err)
|
||||
|
|
25
nohup.out
25
nohup.out
|
@ -1,25 +0,0 @@
|
|||
INFO: 2025/02/22 23:25:47 Requesting WireGuard configuration from remote server
|
||||
INFO: 2025/02/22 23:25:47 Sent registration message
|
||||
INFO: 2025/02/22 23:25:47 Received message: {newt/wg/receive-config map[ipAddress:100.90.128.1/24 listenPort:51822 peers:[]]}
|
||||
INFO: 2025/02/22 23:25:47 Created WireGuard interface wg1
|
||||
INFO: 2025/02/22 23:25:47 Assigning IP address 100.90.128.1/24 to interface wg1
|
||||
INFO: 2025/02/22 23:25:47 WireGuard interface wg1 created and configured
|
||||
INFO: 2025/02/22 23:25:47 Received registration message
|
||||
INFO: 2025/02/22 23:25:47 Received: {Type:newt/wg/connect Data:map[endpoint:pangolin.fosrl.io:51820 publicKey:tng9Z/BN32flFjqwwT1yAxN/twFkmgbZA+D9N+YqdjM= serverIP:100.89.128.1 targets:map[tcp:[] udp:[]] tunnelIP:100.89.128.4]}
|
||||
INFO: 2025/02/22 23:25:47 WireGuard device created. Lets ping the server now...
|
||||
INFO: 2025/02/22 23:25:47 Ping attempt 1 of 5
|
||||
INFO: 2025/02/22 23:25:47 Pinging 100.89.128.1
|
||||
INFO: 2025/02/22 23:25:47 Ping latency: 9.00105ms
|
||||
INFO: 2025/02/22 23:25:47 Starting ping check
|
||||
INFO: 2025/02/22 23:26:48 Peer P9pacnRfUSfvDibaQTdTk59q27eRpgtbMMmMpkNwKl0= removed successfully
|
||||
INFO: 2025/02/22 23:26:48 Peer NMrcorGgTTi4tAUZ1lLru0qISNrt9D9JdsFGyDYlcSQ= added successfully
|
||||
INFO: 2025/02/22 23:28:58 Peer NMrcorGgTTi4tAUZ1lLru0qISNrt9D9JdsFGyDYlcSQ= removed successfully
|
||||
INFO: 2025/02/22 23:28:58 Peer n8ZKTG8vsROL/OiqHYJELU/Rg9XDifz0YjE/lQsL0m0= added successfully
|
||||
INFO: 2025/02/22 23:33:59 Peer n8ZKTG8vsROL/OiqHYJELU/Rg9XDifz0YjE/lQsL0m0= removed successfully
|
||||
INFO: 2025/02/22 23:33:59 Peer /i8YTgrLkZh08HKXLXqNFQJsyg1E8I2ELXqF0zuP9D8= added successfully
|
||||
INFO: 2025/02/22 23:34:06 Peer /i8YTgrLkZh08HKXLXqNFQJsyg1E8I2ELXqF0zuP9D8= removed successfully
|
||||
INFO: 2025/02/22 23:34:06 Peer 50+RB00sDoSG+KAKzl/baaqPkKGOe7upX7uqRCKqsRo= added successfully
|
||||
INFO: 2025/02/22 23:35:07 Peer 50+RB00sDoSG+KAKzl/baaqPkKGOe7upX7uqRCKqsRo= removed successfully
|
||||
INFO: 2025/02/22 23:35:07 Peer Aa2Y2NEmc+SITlT89+fsOeqDkXJVu9RBY14+77TXa3w= added successfully
|
||||
INFO: 2025/02/23 00:55:55 Peer Aa2Y2NEmc+SITlT89+fsOeqDkXJVu9RBY14+77TXa3w= removed successfully
|
||||
INFO: 2025/02/23 00:55:55 Peer 2AXNjMQzT7GGvdbIG6MJVFpO3FIzQ+qCqZkdSnBA3DE= added successfully
|
74
wg/wg.go
74
wg/wg.go
|
@ -51,12 +51,12 @@ type WireGuardService struct {
|
|||
wgClient *wgctrl.Client
|
||||
config WgConfig
|
||||
key wgtypes.Key
|
||||
reachableAt string
|
||||
newtId string
|
||||
lastReadings map[string]PeerReading
|
||||
mu sync.Mutex
|
||||
port uint16
|
||||
Port uint16
|
||||
stopHolepunch chan struct{}
|
||||
host string
|
||||
}
|
||||
|
||||
// Add this type definition
|
||||
|
@ -113,7 +113,7 @@ func FindAvailableUDPPort(minPort, maxPort uint16) (uint16, error) {
|
|||
return 0, fmt.Errorf("no available UDP ports found in range %d-%d", minPort, maxPort)
|
||||
}
|
||||
|
||||
func NewWireGuardService(interfaceName string, mtu int, reachableAt string, generateAndSaveKeyTo string, host string, newtId string, wsClient *websocket.Client) (*WireGuardService, error) {
|
||||
func NewWireGuardService(interfaceName string, mtu int, generateAndSaveKeyTo string, host string, newtId string, wsClient *websocket.Client) (*WireGuardService, error) {
|
||||
wgClient, err := wgctrl.New()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create WireGuard client: %v", err)
|
||||
|
@ -155,20 +155,13 @@ func NewWireGuardService(interfaceName string, mtu int, reachableAt string, gene
|
|||
client: wsClient,
|
||||
wgClient: wgClient,
|
||||
key: key,
|
||||
reachableAt: reachableAt,
|
||||
newtId: newtId,
|
||||
lastReadings: make(map[string]PeerReading),
|
||||
port: port,
|
||||
Port: port,
|
||||
stopHolepunch: make(chan struct{}),
|
||||
host: host,
|
||||
}
|
||||
|
||||
if err := service.sendUDPHolePunch(host + ":21820"); err != nil {
|
||||
logger.Error("Failed to send UDP hole punch: %v", err)
|
||||
}
|
||||
|
||||
// start the UDP holepunch
|
||||
go service.keepSendingUDPHolePunch(host)
|
||||
|
||||
// Register websocket handlers
|
||||
wsClient.RegisterHandler("newt/wg/receive-config", service.handleConfig)
|
||||
wsClient.RegisterHandler("newt/wg/peer/add", service.handleAddPeer)
|
||||
|
@ -185,7 +178,6 @@ func (s *WireGuardService) LoadRemoteConfig() error {
|
|||
|
||||
err := s.client.SendMessage("newt/wg/get-config", map[string]interface{}{
|
||||
"publicKey": fmt.Sprintf("%s", s.key.PublicKey().String()),
|
||||
"endpoint": s.reachableAt,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("Failed to send registration message: %v", err)
|
||||
|
@ -216,9 +208,6 @@ func (s *WireGuardService) handleConfig(msg websocket.WSMessage) {
|
|||
}
|
||||
s.config = config
|
||||
|
||||
// stop the holepunch
|
||||
// close(s.stopHolepunch)
|
||||
|
||||
// Ensure the WireGuard interface and peers are configured
|
||||
if err := s.ensureWireguardInterface(config); err != nil {
|
||||
logger.Error("Failed to ensure WireGuard interface: %v", err)
|
||||
|
@ -227,6 +216,13 @@ func (s *WireGuardService) handleConfig(msg websocket.WSMessage) {
|
|||
if err := s.ensureWireguardPeers(config.Peers); err != nil {
|
||||
logger.Error("Failed to ensure WireGuard peers: %v", err)
|
||||
}
|
||||
|
||||
if err := s.sendUDPHolePunch(s.host + ":21820"); err != nil {
|
||||
logger.Error("Failed to send UDP hole punch: %v", err)
|
||||
}
|
||||
|
||||
// start the UDP holepunch
|
||||
go s.keepSendingUDPHolePunch(s.host)
|
||||
}
|
||||
|
||||
func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
|
||||
|
@ -245,6 +241,17 @@ func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
|
|||
}
|
||||
} else {
|
||||
logger.Info("WireGuard interface %s already exists\n", s.interfaceName)
|
||||
|
||||
// get the exising wireguard port
|
||||
device, err := s.wgClient.Device(s.interfaceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get device: %v", err)
|
||||
}
|
||||
|
||||
// get the existing port
|
||||
s.Port = uint16(device.ListenPort)
|
||||
logger.Info("WireGuard interface %s already exists with port %d\n", s.interfaceName, s.Port)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -273,7 +280,7 @@ func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
|
|||
}
|
||||
|
||||
// Use the service's fixed port instead of the config port
|
||||
*config.ListenPort = int(s.port)
|
||||
*config.ListenPort = int(s.Port)
|
||||
|
||||
// Create and configure the WireGuard interface
|
||||
err = s.wgClient.ConfigureDevice(s.interfaceName, config)
|
||||
|
@ -390,6 +397,7 @@ func (s *WireGuardService) handleAddPeer(msg websocket.WSMessage) {
|
|||
|
||||
err = s.addPeer(peer)
|
||||
if err != nil {
|
||||
logger.Info("Error adding peer: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -411,16 +419,18 @@ func (s *WireGuardService) addPeer(peer Peer) error {
|
|||
}
|
||||
// add keep alive using *time.Duration of 1 second
|
||||
keepalive := time.Second
|
||||
endpoint, err := net.ResolveUDPAddr("udp", peer.Endpoint)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve endpoint address: %w", err)
|
||||
}
|
||||
// endpoint, err := net.ResolveUDPAddr("udp", peer.Endpoint)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to resolve endpoint address: %w", err)
|
||||
// }
|
||||
|
||||
// make the endpoint localhost to test
|
||||
|
||||
peerConfig := wgtypes.PeerConfig{
|
||||
PublicKey: pubKey,
|
||||
AllowedIPs: allowedIPs,
|
||||
PersistentKeepaliveInterval: &keepalive,
|
||||
Endpoint: endpoint,
|
||||
// Endpoint: endpoint,
|
||||
}
|
||||
|
||||
config := wgtypes.Config{
|
||||
|
@ -626,7 +636,7 @@ func (s *WireGuardService) sendUDPHolePunch(serverAddr string) error {
|
|||
|
||||
client := &network.PeerNet{
|
||||
IP: clientIP,
|
||||
Port: s.port,
|
||||
Port: s.Port,
|
||||
NewtID: s.newtId,
|
||||
}
|
||||
|
||||
|
@ -647,27 +657,11 @@ func (s *WireGuardService) sendUDPHolePunch(serverAddr string) error {
|
|||
return fmt.Errorf("failed to send UDP packet: %v", err)
|
||||
}
|
||||
|
||||
// logger.Info("Sent UDP hole punch to %s", serverAddr)
|
||||
|
||||
// // Wait for response if needed
|
||||
// response, err := network.RecvDataPacket(rawConn, server, client)
|
||||
// if err != nil {
|
||||
// if err, ok := err.(net.Error); ok && err.Timeout() {
|
||||
// return fmt.Errorf("connection to %s timed out", serverAddr)
|
||||
// }
|
||||
// return fmt.Errorf("error receiving response: %v", err)
|
||||
// }
|
||||
|
||||
// // Process response if needed
|
||||
// if len(response) > 0 {
|
||||
// logger.Info("Received response from server")
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WireGuardService) keepSendingUDPHolePunch(host string) {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
ticker := time.NewTicker(3 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
|
|
Loading…
Reference in a new issue