Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ test:
docker run fosrl/newt:latest

local:
CGO_ENABLED=0 go build -o newt
CGO_ENABLED=0 go build -o newt

all_arches:
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o newt_linux_arm64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o newt_linux_amd64
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o newt_darwin_arm64
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o newt_darwin_amd64
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o newt_windows_amd64.exe
CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -o newt_freebsd_amd64
CGO_ENABLED=0 GOOS=freebsd GOARCH=arm64 go build -o newt_freebsd_arm64

clean:
rm newt
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ _Sample output of a Newt container connected to Pangolin and hosting various res

### Registers with Pangolin

Using the Newt ID and a secret the client will make HTTP requests to Pangolin to receive a session token. Using that token it will connect to a websocket and maintain that connection. Control messages will be sent over the websocket.
Using the Newt ID and a secret, the client will make HTTP requests to Pangolin to receive a session token. Using that token, it will connect to a websocket and maintain that connection. Control messages will be sent over the websocket.

### Receives WireGuard Control Messages

When Newt receives WireGuard control messages, it will use the information encoded (endpoint, public key) to bring up a WireGuard tunnel using [netstack](https://github.com/WireGuard/wireguard-go/blob/master/tun/netstack/examples/http_server.go) fully in user space. It will ping over the tunnel to ensure the peer on the Gerbil side is brought up.

### Receives Proxy Control Messages

When Newt receives WireGuard control messages, it will use the information encoded to crate local low level TCP and UDP proxies attached to the virtual tunnel in order to relay traffic to programmed targets.
When Newt receives WireGuard control messages, it will use the information encoded to create a local low level TCP and UDP proxies attached to the virtual tunnel in order to relay traffic to programmed targets.

## CLI Args

Expand Down Expand Up @@ -98,4 +98,4 @@ Newt is dual licensed under the AGPLv3 and the Fossorial Commercial license. For

## Contributions

Please see [CONTRIBUTIONS](./CONTRIBUTING.md) in the repository for guidelines and best practices.
Please see [CONTRIBUTIONS](./CONTRIBUTING.md) in the repository for guidelines and best practices.
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ services:
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- LOG_LEVEL=DEBUG
19 changes: 17 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/netip"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -123,6 +124,7 @@ func startPingCheck(tnet *netstack.Net, serverIP string, stopChan chan struct{})
err := ping(tnet, serverIP)
if err != nil {
logger.Warn("Periodic ping failed: %v", err)
logger.Warn("HINT: Do you have UDP port 51280 (or the port in config.yml) open on your Pangolin server?")
}
case <-stopChan:
logger.Info("Stopping ping check")
Expand Down Expand Up @@ -247,6 +249,8 @@ func main() {
endpoint string
id string
secret string
mtu string
mtuInt int
dns string
privateKey wgtypes.Key
err error
Expand All @@ -257,6 +261,7 @@ func main() {
endpoint = os.Getenv("PANGOLIN_ENDPOINT")
id = os.Getenv("NEWT_ID")
secret = os.Getenv("NEWT_SECRET")
mtu = os.Getenv("MTU")
dns = os.Getenv("DNS")
logLevel = os.Getenv("LOG_LEVEL")

Expand All @@ -269,6 +274,9 @@ func main() {
if secret == "" {
flag.StringVar(&secret, "secret", "", "Newt secret")
}
if mtu == "" {
flag.StringVar(&mtu, "mtu", "1280", "MTU to use")
}
if dns == "" {
flag.StringVar(&dns, "dns", "8.8.8.8", "DNS server to use")
}
Expand All @@ -286,6 +294,12 @@ func main() {
logger.Fatal("endpoint, id, and secret are required either via CLI flags or environment variables")
}

// parse the mtu string into an int
mtuInt, err = strconv.Atoi(mtu)
if err != nil {
logger.Fatal("Failed to parse MTU: %v", err)
}

privateKey, err = wgtypes.GeneratePrivateKey()
if err != nil {
logger.Fatal("Failed to generate private key: %v", err)
Expand Down Expand Up @@ -333,7 +347,8 @@ func main() {
err = pingWithRetry(tnet, wgData.ServerIP)
if err != nil {
// Handle complete failure after all retries
logger.Error("Failed to ping %s: %v", wgData.ServerIP, err)
logger.Warn("Failed to ping %s: %v", wgData.ServerIP, err)
logger.Warn("HINT: Do you have UDP port 51280 (or the port in config.yml) open on your Pangolin server?")
}
return
}
Expand All @@ -353,7 +368,7 @@ func main() {
tun, tnet, err = netstack.CreateNetTUN(
[]netip.Addr{netip.MustParseAddr(wgData.TunnelIP)},
[]netip.Addr{netip.MustParseAddr(dns)},
1420)
mtuInt)
if err != nil {
logger.Error("Failed to create TUN device: %v", err)
}
Expand Down