Initial commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
module git.ohea.xyz/restitux/nmcli-vpn-activator
|
||||
|
||||
go 1.21.4
|
||||
|
||||
require git.ohea.xyz/golang/config v0.0.0-20230225082310-91f0f601076e
|
||||
|
||||
require github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
@@ -0,0 +1,14 @@
|
||||
git.ohea.xyz/golang/config v0.0.0-20230225082310-91f0f601076e h1:Hwv4cSg2+VG7vk7uOS/WqGIGySmW1xpjs0blo6dfHYc=
|
||||
git.ohea.xyz/golang/config v0.0.0-20230225082310-91f0f601076e/go.mod h1:86PbXJ2WdqQ+3hYqrnv3ukgKNRK9nQfThnlY03FAO0g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,165 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
|
||||
"git.ohea.xyz/golang/config"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
IgnoreDevices bool
|
||||
Devices []string
|
||||
IgnoreConnections bool
|
||||
Connections []string
|
||||
VPNConnection string
|
||||
}
|
||||
|
||||
func isMatch(ignoreStrings bool, strings []string, match string) bool {
|
||||
if ignoreStrings {
|
||||
for _, s := range strings {
|
||||
if match == s {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
for _, s := range strings {
|
||||
if match == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func PrintArray(message string, items []string) {
|
||||
fmt.Printf("%s: ", message)
|
||||
for i, s := range items {
|
||||
fmt.Print(s)
|
||||
if i < len(items)-1 {
|
||||
fmt.Print(", ")
|
||||
}
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
func enableVPN(vpnCon string) error {
|
||||
cmd := exec.Command("nmcli", "con", "up", vpnCon)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("could not launch VPN: %w\n", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableVPN(vpnCon string) error {
|
||||
cmd := exec.Command("nmcli", "con", "down", vpnCon)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("could not stop VPN: %w\n", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
configData := config.Config[Config]{
|
||||
Name: "nmcli-vpn-activator",
|
||||
Filename: "config",
|
||||
Config: Config{
|
||||
IgnoreDevices: false,
|
||||
Devices: []string{},
|
||||
IgnoreConnections: true,
|
||||
Connections: []string{},
|
||||
VPNConnection: "",
|
||||
},
|
||||
}
|
||||
new, err := configData.Get()
|
||||
if err != nil {
|
||||
fmt.Printf("Could not get config: %w\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if new {
|
||||
fmt.Println("New config created, please update and restart.")
|
||||
return
|
||||
}
|
||||
|
||||
if configData.Config.IgnoreDevices {
|
||||
PrintArray("Ignoring the following devices", configData.Config.Devices)
|
||||
} else {
|
||||
PrintArray("Enabling the VPN on the following devices", configData.Config.Devices)
|
||||
}
|
||||
|
||||
if configData.Config.IgnoreConnections {
|
||||
PrintArray("Ignoring the following connections", configData.Config.Connections)
|
||||
} else {
|
||||
PrintArray("Enabling the VPN on the following connections", configData.Config.Connections)
|
||||
}
|
||||
|
||||
nmcli_monitor := exec.Command("nmcli", "monitor")
|
||||
|
||||
stdout, err := nmcli_monitor.StdoutPipe()
|
||||
if err != nil {
|
||||
fmt.Printf("could not get stdout: %w\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = nmcli_monitor.Start()
|
||||
if err != nil {
|
||||
fmt.Printf("Could not start process: %w\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
connectingEnable := false
|
||||
connectingDisable := false
|
||||
|
||||
for {
|
||||
n, err := stdout.Read(buf)
|
||||
if err != nil {
|
||||
fmt.Printf("could not read stdout: %w\n, err")
|
||||
return
|
||||
}
|
||||
logLine := string(buf[:n])
|
||||
|
||||
usingConnection := regexp.MustCompile(`(?P<device>\S+?): using connection \'(?P<network>.+?)\'`)
|
||||
results := usingConnection.FindStringSubmatch(logLine)
|
||||
if len(results) > 0 {
|
||||
if !isMatch(configData.Config.IgnoreDevices, configData.Config.Devices, results[1]) {
|
||||
continue
|
||||
}
|
||||
if !isMatch(configData.Config.IgnoreConnections, configData.Config.Connections, results[2]) {
|
||||
fmt.Printf("Monitored device %s has started connecting to VPN disabled network %s.\n", results[1], results[2])
|
||||
connectingDisable = true
|
||||
connectingEnable = false
|
||||
} else {
|
||||
fmt.Printf("Monitored device %s has started connecting to VPN enabled network %s.\n", results[1], results[2])
|
||||
connectingEnable = true
|
||||
connectingDisable = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
deviceConnected := regexp.MustCompile(`(?P<device>\S+?): connected`)
|
||||
results = deviceConnected.FindStringSubmatch(logLine)
|
||||
if len(results) > 0 {
|
||||
if connectingEnable {
|
||||
fmt.Printf("Monitored device %s has connected to VPN enabled network, enabling VPN.\n", results[1])
|
||||
err = enableVPN(configData.Config.VPNConnection)
|
||||
if err != nil {
|
||||
fmt.Printf("Could not enable VPN: %w\n", err)
|
||||
}
|
||||
connectingEnable = false
|
||||
}
|
||||
if connectingDisable {
|
||||
fmt.Printf("Monitored device %s has connected to VPN disabled network, disabling VPN.\n", results[1])
|
||||
err = disableVPN(configData.Config.VPNConnection)
|
||||
if err != nil {
|
||||
fmt.Printf("Could not disable VPN: %w\n", err)
|
||||
}
|
||||
connectingDisable = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user