Make the success action configurable

Instead of using the hardcoded proof of concept for iptables, the success action is now read from the hypd configuration file and whatever is defined there is executed.
This commit is contained in:
Steven Polley 2024-04-18 11:22:03 -06:00
parent 79aa8136c5
commit 05e37193b4
2 changed files with 15 additions and 10 deletions

View File

@ -7,11 +7,11 @@ import (
)
type HypdConfiguration struct {
NetworkInterface string `json:"networkInterface"`
NetworkInterface string `json:"networkInterface"` // The network interface that the eBPF program attaches to
PreSharedKeyDirectory string `json:"preSharedKeyDirectory"` // hypd will load all *.secret files from this directory
SuccessAction string `json:"successAction"` // The action to take
TimeoutSeconds int `json:"timeoutSeconds"` // If > 0, once a knock sequence has been successful this value will count down and when it reaches 0, it will perform the TimeoutAction on the client.
TimeoutAction string `json:"timeoutAction"` // The action to take after TimeoutSeconds has elapsed. only applicable if TimeoutSeconds is > 0
SuccessAction string `json:"successAction"` // The action to take for a successful knock, each argument is a separate string
TimeoutSeconds int `json:"timeoutSeconds"` // If > 0, once a knock sequence has been successful this value will count down and when it reaches 0, it will perform the TimeoutAction on the client
TimeoutAction string `json:"timeoutAction"` // The action to take after TimeoutSeconds has elapsed. only applicable if TimeoutSeconds is > 0, each argument is a separate string
}

View File

@ -44,15 +44,17 @@ var (
clients map[uint32]*Client // Contains a map of clients, key is IPv4 address
knockSequences []KnockSequence // We have 3 valid knock sequences at any time to account for clock skew
sharedSecret string // base32 encoded shared secret used for totp
serverConfig *configuration.HypdConfiguration
)
// PacketServer is the main function when operating in server mode
// it sets up the pcap on the capture device and starts a goroutine
// to rotate the knock sequence
func PacketServer(config *configuration.HypdConfiguration) error {
iface, err := net.InterfaceByName(config.NetworkInterface)
serverConfig = config
iface, err := net.InterfaceByName(serverConfig.NetworkInterface)
if err != nil {
log.Fatalf("lookup network iface %q: %v", config.NetworkInterface, err)
log.Fatalf("lookup network iface %q: %v", serverConfig.NetworkInterface, err)
}
secretBytes, err := os.ReadFile("hyp.secret")
@ -197,12 +199,15 @@ func rotateSequence() {
}
}
// TBD: Implement - this is a temporary routine to demonstrate an application
// handleSuccess is ran when a source IP successfully enters the authentic knock sequence
// the configured success action is ran
func handleSuccess(srcip net.IP) {
fmt.Println("Success for ", srcip)
cmd := exec.Command("iptables", "-A", "INPUT", "-p", "tcp", "-s", fmt.Sprint(srcip), "--dport", "22", "-j", "ACCEPT")
fmt.Println("Successful knock from:", srcip)
// Don't care about command injection, the configuration file providing the command literally NEEDS to be trusted
// TBD: Use template / substitution instead of string formatting directive - allows for srcip token to be used multiple times
cmd := exec.Command("sh", "-c", fmt.Sprintf(serverConfig.SuccessAction, srcip))
err := cmd.Run()
if err != nil {
log.Printf("failed to execute iptables command for '%s': %v", srcip, err)
log.Printf("failed to execute success action command for '%s': %v", srcip, err)
}
}