In meinem Skript habe ich:
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}"
Wenn Sie dies unter Windows in Git Bash 3.1 ausführen, erhalten Sie:
Subject does not start with '/'.
Versucht, dem Subjekt wie folgt zu entkommen: -subj "/ C = UK / ST = irgendwo / L = Provo / O = Achme / CN = $ {FQDN}"
Funktioniert immer noch nicht. Irgendwelche Ideen?
cat -vet /path/to/script
, und prüfen Sie, ob die Zeilen mit '^ M $' (Windows-Stil) oder nur mit '$' (Unix-Stil) enden.set -vx
zum Anfang der Skriptshow für diese Zeile?set -vx
ist nützlich, danke! Umgebung ist Windows, Git Bash 3.1. Mit -vx erhalte ich+ 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
die-subj
Zeichenfolge ohne Anführungszeichen . Aber ich kann nicht herausfinden, wie ich dies aus dem Skript in eine zitierte Form bringen kann.-vx
Ausgabe ist nicht überraschend oder ein Problem. Die Anführungszeichen beziehen sich auf die Shell-Analyse und nicht auf die Befehlsausführung selbst. Diese Ausgabe sieht für mich korrekt aus. DOS-Zeilenenden sind im Allgemeinen keine gute Idee, scheinen hier jedoch keine Probleme verursacht zu haben (es sei denn, das Entfernen behebt das Problem. In diesem Fall bin ich durch die Fehlermeldung etwas verwirrt).Antworten:
Dieses Problem ist spezifisch für MinGW / MSYS, das üblicherweise als Teil des Git für Windows- Pakets verwendet wird.
Die Lösung besteht darin, das
-subj
Argument mit führenden//
(doppelte Schrägstriche) zu übergeben und dann\
die Schlüssel / Wert-Paare mit (umgekehrten Schrägstrichen) zu trennen. So was:"//O=Org\CN=Name"
Dies wird dann auf magische Weise
openssl
in der erwarteten Form weitergegeben:"/O=Org/CN=Name"
Um die spezifische Frage zu beantworten, sollten Sie die
-subj
Zeile in Ihrem Skript wie folgt ändern .-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"
Das sollte alles sein, was Sie brauchen.
Was ist das für eine Magie?
Für diejenigen, die genau wissen wollen, was hier vor sich geht, kann ich dieses Rätsel erklären. Der Grund dafür ist, dass MSYS vernünftigerweise davon ausgeht, dass Argumente, die Schrägstriche enthalten, tatsächlich Pfade sind. Wenn diese Argumente an eine ausführbare Datei übergeben werden, die nicht speziell für MSYS kompiliert wurde (wie
openssl
in diesem Fall), werden POSIX-Pfade in Win32-Pfade konvertiert . Die Regeln für diese Konvertierung sind recht komplex, da MSYS sein Bestes versucht, die gängigsten Szenarien für die Interoperabilität abzudecken. Dies erklärt auch, warum die Verwendungopenssl
an einer Windows-Eingabeaufforderung (cmd.exe
) gut funktioniert, da keine magischen Konvertierungen vorgenommen werden.Sie können die Konvertierung folgendermaßen testen.
$ cmd //c echo "/CN=Name" "C:/Program Files (x86)/Git/CN=Name"
Wir können die
echo
mit MSYSecho
gelieferte ausführbare Datei nicht verwenden , da sie für MSYS kompiliert wurde. Stattdessen verwenden wir die integrierte Dateicmd
. Beachten Sie, dass wir , dacmd
Schalter mit beginnen/
(häufig für Windows-Befehle), dies mit doppelten Schrägstrichen behandeln müssen. Wie wir in der Ausgabe sehen können, wurde das Argument zu einem Windows-Pfad erweitert, und es wird klar, warumopenssl
dies tatsächlich behauptet wirdSubject does not start with '/'.
.Sehen wir uns noch einige Conversions an.
$ cmd //c echo "//CN=Name" /CN=Name
Doppelte Schrägstriche lassen MSYS glauben, dass das Argument ein Windows-Stilschalter ist, der dazu führt, dass
/
nur ein Strip entfernt wird (keine Pfadkonvertierung). Sie würden denken, dass wir damit nur Schrägstriche verwenden könnten, um weitere Schlüssel / Wert-Paare hinzuzufügen. Lass es uns versuchen.$ cmd //c echo "//O=Org/CN=Name" //O=Org/CN=Name
Plötzlich werden die doppelten Schrägstriche am Start nicht mehr reduziert. Dies liegt daran, dass MSYS jetzt mit einem Schrägstrich nach den anfänglichen doppelten Schrägstrichen denkt, dass wir auf einen UNC-Pfad verweisen (z. B. // Server / Pfad). Wenn dies an übergeben
openssl
würde, würde es den ersten Schlüssel / Wert-Spruch überspringenSubject Attribute /O has no known NID, skipped
.Hier ist die relevante Regel aus dem MinGW-Wiki , die dieses Verhalten erklärt:
In dieser Regel sehen wir die Methode, mit der wir das gewünschte Argument erstellen können. Da alles
\
, was in einem Argument folgt, das mit beginnt, in//
normal konvertiert wird/
. Probieren wir das aus.$ cmd //c echo "//O=Org\CN=Name" /O=Org/CN=Name
Und wie wir sehen können, funktioniert es.
Hoffe das entmystifiziert die Magie ein wenig.
quelle
bash
Skript verwende, um Schlüssel in einer Linux-Umgebung zu generieren? Wie würde man interpretieren, dass führende doppelte Schrägstriche und Backslashes in der Mitte der Linie liegen?case
Anweisung verwendet unduname -s
die Umgebung erkennt, die Sie dann mit einem verwenden könnenif
, um die entsprechende zu verwenden Schrägstriche - stackoverflow.com/questions/3466166/…Ich persönlich fand dies spezifisch für die verwendete OpenSSL-Binärdatei. Auf meinem System mit msys2 / mingw64 habe ich festgestellt, dass zwei verschiedene OpenSSL-Binärdateien vorhanden sind, zum Beispiel:
$ 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
Ich glaube, um dies zu tun
/mingw64/bin/openssl
, muss ein Betreff verwendet werden, der mit beginnt.//
Ich bin mir jedoch nicht sicher, ob dies für das Paket / den Build oder die Version von OpenSSL spezifisch ist. Um sicherzugehen, ist die Version jeder Binärdatei unten aufgeführt:$ 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
Ich habe das folgende Beispiel für Bash-Code gefunden, um die richtige Binärdatei basierend auf der OpenSSL-Version auszuwählen, wenn msys / mingw für die Arbeit auf meinem Computer verwendet wird:
# 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
Zusätzlich zur Behebung von Problemen beim Übergeben der Betreffzeichenfolge habe ich festgestellt, dass dies Probleme mit der Größe des DN behebt (ich habe eine benutzerdefinierte openssl.cnf mit einer Richtlinie übergeben, die für keines der Felder eine max_size festgelegt hat und die immer noch Probleme hatte bei der Verwendung
/mingw64/bin/openssl.exe
).quelle