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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
@ -15,7 +15,13 @@ import (
|
|||||||
hvpnnode3 "gitea.hbanafa.com/HeshamTB/hvpn-node3"
|
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 VPNIPCIDR string
|
||||||
var PrivateKeyPath cli.Path
|
var PrivateKeyPath cli.Path
|
||||||
var InterfaceName string
|
var InterfaceName string
|
||||||
@ -30,6 +36,13 @@ func main() {
|
|||||||
// TODO: Define error exit codes
|
// TODO: Define error exit codes
|
||||||
slog.SetLogLoggerLevel(slog.LevelDebug)
|
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()
|
app := createCliApp()
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -40,27 +53,8 @@ func main() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() {
|
func run(ctx *cli.Context) {
|
||||||
IPPool, err := hvpnnode3.NewPool(VPNIPCIDR)
|
slog.Debug("Starting run()")
|
||||||
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")
|
|
||||||
|
|
||||||
apiMux := http.NewServeMux()
|
apiMux := http.NewServeMux()
|
||||||
apiMux.HandleFunc("GET /peer", hvpnnode3.HandleGetPeer(wgLink))
|
apiMux.HandleFunc("GET /peer", hvpnnode3.HandleGetPeer(wgLink))
|
||||||
@ -71,7 +65,11 @@ func run() {
|
|||||||
handler = hvpnnode3.HttpLogHandler2(handler)
|
handler = hvpnnode3.HttpLogHandler2(handler)
|
||||||
|
|
||||||
port := fmt.Sprintf("%d", httpPort)
|
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)
|
hostPort := fmt.Sprintf("%s:%s", host, port)
|
||||||
|
|
||||||
slog.Info(fmt.Sprintf("Starting HVPN node on %s", hostPort))
|
slog.Info(fmt.Sprintf("Starting HVPN node on %s", hostPort))
|
||||||
@ -156,6 +154,20 @@ func createCliApp() *cli.App {
|
|||||||
}
|
}
|
||||||
app.Flags = append(app.Flags, &wgPort)
|
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{
|
httpPort := cli.IntFlag{
|
||||||
Name: "http-port",
|
Name: "http-port",
|
||||||
Usage: "TCP Port for HTTP API",
|
Usage: "TCP Port for HTTP API",
|
||||||
@ -170,7 +182,7 @@ func createCliApp() *cli.App {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
run()
|
run(ctx)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +190,7 @@ func createCliApp() *cli.App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setup() error {
|
func setup() error {
|
||||||
|
slog.Debug("Starting setup()")
|
||||||
privKeyFile, err := os.Open(PrivateKeyPath)
|
privKeyFile, err := os.Open(PrivateKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.Exit(err, 1)
|
return cli.Exit(err, 1)
|
||||||
@ -208,24 +221,14 @@ func setup() error {
|
|||||||
WgPort,
|
WgPort,
|
||||||
)
|
)
|
||||||
if err != nil {
|
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)
|
return cli.Exit(err, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
wgLink = wg
|
wgLink = wg
|
||||||
|
|
||||||
// this is done to recover from the next call to wgLink.Device call
|
slog.Info("Wireguard netlink is setup and running")
|
||||||
// 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")
|
|
||||||
|
|
||||||
|
|
||||||
dev, err := wgLink.Device(InterfaceName)
|
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()
|
//defer wgLink.Close()
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt, os.Kill)
|
signal.Notify(c, os.Interrupt, os.Kill)
|
||||||
|
Loading…
Reference in New Issue
Block a user