From 1ffadf5c86f42be6a427b211d5053a69d23c3279 Mon Sep 17 00:00:00 2001 From: Steven Polley Date: Wed, 17 Apr 2024 19:41:24 -0600 Subject: [PATCH] BREAKING: Interface name is now specified by configuration file The syntax for the hypd server command has changed. Now instead of specifying an interface name as an argument to the server command, you instead specify a configuration file path. Example: ./hypd server hypdconfig.json --- .gitignore | 1 + hypd/cmd/defaultconfig.go | 4 ++- hypd/cmd/server.go | 42 +++++++++++++++++------------ hypd/configuration/configuration.go | 8 ++++-- hypd/server/packet.go | 6 ++--- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 0e6d7bb..9ce6d70 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ hyp.secret *.exe hypd/hypd hyp/hyp +hypdconfig.json \ No newline at end of file diff --git a/hypd/cmd/defaultconfig.go b/hypd/cmd/defaultconfig.go index 29957f0..d05e868 100644 --- a/hypd/cmd/defaultconfig.go +++ b/hypd/cmd/defaultconfig.go @@ -16,7 +16,9 @@ var defaultconfigCmd = &cobra.Command{ Use: "defaultconfig", Short: "Prints the default configuration to stdout", Long: `The default configuration is used if one is not set. The default configuration - can be used as a reference to build your own. `, +can be used as a reference to build your own. + +hypd generate defaultconfig | tee hypdconfig.json`, Run: func(cmd *cobra.Command, args []string) { config := configuration.DefaultConfig() b, err := json.MarshalIndent(config, "", " ") diff --git a/hypd/cmd/server.go b/hypd/cmd/server.go index 8fb62e0..8f9ddf3 100644 --- a/hypd/cmd/server.go +++ b/hypd/cmd/server.go @@ -5,6 +5,7 @@ package cmd import ( "fmt" + "os/user" "deadbeef.codes/steven/hyp/hypd/configuration" "deadbeef.codes/steven/hyp/hypd/server" @@ -13,34 +14,43 @@ import ( // serverCmd represents the server command var serverCmd = &cobra.Command{ - Use: "server ", + Use: "server ", Args: cobra.ExactArgs(1), Short: "Runs hyp in server mode", - Long: `Runs the hyp server and begins capture on the NIC specified + Long: `Runs the hyp server and begins watching for authentic knock sequences. + +Before running this command, you must first have a configuration file. You can +generate a configuration file with: hypd generate defaultconfig > hypdconfig.json + +You should then edit the config file to meet your needs. + +In addition to a config file you will need to generate pre-shared keys: +mkdir -p ./secrets +hypd generate secret > secrets/mykey.secret Example Usage: - # Linux - capture enp0s0 - hyp server enp0s0 - - # Linux - capture eth0 - hyp server eth0 - - # Windows - get-netadapter | where {$_.Name -eq “Ethernet”} | Select-Object -Property DeviceName - hyp.exe server "\\Device\\NPF_{A6F067DE-C2DC-4B4E-9C74-BE649C4C0F03}" + # Use config file in local directory + hypd server hypdconfig.json + # Use config file in /etc/hyp/ + hypd server /etc/hyp/hypdconfig.json `, Run: func(cmd *cobra.Command, args []string) { - configFile, err := cmd.Flags().GetString("configfile") + + currentUser, err := user.Current() if err != nil { - panic(fmt.Errorf("failed to get configfile flag: %w", err)) + panic(fmt.Errorf("could not determine current user: %w", err)) } - hypdConfiguration, err := configuration.LoadConfiguration(configFile) + if currentUser.Username != "root" { + fmt.Println("WARNING: It's recommended you run this as root, but will proceed anyways...") + } + + hypdConfiguration, err := configuration.LoadConfiguration(args[0]) if err != nil { panic(fmt.Errorf("failed to start packet server: %w", err)) } - - err = server.PacketServer(args[0], hypdConfiguration) + err = server.PacketServer(hypdConfiguration) if err != nil { panic(fmt.Errorf("failed to start packet server: %w", err)) } @@ -50,6 +60,4 @@ Example Usage: func init() { rootCmd.AddCommand(serverCmd) - serverCmd.PersistentFlags().String("configfile", "", "Path to the file containing the hypd configuration.") - } diff --git a/hypd/configuration/configuration.go b/hypd/configuration/configuration.go index a6ff44a..38ce2db 100644 --- a/hypd/configuration/configuration.go +++ b/hypd/configuration/configuration.go @@ -7,6 +7,7 @@ import ( ) type HypdConfiguration struct { + NetworkInterface string `json:"networkInterface"` 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. @@ -19,6 +20,7 @@ type HypdConfiguration struct { func LoadConfiguration(configFilePath string) (*HypdConfiguration, error) { if configFilePath == "" { commonLocations := []string{"hypdconfig.json", + "~/.hypdconfig.json", "~/.config/hyp/hypdConfig.json", "/etc/hyp/hypdConfig.json", "/usr/local/etc/hyp/hypdConfig.json", @@ -33,6 +35,7 @@ func LoadConfiguration(configFilePath string) (*HypdConfiguration, error) { } // if it's still not found after checking common locations, load default config if configFilePath == "" { + fmt.Println("no configuration file found. You can generate one with ./hypd generate defaultconfig | tee hypdconfig.json") return DefaultConfig(), nil } @@ -45,17 +48,18 @@ func LoadConfiguration(configFilePath string) (*HypdConfiguration, error) { return nil, fmt.Errorf("failed to read config file '%s': %w", configFilePath, err) } - var hypdConfiguration *HypdConfiguration + hypdConfiguration := &HypdConfiguration{} err = json.Unmarshal(b, hypdConfiguration) if err != nil { return nil, fmt.Errorf("failed to unmarshal config file json to HypdConfiguration (is the config file malformed?): %w", err) } - return nil, nil + return hypdConfiguration, nil } func DefaultConfig() *HypdConfiguration { return &HypdConfiguration{ + NetworkInterface: "enp0s3", PreSharedKeyDirectory: "./secrets/", SuccessAction: "iptables -A INPUT -p tcp -s %s --dport 22 -j ACCEPT", TimeoutSeconds: 1440, diff --git a/hypd/server/packet.go b/hypd/server/packet.go index e1f08b7..a90b4f0 100644 --- a/hypd/server/packet.go +++ b/hypd/server/packet.go @@ -49,11 +49,11 @@ var ( // 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(captureDevice string, config *configuration.HypdConfiguration) error { +func PacketServer(config *configuration.HypdConfiguration) error { - iface, err := net.InterfaceByName(captureDevice) + iface, err := net.InterfaceByName(config.NetworkInterface) if err != nil { - log.Fatalf("lookup network iface %q: %v", captureDevice, err) + log.Fatalf("lookup network iface %q: %v", config.NetworkInterface, err) } secretBytes, err := os.ReadFile("hyp.secret")