systemd-journal-self-signed-certs.sh 7.0 KB

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