В моем сценарии есть:
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} \"
По-прежнему не работает. Есть идеи?
cat -vet /path/to/script
и посмотрите, заканчиваются ли строки на «^ M $» (стиль Windows) или просто «$» (стиль unix).set -vx
в начало показа сценария для этой строки?set -vx
полезно спасибо! Среда - Windows, Git bash 3.1. С -vx я получаю,+ 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=domain.com
что показывает-subj
строку без кавычек . Но я не могу понять, как перевести это в цитируемую форму из сценария.-vx
выводе не вызывает удивления или проблемы. Кавычки предназначены для синтаксического анализа оболочки, а не для самого выполнения команды. Мне этот вывод кажется правильным. Окончания строк DOS, как правило, не являются хорошей идеей, но, похоже, не вызывают здесь каких-либо проблем (если только их удаление не решает проблему, и в этом случае я немного смущен сообщением об ошибке).Ответы:
Эта проблема характерна для MinGW / MSYS, который обычно используется как часть пакета Git для Windows .
Решение состоит в том, чтобы передать
-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, объясняющее это поведение:
В этом правиле мы можем увидеть метод, который мы могли бы использовать для создания нужного нам аргумента. Поскольку все,
\
что следует за аргументом, начинающимся с,//
будет преобразовано в простой/
. Давай попробуем.$ cmd //c echo "//O=Org\CN=Name" /O=Org/CN=Name
И, как мы видим, это действительно работает.
Надеюсь, это немного проясняет магию.
источник
bash
сценарий для генерации ключей в среде Linux? Как можно было бы интерпретировать эти ведущие двойные косые черты и обратные косые черты в середине строки?case
оператор иuname -s
определяет среду, которую вы затем можете использовать с помощью,if
чтобы использовать соответствующий слэши - stackoverflow.com/questions/3466166/…Я лично обнаружил, что это характерно для используемого двоичного файла 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
Я нашел следующий пример кода bash для выбора правильного двоичного файла на основе версии OpenSSL при использовании msys / mingw для работы на моем компьютере:
# 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
В дополнение к исправлению проблем с передачей строки темы я также обнаружил, что это решает проблемы с размером DN (я передал настраиваемый openssl.cnf с политикой, которая не устанавливала max_size ни для одного из полей и у которой все еще были проблемы при использовании
/mingw64/bin/openssl.exe
).источник