mirror of
https://github.com/fosrl/gerbil.git
synced 2026-02-08 05:56:40 +00:00
Add reachableAt
This commit is contained in:
9
Makefile
9
Makefile
@@ -1,6 +1,11 @@
|
|||||||
|
|
||||||
all:
|
all: build push
|
||||||
docker build -t gerbil .
|
|
||||||
|
build:
|
||||||
|
docker build -t fossorial/gerbil:latest .
|
||||||
|
|
||||||
|
push:
|
||||||
|
docker push fossorial/gerbil:latest
|
||||||
|
|
||||||
test:
|
test:
|
||||||
docker run -it -p 3002:3002 -v ./config_example.json:/config/config.json --cap-add=NET_ADMIN --cap-add=SYS_MODULE gerbil --config /config/config.json
|
docker run -it -p 3002:3002 -v ./config_example.json:/config/config.json --cap-add=NET_ADMIN --cap-add=SYS_MODULE gerbil --config /config/config.json
|
||||||
|
|||||||
90
main.go
90
main.go
@@ -63,6 +63,8 @@ func main() {
|
|||||||
remoteConfigURL := flag.String("remoteConfig", "", "URL to fetch remote configuration")
|
remoteConfigURL := flag.String("remoteConfig", "", "URL to fetch remote configuration")
|
||||||
listenAddrArg := flag.String("listen", ":3002", "Address to listen on")
|
listenAddrArg := flag.String("listen", ":3002", "Address to listen on")
|
||||||
reportBandwidthTo := flag.String("reportBandwidthTo", "", "Address to listen on")
|
reportBandwidthTo := flag.String("reportBandwidthTo", "", "Address to listen on")
|
||||||
|
generateAndSaveKeyTo := flag.String("generateAndSaveKeyTo", "", "Path to save generated private key")
|
||||||
|
reachableAt := flag.String("reachableAt", "", "Endpoint of the http server to tell remote config about")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *interfaceNameArg != "" {
|
if *interfaceNameArg != "" {
|
||||||
@@ -77,23 +79,64 @@ func main() {
|
|||||||
log.Fatal("Please provide either --config or --remoteConfig, but not both")
|
log.Fatal("Please provide either --config or --remoteConfig, but not both")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var key wgtypes.Key
|
||||||
|
// if generateAndSaveKeyTo is provided, generate a private key and save it to the file. if the file already exists, load the key from the file
|
||||||
|
if *generateAndSaveKeyTo != "" {
|
||||||
|
if _, err := os.Stat(*generateAndSaveKeyTo); os.IsNotExist(err) {
|
||||||
|
// generate a new private key
|
||||||
|
key, err = wgtypes.GeneratePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to generate private key: %v", err)
|
||||||
|
}
|
||||||
|
// save the key to the file
|
||||||
|
err = os.WriteFile(*generateAndSaveKeyTo, []byte(key.String()), 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to save private key: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keyData, err := os.ReadFile(*generateAndSaveKeyTo)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to read private key: %v", err)
|
||||||
|
}
|
||||||
|
key, err = wgtypes.ParseKey(string(keyData))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to parse private key: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if no generateAndSaveKeyTo is provided, ensure that the private key is provided
|
||||||
|
if wgconfig.PrivateKey == "" {
|
||||||
|
// generate a new one
|
||||||
|
key, err = wgtypes.GeneratePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to generate private key: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load configuration based on provided argument
|
||||||
|
if *configFile != "" {
|
||||||
|
wgconfig, err = loadConfig(*configFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to load configuration: %v", err)
|
||||||
|
}
|
||||||
|
if wgconfig.PrivateKey == "" {
|
||||||
|
wgconfig.PrivateKey = key.String()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wgconfig, err = loadRemoteConfig(*remoteConfigURL, key, *reachableAt)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to load configuration: %v", err)
|
||||||
|
}
|
||||||
|
wgconfig.PrivateKey = key.String()
|
||||||
|
}
|
||||||
|
|
||||||
wgClient, err = wgctrl.New()
|
wgClient, err = wgctrl.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to create WireGuard client: %v", err)
|
log.Fatalf("Failed to create WireGuard client: %v", err)
|
||||||
}
|
}
|
||||||
defer wgClient.Close()
|
defer wgClient.Close()
|
||||||
|
|
||||||
// Load configuration based on provided argument
|
|
||||||
if *configFile != "" {
|
|
||||||
wgconfig, err = loadConfig(*configFile)
|
|
||||||
} else {
|
|
||||||
wgconfig, err = loadRemoteConfig(*remoteConfigURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to load configuration: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the WireGuard interface exists and is configured
|
// Ensure the WireGuard interface exists and is configured
|
||||||
if err := ensureWireguardInterface(wgconfig); err != nil {
|
if err := ensureWireguardInterface(wgconfig); err != nil {
|
||||||
log.Fatalf("Failed to ensure WireGuard interface: %v", err)
|
log.Fatalf("Failed to ensure WireGuard interface: %v", err)
|
||||||
@@ -111,9 +154,17 @@ func main() {
|
|||||||
log.Fatal(http.ListenAndServe(listenAddr, nil))
|
log.Fatal(http.ListenAndServe(listenAddr, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadRemoteConfig(url string) (WgConfig, error) {
|
func loadRemoteConfig(url string, key wgtypes.Key, reachableAt string) (WgConfig, error) {
|
||||||
resp, err := http.Get(url)
|
var body *bytes.Buffer
|
||||||
|
if reachableAt == "" {
|
||||||
|
body = bytes.NewBuffer([]byte(fmt.Sprintf(`{"publicKey": "%s"}`, key.PublicKey().String())))
|
||||||
|
} else {
|
||||||
|
body = bytes.NewBuffer([]byte(fmt.Sprintf(`{"publicKey": "%s", "reachableAt": "%s"}`, key.PublicKey().String(), reachableAt)))
|
||||||
|
}
|
||||||
|
resp, err := http.Post(url, "application/json", body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// print the error
|
||||||
|
fmt.Println("Error fetching remote config:", err)
|
||||||
return WgConfig{}, err
|
return WgConfig{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@@ -125,6 +176,7 @@ func loadRemoteConfig(url string) (WgConfig, error) {
|
|||||||
|
|
||||||
var config WgConfig
|
var config WgConfig
|
||||||
err = json.Unmarshal(data, &config)
|
err = json.Unmarshal(data, &config)
|
||||||
|
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,12 +485,16 @@ func calculatePeerBandwidth() ([]PeerBandwidth, error) {
|
|||||||
var bytesInDiff, bytesOutDiff float64
|
var bytesInDiff, bytesOutDiff float64
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
timeDiff := now.Sub(lastReading.LastChecked).Seconds()
|
// Calculate total bytes transferred since last reading
|
||||||
bytesInDiff = float64(currentReading.BytesReceived-lastReading.BytesReceived) / timeDiff
|
bytesInDiff = float64(currentReading.BytesReceived - lastReading.BytesReceived)
|
||||||
bytesOutDiff = float64(currentReading.BytesTransmitted-lastReading.BytesTransmitted) / timeDiff
|
bytesOutDiff = float64(currentReading.BytesTransmitted - lastReading.BytesTransmitted)
|
||||||
|
} else {
|
||||||
|
// For first reading, use total bytes as the increment
|
||||||
|
bytesInDiff = float64(currentReading.BytesReceived)
|
||||||
|
bytesOutDiff = float64(currentReading.BytesTransmitted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to MB/s
|
// Convert to MB
|
||||||
bytesInMB := bytesInDiff / (1024 * 1024)
|
bytesInMB := bytesInDiff / (1024 * 1024)
|
||||||
bytesOutMB := bytesOutDiff / (1024 * 1024)
|
bytesOutMB := bytesOutDiff / (1024 * 1024)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user