sshTunnelGateway refactor (#3784)

This commit is contained in:
fatedier
2023-11-21 11:19:35 +08:00
parent 8b432e179d
commit d5b41f1e14
34 changed files with 1036 additions and 1255 deletions

View File

@@ -16,21 +16,11 @@ package v1
import (
"github.com/samber/lo"
"golang.org/x/crypto/ssh"
"github.com/fatedier/frp/pkg/config/types"
"github.com/fatedier/frp/pkg/util/util"
)
type SSHTunnelGateway struct {
BindPort int `json:"bindPort,omitempty" validate:"gte=0,lte=65535"`
PrivateKeyFilePath string `json:"privateKeyFilePath,omitempty"`
PublicKeyFilesPath string `json:"publicKeyFilesPath,omitempty"`
// store all public key file. load all when init
PublicKeyFilesMap map[string]ssh.PublicKey
}
type ServerConfig struct {
APIMetadata
@@ -41,9 +31,6 @@ type ServerConfig struct {
// BindPort specifies the port that the server listens on. By default, this
// value is 7000.
BindPort int `json:"bindPort,omitempty"`
SSHTunnelGateway SSHTunnelGateway `json:"sshGatewayConfig,omitempty"`
// KCPBindPort specifies the KCP port that the server listens on. If this
// value is 0, the server will not listen for KCP connections.
KCPBindPort int `json:"kcpBindPort,omitempty"`
@@ -80,6 +67,8 @@ type ServerConfig struct {
// value is "", a default page will be displayed.
Custom404Page string `json:"custom404Page,omitempty"`
SSHTunnelGateway SSHTunnelGateway `json:"sshTunnelGateway,omitempty"`
WebServer WebServerConfig `json:"webServer,omitempty"`
// EnablePrometheus will export prometheus metrics on webserver address
// in /metrics api.
@@ -114,6 +103,7 @@ func (c *ServerConfig) Complete() {
c.Log.Complete()
c.Transport.Complete()
c.WebServer.Complete()
c.SSHTunnelGateway.Complete()
c.BindAddr = util.EmptyOr(c.BindAddr, "0.0.0.0")
c.BindPort = util.EmptyOr(c.BindPort, 7000)
@@ -202,3 +192,14 @@ type TLSServerConfig struct {
TLSConfig
}
type SSHTunnelGateway struct {
BindPort int `json:"bindPort,omitempty"`
PrivateKeyFile string `json:"privateKeyFile,omitempty"`
AutoGenPrivateKeyPath string `json:"autoGenPrivateKeyPath,omitempty"`
AuthorizedKeysFile string `json:"authorizedKeysFile,omitempty"`
}
func (c *SSHTunnelGateway) Complete() {
c.AutoGenPrivateKeyPath = util.EmptyOr(c.AutoGenPrivateKeyPath, "./.autogen_ssh_key")
}

View File

@@ -1,72 +0,0 @@
package v1
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"os"
"path/filepath"
"golang.org/x/crypto/ssh"
)
const (
// custom define
SSHClientLoginUserPrefix = "_frpc_ssh_client_"
)
// encodePrivateKeyToPEM encodes Private Key from RSA to PEM format
func GeneratePrivateKey() ([]byte, error) {
privateKey, err := generatePrivateKey()
if err != nil {
return nil, errors.New("gen private key error")
}
privBlock := pem.Block{
Type: "RSA PRIVATE KEY",
Headers: nil,
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
}
return pem.EncodeToMemory(&privBlock), nil
}
// generatePrivateKey creates a RSA Private Key of specified byte size
func generatePrivateKey() (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return nil, err
}
err = privateKey.Validate()
if err != nil {
return nil, err
}
return privateKey, nil
}
func LoadSSHPublicKeyFilesInDir(dirPath string) (map[string]ssh.PublicKey, error) {
fileMap := make(map[string]ssh.PublicKey)
files, err := os.ReadDir(dirPath)
if err != nil {
return nil, err
}
for _, file := range files {
filePath := filepath.Join(dirPath, file.Name())
content, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
parsedAuthorizedKey, _, _, _, err := ssh.ParseAuthorizedKey(content)
if err != nil {
continue
}
fileMap[ssh.FingerprintSHA256(parsedAuthorizedKey)] = parsedAuthorizedKey
}
return fileMap, nil
}