Compare commits

...

10 Commits
v0.59.1 ... ssh

Author SHA1 Message Date
braginini
c45f1083d6 Merge remote-tracking branch 'origin/main' into ssh
# Conflicts:
#	go.sum
2022-06-05 21:44:50 +02:00
braginini
1aef5282a6 Update go.mod 2022-06-05 21:44:23 +02:00
braginini
ae502e9947 Remove main from ssh server 2022-06-05 13:08:11 +02:00
braginini
af16192e50 Merge branch 'ssh' of github.com:wiretrustee/wiretrustee into ssh 2022-06-05 13:07:32 +02:00
braginini
7b352ac474 Add hostkey to the ssh server 2022-06-05 13:06:17 +02:00
braginini
0d722237c8 Do map lookup for allowed keys 2022-06-05 13:06:17 +02:00
braginini
307e08d76d Playing with ssh 2022-06-05 13:06:17 +02:00
braginini
7934e62c93 Add hostkey to the ssh server 2022-06-04 22:09:25 +02:00
braginini
cd47599900 Do map lookup for allowed keys 2022-06-04 21:54:55 +02:00
braginini
7019b00643 Playing with ssh 2022-06-04 21:16:41 +02:00
3 changed files with 137 additions and 1 deletions

84
client/ssh/server.go Normal file
View 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
View 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
View File

@@ -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.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.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=