Skip to content

Commit bd952f5

Browse files
author
Jeff McCormick
committed
TLS changes
1 parent 46e9616 commit bd952f5

File tree

21 files changed

+268
-114
lines changed

21 files changed

+268
-114
lines changed

apiserver.go

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package main
22

33
import (
4-
//"crypto/tls"
5-
//"crypto/x509"
4+
"crypto/tls"
5+
"crypto/x509"
66
log "github.com/Sirupsen/logrus"
77
"github.com/crunchydata/postgres-operator/apiserver/backupservice"
88
"github.com/crunchydata/postgres-operator/apiserver/cloneservice"
@@ -15,11 +15,14 @@ import (
1515
"github.com/crunchydata/postgres-operator/apiserver/userservice"
1616
"github.com/crunchydata/postgres-operator/apiserver/versionservice"
1717
"github.com/gorilla/mux"
18-
//"io/ioutil"
18+
"io/ioutil"
1919
"net/http"
2020
"os"
2121
)
2222

23+
const serverCert = "/config/server.crt"
24+
const serverKey = "/config/server.key"
25+
2326
func main() {
2427

2528
debugFlag := os.Getenv("DEBUG")
@@ -51,25 +54,33 @@ func main() {
5154
r.HandleFunc("/backups", backupservice.CreateBackupHandler).Methods("POST")
5255
//log.Fatal(http.ListenAndServeTLS(":8443", "/config/cert.pem", "/config/key.pem", r))
5356
//log.Fatal(http.ListenAndServeTLS(":8443", "/config/secure.domain.com.crt", "/config/secure.domain.com.key", r))
54-
//caCert, err := ioutil.ReadFile("/config/client.crt")
55-
//if err != nil {
56-
//log.Fatal(err)
57-
//log.Error("could not read /config/client.crt")
58-
//os.Exit(2)
59-
//}
60-
//caCertPool := x509.NewCertPool()
61-
//caCertPool.AppendCertsFromPEM(caCert)
62-
//cfg := &tls.Config{
63-
//ClientAuth: tls.RequireAndVerifyClientCert,
64-
//ClientCAs: caCertPool,
65-
//}
66-
//srv := &http.Server{
67-
////Addr: ":8443",
68-
//Handler: &handler{},
69-
//Handler: r,
70-
//TLSConfig: cfg,
71-
//}
7257

73-
//log.Fatal(srv.ListenAndServeTLS("/config/server.crt", "/config/server.key"))
74-
log.Fatal(http.ListenAndServe(":8080", r))
58+
caCert, err := ioutil.ReadFile(serverCert)
59+
if err != nil {
60+
log.Fatal(err)
61+
log.Error("could not read " + serverCert)
62+
os.Exit(2)
63+
}
64+
caCertPool := x509.NewCertPool()
65+
caCertPool.AppendCertsFromPEM(caCert)
66+
cfg := &tls.Config{
67+
//ClientAuth: tls.RequireAndVerifyClientCert,
68+
ClientCAs: caCertPool,
69+
}
70+
71+
srv := &http.Server{
72+
Addr: ":8443",
73+
Handler: r,
74+
TLSConfig: cfg,
75+
}
76+
77+
_, err = ioutil.ReadFile(serverKey)
78+
if err != nil {
79+
log.Fatal(err)
80+
log.Error("could not read " + serverKey)
81+
os.Exit(2)
82+
}
83+
84+
log.Fatal(srv.ListenAndServeTLS(serverCert, serverKey))
85+
//log.Fatal(http.ListenAndServe(":8080", r))
7586
}

apiserver/clusterservice/clusterservice.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ func ShowClusterHandler(w http.ResponseWriter, r *http.Request) {
8686

8787
w.WriteHeader(http.StatusOK)
8888
w.Header().Set("Content-Type", "application/json")
89+
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
8990

9091
switch r.Method {
9192
case "GET":
@@ -113,6 +114,7 @@ func TestClusterHandler(w http.ResponseWriter, r *http.Request) {
113114

114115
w.WriteHeader(http.StatusOK)
115116
w.Header().Set("Content-Type", "application/json")
117+
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
116118

117119
resp := TestCluster(namespace, clustername)
118120

bin/make-certs.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
3+
# Copyright 2017 Crunchy Data Solutions, Inc.
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
#
17+
# generate self signed cert for apiserver REST service
18+
#
19+
20+
openssl req \
21+
-x509 \
22+
-nodes \
23+
-newkey rsa:2048 \
24+
-keyout $COROOT/conf/apiserver/server.key \
25+
-out $COROOT/conf/apiserver/server.crt \
26+
-days 3650 \
27+
-subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=*"
28+
exit
29+
30+
# generate CA
31+
#openssl genrsa -out $COROOT/conf/apiserver/rootCA.key 4096
32+
#openssl req -x509 -new -key $COROOT/conf/apiserver/rootCA.key -days 3650 -out $COROOT/conf/apiserver/rootCA.crt
33+
34+
# generate cert for secure.domain.com signed with the created CA
35+
openssl genrsa -out $COROOT/conf/apiserver/secure.domain.com.key 2048
36+
openssl req -new -key $COROOT/conf/apiserver/secure.domain.com.key -out $COROOT/conf/apiserver/secure.domain.com.csr
37+
#In answer to question `Common Name (e.g. server FQDN or YOUR name) []:` you should set `secure.domain.com` (your real domain name)
38+
openssl x509 -req -in $COROOT/conf/apiserver/secure.domain.com.csr -CA $COROOT/conf/apiserver/rootCA.crt -CAkey $COROOT/conf/apiserver/rootCA.key -CAcreateserial -days 365 -out $COROOT/conf/apiserver/secure.domain.com.crt
39+
40+
#openssl genrsa 2048 > $COROOT/conf/apiserver/key.pem
41+
#openssl req -new -x509 -key $COROOT/conf/apiserver/key.pem -out $COROOT/conf/apiserver/cert.pem -days 1095

bin/save-images.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
# Copyright 2017 Crunchy Data Solutions, Inc.
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
docker save crunchydata/lspvc:$CO_IMAGE_TAG > /tmp/lspvc-$CO_IMAGE_TAG.tar
17+
docker save crunchydata/postgres-operator:$CO_IMAGE_TAG > /tmp/postgres-operator-$CO_IMAGE_TAG.tar
18+
docker save crunchydata/csvload:$CO_IMAGE_TAG > /tmp/csvload-$CO_IMAGE_TAG.tar
19+
docker save crunchydata/apiserver:$CO_IMAGE_TAG > /tmp/apiserver-$CO_IMAGE_TAG.tar

centos7/Dockerfile.apiserver.centos7

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ ADD bin/postgres-operator/runpsql.sh /usr/local/bin
1414

1515
VOLUME ["/config", "/operator-conf"]
1616

17-
EXPOSE 8080
17+
EXPOSE 8443
1818

1919
USER daemon
2020

conf/apiserver/server.crt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDrTCCApWgAwIBAgIJAPqgQ8XMF5ZnMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNV
3+
BAYTAkdCMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxvbmRvbjEYMBYGA1UE
4+
CgwPR2xvYmFsIFNlY3VyaXR5MRYwFAYDVQQLDA1JVCBEZXBhcnRtZW50MQowCAYD
5+
VQQDDAEqMB4XDTE3MTIxMTIxMzcxNloXDTI3MTIwOTIxMzcxNlowbTELMAkGA1UE
6+
BhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMRgwFgYDVQQK
7+
DA9HbG9iYWwgU2VjdXJpdHkxFjAUBgNVBAsMDUlUIERlcGFydG1lbnQxCjAIBgNV
8+
BAMMASowggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1OzrCLXU91VGF
9+
rG3Ukg+/YvXvY4hA0Cs+M2JV1+ypewRXF/S2UJDSDLP8nG3U5xLclH7rtCVEps3S
10+
tDmX6UHYsQYs/tTVmVGyToZJUmpSICETUV15muPQsBqc/on+5dEQCcQc4IwCuQs3
11+
sox11pTcg1vZsEfCUsLQrgTI/RgHDJEMa4yTgCaCCv9gQ9o6vPHWS8h7f1ej6+zf
12+
AUIRwN1y3DkiPbwT+3A8hOd90fqz+9RcWmWIJaYfHGz8jx5nErCDgyxlJir1r6Eb
13+
+6gQGo5xfg1Q/8znPhbjr1XzyswD5Kzdq+08mnx9gry7wi/Y8GyZWUWB3pm+MUSk
14+
xa63e75bAgMBAAGjUDBOMB0GA1UdDgQWBBQgZQYy3rqbS57vDHohT+NfGqf4DTAf
15+
BgNVHSMEGDAWgBQgZQYy3rqbS57vDHohT+NfGqf4DTAMBgNVHRMEBTADAQH/MA0G
16+
CSqGSIb3DQEBCwUAA4IBAQAuS63ceqpcMhhDSFgTs225Lk5HCQYwDcBVeelIaZ+l
17+
S4PeFIwcocPpw7pEPSPlZwOPfFny0nfZv1eqNhaGMig3wkM5V3M9qVM4NSnq7Gid
18+
Z+ttnvaPcRVROzoj+w6+VzBSvhC006EBEGLM/m/0GImJcQiBnAHzDpuRuOWbSuIy
19+
1YArI86VVeZGr+sc9bzHucja/wh4vFGAF4mglHrn8Nm/cb7cS4Q2c94kWW6hYsKv
20+
zhXuPQxJjEwpl80OJ6sQow54zYIOeKrkOoFtss3oqw+cdSSihdP4SDgkuB1tHiy6
21+
8DrOXaFEZpmjEvxpyPdw8LiXWcgGKJPvoPR8IMHd+roi
22+
-----END CERTIFICATE-----

conf/apiserver/server.key

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1OzrCLXU91VGF
3+
rG3Ukg+/YvXvY4hA0Cs+M2JV1+ypewRXF/S2UJDSDLP8nG3U5xLclH7rtCVEps3S
4+
tDmX6UHYsQYs/tTVmVGyToZJUmpSICETUV15muPQsBqc/on+5dEQCcQc4IwCuQs3
5+
sox11pTcg1vZsEfCUsLQrgTI/RgHDJEMa4yTgCaCCv9gQ9o6vPHWS8h7f1ej6+zf
6+
AUIRwN1y3DkiPbwT+3A8hOd90fqz+9RcWmWIJaYfHGz8jx5nErCDgyxlJir1r6Eb
7+
+6gQGo5xfg1Q/8znPhbjr1XzyswD5Kzdq+08mnx9gry7wi/Y8GyZWUWB3pm+MUSk
8+
xa63e75bAgMBAAECggEBAJKubKFKz5CLPd8WLxKUYUCC5RCrG1Vx5v4B8r4N9FM7
9+
6Mhg8EQ7Mut/MpHrPg3KNH7phUxaUquc4gt+qPql5RBwPtJeMn7rB69sVM21ca4k
10+
qQCMoz5QOcDnN7MHZUM0WKBFdz/0Ef4GLOkYjwy072kGvGmVfo7uExV5MxBFoJPa
11+
oD/tYVZGn1n+3gNiVUFSSDNk8an7YDuf9cydV9+oY46w4CDjcPm4i3yF7ebNgaQ6
12+
4WfC7rofI7a7CzXDJTR+fhsoA3iEHRKkojDLdAMb/CR/L6t31tpG7JIsN/3sLe1U
13+
iDeI38dpMYK4460F/vjAElOt03xiZPkuZdMrNhdICxkCgYEA2WW75EmBL841/t+S
14+
IMpKSAUUOtVgu/TPK7WAdfmoyd+09XkvYUD0DXx59k2LfjBuhfzN/+5HpKAPiHqR
15+
VjryRsvBjM+mixhjTDdZ6CqDJs5VEKPg0v1r29b3FxZY1aHqtL2//cmYMswYXANE
16+
zTxs/PvinsdYTxs9TC0QmG1eGC0CgYEA1Wl9pXF16LLOzNdQg+wg0lwIzkXnHVeD
17+
uJVDcXxUY60T+XyM3dUtyZLWfjQzs0xVAmoMe9rPaDvZusVnKyf4/6v6ytlVdFjc
18+
oNoLcicLnFGQx7C1lBpCPo7Tz/xMd8SPfUbDVdFlgH7qk4DNDq3LzP66A/7NbJxY
19+
E7z21sX8facCgYEAuoLfmlG9tefyx0HEOsGSzQseegNKxLaZbuR+27hfqSJ2PAvG
20+
LGfvegqLEFcjEBY5HFbx3VruuDxiVzLgsdxMs5Rn74jPV5KKzn7GcbrXXlmy/V27
21+
qwikmq1ou7P+bvpFRN9uciucmigj1f0v7+yhjMIFgTeBegzioBIhpMRf79kCgYAz
22+
xdrIdyUOpcpLoXST/IXd4pv0RrsRwDhhYDyzXGEwqT1uSgv2iRAJlcjZZxqfxcXd
23+
xxJuPaARfmuMxvUHYDQk+njmGyGDD0e+8gbS06waaSNBfpoeatxlRssV6vQ2HgZd
24+
cvxSZnFEYgXQcO/OPtVxTt6bt4XocmlfqHkNk4x0gwKBgBFnQ20ZLiN9SFeQk6u1
25+
sDZn6p24/AggWt5/88ekXlGTkXrs7rGzxl0+NMVG93KiGhJjtND150dC0mRLXAjx
26+
8iZTtX6+cGY17+hyPlhZreOadtFUXvplAJgYt25tN0CjSBqDXS9ePRapIjjkL5sI
27+
+1Q+Xy5KO5e6+5zkIDPHzpuO
28+
-----END PRIVATE KEY-----

deploy/deploy.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
1818
$DIR/cleanup.sh
1919

2020
$CO_CMD --namespace=$CO_NAMESPACE create configmap apiserver-conf \
21+
--from-file=$COROOT/conf/apiserver/server.crt \
22+
--from-file=$COROOT/conf/apiserver/server.key \
2123
--from-file=$COROOT/conf/apiserver/pgouser \
2224
--from-file=$COROOT/conf/apiserver/pgo.yaml \
2325
--from-file=$COROOT/conf/apiserver/pgo.csvload-template.json \

deploy/service.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,22 @@
88
}
99
},
1010
"spec": {
11-
"ports": [{
11+
"ports": [
12+
{
13+
"name": "postgres-operator",
1214
"protocol": "TCP",
1315
"port": 8080,
1416
"targetPort": 8080,
1517
"nodePort": 0
16-
}],
18+
},
19+
{
20+
"name": "apiserver",
21+
"protocol": "TCP",
22+
"port": 8443,
23+
"targetPort": 8443,
24+
"nodePort": 0
25+
}
26+
],
1727
"selector": {
1828
"name": "postgres-operator"
1929
},

pgo/cmd/auth.go

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ var BasicAuthUsername, BasicAuthPassword string
3434

3535
var caCertPool *x509.CertPool
3636
var cert tls.Certificate
37+
var httpclient *http.Client
38+
var caCertPath, clientCertPath, clientKeyPath string
3739

3840
// StatusCheck ...
3941
func StatusCheck(resp *http.Response) {
@@ -72,45 +74,57 @@ func GetCredentials() {
7274
fullPath := dir + "/" + ".pgouser"
7375
log.Debug("looking in " + fullPath + " for credentials")
7476
dat, err := ioutil.ReadFile(fullPath)
77+
found := false
7578
if err != nil {
7679
log.Debug(fullPath + " not found")
7780
} else {
7881
log.Debug(fullPath + " found")
7982
log.Debug("pgouser file found at " + fullPath + "contains " + string(dat))
8083
BasicAuthUsername, BasicAuthPassword = parseCredentials(string(dat))
81-
return
84+
found = true
85+
8286
}
8387

84-
fullPath = etcpath
85-
dat, err = ioutil.ReadFile(fullPath)
86-
if err != nil {
87-
log.Debug(etcpath + " not found")
88-
} else {
89-
log.Debug(fullPath + " found")
88+
if !found {
89+
fullPath = etcpath
90+
dat, err = ioutil.ReadFile(fullPath)
91+
if err != nil {
92+
log.Debug(etcpath + " not found")
93+
} else {
94+
log.Debug(fullPath + " found")
95+
log.Debug("pgouser file found at " + fullPath + "contains " + string(dat))
96+
BasicAuthUsername, BasicAuthPassword = parseCredentials(string(dat))
97+
found = true
98+
}
99+
}
100+
101+
if !found {
102+
pgoUser := os.Getenv(pgouserenvvar)
103+
if pgoUser == "" {
104+
log.Error(pgouserenvvar + " env var not set")
105+
os.Exit(2)
106+
}
107+
108+
fullPath = pgoUser
109+
log.Debug(pgouserenvvar + " env var is being used at " + fullPath)
110+
dat, err = ioutil.ReadFile(fullPath)
111+
if err != nil {
112+
log.Error(fullPath + " file not found")
113+
os.Exit(2)
114+
}
115+
90116
log.Debug("pgouser file found at " + fullPath + "contains " + string(dat))
91117
BasicAuthUsername, BasicAuthPassword = parseCredentials(string(dat))
92-
return
93118
}
94119

95-
pgoUser := os.Getenv(pgouserenvvar)
96-
if pgoUser == "" {
97-
log.Error(pgouserenvvar + " env var not set")
98-
os.Exit(2)
99-
}
120+
caCertPath = os.Getenv("PGO_CA_CERT")
100121

101-
fullPath = pgoUser
102-
log.Debug(pgouserenvvar + " env var is being used at " + fullPath)
103-
dat, err = ioutil.ReadFile(fullPath)
104-
if err != nil {
105-
log.Error(fullPath + " file not found")
122+
if caCertPath == "" {
123+
log.Error("PGO_CA_CERT not specified")
106124
os.Exit(2)
107125
}
108-
109-
log.Debug("pgouser file found at " + fullPath + "contains " + string(dat))
110-
BasicAuthUsername, BasicAuthPassword = parseCredentials(string(dat))
111-
112-
/**
113-
caCert, err := ioutil.ReadFile("/tmp/server.crt")
126+
//caCert, err := ioutil.ReadFile("/tmp/server.crt")
127+
caCert, err := ioutil.ReadFile(caCertPath)
114128
if err != nil {
115129
log.Error(err)
116130
log.Error("could not read ca certificate")
@@ -119,11 +133,48 @@ func GetCredentials() {
119133
caCertPool = x509.NewCertPool()
120134
caCertPool.AppendCertsFromPEM(caCert)
121135

122-
cert, err = tls.LoadX509KeyPair("/tmp/client.crt", "/tmp/client.key")
136+
clientCertPath = os.Getenv("PGO_CLIENT_CERT")
137+
138+
if clientCertPath == "" {
139+
log.Error("PGO_CLIENT_CERT not specified")
140+
os.Exit(2)
141+
}
142+
143+
_, err = ioutil.ReadFile(clientCertPath)
144+
if err != nil {
145+
log.Debug(clientCertPath + " not found")
146+
os.Exit(2)
147+
}
148+
149+
clientKeyPath = os.Getenv("PGO_CLIENT_KEY")
150+
151+
if clientKeyPath == "" {
152+
log.Error("PGO_CLIENT_KEY not specified")
153+
os.Exit(2)
154+
}
155+
156+
_, err = ioutil.ReadFile(clientKeyPath)
157+
if err != nil {
158+
log.Debug(clientKeyPath + " not found")
159+
os.Exit(2)
160+
}
161+
//cert, err = tls.LoadX509KeyPair("/tmp/example.com.crt", "/tmp/example.com.key")
162+
cert, err = tls.LoadX509KeyPair(clientCertPath, clientKeyPath)
123163
if err != nil {
124164
log.Fatal(err)
125-
log.Error("could not load client.crt and client.key")
165+
log.Error("could not load example.com.crt and example.com.key")
126166
os.Exit(2)
127-
} */
167+
}
168+
169+
log.Info("setting up httpclient with TLS")
170+
httpclient = &http.Client{
171+
Transport: &http.Transport{
172+
TLSClientConfig: &tls.Config{
173+
RootCAs: caCertPool,
174+
InsecureSkipVerify: true,
175+
Certificates: []tls.Certificate{cert},
176+
},
177+
},
178+
}
128179

129180
}

0 commit comments

Comments
 (0)