Cybersecurity-Projects/PROJECTS/advanced/honeypot-network/internal/cli/keygen.go

84 lines
1.6 KiB
Go

/*
©AngelaMos | 2026
keygen.go
Generate and persist an Ed25519 SSH host key
Writes a PEM-encoded private key to disk for use by the SSH
honeypot. The key is used to present a stable host fingerprint
across restarts so that returning attackers see the same server
identity.
*/
package cli
import (
"crypto/ed25519"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
)
func newKeygenCmd() *cobra.Command {
var outputPath string
cmd := &cobra.Command{
Use: "keygen",
Short: "Generate an SSH host key",
RunE: func(cmd *cobra.Command, args []string) error {
return generateHostKey(outputPath)
},
}
cmd.Flags().StringVarP(
&outputPath,
"output", "o",
"data/hostkey_ed25519",
"Output path for the private key",
)
return cmd
}
func generateHostKey(path string) error {
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return fmt.Errorf("creating key directory: %w", err)
}
_, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return fmt.Errorf("generating key: %w", err)
}
der, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
return fmt.Errorf("marshaling key: %w", err)
}
block := &pem.Block{
Type: "PRIVATE KEY",
Bytes: der,
}
f, err := os.OpenFile(
path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600,
)
if err != nil {
return fmt.Errorf("creating key file: %w", err)
}
defer func() { _ = f.Close() }()
if err := pem.Encode(f, block); err != nil {
return fmt.Errorf("writing key: %w", err)
}
fmt.Printf(" %s Host key written to %s\n", "✓", path)
return nil
}