mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-07 01:53:51 -04:00
Compare commits
10 Commits
wg_bind_pa
...
ssh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c45f1083d6 | ||
|
|
1aef5282a6 | ||
|
|
ae502e9947 | ||
|
|
af16192e50 | ||
|
|
7b352ac474 | ||
|
|
0d722237c8 | ||
|
|
307e08d76d | ||
|
|
7934e62c93 | ||
|
|
cd47599900 | ||
|
|
7019b00643 |
84
client/ssh/server.go
Normal file
84
client/ssh/server.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package ssh
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gliderlabs/ssh"
|
||||||
|
gossh "golang.org/x/crypto/ssh"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
listener net.Listener
|
||||||
|
allowedKeys map[string]ssh.PublicKey
|
||||||
|
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 {
|
||||||
|
srv.mu.Lock()
|
||||||
|
defer srv.mu.Unlock()
|
||||||
|
|
||||||
|
srv.allowedKeys = make(map[string]ssh.PublicKey, len(newKeys))
|
||||||
|
for _, strKey := range newKeys {
|
||||||
|
parsedKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(strKey))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
srv.allowedKeys[strKey] = parsedKey
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop stops SSH server. Blocking
|
||||||
|
func (srv *Server) Stop() error {
|
||||||
|
err := srv.listener.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts SSH server. Blocking
|
||||||
|
func (srv *Server) Start() error {
|
||||||
|
handler := func(s ssh.Session) {
|
||||||
|
authorizedKey := gossh.MarshalAuthorizedKey(s.PublicKey())
|
||||||
|
io.WriteString(s, fmt.Sprintf("public key used by %s:\n", s.User()))
|
||||||
|
s.Write(authorizedKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKeyOption := ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool {
|
||||||
|
srv.mu.Lock()
|
||||||
|
defer srv.mu.Unlock()
|
||||||
|
|
||||||
|
k := strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key)))
|
||||||
|
if allowed, ok := srv.allowedKeys[k]; ok {
|
||||||
|
if ssh.KeysEqual(allowed, key) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
hostKeyPEM := ssh.HostKeyPEM(srv.hostKeyPEM)
|
||||||
|
|
||||||
|
err := ssh.Serve(srv.listener, handler, publicKeyOption, hostKeyPEM)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return 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
|
||||||
|
}
|
||||||
2
go.sum
2
go.sum
@@ -1201,4 +1201,4 @@ sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:w
|
|||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
Reference in New Issue
Block a user