BREAKING: Interface name is now specified by configuration file
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
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
This commit is contained in:
parent
e95b4972da
commit
1ffadf5c86
|
@ -2,3 +2,4 @@ hyp.secret
|
|||
*.exe
|
||||
hypd/hypd
|
||||
hyp/hyp
|
||||
hypdconfig.json
|
|
@ -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, "", " ")
|
||||
|
|
|
@ -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 <NIC>",
|
||||
Use: "server <configFilePath>",
|
||||
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.")
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue