Bashでopensslコマンドを実行中にエラーが発生しましたが、コマンドラインで機能します。

Bashでopensslコマンドを実行中にエラーが発生しましたが、コマンドラインで機能します。

SSL証明書、秘密鍵、CSRなどを頻繁に扱います。私の仕事を自動化するいくつかの小さなbashスクリプトがあります。スクリプトの1つはopensslを使用して、SSL証明書の新しい秘密鍵とCSRを生成します。このスクリプトは実際には1行にエラーチェックを加えたものです。入力する時間を節約するためです。

#!/usr/bin/env bash

if [[ $# -ne 1 ]]; then
    echo "Format: $0 hostname"
    echo "   e.g. $0 www.example.com"
    exit 2
fi

openssl req -new -newkey rsa:2048 -nodes -keyout "$1.key" -out "$1.csr" \
            -subj "/C=GB/ST=County/L=City/O=My Company Ltd./CN=$1"

cat "$1.csr"

これはうまくいきました。しかし最近、SANにはますます多くの証明書が必要になり、次のようにスクリプトを修正しました。

#!/usr/bin/env bash

if [[ $# -eq 0 ]]; then
    echo "Format: $0 hostname"
        echo "   e.g. $0 www.example.com [SAN1 SAN2 ...]"
        exit 2
fi

SANS=""
if [[ $# -gt 1 ]]; then
    SANS=""
    for san in "${@:2}"; do
        SANS="${SANS}DNS:${san}, "
    done
    SANS="-addext \"subjectAltName = ${SANS%,*}\""
fi


openssl req -new -newkey rsa:2048 -nodes -keyout "$1.key" -out "$1.csr" \
            -subj "/C=GB/ST=County/L=City/O=My Company Ltd./CN=$1" \
            $SANS

cat "$1.csr"

これでスクリプトは機能しなくなりました。ただ作成してください。

req: Use -help for summary.

スクリプトの最後の部分を次のように修正しました。

CMD="openssl req -new -newkey rsa:2048 -nodes -keyout \"$1.key\" -out \"$1.csr\" \
            -subj \"/C=GB/ST=County/L=City/O=My Company Ltd./CN=$1\" \
            $SANS"
echo $CMD
$CMD

これにより、コマンドを実行する前にコマンドを表示できます。コマンドが正確で、このコマンドをbashプロンプトにコピーして貼り付けると、正しい結果が得られます。もしそうなら、このコマンドがスクリプトで実行されたときに失敗するのはなぜですか?

答え1

問題はSANS文字列である変数です。引用符なしで変数を使用します。これは、シェルが変数をスペースに分割することを意味します(そして、すべてのパーティションにファイル名のグロービングを適用します)。

保存する代わりに複数の個別文字列文字列は配列を使用します。

SANS=()
if [[ $# -gt 1 ]]; then
    subjAltNames=("${@:2}")
    IFS=,
    SANS=(-addext "subjectAltName = ${subjAltNames[*]}")
fi

$#1より大きい場合は、2つの要素と文字列を含む配列を提供し、その後にSANSコマンドライン引数でカンマ区切りの文字列のリストが表示されます。カンマで区切られたリストはasを使用して別の配列から生成され、その要素を最初の文字と区切り文字で連結します(それであらかじめコンマに設定しました)。-addextsubjectAltNames =subjAltNames${subjAltNames[*]}$IFSIFS

後で個別に参照される要素のリストに適切にアクセスするには、SANS次のようにします。"${SANS[@]}"

openssl req -new -newkey rsa:2048 -nodes -keyout "$1.key" -out "$1.csr" \
            -subj "/C=GB/ST=County/L=City/O=My Company Ltd./CN=$1" \
            "${SANS[@]}"

配列が空の場合、SANSパラメータリストの末尾に空のパラメータは提供されません。

関連情報