mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-15 09:42:47 +02:00
Add hostkey to the ssh server
This commit is contained in:
@ -1,8 +1,6 @@
|
|||||||
package main
|
package ssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gliderlabs/ssh"
|
"github.com/gliderlabs/ssh"
|
||||||
gossh "golang.org/x/crypto/ssh"
|
gossh "golang.org/x/crypto/ssh"
|
||||||
@ -16,6 +14,16 @@ type Server struct {
|
|||||||
listener net.Listener
|
listener net.Listener
|
||||||
allowedKeys map[string]ssh.PublicKey
|
allowedKeys map[string]ssh.PublicKey
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
hostKeyPEM []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSSHServer creates new server with provided host key
|
||||||
|
func NewSSHServer(hostKeyPEM []byte) (*Server, error) {
|
||||||
|
ln, err := net.Listen("tcp", ":2222")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Server{listener: ln, mu: sync.Mutex{}, hostKeyPEM: hostKeyPEM}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) UpdateKeys(newKeys []string) error {
|
func (srv *Server) UpdateKeys(newKeys []string) error {
|
||||||
@ -34,14 +42,6 @@ func (srv *Server) UpdateKeys(newKeys []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSSHServer() (*Server, error) {
|
|
||||||
ln, err := net.Listen("tcp", ":2222")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Server{listener: ln, mu: sync.Mutex{}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop stops SSH server. Blocking
|
// Stop stops SSH server. Blocking
|
||||||
func (srv *Server) Stop() error {
|
func (srv *Server) Stop() error {
|
||||||
err := srv.listener.Close()
|
err := srv.listener.Close()
|
||||||
@ -73,7 +73,9 @@ func (srv *Server) Start() error {
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
err := ssh.Serve(srv.listener, handler, publicKeyOption)
|
hostKeyPEM := ssh.HostKeyPEM(srv.hostKeyPEM)
|
||||||
|
|
||||||
|
err := ssh.Serve(srv.listener, handler, publicKeyOption, hostKeyPEM)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -83,7 +85,8 @@ func (srv *Server) Start() error {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
server, err := NewSSHServer()
|
strKey := "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----\n"
|
||||||
|
server, err := NewSSHServer([]byte(strKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -98,28 +101,3 @@ func main() {
|
|||||||
// will throw error when Stop has been called
|
// will throw error when Stop has been called
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generatePrivateKey creates RSA Private Key of specified byte size
|
|
||||||
func generatePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
|
|
||||||
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = privateKey.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return privateKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// generatePublicKey takes a rsa.PublicKey and return bytes suitable for writing to .pub file
|
|
||||||
// returns the key in format format "ssh-rsa ..."
|
|
||||||
func generatePublicKey(privateKey *rsa.PublicKey) ([]byte, error) {
|
|
||||||
publicRsaKey, err := gossh.NewPublicKey(privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return gossh.MarshalAuthorizedKey(publicRsaKey), nil
|
|
||||||
}
|
|
||||||
|
52
client/ssh/ssh.go
Normal file
52
client/ssh/ssh.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package ssh
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
gossh "golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GeneratePrivateKey creates RSA Private Key of specified byte size
|
||||||
|
func GeneratePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
|
||||||
|
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = privateKey.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GeneratePublicKey takes a rsa.PublicKey and return bytes suitable for writing to .pub file
|
||||||
|
// returns the key in format format "ssh-rsa ..."
|
||||||
|
func GeneratePublicKey(privateKey *rsa.PublicKey) ([]byte, error) {
|
||||||
|
publicRsaKey, err := gossh.NewPublicKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return gossh.MarshalAuthorizedKey(publicRsaKey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodePrivateKeyToPEM encodes Private Key from RSA to PEM format
|
||||||
|
func EncodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte {
|
||||||
|
// Get ASN.1 DER format
|
||||||
|
privDER := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||||
|
|
||||||
|
// pem.Block
|
||||||
|
privBlock := pem.Block{
|
||||||
|
Type: "RSA PRIVATE KEY",
|
||||||
|
Headers: nil,
|
||||||
|
Bytes: privDER,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private key in PEM format
|
||||||
|
privatePEM := pem.EncodeToMemory(&privBlock)
|
||||||
|
|
||||||
|
return privatePEM
|
||||||
|
}
|
Reference in New Issue
Block a user