master
sh 267 lines 7 KB
Raw
1 #!/usr/bin/env bash
2
3 me="${0}"
4 dst="/etc/ssl/systemd-journal"
5
6 show_usage() {
7 cat <<EOFUSAGE
8
9 ${me} [options] server_name alias1 alias2 ...
10
11 server_name
12 the canonical name of the server on the certificates
13
14 aliasN
15 a hostname or IP this server is reachable with
16 DNS names should be like DNS:hostname
17 IPs should be like IP:1.2.3.4
18 Any number of aliases are accepted per server
19
20 options can be:
21
22 -h, --help
23 show this message
24
25 -d, --directory DIRECTORY
26 change the default certificates install dir
27 default: ${dst}
28
29 EOFUSAGE
30 }
31
32 while [ ! -z "${1}" ]; do
33 case "${1}" in
34 -h|--help)
35 show_usage
36 exit 0
37 ;;
38
39 -d|--directory)
40 dst="${2}"
41 echo >&2 "directory set to: ${dst}"
42 shift
43 ;;
44
45 *)
46 break 2
47 ;;
48 esac
49
50 shift
51 done
52
53 if [ -z "${1}" ]; then
54 show_usage
55 exit 1
56 fi
57
58
59 # Define a regular expression pattern for a valid canonical name
60 valid_canonical_name_pattern="^[a-zA-Z0-9][a-zA-Z0-9.-]+$"
61
62 # Check if ${1} matches the pattern
63 if [[ ! "${1}" =~ ${valid_canonical_name_pattern} ]]; then
64 echo "Certificate name '${1}' is not valid."
65 exit 1
66 fi
67
68 # -----------------------------------------------------------------------------
69 # Create the CA
70
71 # stop on all errors
72 set -e
73
74 if [ $UID -ne 0 ]
75 then
76 echo >&2 "Hey! sudo me: sudo ${me}"
77 exit 1
78 fi
79
80 if ! getent group systemd-journal >/dev/null 2>&1; then
81 echo >&2 "Missing system group: systemd-journal. Did you install systemd-journald?"
82 exit 1
83 fi
84
85 if ! getent passwd systemd-journal-remote >/dev/null 2>&1; then
86 echo >&2 "Missing system user: systemd-journal-remote. Did you install systemd-journal-remote?"
87 exit 1
88 fi
89
90 if [ ! -d "${dst}" ]
91 then
92 mkdir -p "${dst}"
93 chown systemd-journal-remote:systemd-journal "${dst}"
94 chmod 750 "${dst}"
95 fi
96
97 cd "${dst}"
98
99 test ! -f ca.conf && cat >ca.conf <<EOF
100 [ ca ]
101 default_ca = CA_default
102 [ CA_default ]
103 new_certs_dir = .
104 certificate = ca.pem
105 database = ./index
106 private_key = ca.key
107 serial = ./serial
108 default_days = 3650
109 default_md = default
110 policy = policy_anything
111 [ policy_anything ]
112 countryName = optional
113 stateOrProvinceName = optional
114 localityName = optional
115 organizationName = optional
116 organizationalUnitName = optional
117 commonName = supplied
118 emailAddress = optional
119 EOF
120
121 test ! -f index && touch index
122 test ! -f serial && echo 0001 >serial
123
124 if [ ! -f ca.pem -o ! -f ca.key ]; then
125 echo >&2 "Generating ca.pem ..."
126
127 openssl req -newkey rsa:2048 -days 3650 -x509 -nodes -out ca.pem -keyout ca.key -subj "/CN=systemd-journal-remote-ca/"
128 chown systemd-journal-remote:systemd-journal ca.pem
129 chmod 0640 ca.pem
130 fi
131
132 # -----------------------------------------------------------------------------
133 # Create a server certificate
134
135 generate_server_certificate() {
136 local cn="${1}"; shift
137
138 if [ ! -f "${cn}.pem" -o ! -f "${cn}.key" ]; then
139 if [ -z "${*}" ]; then
140 echo >"${cn}.conf"
141 else
142 echo "subjectAltName = $(echo "${@}" | tr " " ",")" >"${cn}.conf"
143 fi
144
145 echo >&2 "Generating server: ${cn}.pem and ${cn}.key ..."
146
147 openssl req -newkey rsa:2048 -nodes -out "${cn}.csr" -keyout "${cn}.key" -subj "/CN=${cn}/"
148 openssl ca -batch -config ca.conf -notext -in "${cn}.csr" -out "${cn}.pem" -extfile "${cn}.conf"
149 else
150 echo >&2 "certificates for ${cn} are already available."
151 fi
152
153 chown systemd-journal-remote:systemd-journal "${cn}.pem" "${cn}.key"
154 chmod 0640 "${cn}.pem" "${cn}.key"
155 }
156
157
158 # -----------------------------------------------------------------------------
159 # Create a script to install the certificate on each server
160
161 generate_install_script() {
162 local cn="${1}"
163 local dst="/etc/ssl/systemd-journal"
164
165 cat >"runme-on-${cn}.sh" <<EOFC1
166 #!/usr/bin/env bash
167
168 # stop on all errors
169 set -e
170
171 if [ \$UID -ne 0 ]; then
172 echo >&2 "Hey! sudo me: sudo \${0}"
173 exit 1
174 fi
175
176 # make sure the systemd-journal group exists
177 # all certificates will be owned by this group
178 if ! getent group systemd-journal >/dev/null 2>&1; then
179 echo >&2 "Missing system group: systemd-journal. Did you install systemd-journald?"
180 exit 1
181 fi
182
183 if ! getent passwd systemd-journal-remote >/dev/null 2>&1; then
184 echo >&2 "Missing system user: systemd-journal-remote. Did you install systemd-journal-remote?"
185 exit 1
186 fi
187
188 if [ ! -d ${dst} ]; then
189 echo >&2 "creating directory: ${dst}"
190 mkdir -p "${dst}"
191 fi
192 chown systemd-journal-remote:systemd-journal "${dst}"
193 chmod 750 "${dst}"
194 cd "${dst}"
195
196 echo >&2 "saving trusted certificate file as: ${dst}/ca.pem"
197 cat >ca.pem <<EOFCAPEM
198 $(cat ca.pem)
199 EOFCAPEM
200
201 chown systemd-journal-remote:systemd-journal ca.pem
202 chmod 0640 ca.pem
203
204 echo >&2 "saving server ${cn} certificate file as: ${dst}/${cn}.pem"
205 cat >"${cn}.pem" <<EOFSERPEM
206 $(cat "${cn}.pem")
207 EOFSERPEM
208
209 chown systemd-journal-remote:systemd-journal "${cn}.pem"
210 chmod 0640 "${cn}.pem"
211
212 echo >&2 "saving server ${cn} key file as: ${dst}/${cn}.key"
213 cat >"${cn}.key" <<EOFSERKEY
214 $(cat "${cn}.key")
215 EOFSERKEY
216
217 chown systemd-journal-remote:systemd-journal "${cn}.key"
218 chmod 0640 "${cn}.key"
219
220 for cfg in /etc/systemd/journal-remote.conf /etc/systemd/journal-upload.conf
221 do
222 if [ -f \${cfg} ]; then
223 # keep a backup of the file
224 test ! -f \${cfg}.orig && cp \${cfg} \${cfg}.orig
225
226 # fix its contents
227 echo >&2 "updating the certificates in \${cfg}"
228 sed -i "s|^#\\?\\s*ServerKeyFile=.*$|ServerKeyFile=${dst}/${cn}.key|" \${cfg}
229 sed -i "s|^#\\?\\s*ServerCertificateFile=.*$|ServerCertificateFile=${dst}/${cn}.pem|" \${cfg}
230 sed -i "s|^#\\?\\s*TrustedCertificateFile=.*$|TrustedCertificateFile=${dst}/ca.pem|" \${cfg}
231 fi
232 done
233
234 echo >&2 "certificates installed - you may need to restart services to active them"
235 echo >&2
236 echo >&2 "If this is a central server:"
237 echo >&2 "# systemctl restart systemd-journal-remote.socket"
238 echo >&2
239 echo >&2 "If this is a passive client:"
240 echo >&2 "# systemctl restart systemd-journal-upload.service"
241 echo >&2
242 echo >&2 "If this is an active client:"
243 echo >&2 "# systemctl restart systemd-journal-gateway.socket"
244 EOFC1
245
246 chmod 0700 "runme-on-${cn}.sh"
247 }
248
249 # -----------------------------------------------------------------------------
250 # Create the client certificates
251
252 generate_server_certificate "${@}"
253 generate_install_script "${1}"
254
255
256 # Set ANSI escape code for colors
257 yellow_color="\033[1;33m"
258 green_color="\033[0;32m"
259 # Reset ANSI color after the message
260 reset_color="\033[0m"
261
262
263 echo >&2 -e "use this script to install it on ${1}: ${yellow_color}$(ls ${dst}/runme-on-${1}.sh)${reset_color}"
264 echo >&2 "copy it to your server ${1}, like this:"
265 echo >&2 -e "# ${green_color}scp ${dst}/runme-on-${1}.sh ${1}:/tmp/${reset_color}"
266 echo >&2 "and then run it on that server to install the certificates"
267 echo >&2