Skip to content
Snippets Groups Projects
Commit 369c103c authored by Niall Sheridan's avatar Niall Sheridan
Browse files

Use a simple config file for configuring the client.

parent 054e32ed
Branches
Tags
No related merge requests found
......@@ -37,8 +37,8 @@ The user can now ssh to the production machine, and continue to ssh to any machi
# Usage
Cashier comes in two parts, a [cli](cmd/cashier) and a [server](cmd/cashierd).
The client is configured using command-line flags.
The server is configured using a JSON configuration file - [example](exampleconfig.json).
The client is configured using a [HCL](https://github.com/hashicorp/hcl) configuration file - [example](example-client.cfg).
The server is configured using a JSON configuration file - [example](example-server.json).
For the server you need the following:
- A new ssh private key. Generate one in the usual way using `ssh-keygen -f ssh_ca` - this is your CA signing key. At this time Cashier supports RSA, ECDSA and Ed25519 keys. *Important* This key should be kept safe - *ANY* ssh key signed with this key will be able to access your machines.
......@@ -50,11 +50,11 @@ For the server you need the following:
```
go get github.com/cashier/cmd/...
```
2. Create a signing key with `ssh-keygen` and a [config.json](exampleconfig.json)
2. Create a signing key with `ssh-keygen` and a [config.json](example-server.json)
3. Run the cashier server with `cashierd` and the cli with `cashier`.
## Using docker
1. Create a signing key with `ssh-keygen` and a [config.json](exampleconfig.json)
1. Create a signing key with `ssh-keygen` and a [config.json](example-server.json)
2. Run
```
docker run -it --rm -p 10000:10000 --name cashier -v $(pwd):/cashier nsheridan/cashier
......
package main
import (
"github.com/spf13/viper"
)
type config struct {
CA string `mapstructure:"ca"`
Keytype string `mapstructure:"key_type"`
Keysize int `mapstructure:"key_size"`
Validity string `mapstructure:"validity"`
}
func setDefaults() {
viper.SetDefault("ca", "http://localhost:10000")
viper.SetDefault("key_type", "rsa")
viper.SetDefault("key_size", 2048)
viper.SetDefault("validity", "24h")
}
func readConfig(path string) (*config, error) {
setDefaults()
viper.SetConfigFile(path)
viper.SetConfigType("hcl")
if err := viper.ReadInConfig(); err != nil {
return nil, err
}
c := &config{}
if err := viper.Unmarshal(c); err != nil {
return nil, err
}
return c, nil
}
......@@ -10,6 +10,8 @@ import (
"net"
"net/http"
"os"
"os/user"
"path"
"time"
"github.com/nsheridan/cashier/lib"
......@@ -19,10 +21,8 @@ import (
)
var (
ca = flag.String("ca", "http://localhost:10000", "CA server")
keybits = flag.Int("bits", 2048, "Key size. Ignored for ed25519 keys")
validity = flag.Duration("validity", time.Hour*24, "Key validity")
keytype = flag.String("key_type", "rsa", "Type of private key to generate - rsa, ecdsa or ed25519")
u, _ = user.Current()
cfg = flag.String("config", path.Join(u.HomeDir, ".cashier.cfg"), "Path to config file")
)
func installCert(a agent.Agent, cert *ssh.Certificate, key key) error {
......@@ -37,8 +37,8 @@ func installCert(a agent.Agent, cert *ssh.Certificate, key key) error {
return nil
}
func send(s []byte, token string) (*lib.SignResponse, error) {
req, err := http.NewRequest("POST", *ca+"/sign", bytes.NewReader(s))
func send(s []byte, token, ca string) (*lib.SignResponse, error) {
req, err := http.NewRequest("POST", ca+"/sign", bytes.NewReader(s))
if err != nil {
return nil, err
}
......@@ -65,17 +65,21 @@ func send(s []byte, token string) (*lib.SignResponse, error) {
return c, nil
}
func sign(pub ssh.PublicKey, token string) (*ssh.Certificate, error) {
func sign(pub ssh.PublicKey, token string, conf *config) (*ssh.Certificate, error) {
validity, err := time.ParseDuration(conf.Validity)
if err != nil {
return nil, err
}
marshaled := ssh.MarshalAuthorizedKey(pub)
marshaled = marshaled[:len(marshaled)-1]
s, err := json.Marshal(&lib.SignRequest{
Key: string(marshaled),
ValidUntil: time.Now().Add(*validity),
ValidUntil: time.Now().Add(validity),
})
if err != nil {
return nil, err
}
resp, err := send(s, token)
resp, err := send(s, token, conf.CA)
if err != nil {
return nil, err
}
......@@ -95,13 +99,16 @@ func sign(pub ssh.PublicKey, token string) (*ssh.Certificate, error) {
func main() {
flag.Parse()
fmt.Printf("Your browser has been opened to visit %s\n", *ca)
if err := browser.OpenURL(*ca); err != nil {
c, err := readConfig(*cfg)
if err != nil {
log.Fatalf("Error parsing config file: %v\n", err)
}
fmt.Printf("Your browser has been opened to visit %s\n", c.CA)
if err := browser.OpenURL(c.CA); err != nil {
fmt.Println("Error launching web browser. Go to the link in your web browser")
}
fmt.Println("Generating new key pair")
priv, pub, err := generateKey(*keytype, *keybits)
priv, pub, err := generateKey(c.Keytype, c.Keysize)
if err != nil {
log.Fatalln("Error generating key pair: ", err)
}
......@@ -110,7 +117,7 @@ func main() {
var token string
fmt.Scanln(&token)
cert, err := sign(pub, token)
cert, err := sign(pub, token, c)
if err != nil {
log.Fatalln(err)
}
......
ca = "https://sshca.example.com" // Address of the cashierd CA
key_type = "rsa" // Type of ssh key to generate - rsa, ecdsa, ed25519
key_size = 2048 // Size of key to generate. ecdsa must be one of 256, 384, 521. This value is ignored for ed25519 keys.
validity = "24h" // How long the cert will be valid for. Must be a valid go time.Duration.
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment