forked from rzhilkibaev/mongo-x509-auth-ssl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-certs.sh
executable file
·147 lines (127 loc) · 6.38 KB
/
create-certs.sh
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env bash
#
# This script creates all necessary keys and certificates.
# By default the server certificate is created for hostname localhost.
# To override the hostname specify it as the first argument to this script.
# If you execute this script all existing files are going
# to be overwritten with new ones and existing clients will no longer work.
set -eo pipefail
# the script first argument is a hostname to be used in the server certificate subj (the CN field)
SRV_SUBJ_CN=${1:-localhost}
# Generated files
# CA pem file (private key + x509 cert)
CA_PEM=mongodb-CA.pem
# Server pem file (private key + x509 cert)
SRV_PEM=mongodb-server.pem
# Client pem file (private key + x509 cert)
CLIENT_PEM=mongodb-client.pem
# Client JKS type store with client private key and certificate in it
CLIENT_JKS=mongodb-client.jks
# Temp files
# CA (Certificate Authority) private key
CA_KEY=mongodb-CA.key
# CA x509 certificate
CA_CRT=mongodb-CA.crt
# CA serial file (autogenerated)
CA_SRL=mongodb-CA.srl
# Server private key
SRV_KEY=mongodb-server.key
# Server x509 certificate
SRV_CRT=mongodb-server.crt
# Server CSR file (Certificate Signing Request)
SRV_CSR=mongodb-server.csr
# Client private key
CLIENT_KEY=mongodb-client.key
# Client x509 certificate
CLIENT_CRT=mongodb-client.crt
# Client CSR file
CLIENT_CSR=mongodb-client.csr
# Client PKCS12 type store with client private key and certificate in it
CLIENT_P12=mongodb-client.p12
# Check if the key files exist
if [ -f $CA_PEM ]; then
echo "$CA_PEM already exists, removing..."
rm -f $CA_PEM
fi
if [ -f $CLIENT_PEM ]; then
echo "$CLIENT_PEM already exists, removing..."
rm -f $CLIENT_PEM
fi
if [ -f $SRV_PEM ]; then
echo "$SRV_PEM already exists, removing..."
rm -f $SRV_PEM
fi
if [ -f $CLIENT_JKS ]; then
echo "$CLIENT_JKS already exists, removing..."
rm -f $CLIENT_JKS
fi
# common subj part
SUBJ_PART='/OU=JSDev/O=Jaspersoft/L=San Francisco/ST=CA/C=US'
# Certification Authority certificate subj
CA_SUBJ="/CN=CA$SUBJ_PART"
# Server certificate subj, the CN must match the hosname of the server
SRV_SUBJ="/CN=$SRV_SUBJ_CN$SUBJ_PART"
# Client certificate subj
CLIENT_SUBJ="/CN=admin$SUBJ_PART"
log() {
echo "[$0] $1"
}
log "Generating CA certs"
# Using self-signed certificates.
# The first step is to create private and public key and wrap the public key into a x509 certificate, signing it with the private key.
# This generates the private key (.key) and certificate (.crt) files. The certificate is going to be our CA (Certification Authority).
# We'll use this root certificate to signt server and client certificates.
#
# This cone command creates private key and self-signed x509 certificate
openssl req -newkey rsa:4096 -new -x509 -extensions v3_ca -days 9999 -nodes -out $CA_CRT -keyout $CA_KEY -subj "$CA_SUBJ"
# Concatenate the private key and the certificate into a pem file which will be used by mongod and mongo.
cat $CA_KEY $CA_CRT > $CA_PEM
# Now that we have CA.key, CA.crt and CA.pem we can create server private and public key.
# And wrap the public key into a x509 certificate, signing it with the root CA.crt we created earlier.
# This will prove server identity to the client and enable SSL.
log "Generating server certs"
# Create server private key and CSR (certificate signing request).
openssl req -new -nodes -newkey rsa:4096 -keyout $SRV_KEY -out $SRV_CSR -subj "$SRV_SUBJ"
# Now we have server private key (.key) and server certificate signing request (.csr).
# Use CA.key and CA.crt to sign the server .csr file. This command will also generate a serial file (.srl)
# This is a file with a random number which is incremented each time CA.crt is used to sign something.
openssl x509 -sha256 -req -days 365 -CA $CA_CRT -CAkey $CA_KEY -CAcreateserial -in $SRV_CSR -out $SRV_CRT
# Concatentate the server private key and certificate into a pem file which will be used by mongod.
cat $SRV_KEY $SRV_CRT > $SRV_PEM
# Remove server .csr file, we won't need it anymore.
rm $SRV_CSR
# Now we have server private key (.key), x509 certificate (.crt) and pem file.
log "Generating client certs"
# Now generate client files the same way.
openssl req -new -nodes -newkey rsa:4096 -keyout $CLIENT_KEY -out $CLIENT_CSR -subj "$CLIENT_SUBJ"
openssl x509 -sha256 -req -days 365 -CA $CA_CRT -CAkey $CA_KEY -CAcreateserial -in $CLIENT_CSR -out $CLIENT_CRT
# Create pem file to be used by mongo.
cat $CLIENT_KEY $CLIENT_CRT > $CLIENT_PEM
rm $CLIENT_CSR
# Now we have client private key (.key), x509 certificate (.crt) and pem file.
# At this point the files can be used by the mongod and mongo.
# $ mongod --sslMode requireSSL --sslPEMKeyFile server.pem --sslCAFile CA.pem --auth --clusterAuthMode x509
# $ mongo admin --authenticationDatabase '$external' --ssl --sslPEMKeyFile mongodb-client.pem --sslCAFile mongodb-CA.pem --authenticationMechanism MONGODB-X509 -u "C=US,ST=CA,L=San Francisco,O=Jaspersoft,OU=JSDev,CN=admin"
# Note the reverse order of elements in the subj (I don't know why).
# Now for the java client we need to create trust-store.jks with CA.crt in it and key-store.jks with client.key and client.crt in it.
log "Creating jks store"
read -s -p "Input keystore password: " KEYSTORE_PASS
# remove JKS store from previous run
rm -f $CLIENT_JKS
# Create intermediate PKCS12 type store with client cert and key (I couldn't find another way to import client cert and key into JKS store).
openssl pkcs12 -export -in $CLIENT_CRT -inkey $CLIENT_KEY -chain -CAfile $CA_PEM -out $CLIENT_P12 -password pass:$KEYSTORE_PASS
# create JKS type key store with client cert and key
keytool -importkeystore -deststorepass $KEYSTORE_PASS -srcstorepass $KEYSTORE_PASS -destkeystore $CLIENT_JKS -srckeystore $CLIENT_P12 -srcstoretype PKCS12
# Won't need the .p12 file anymore.
rm $CLIENT_P12
# Create JKS type trust store with CA cert in it.
keytool -importcert -trustcacerts -noprompt -file $CA_CRT -keystore $CLIENT_JKS -storepass $KEYSTORE_PASS
# Won't need these eighter.
rm $CA_KEY $CA_CRT $SRV_KEY $SRV_CRT $CLIENT_KEY $CLIENT_CRT $CA_SRL
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "Created:"
echo "CA PEM file with the private key and self-signed certificate in it: $CA_PEM"
echo "Server PEM file with the private key and certificate signed by CA: $SRV_PEM"
echo "Client PEM file with the private key and certificate signed by CA: $CLIENT_PEM"
echo "Client JKS type key store with client private key/certificate and CA certifcate in it (password: 123456): $CLIENT_JKS"
echo "Done!"