diff --git a/CONFIG.md b/CONFIG.md index cbaa2d6..7e7f428 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -66,6 +66,14 @@ with [hugo](https://gohugo.io/) network overview page. The shortcode file is included in this repository under `etc/`. + "PostUp": "" + "PostDown": "" + +Allows a user to specify commands to run after the device is up or down. This is +typcially a collection of `iptables` invocations. The commands are executed by +`/bin/sh`. *NOTE* These commands run as root, so make sure you check that they +are secure. + "PrivateKey": "uC+xz3v1mfjWBHepwiCgAmPebZcY+EdhaHAvqX2r7U8=", The server private key, automatically generated and very sensitive! diff --git a/README.md b/README.md index 273d4d8..9b2952d 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ Main (automatically generated) configuration example: "Networks": [], "ReportFile": "/var/lib/dsnetreport.json", "PrivateKey": "uC+xz3v1mfjWBHepwiCgAmPebZcY+EdhaHAvqX2r7U8=", + "PostUp": "", + "PostDown" "", "Peers": [ { "Hostname": "test", diff --git a/add.go b/add.go index 3a0a56d..548a90b 100644 --- a/add.go +++ b/add.go @@ -151,7 +151,6 @@ func PrintPeerCfg(peer PeerConfig, conf *DsnetConfig) { wgifSeed += int(b) } - t := template.Must(template.New("peerConf").Parse(peerConf)) err := t.Execute(os.Stdout, map[string]interface{}{ "Peer": peer, @@ -162,7 +161,7 @@ func PrintPeerCfg(peer PeerConfig, conf *DsnetConfig) { // vyatta requires an interface in range/format wg0-wg999 // deterministically choosing one in this range will probably allow use // of the config without a colliding interface name - "Wgif": fmt.Sprintf("wg%d", wgifSeed % 999), + "Wgif": fmt.Sprintf("wg%d", wgifSeed%999), }) check(err) } diff --git a/configtypes.go b/configtypes.go index 2e88658..7a72022 100644 --- a/configtypes.go +++ b/configtypes.go @@ -51,9 +51,11 @@ type DsnetConfig struct { // extra networks available, will be added to AllowedIPs Networks []JSONIPNet `validate:"required"` // TODO Default subnets to route via VPN - ReportFile string `validate:"required"` - PrivateKey JSONKey `validate:"required,len=44"` - Peers []PeerConfig `validate:"dive"` + ReportFile string `validate:"required"` + PrivateKey JSONKey `validate:"required,len=44"` + PostUp string + PostDown string + Peers []PeerConfig `validate:"dive"` } func MustLoadDsnetConfig() *DsnetConfig { diff --git a/down.go b/down.go index db82332..3103347 100644 --- a/down.go +++ b/down.go @@ -7,6 +7,11 @@ import ( func Down() { conf := MustLoadDsnetConfig() DelLink(conf) + RunPostDown(conf) +} + +func RunPostDown(conf *DsnetConfig) { + ShellOut(conf.PostDown, "PostDown") } func DelLink(conf *DsnetConfig) { diff --git a/reporttypes.go b/reporttypes.go index c3c12f2..63af1f5 100644 --- a/reporttypes.go +++ b/reporttypes.go @@ -163,7 +163,7 @@ type PeerReport struct { // date peer was added to dsnet config Added time.Time // Internal VPN IP address. Added to AllowedIPs in server config as a /32 - IP net.IP + IP net.IP IP6 net.IP // Last known external IP ExternalIP net.IP diff --git a/up.go b/up.go index 89ad419..3988197 100644 --- a/up.go +++ b/up.go @@ -10,6 +10,11 @@ func Up() { conf := MustLoadDsnetConfig() CreateLink(conf) ConfigureDevice(conf) + RunPostUp(conf) +} + +func RunPostUp(conf *DsnetConfig) { + ShellOut(conf.PostUp, "PostUp") } func CreateLink(conf *DsnetConfig) { diff --git a/util.go b/util.go index 3f8d3e8..a6b021a 100644 --- a/util.go +++ b/util.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "os" + "os/exec" "strings" ) @@ -35,6 +36,17 @@ func ExitFail(format string, a ...interface{}) { os.Exit(1) } +func ShellOut(command string, name string) { + if command != "" { + fmt.Printf("Running %s commands:\n %s", name, command) + shell := exec.Command("/bin/sh", "-c", command) + err := shell.Run() + if err != nil { + ExitFail("%s '%s' failed", name, command, err) + } + } +} + func ConfirmOrAbort(format string, a ...interface{}) { fmt.Fprintf(os.Stderr, format+" [y/n] ", a...)