|
| 1 | +#!/bin/bash |
| 2 | +set -eu |
| 3 | + |
| 4 | +# allow the container to be started with `--user` |
| 5 | +if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then |
| 6 | + if [ "$1" = 'rabbitmq-server' ]; then |
| 7 | + chown -R rabbitmq /var/lib/rabbitmq |
| 8 | + fi |
| 9 | + exec su-exec rabbitmq "$BASH_SOURCE" "$@" |
| 10 | +fi |
| 11 | + |
| 12 | +# backwards compatibility for old environment variables |
| 13 | +: "${RABBITMQ_SSL_CERTFILE:=${RABBITMQ_SSL_CERT_FILE:-}}" |
| 14 | +: "${RABBITMQ_SSL_KEYFILE:=${RABBITMQ_SSL_KEY_FILE:-}}" |
| 15 | +: "${RABBITMQ_SSL_CACERTFILE:=${RABBITMQ_SSL_CA_FILE:-}}" |
| 16 | + |
| 17 | +# "management" SSL config should default to using the same certs |
| 18 | +: "${RABBITMQ_MANAGEMENT_SSL_CACERTFILE:=$RABBITMQ_SSL_CACERTFILE}" |
| 19 | +: "${RABBITMQ_MANAGEMENT_SSL_CERTFILE:=$RABBITMQ_SSL_CERTFILE}" |
| 20 | +: "${RABBITMQ_MANAGEMENT_SSL_KEYFILE:=$RABBITMQ_SSL_KEYFILE}" |
| 21 | + |
| 22 | +# https://www.rabbitmq.com/configure.html |
| 23 | +sslConfigKeys=( |
| 24 | + cacertfile |
| 25 | + certfile |
| 26 | + fail_if_no_peer_cert |
| 27 | + keyfile |
| 28 | + verify |
| 29 | +) |
| 30 | +managementConfigKeys=( |
| 31 | + "${sslConfigKeys[@]/#/ssl_}" |
| 32 | +) |
| 33 | +rabbitConfigKeys=( |
| 34 | + default_pass |
| 35 | + default_user |
| 36 | + default_vhost |
| 37 | + hipe_compile |
| 38 | +) |
| 39 | +fileConfigKeys=( |
| 40 | + management_ssl_cacertfile |
| 41 | + management_ssl_certfile |
| 42 | + management_ssl_keyfile |
| 43 | + ssl_cacertfile |
| 44 | + ssl_certfile |
| 45 | + ssl_keyfile |
| 46 | +) |
| 47 | +allConfigKeys=( |
| 48 | + "${managementConfigKeys[@]/#/management_}" |
| 49 | + "${rabbitConfigKeys[@]}" |
| 50 | + "${sslConfigKeys[@]/#/ssl_}" |
| 51 | +) |
| 52 | + |
| 53 | +declare -A configDefaults=( |
| 54 | + [management_ssl_fail_if_no_peer_cert]='false' |
| 55 | + [management_ssl_verify]='verify_none' |
| 56 | + |
| 57 | + [ssl_fail_if_no_peer_cert]='true' |
| 58 | + [ssl_verify]='verify_peer' |
| 59 | +) |
| 60 | + |
| 61 | +haveConfig= |
| 62 | +haveSslConfig= |
| 63 | +haveManagementSslConfig= |
| 64 | +for conf in "${allConfigKeys[@]}"; do |
| 65 | + var="RABBITMQ_${conf^^}" |
| 66 | + val="${!var:-}" |
| 67 | + if [ "$val" ]; then |
| 68 | + haveConfig=1 |
| 69 | + case "$conf" in |
| 70 | + ssl_*) haveSslConfig=1 ;; |
| 71 | + management_ssl_*) haveManagementSslConfig=1 ;; |
| 72 | + esac |
| 73 | + fi |
| 74 | +done |
| 75 | +if [ "$haveSslConfig" ]; then |
| 76 | + missing=() |
| 77 | + for sslConf in cacertfile certfile keyfile; do |
| 78 | + var="RABBITMQ_SSL_${sslConf^^}" |
| 79 | + val="${!var}" |
| 80 | + if [ -z "$val" ]; then |
| 81 | + missing+=( "$var" ) |
| 82 | + fi |
| 83 | + done |
| 84 | + if [ "${#missing[@]}" -gt 0 ]; then |
| 85 | + { |
| 86 | + echo |
| 87 | + echo 'error: SSL requested, but missing required configuration' |
| 88 | + for miss in "${missing[@]}"; do |
| 89 | + echo " - $miss" |
| 90 | + done |
| 91 | + echo |
| 92 | + } >&2 |
| 93 | + exit 1 |
| 94 | + fi |
| 95 | +fi |
| 96 | +missingFiles=() |
| 97 | +for conf in "${fileConfigKeys[@]}"; do |
| 98 | + var="RABBITMQ_${conf^^}" |
| 99 | + val="${!var}" |
| 100 | + if [ "$val" ] && [ ! -f "$val" ]; then |
| 101 | + missingFiles+=( "$val ($var)" ) |
| 102 | + fi |
| 103 | +done |
| 104 | +if [ "${#missingFiles[@]}" -gt 0 ]; then |
| 105 | + { |
| 106 | + echo |
| 107 | + echo 'error: files specified, but missing' |
| 108 | + for miss in "${missingFiles[@]}"; do |
| 109 | + echo " - $miss" |
| 110 | + done |
| 111 | + echo |
| 112 | + } >&2 |
| 113 | + exit 1 |
| 114 | +fi |
| 115 | + |
| 116 | +# set defaults for missing values (but only after we're done with all our checking so we don't throw any of that off) |
| 117 | +for conf in "${!configDefaults[@]}"; do |
| 118 | + default="${configDefaults[$conf]}" |
| 119 | + var="RABBITMQ_${conf^^}" |
| 120 | + [ -z "${!var:-}" ] || continue |
| 121 | + eval "export $var=\"\$default\"" |
| 122 | +done |
| 123 | + |
| 124 | +# If long & short hostnames are not the same, use long hostnames |
| 125 | +if [ "$(hostname)" != "$(hostname -s)" ]; then |
| 126 | + : "${RABBITMQ_USE_LONGNAME:=true}" |
| 127 | +fi |
| 128 | + |
| 129 | +if [ "${RABBITMQ_ERLANG_COOKIE:-}" ]; then |
| 130 | + cookieFile='/var/lib/rabbitmq/.erlang.cookie' |
| 131 | + if [ -e "$cookieFile" ]; then |
| 132 | + if [ "$(cat "$cookieFile" 2>/dev/null)" != "$RABBITMQ_ERLANG_COOKIE" ]; then |
| 133 | + echo >&2 |
| 134 | + echo >&2 "warning: $cookieFile contents do not match RABBITMQ_ERLANG_COOKIE" |
| 135 | + echo >&2 |
| 136 | + fi |
| 137 | + else |
| 138 | + echo "$RABBITMQ_ERLANG_COOKIE" > "$cookieFile" |
| 139 | + chmod 600 "$cookieFile" |
| 140 | + fi |
| 141 | +fi |
| 142 | + |
| 143 | +# prints "$2$1$3$1...$N" |
| 144 | +join() { |
| 145 | + local sep="$1"; shift |
| 146 | + local out; printf -v out "${sep//%/%%}%s" "$@" |
| 147 | + echo "${out#$sep}" |
| 148 | +} |
| 149 | +indent() { |
| 150 | + if [ "$#" -gt 0 ]; then |
| 151 | + echo "$@" |
| 152 | + else |
| 153 | + cat |
| 154 | + fi | sed 's/^/\t/g' |
| 155 | +} |
| 156 | +rabbit_array() { |
| 157 | + echo -n '[' |
| 158 | + case "$#" in |
| 159 | + 0) echo -n ' ' ;; |
| 160 | + 1) echo -n " $1 " ;; |
| 161 | + *) |
| 162 | + local vals="$(join $',\n' "$@")" |
| 163 | + echo |
| 164 | + indent "$vals" |
| 165 | + esac |
| 166 | + echo -n ']' |
| 167 | +} |
| 168 | +rabbit_env_config() { |
| 169 | + local prefix="$1"; shift |
| 170 | + |
| 171 | + local ret=() |
| 172 | + local conf |
| 173 | + for conf; do |
| 174 | + local var="rabbitmq${prefix:+_$prefix}_$conf" |
| 175 | + var="${var^^}" |
| 176 | + |
| 177 | + local val="${!var:-}" |
| 178 | + |
| 179 | + local rawVal= |
| 180 | + case "$conf" in |
| 181 | + verify|fail_if_no_peer_cert) |
| 182 | + [ "$val" ] || continue |
| 183 | + rawVal="$val" |
| 184 | + ;; |
| 185 | + |
| 186 | + hipe_compile) |
| 187 | + [ "$val" ] && rawVal='true' || rawVal='false' |
| 188 | + ;; |
| 189 | + |
| 190 | + cacertfile|certfile|keyfile) |
| 191 | + [ "$val" ] || continue |
| 192 | + rawVal='"'"$val"'"' |
| 193 | + ;; |
| 194 | + |
| 195 | + *) |
| 196 | + [ "$val" ] || continue |
| 197 | + rawVal='<<"'"$val"'">>' |
| 198 | + ;; |
| 199 | + esac |
| 200 | + [ "$rawVal" ] || continue |
| 201 | + |
| 202 | + ret+=( "{ $conf, $rawVal }" ) |
| 203 | + done |
| 204 | + |
| 205 | + join $'\n' "${ret[@]}" |
| 206 | +} |
| 207 | + |
| 208 | +if [ "$1" = 'rabbitmq-server' ] && [ "$haveConfig" ]; then |
| 209 | + fullConfig=() |
| 210 | + |
| 211 | + rabbitConfig=( |
| 212 | + "{ loopback_users, $(rabbit_array) }" |
| 213 | + ) |
| 214 | + |
| 215 | + if [ "$haveSslConfig" ]; then |
| 216 | + IFS=$'\n' |
| 217 | + rabbitSslOptions=( $(rabbit_env_config 'ssl' "${sslConfigKeys[@]}") ) |
| 218 | + unset IFS |
| 219 | + |
| 220 | + rabbitConfig+=( |
| 221 | + "{ tcp_listeners, $(rabbit_array) }" |
| 222 | + "{ ssl_listeners, $(rabbit_array 5671) }" |
| 223 | + "{ ssl_options, $(rabbit_array "${rabbitSslOptions[@]}") }" |
| 224 | + ) |
| 225 | + else |
| 226 | + rabbitConfig+=( |
| 227 | + "{ tcp_listeners, $(rabbit_array 5672) }" |
| 228 | + "{ ssl_listeners, $(rabbit_array) }" |
| 229 | + ) |
| 230 | + fi |
| 231 | + |
| 232 | + IFS=$'\n' |
| 233 | + rabbitConfig+=( $(rabbit_env_config '' "${rabbitConfigKeys[@]}") ) |
| 234 | + unset IFS |
| 235 | + |
| 236 | + fullConfig+=( "{ rabbit, $(rabbit_array "${rabbitConfig[@]}") }" ) |
| 237 | + |
| 238 | + # If management plugin is installed, then generate config consider this |
| 239 | + if [ "$(rabbitmq-plugins list -m -e rabbitmq_management)" ]; then |
| 240 | + if [ "$haveManagementSslConfig" ]; then |
| 241 | + IFS=$'\n' |
| 242 | + rabbitManagementSslOptions=( $(rabbit_env_config 'management_ssl' "${sslConfigKeys[@]}") ) |
| 243 | + unset IFS |
| 244 | + |
| 245 | + rabbitManagementListenerConfig+=( |
| 246 | + '{ port, 15671 }' |
| 247 | + '{ ssl, true }' |
| 248 | + "{ ssl_opts, $(rabbit_array "${rabbitManagementSslOptions[@]}") }" |
| 249 | + ) |
| 250 | + else |
| 251 | + rabbitManagementListenerConfig+=( |
| 252 | + '{ port, 15672 }' |
| 253 | + '{ ssl, false }' |
| 254 | + ) |
| 255 | + fi |
| 256 | + |
| 257 | + fullConfig+=( |
| 258 | + "{ rabbitmq_management, $(rabbit_array "{ listener, $(rabbit_array "${rabbitManagementListenerConfig[@]}") }") }" |
| 259 | + ) |
| 260 | + fi |
| 261 | + |
| 262 | + echo "$(rabbit_array "${fullConfig[@]}")." > /etc/rabbitmq/rabbitmq.config |
| 263 | +fi |
| 264 | + |
| 265 | +combinedSsl='/tmp/combined.pem' |
| 266 | +if [ "$haveSslConfig" ] && [[ "$1" == rabbitmq* ]] && [ ! -f "$combinedSsl" ]; then |
| 267 | + # Create combined cert |
| 268 | + cat "$RABBITMQ_SSL_CERTFILE" "$RABBITMQ_SSL_KEYFILE" > "$combinedSsl" |
| 269 | + chmod 0400 "$combinedSsl" |
| 270 | +fi |
| 271 | +if [ "$haveSslConfig" ] && [ -f "$combinedSsl" ]; then |
| 272 | + # More ENV vars for make clustering happiness |
| 273 | + # we don't handle clustering in this script, but these args should ensure |
| 274 | + # clustered SSL-enabled members will talk nicely |
| 275 | + export ERL_SSL_PATH="$(erl -eval 'io:format("~p", [code:lib_dir(ssl, ebin)]),halt().' -noshell)" |
| 276 | + export RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-pa $ERL_SSL_PATH -proto_dist inet_tls -ssl_dist_opt server_certfile $combinedSsl -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true" |
| 277 | + export RABBITMQ_CTL_ERL_ARGS="$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" |
| 278 | +fi |
| 279 | + |
| 280 | +exec "$@" |
0 commit comments