Skip to content

Instantly share code, notes, and snippets.

@lxfontes
Created October 31, 2018 23:55
Show Gist options
  • Save lxfontes/ba933c42fb41515f78ebd56c3d96616f to your computer and use it in GitHub Desktop.
Save lxfontes/ba933c42fb41515f78ebd56c3d96616f to your computer and use it in GitHub Desktop.
golang ssh server with github authentication
package main
import (
"context"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"github.com/gliderlabs/ssh"
"github.com/pkg/errors"
gossh "golang.org/x/crypto/ssh"
)
func fetchKeys(ctx context.Context, username string) ([]ssh.PublicKey, error) {
keyURL := fmt.Sprintf("https://github.com/%s.keys", username)
log.Println(keyURL)
req, err := http.NewRequest("GET", keyURL, nil)
if err != nil {
return nil, errors.Wrap(err, "creating request")
}
req = req.WithContext(ctx)
client := http.DefaultClient
res, err := client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "fetching keys")
}
defer res.Body.Close()
if res.StatusCode != 200 {
return nil, errors.New("invalid response from github")
}
authorizedKeysBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, errors.Wrap(err, "reading body")
}
keys := []ssh.PublicKey{}
for len(authorizedKeysBytes) > 0 {
pubKey, _, _, rest, err := ssh.ParseAuthorizedKey(authorizedKeysBytes)
if err != nil {
return nil, errors.Wrap(err, "parsing key")
}
keys = append(keys, pubKey)
authorizedKeysBytes = rest
}
return keys, nil
}
func main() {
ssh.Handle(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 {
user := ctx.User()
keys, err := fetchKeys(ctx, user)
if err != nil {
log.Printf("%s: %s", user, err)
return false
}
for _, k := range keys {
if ssh.KeysEqual(key, k) {
log.Println(user, "allowed")
return true
}
}
log.Println(user, "denied")
return false
})
log.Fatal(ssh.ListenAndServe(":2222", nil, publicKeyOption))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment