Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9348842
added use of hostname if available
woutervanelten Jul 1, 2025
a896291
Update go.mod
woutervanelten Jul 1, 2025
2ecf329
Bump github.com/docker/docker in the prod-patch-updates group
dependabot[bot] Jul 3, 2025
be56550
Merge pull request #75 from woutervanelten/patch-4
oschwartz10612 Jul 3, 2025
c2a326c
Working packages?
oschwartz10612 Jul 3, 2025
a88d25f
Fix missing netstack pack
oschwartz10612 Jul 3, 2025
54416bb
Merge pull request #76 from fosrl/dependabot/go_modules/prod-patch-up…
oschwartz10612 Jul 3, 2025
61a9097
Make linux clients build correctly
oschwartz10612 Jul 3, 2025
d10c5e0
Merge branch 'main' into dev
oschwartz10612 Jul 3, 2025
b7d4ea0
Fix nil issues
oschwartz10612 Jul 4, 2025
07bd283
Remove dup code
oschwartz10612 Jul 6, 2025
e4bdbbe
Adjust logging
oschwartz10612 Jul 8, 2025
221d586
Fix disconnect errors about closed connection
oschwartz10612 Jul 8, 2025
5339766
Adjust logging
oschwartz10612 Jul 9, 2025
9410b92
Bump golang in the patch-updates group
dependabot[bot] Jul 9, 2025
99506a1
Bump github.com/docker/docker in the prod-patch-updates group
dependabot[bot] Jul 10, 2025
2d9b761
Get newt script
oschwartz10612 Jul 11, 2025
b1cfd3b
Update link
oschwartz10612 Jul 11, 2025
675797c
Merge pull request #79 from fosrl/dependabot/go_modules/prod-patch-up…
oschwartz10612 Jul 11, 2025
5aa00a6
Merge pull request #78 from fosrl/dependabot/docker/patch-updates-6b6…
oschwartz10612 Jul 11, 2025
c3483de
Merge branch 'main' into dev
oschwartz10612 Jul 11, 2025
c593e2a
Merge pull request #72 from fosrl/dev
oschwartz10612 Jul 11, 2025
9eb8e51
Fix link again
oschwartz10612 Jul 11, 2025
71d1bba
Merge branch 'main' of github.com:fosrl/newt
oschwartz10612 Jul 11, 2025
4d343e3
Update README.md for health check
woutervanelten Jul 11, 2025
6160e4c
Bump the prod-minor-updates group with 2 updates
dependabot[bot] Jul 11, 2025
b881808
Loosen up the ping intervals
oschwartz10612 Jul 11, 2025
fc965ab
Merge pull request #82 from fosrl/dependabot/go_modules/prod-minor-up…
oschwartz10612 Jul 13, 2025
58a74fc
Merge branch 'patch-5' of github.com:woutervanelten/newt into wouterv…
oschwartz10612 Jul 13, 2025
ce4f3e4
Bump github.com/vishvananda/netlink in the prod-patch-updates group
dependabot[bot] Jul 13, 2025
f513f97
Working on better ping
oschwartz10612 Jul 13, 2025
663e283
Fix typo with _
oschwartz10612 Jul 13, 2025
6f4469a
Merge branch 'woutervanelten-patch-5' into dev
oschwartz10612 Jul 13, 2025
dcacc03
Merge pull request #81 from fosrl/dependabot/go_modules/prod-patch-up…
oschwartz10612 Jul 13, 2025
86e262a
Merge branch 'main' into dev
oschwartz10612 Jul 13, 2025
7264bb7
Merge branch 'patch-2' of github.com:woutervanelten/newt into wouterv…
oschwartz10612 Jul 13, 2025
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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24.4-alpine AS builder
FROM golang:1.24.5-alpine AS builder

