Windows의 bash 스크립트에서 Openssl 실행-제목이 '/'로 시작하지 않음
내 스크립트에는 다음이 있습니다.
openssl req \
-x509 \
-new \
-nodes \
-key certs/ca/my-root-ca.key.pem \
-days 3652 \
-out certs/ca/my-root-ca.crt.pem \
-subj "/C=GB/ST=someplace/L=Provo/O=Achme/CN=${FQDN}"
Windows에서 Git Bash 3.1을 실행하면 다음이 제공됩니다.
Subject does not start with '/'.
다음과 같이 subj를 이스케이프했습니다. -subj \ "/ C = UK / ST = someplace / L = Provo / O = Achme / CN = $ {FQDN} \"
여전히 작동하지 않습니다. 어떤 아이디어?
이 문제는 Windows 용 Git 패키지의 일부로 일반적으로 사용되는 MinGW / MSYS 에만 해당됩니다 .
해결책은 -subj
인수를 선행 //
(이중 슬래시) 으로 전달한 다음 \
(백 슬래시)를 사용 하여 키 / 값 쌍을 구분하는 것입니다. 이렇게 :
"//O=Org\CN=Name"
그러면 openssl
예상 된 형식 으로 마술처럼 전달됩니다 .
"/O=Org/CN=Name"
따라서 특정 질문에 답하려면 -subj
스크립트 의 줄을 다음과 같이 변경해야합니다 .
-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"
그게 필요한 전부입니다.
이 마법은 무엇입니까?
여기서 무슨 일이 일어나고 있는지 정확히 궁금한 사람들을 위해이 미스터리를 설명 할 수 있습니다. 그 이유는 MSYS가 슬래시를 포함하는 인수가 실제로 경로라고 합리적으로 가정하기 때문입니다. 그리고 이러한 인수가 MSYS를 위해 특별히 컴파일되지 않은 실행 파일에 전달되면 ( openssl
이 경우 처럼 ) POSIX 경로를 Win32 경로로 변환합니다 . MSYS는 상호 운용성에 대한 가장 일반적인 시나리오를 처리하기 위해 최선을 다하기 때문에이 변환에 대한 규칙은 매우 복잡합니다. 이것은 또한 마법적인 변환이 수행되지 않기 때문에 openssl
Windows 명령 프롬프트 ( cmd.exe
) 에서 사용 하는 것이 잘 작동 하는 이유를 설명합니다 .
이와 같이 변환을 테스트 할 수 있습니다.
$ cmd //c echo "/CN=Name"
"C:/Program Files (x86)/Git/CN=Name"
우리는 사용할 수 없습니다 echo
대신에 우리가 사용하는 것, 그것이 MSYS 컴파일 된 이후 MSYS와 함께 제공 실행 echo
에 내장을 cmd
. cmd
스위치가 /
(Windows 명령의 경우 공통)으로 시작 하므로 이중 슬래시로 처리해야합니다. 출력에서 볼 수 있듯이 인수는 Windows 경로로 확장되었으며 openssl
실제로 Subject does not start with '/'.
.
더 많은 전환을 보겠습니다.
$ cmd //c echo "//CN=Name"
/CN=Name
이중 슬래시는 MSYS가 인수가 Windows 스타일 스위치라고 믿게하여 /
경로 변환없이 만 제거하는 결과를 가져옵니다 . 이를 통해 더 많은 키 / 값 쌍을 추가하기 위해 슬래시를 사용할 수 있다고 생각할 것입니다. 시도해 봅시다.
$ cmd //c echo "//O=Org/CN=Name"
//O=Org/CN=Name
갑자기 시작 부분의 이중 슬래시가 제거되지 않습니다. 이것은 초기 이중 슬래시 뒤에 슬래시가있는 MSYS가 UNC 경로 (예 : // server / path)를 참조하고 있다고 생각하기 때문입니다. 이것이 전달되면 openssl
라고 말하는 첫 번째 키 / 값을 건너 뜁니다 Subject Attribute /O has no known NID, skipped
.
이 동작을 설명 하는 MinGW 위키 의 관련 규칙은 다음과 같습니다 .
- 2 개 이상의 /로 시작하는 인수는 이스케이프 된 Windows 스타일 스위치로 간주되며 선행 / 제거되고 모든 \가 /로 변경된 상태로 전달됩니다.
- /의 선행 블록 뒤에 /가있는 경우를 제외하고는 인수는 UNC 경로로 간주되고 선행 /는 제거되지 않습니다.
이 규칙에서 원하는 인수를 생성하는 데 사용할 수있는 방법을 볼 수 있습니다. 로 \
시작하는 인수 뒤에 오는 모든 것은 //
plain으로 변환되기 때문 /
입니다. 그것을 시도해 봅시다.
$ cmd //c echo "//O=Org\CN=Name"
/O=Org/CN=Name
그리고 우리가 볼 수 있듯이 작동합니다.
이것이 마법을 조금 이해하기를 바랍니다.
개인적으로 이것이 사용중인 OpenSSL 바이너리에만 해당된다는 것을 알았습니다. msys2 / mingw64를 사용하는 시스템에서 두 개의 다른 OpenSSL 바이너리가 있음을 발견했습니다. 예를 들면 다음과 같습니다.
$ whereis openssl; echo; which openssl
openssl: /usr/bin/openssl.exe /usr/lib/openssl /mingw64/bin/openssl.exe /usr/share/man/man1/openssl.1ssl.gz
/mingw64/bin/openssl
으로 /mingw64/bin/openssl
시작하는 주제를 사용해야한다고 생각 //
하지만 이것이 패키지 / 빌드 또는 OpenSSL 버전에 특정한 것인지 확실하지 않으므로 각 바이너리의 버전은 다음과 같습니다.
$ while read -r _openSslBin; do printf "${_openSslBin}: "; ${_openSslBin} version; done < <(whereis openssl | egrep -o '[^ ]+?\.exe ')
/usr/bin/openssl.exe: OpenSSL 1.0.2p 14 Aug 2018
/mingw64/bin/openssl.exe: OpenSSL 1.1.1 11 Sep 2018
I've found the following example of bash code to select the correct binary based on the OpenSSL version when using msys/mingw to work on my machine:
# determine openssl binary to use based on OS
# -------------------------------------------
_os="$(uname -s | awk 'BEGIN{FS="_"} {print $1}' | egrep -o '[A-Za-z]+')"
if [ "${_os,,}" = "mingw" ] || [ "${_os,,}" == "msys" ]; then
while read -r _currentOpenSslBin; do
if [[ "$(${_currentOpenSslBin} version | awk '{print $2}')" =~ ^(1\.0\.[0-9].*|0\.\9\.8.*)$ ]]; then
_openSslBin="${_currentOpenSslBin}"
fi
done < <(whereis openssl | egrep -o '\/[^ ]+?\.exe ' | egrep -v 'mingw')
if [ -n "${_openSslBin}" ]; then
printf "OpenSSL Binary: ${_openSslBin} (v. $(${_openSslBin} version | awk '{print $2}'))\n"
else
printf "Unable to find compatible version of OpenSSL for use with '${_os}' OS, now exiting...\n"
exit 1
fi
else
_openSslBin="openssl"
fi
# display selected openssl binary and it's version
# ------------------------------------------------
printf "${_openSslBin}: "; ${_openSslBin} version
In addition to fixing issues with passing the subject string I also found this to resolve issues with the size of the DN (I passed a custom openssl.cnf with a policy that did not set a max_size for any of the fields and that still had problems when using /mingw64/bin/openssl.exe
).
'code' 카테고리의 다른 글
ASP.Net MVC 뷰에서 컨트롤러로 데이터를 전달하는 방법 (0) | 2020.11.07 |
---|---|
2 차원 배열 이니셜 라이저와 대괄호 (0) | 2020.11.07 |
데이터 프로토콜 URL 크기 제한 (0) | 2020.11.07 |
C # Linq Where Date Between 2 Dates (0) | 2020.11.07 |
클래스 이름이있는 동적 클래스 정의 (0) | 2020.11.07 |