From caaf48aa11ccff40658f079a81657dd4c2f57faf Mon Sep 17 00:00:00 2001 From: atanarjuat Date: Wed, 15 Feb 2023 16:27:54 +0100 Subject: headless mode stub --- cmd/bitmaskd/main.go | 64 ++++++++++++++++++++++++++++++++++++++++ docs/headless.md | 50 +++++++++++++++++++++++++++++++ pkg/backend/api.go | 2 +- pkg/backend/init.go | 2 +- pkg/config/version/checknewer.go | 2 ++ pkg/pickle/helpers.go | 8 +++++ 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 cmd/bitmaskd/main.go create mode 100644 docs/headless.md diff --git a/cmd/bitmaskd/main.go b/cmd/bitmaskd/main.go new file mode 100644 index 0000000..12887a8 --- /dev/null +++ b/cmd/bitmaskd/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "runtime" + + "0xacab.org/leap/bitmask-vpn/pkg/backend" +) + +func main() { + var c string + var installHelpers bool + + flag.StringVar(&c, "c", "", "Config file") + flag.BoolVar(&installHelpers, "i", false, "Install helpers (asks for sudo)") + flag.Parse() + + if installHelpers { + backend.InstallHelpers() + os.Exit(0) + } + + if len(c) == 0 { + fmt.Println("Please setup a config file with -c") + os.Exit(1) + } + + if _, err := os.Stat(c); err == nil { + log.Println("Loading config file from", c) + // all good. we could validate the json. + } else if errors.Is(err, os.ErrNotExist) { + fmt.Println("Cannot find file:", c) + os.Exit(1) + } else { + // Schrodinger: file may or may not exist. + log.Println("Error:", err) + } + + providerDefinitionJSON, err := ioutil.ReadFile(c) + if err != nil { + fmt.Println("Error reading config file") + os.Exit(1) + } + + // TODO daemonize, or run in foreground to debug. + log.Println("Starting bitmaskd...") + + opts := backend.InitOptsFromJSON("riseup", string(providerDefinitionJSON)) + opts.DisableAutostart = true + opts.Obfs4 = false + opts.StartVPN = "off" + backend.EnableWebAPI("8000") + backend.InitializeBitmaskContext(opts) + + log.Println("Backend initialized") + + runtime.Goexit() + fmt.Println("Exit") +} diff --git a/docs/headless.md b/docs/headless.md new file mode 100644 index 0000000..0061016 --- /dev/null +++ b/docs/headless.md @@ -0,0 +1,50 @@ +# headless mode + +As a wise person once said, "you don't want to struggle with Qt every day". + +## backend + +There's a barebones binary that launches the same backend that the qt5 client uses. + +You will need a `providers.json` file containing the parameters for you own deployment. This is usually generated during the vendoring step, but you can manually edit the one for riseup: + +``` +go build ./cmd/bitmaskd +``` + + +You might need to install the helpers (bitmask-root, polkit policies etc...). Do it manually, or use the embedded files (It will ask for sudo). + +``` +./bitmaskd -i +``` + + +With the polkit files in place, you can now run bitmask backend in the foreground: + +``` +./bitmaskd -d gui/providers/providers.json +``` + +TODO: make it a proper daemon, logging etc. + +If you find problems while running (like polkit asking for password every time), you probably need to debug your polkit installation. Every system has its quirks, and bitmask has mostly been tested in debian-based desktops. For arch, you might need to add your user to group wheel. + +## firewall + +While testing, you are likely to get the iptables firewall leaving you with blocked outgoing connections. You can control `bitmask-root` manually: + +``` +sudo /usr/sbin/bitmask-root help +sudo /usr/sbin/bitmask-root firewall stop +``` + +## cli + +There's no cli at the moment, but you can use the web api. To authenticate, you need to pass a token that is writen to a temporary file when the backend is initialized: + +``` +curl -H "X-Auth-Token:`cat /tmp/bitmask-token`" http://localhost:8000/vpn/status +curl -H "X-Auth-Token:`cat /tmp/bitmask-token`" http://localhost:8000/vpn/start +curl -H "X-Auth-Token:`cat /tmp/bitmask-token`" http://localhost:8000/vpn/stop +``` diff --git a/pkg/backend/api.go b/pkg/backend/api.go index 02aa383..691800e 100644 --- a/pkg/backend/api.go +++ b/pkg/backend/api.go @@ -231,7 +231,7 @@ func EnableMockBackend() { func EnableWebAPI(port string) { intPort, err := strconv.Atoi(port) if err != nil { - log.Fatal("Cannot parse port", port) + log.Fatal("Cannot parse port:", port) } go enableWebAPI(intPort) } diff --git a/pkg/backend/init.go b/pkg/backend/init.go index b007c61..1451b68 100644 --- a/pkg/backend/init.go +++ b/pkg/backend/init.go @@ -101,7 +101,7 @@ func setConfigOpts(opts *InitOpts, conf *config.Config) { conf.SkipLaunch = opts.SkipLaunch if opts.StartVPN != "" { if opts.StartVPN != "on" && opts.StartVPN != "off" { - log.Println("-start-vpn should be 'on' or 'off'") + log.Println("-start-vpn should be 'on' or 'off', not ", opts.StartVPN) } else { conf.StartVPN = opts.StartVPN == "on" } diff --git a/pkg/config/version/checknewer.go b/pkg/config/version/checknewer.go index 78b5b31..83e82a1 100644 --- a/pkg/config/version/checknewer.go +++ b/pkg/config/version/checknewer.go @@ -11,6 +11,8 @@ import ( const verURI = "https://downloads.leap.se/RiseupVPN/" +var VERSION string + // returns true if there's a newer version string published on the server // this needs to manually bump latest version for every platform in the // downloads server. diff --git a/pkg/pickle/helpers.go b/pkg/pickle/helpers.go index c0bd024..fbc45c3 100644 --- a/pkg/pickle/helpers.go +++ b/pkg/pickle/helpers.go @@ -85,6 +85,14 @@ func copyAsRoot(orig, dest string, isExec bool) { } err = cmd.Run() check(err) + } else { + if isRoot() { + cmd = exec.Command("chmod", "644", dest) + } else { + cmd = exec.Command("sudo", "chmod", "644", dest) + } + err = cmd.Run() + check(err) } fmt.Println("> done") -- cgit v1.2.3