Reorg and add host flag, and catch error when not root:
- A previous workaround done to recover from a panic on nil ref is now not needed and removed. The issue was that I assumed cli.Exit(err, int) was a way to exit; i.e. it uses os.Exit() under the hood. However, it only constructs a struct that implements error. Hence, we should return it, not just execute it. - Also warn on root and Windows - Move IPPool init to setup rather than run
This commit is contained in:
parent
1a611616bd
commit
a9ad981137
@ -1,10 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
@ -15,7 +15,13 @@ import (
|
||||
hvpnnode3 "gitea.hbanafa.com/HeshamTB/hvpn-node3"
|
||||
)
|
||||
|
||||
var IPPool *hvpnnode3.IPPool
|
||||
/*
|
||||
Can change all therse vars to local func vars
|
||||
IPPool can be internal to wglink or other abstraction. As well as
|
||||
POrt, ifname and CIDR and so on. Use Clie.ctx to get the values
|
||||
*/
|
||||
|
||||
var IPPool hvpnnode3.IPPool
|
||||
var VPNIPCIDR string
|
||||
var PrivateKeyPath cli.Path
|
||||
var InterfaceName string
|
||||
@ -30,6 +36,13 @@ func main() {
|
||||
// TODO: Define error exit codes
|
||||
slog.SetLogLoggerLevel(slog.LevelDebug)
|
||||
|
||||
uid := os.Getuid()
|
||||
if uid == -1 {
|
||||
slog.Warn("Running on windows! whatrr u doing?")
|
||||
} else if uid == 0 {
|
||||
slog.Warn("Running as root! avoid running as root by setting CAP_NET_ADMIN")
|
||||
}
|
||||
|
||||
app := createCliApp()
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
@ -40,27 +53,8 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
func run() {
|
||||
IPPool, err := hvpnnode3.NewPool(VPNIPCIDR)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("main.IPPool: %s", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
slog.Info(fmt.Sprintf("Init ip pool %s", VPNIPCIDR))
|
||||
|
||||
testVip, err := IPPool.Allocate()
|
||||
if err != nil {
|
||||
slog.Error("main.testVip: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
slog.Info(fmt.Sprintf("main.testVip: IP Pool Test IP: %s", testVip.String()))
|
||||
err = IPPool.Free(testVip)
|
||||
if err != nil {
|
||||
slog.Error("main.testVip: Could not free test Vip from IPPool!", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
slog.Info("main.testVip: Test IP Freed")
|
||||
func run(ctx *cli.Context) {
|
||||
slog.Debug("Starting run()")
|
||||
|
||||
apiMux := http.NewServeMux()
|
||||
apiMux.HandleFunc("GET /peer", hvpnnode3.HandleGetPeer(wgLink))
|
||||
@ -71,7 +65,11 @@ func run() {
|
||||
handler = hvpnnode3.HttpLogHandler2(handler)
|
||||
|
||||
port := fmt.Sprintf("%d", httpPort)
|
||||
host := "0.0.0.0"
|
||||
host := ctx.String("host")
|
||||
if host == "" {
|
||||
slog.Info("Host is not set. Using 0.0.0.0")
|
||||
host = "0.0.0.0"
|
||||
}
|
||||
hostPort := fmt.Sprintf("%s:%s", host, port)
|
||||
|
||||
slog.Info(fmt.Sprintf("Starting HVPN node on %s", hostPort))
|
||||
@ -156,6 +154,20 @@ func createCliApp() *cli.App {
|
||||
}
|
||||
app.Flags = append(app.Flags, &wgPort)
|
||||
|
||||
httpListenAddr := cli.StringFlag{
|
||||
Name: "host",
|
||||
Usage: "IP address to listen on for HTTP API requests",
|
||||
Value: "0.0.0.0",
|
||||
Action: func(ctx *cli.Context, s string) error {
|
||||
_, err := netip.ParseAddr(s)
|
||||
if err != nil {
|
||||
return cli.Exit(fmt.Sprintf("Can not parse %s as a network IP", s), 1)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
app.Flags = append(app.Flags, &httpListenAddr)
|
||||
|
||||
httpPort := cli.IntFlag{
|
||||
Name: "http-port",
|
||||
Usage: "TCP Port for HTTP API",
|
||||
@ -170,7 +182,7 @@ func createCliApp() *cli.App {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
run()
|
||||
run(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -178,6 +190,7 @@ func createCliApp() *cli.App {
|
||||
}
|
||||
|
||||
func setup() error {
|
||||
slog.Debug("Starting setup()")
|
||||
privKeyFile, err := os.Open(PrivateKeyPath)
|
||||
if err != nil {
|
||||
return cli.Exit(err, 1)
|
||||
@ -208,24 +221,14 @@ func setup() error {
|
||||
WgPort,
|
||||
)
|
||||
if err != nil {
|
||||
slog.Warn("Error while initlizing Wireguard netlink and device!")
|
||||
slog.Warn("Ensure to run as root or with CAP_NET_ADMIN")
|
||||
return cli.Exit(err, 1)
|
||||
}
|
||||
|
||||
wgLink = wg
|
||||
|
||||
// this is done to recover from the next call to wgLink.Device call
|
||||
// idk a better way to recover or prevent the panic when running user
|
||||
// does not have root or CAP_NET_ADMIN.
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
slog.Error(fmt.Sprint(r))
|
||||
slog.Error("Recovered from panic. Ensure to run as root or with CAP_NET_ADMIN")
|
||||
cli.Exit(errors.New("Recovered from panic. Ensure to run as root or with CAP_NET_ADMIN"),1)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}()
|
||||
|
||||
slog.Info("Wireguard device is setup and running")
|
||||
slog.Info("Wireguard netlink is setup and running")
|
||||
|
||||
|
||||
dev, err := wgLink.Device(InterfaceName)
|
||||
@ -241,6 +244,29 @@ func setup() error {
|
||||
),
|
||||
)
|
||||
|
||||
ipPool, err := hvpnnode3.NewPool(VPNIPCIDR)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("main.IPPool: %s", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
slog.Info(fmt.Sprintf("Init ip pool %s", VPNIPCIDR))
|
||||
|
||||
testVip, err := ipPool.Allocate()
|
||||
if err != nil {
|
||||
slog.Error("main.testVip: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
slog.Info(fmt.Sprintf("main.testVip: IP Pool Test IP: %s", testVip.String()))
|
||||
err = ipPool.Free(testVip)
|
||||
if err != nil {
|
||||
slog.Error("main.testVip: Could not free test Vip from IPPool!", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
slog.Info("main.testVip: Test IP Freed")
|
||||
|
||||
IPPool = ipPool
|
||||
|
||||
//defer wgLink.Close()
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, os.Kill)
|
||||
|
Loading…
Reference in New Issue
Block a user