-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconfig.go
131 lines (112 loc) · 3.95 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"crypto/tls"
"crypto/x509"
"encoding/base64"
"flag"
"fmt"
"golang.org/x/crypto/ssh"
"github.com/adrianmoye/ssh-gateway/src/api"
"github.com/adrianmoye/ssh-gateway/src/gencert"
"github.com/adrianmoye/ssh-gateway/src/log"
"github.com/adrianmoye/ssh-gateway/src/sshnet"
"github.com/adrianmoye/ssh-gateway/src/sshserver"
"github.com/adrianmoye/ssh-gateway/src/users"
)
type gwConfig struct {
API api.Config
Port string
SSH *ssh.ServerConfig
ProxyCert gencert.RawPEM
ProxyCA string
TLSConfig *tls.Config
OperationMode string
SecretName string
ResourceType string
SkipHeaders []string
Listener *sshnet.Listener
}
func setupConfig() gwConfig {
var config gwConfig
flagPort := flag.String("port", "2200", "Listen Port")
flagConfigSecret := flag.String("config", "ssh-gateway-config", "Config Secret Name")
flagOperatingMode := flag.String("mode", "impersonate", "Operating mode (serviceaccount|proxy|impersonate)")
flagResourceType := flag.String("resource", "serviceaccounts", "Resource type for user records")
flag.Parse()
config.Port = *flagPort
config.OperationMode = *flagOperatingMode
config.SecretName = *flagConfigSecret
config.ResourceType = *flagResourceType
users.ResourceType = config.ResourceType
users.OperationMode = config.OperationMode
config.API = api.ClientConfig()
var secret api.Secret
var updateSecret bool = false
config.API.Get("/api/v1/namespaces/"+config.API.Namespace+"/secrets/"+config.SecretName, &secret)
if secret.Data == nil {
secret.Data = make(map[string]string)
}
if _, ok := secret.Data["sshd_key"]; !ok {
keys := sshserver.GenKeys()
secret.Data["sshd_key"] = base64.StdEncoding.EncodeToString(keys.PrivateKey)
updateSecret = true
}
var CA gencert.RawPEM
if _, ok := secret.Data["ca_cert"]; !ok {
log.Info("Regenerating CA Cert", "server")
CA = gencert.GenCA("SSH Gateway CA")
//log.Println(string(CA.Cert))
//log.Println(string(CA.Key))
secret.Data["ca_cert"] = base64.StdEncoding.EncodeToString([]byte(CA.Cert))
secret.Data["ca_key"] = base64.StdEncoding.EncodeToString([]byte(CA.Key))
}
config.ProxyCA = secret.Data["ca_cert"]
c, err := base64.StdEncoding.DecodeString(secret.Data["ca_cert"])
if err != nil {
log.Fatal(fmt.Sprint(err), "server")
}
k, err := base64.StdEncoding.DecodeString(secret.Data["ca_key"])
if err != nil {
log.Fatal(fmt.Sprint(err), "server")
}
CA.Cert, CA.Key = c, k
config.ProxyCert = gencert.SignedCert("kubernetes.default", CA)
if updateSecret {
secret.APIVersion = "v1"
secret.Kind = "Secret"
secret.Metadata.Name = config.SecretName
secret.Metadata.Namespace = config.API.Namespace
secret.Metadata.Labels = make(map[string]string)
config.API.Post("/api/v1/namespaces/"+config.API.Namespace+"/secrets", &secret)
log.Info("Created secret with keys: ["+config.SecretName+"]", "server")
}
// now we have the server cert
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM([]byte(config.API.CA))
//log.Println("keycert:", ProxyCert)
cert, err := tls.X509KeyPair(config.ProxyCert.Cert, config.ProxyCert.Key)
if err != nil {
log.Panic(fmt.Sprint(err), "server")
}
//log.Println("keycert past fatal:", ProxyCert)
// Setup HTTPS client
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
tlsConfig.BuildNameToCertificate()
config.TLSConfig = tlsConfig
sshdKey, _ := base64.StdEncoding.DecodeString(secret.Data["sshd_key"])
config.SSH = sshserver.GenSSHServerConfig(sshdKey)
// decide which headers to pass through to the API server
// depending on what mode we're in.
switch config.OperationMode {
case "serviceaccount":
config.SkipHeaders = []string{"X-Remote-User", "X-Remote-Group"}
case "proxy":
config.SkipHeaders = []string{"X-Remote-User", "X-Remote-Group"}
default: // "impersonate"
config.SkipHeaders = []string{"X-Remote-User", "X-Remote-Group", "Impersonate-User", "Impersonate-Group"}
}
return config
}