ssh.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package v1
  2. import (
  3. "crypto/rand"
  4. "crypto/rsa"
  5. "crypto/x509"
  6. "encoding/pem"
  7. "errors"
  8. "os"
  9. "path/filepath"
  10. "golang.org/x/crypto/ssh"
  11. )
  12. const (
  13. // custom define
  14. SSHClientLoginUserPrefix = "_frpc_ssh_client_"
  15. )
  16. // encodePrivateKeyToPEM encodes Private Key from RSA to PEM format
  17. func GeneratePrivateKey() ([]byte, error) {
  18. privateKey, err := generatePrivateKey()
  19. if err != nil {
  20. return nil, errors.New("gen private key error")
  21. }
  22. privBlock := pem.Block{
  23. Type: "RSA PRIVATE KEY",
  24. Headers: nil,
  25. Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
  26. }
  27. return pem.EncodeToMemory(&privBlock), nil
  28. }
  29. // generatePrivateKey creates a RSA Private Key of specified byte size
  30. func generatePrivateKey() (*rsa.PrivateKey, error) {
  31. privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
  32. if err != nil {
  33. return nil, err
  34. }
  35. err = privateKey.Validate()
  36. if err != nil {
  37. return nil, err
  38. }
  39. return privateKey, nil
  40. }
  41. func LoadSSHPublicKeyFilesInDir(dirPath string) (map[string]ssh.PublicKey, error) {
  42. fileMap := make(map[string]ssh.PublicKey)
  43. files, err := os.ReadDir(dirPath)
  44. if err != nil {
  45. return nil, err
  46. }
  47. for _, file := range files {
  48. filePath := filepath.Join(dirPath, file.Name())
  49. content, err := os.ReadFile(filePath)
  50. if err != nil {
  51. return nil, err
  52. }
  53. parsedAuthorizedKey, _, _, _, err := ssh.ParseAuthorizedKey(content)
  54. if err != nil {
  55. continue
  56. }
  57. fileMap[ssh.FingerprintSHA256(parsedAuthorizedKey)] = parsedAuthorizedKey
  58. }
  59. return fileMap, nil
  60. }