# Set the working directory inside the container
WORKDIR /app
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ When Newt receives WireGuard control messages, it will use the information encod
- `tls-client-cert` (optional): Client certificate (p12 or pfx) for mTLS. See [mTLS](#mtls)
- `docker-socket` (optional): Set the Docker socket to use the container discovery integration
- `docker-enforce-network-validation` (optional): Validate the container target is on the same network as the newt process
- `health-file` (optional): Check if connection to WG server (pangolin) is ok. creates a file if ok, removes it if not ok. Can be used with docker healtcheck to restart newt

- Example:

Expand All @@ -61,7 +62,8 @@ services:
environment:
- PANGOLIN_ENDPOINT=https://example.com
- NEWT_ID=2ix2t8xk22ubpfy
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2
- HEALTH_FILE=/tmp/healthy
```

You can also pass the CLI args to the container:
Expand All @@ -76,6 +78,7 @@ services:
- --id 31frd0uzbjvp721
- --secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6
- --endpoint https://example.com
- --health-file /tmp/healthy
```

### Docker Socket Integration
Expand Down
11 changes: 11 additions & 0 deletions docker/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type Container struct {
Labels map[string]string `json:"labels"`
Created int64 `json:"created"`
Networks map[string]Network `json:"networks"`
Hostname string `json:"hostname"` // added to use hostname if available instead of network address

}

// Port represents a port mapping for a Docker container
Expand Down Expand Up @@ -173,6 +175,14 @@ func ListContainers(socketPath string, enforceNetworkValidation bool) ([]Contain
// Short ID like docker ps
shortId := c.ID[:12]

// Inspect container to get hostname
hostname := ""
containerInfo, err := cli.ContainerInspect(ctx, c.ID)
if err == nil && containerInfo.Config != nil {
hostname = containerInfo.Config.Hostname
}


// Skip host container if set
if hostContainerId != "" && c.ID == hostContainerId {
continue
Expand Down Expand Up @@ -238,6 +248,7 @@ func ListContainers(socketPath string, enforceNetworkValidation bool) ([]Contain
Labels: c.Labels,
Created: c.Created,
Networks: networks,
Hostname: hostname, // added
}

dockerContainers = append(dockerContainers, dockerContainer)
Expand Down
235 changes: 235 additions & 0 deletions get-newt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#!/bin/bash

# Get Newt - Cross-platform installation script
# Usage: curl -fsSL https://raw.githubusercontent.com/fosrl/newt/refs/heads/main/get-newt.sh | bash

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# GitHub repository info
REPO="fosrl/newt"
GITHUB_API_URL="https://api.github.com/repos/${REPO}/releases/latest"

# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}

print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}

print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}

# Function to get latest version from GitHub API
get_latest_version() {
local latest_info

if command -v curl >/dev/null 2>&1; then
latest_info=$(curl -fsSL "$GITHUB_API_URL" 2>/dev/null)
elif command -v wget >/dev/null 2>&1; then
latest_info=$(wget -qO- "$GITHUB_API_URL" 2>/dev/null)
else
print_error "Neither curl nor wget is available. Please install one of them." >&2
exit 1
fi

if [ -z "$latest_info" ]; then
print_error "Failed to fetch latest version information" >&2
exit 1
fi

# Extract version from JSON response (works without jq)
local version=$(echo "$latest_info" | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')

if [ -z "$version" ]; then
print_error "Could not parse version from GitHub API response" >&2
exit 1
fi

# Remove 'v' prefix if present
version=$(echo "$version" | sed 's/^v//')

echo "$version"
}

# Detect OS and architecture
detect_platform() {
local os arch

# Detect OS
case "$(uname -s)" in
Linux*) os="linux" ;;
Darwin*) os="darwin" ;;
MINGW*|MSYS*|CYGWIN*) os="windows" ;;
FreeBSD*) os="freebsd" ;;
*)
print_error "Unsupported operating system: $(uname -s)"
exit 1
;;
esac

# Detect architecture
case "$(uname -m)" in
x86_64|amd64) arch="amd64" ;;
arm64|aarch64) arch="arm64" ;;
armv7l|armv6l)
if [ "$os" = "linux" ]; then
if [ "$(uname -m)" = "armv6l" ]; then
arch="arm32v6"
else
arch="arm32"
fi
else
arch="arm64" # Default for non-Linux ARM
fi
;;
riscv64)
if [ "$os" = "linux" ]; then
arch="riscv64"
else
print_error "RISC-V architecture only supported on Linux"
exit 1
fi
;;
*)
print_error "Unsupported architecture: $(uname -m)"
exit 1
;;
esac

echo "${os}_${arch}"
}

