code

Windows의 bash 스크립트에서 Openssl 실행-제목이 '/'로 시작하지 않음

codestyles 2020. 11. 7. 09:59
반응형

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는 상호 운용성에 대한 가장 일반적인 시나리오를 처리하기 위해 최선을 다하기 때문에이 변환에 대한 규칙은 매우 복잡합니다. 이것은 또한 마법적인 변환이 수행되지 않기 때문에 opensslWindows 명령 프롬프트 ( 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).

참고URL : https://stackoverflow.com/questions/31506158/running-openssl-from-a-bash-script-on-windows-subject-does-not-start-with

반응형