SSL 인증서, 개인 키, CSR 등을 자주 다룹니다. 내 작업을 자동화하는 여러 개의 작은 bash 스크립트가 있습니다. 스크립트 중 하나는 openssl을 사용하여 SSL 인증서에 대한 새 개인 키와 CSR을 생성합니다. 이 스크립트는 실제로 한 줄에 오류 검사를 더한 것입니다. 입력하는 시간을 절약하기 위한 것입니다.
#!/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보다 크면 두 요소와 문자열을 포함하는 배열을 제공하고 그 뒤에는 SANS
명령 줄 인수에서 쉼표로 구분된 문자열 목록이 표시됩니다. 쉼표로 구분된 목록은 as를 사용하여 다른 배열에서 생성되며 해당 요소를 첫 번째 문자와 구분 기호로 연결합니다 (그래서 미리 쉼표로 설정했습니다).-addext
subjectAltNames =
subjAltNames
${subjAltNames[*]}
$IFS
IFS
나중에 개별적으로 참조되는 요소 목록에 적절하게 액세스하려면 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
매개변수 목록 끝에 빈 매개변수가 제공되지 않습니다.