# Get installation directory
get_install_dir() {
if [ "$OS" = "windows" ]; then
echo "$HOME/bin"
else
# Try to use a directory in PATH, fallback to ~/.local/bin
if echo "$PATH" | grep -q "/usr/local/bin"; then
if [ -w "/usr/local/bin" ] 2>/dev/null; then
echo "/usr/local/bin"
else
echo "$HOME/.local/bin"
fi
else
echo "$HOME/.local/bin"
fi
fi
}

# Download and install newt
install_newt() {
local platform="$1"
local install_dir="$2"
local binary_name="newt_${platform}"
local exe_suffix=""

# Add .exe suffix for Windows
if [[ "$platform" == *"windows"* ]]; then
binary_name="${binary_name}.exe"
exe_suffix=".exe"
fi

local download_url="${BASE_URL}/${binary_name}"
local temp_file="/tmp/newt${exe_suffix}"
local final_path="${install_dir}/newt${exe_suffix}"

print_status "Downloading newt from ${download_url}"

# Download the binary
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$download_url" -o "$temp_file"
elif command -v wget >/dev/null 2>&1; then
wget -q "$download_url" -O "$temp_file"
else
print_error "Neither curl nor wget is available. Please install one of them."
exit 1
fi

# Create install directory if it doesn't exist
mkdir -p "$install_dir"

# Move binary to install directory
mv "$temp_file" "$final_path"

# Make executable (not needed on Windows, but doesn't hurt)
chmod +x "$final_path"

print_status "newt installed to ${final_path}"

# Check if install directory is in PATH
if ! echo "$PATH" | grep -q "$install_dir"; then
print_warning "Install directory ${install_dir} is not in your PATH."
print_warning "Add it to your PATH by adding this line to your shell profile:"
print_warning " export PATH=\"${install_dir}:\$PATH\""
fi
}

# Verify installation
verify_installation() {
local install_dir="$1"
local exe_suffix=""

if [[ "$PLATFORM" == *"windows"* ]]; then
exe_suffix=".exe"
fi

local newt_path="${install_dir}/newt${exe_suffix}"

if [ -f "$newt_path" ] && [ -x "$newt_path" ]; then
print_status "Installation successful!"
print_status "newt version: $("$newt_path" --version 2>/dev/null || echo "unknown")"
return 0
else
print_error "Installation failed. Binary not found or not executable."
return 1
fi
}

# Main installation process
main() {
print_status "Installing latest version of newt..."

# Get latest version
print_status "Fetching latest version from GitHub..."
VERSION=$(get_latest_version)
print_status "Latest version: v${VERSION}"

# Set base URL with the fetched version
BASE_URL="https://github.com/${REPO}/releases/download/${VERSION}"

# Detect platform
PLATFORM=$(detect_platform)
print_status "Detected platform: ${PLATFORM}"

# Get install directory
INSTALL_DIR=$(get_install_dir)
print_status "Install directory: ${INSTALL_DIR}"

# Install newt
install_newt "$PLATFORM" "$INSTALL_DIR"

# Verify installation
if verify_installation "$INSTALL_DIR"; then
print_status "newt is ready to use!"
if [[ "$PLATFORM" == *"windows"* ]]; then
print_status "Run 'newt --help' to get started"
else
print_status "Run 'newt --help' to get started"
fi
else
exit 1
fi
}

# Run main function
main "$@"
17 changes: 8 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ go 1.23.1
toolchain go1.23.2

require (
github.com/docker/docker v28.3.2+incompatible
github.com/google/gopacket v1.1.19
github.com/docker/docker v28.3.0+incompatible
github.com/gorilla/websocket v1.5.3
github.com/vishvananda/netlink v1.3.0
golang.org/x/crypto v0.39.0
github.com/vishvananda/netlink v1.3.1
golang.org/x/crypto v0.40.0
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
golang.org/x/net v0.41.0
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
golang.org/x/net v0.42.0
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259
gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c
software.sslmate.com/src/go-pkcs12 v0.5.0
)

require (
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
Expand All @@ -43,7 +42,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/vishvananda/netns v0.0.5 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
Expand All @@ -52,7 +51,7 @@ require (
go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.30.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
Expand Down
Loading