En mi guión tengo:
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}"
Ejecutar esto en Windows en Git Bash 3.1 da:
Subject does not start with '/'.
Intenté escapar del sujeto así: -subj \ "/ C = UK / ST = en algún lugar / L = Provo / O = Achme / CN = $ {FQDN} \"
Todavía no funciona. ¿Algunas ideas?

cat -vet /path/to/script, y vea si las líneas terminan con '^ M $' (estilo Windows) o simplemente '$' (estilo Unix).set -vxse está ejecutando para esta línea al agregar al principio del script?set -vxes útil gracias! El entorno es Windows, Git bash 3.1. Con -vx , obtengo+ 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.comque muestra la-subjcadena sin comillas . Pero no puedo averiguar cómo hacer esto en una forma citada del guión.-vxsalida no es sorprendente ni es un problema. Las comillas son para el análisis del shell, no para la ejecución del comando en sí. Esa salida me parece correcta. Los finales de línea de DOS generalmente no son una buena idea, pero no parecen haber causado ningún problema aquí (a menos que eliminarlos solucione el problema, en cuyo caso estoy un poco confundido por el mensaje de error).Respuestas:
Este problema es específico de MinGW / MSYS, que se usa comúnmente como parte del paquete Git para Windows .
La solución es pasar el
-subjargumento al principio//(barras diagonales dobles) y luego usar\(barras diagonales inversas) para separar los pares clave / valor. Me gusta esto:"//O=Org\CN=Name"Esto luego se pasará mágicamente a
opensslen la forma esperada:"/O=Org/CN=Name"Entonces, para responder la pregunta específica, debe cambiar la
-subjlínea en su secuencia de comandos a la siguiente.-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"Eso deberia ser todo lo que necesitas.
¿Qué es esta magia?
Para aquellos que tengan curiosidad por saber exactamente qué está pasando aquí, puedo explicar este misterio. La razón es que MSYS asume razonablemente que los argumentos que contienen barras son en realidad rutas. Y cuando esos argumentos se pasan a un ejecutable que no se ha compilado específicamente para MSYS (como
opensslen este caso), convertirá las rutas POSIX en rutas Win32 . Las reglas para esta conversión son bastante complejas ya que MSYS hace todo lo posible para cubrir los escenarios más comunes de interoperabilidad. Esto también explica por qué el usoopenssldesde un símbolo del sistema de Windows (cmd.exe) funciona bien, porque no se realizan conversiones mágicas.Puede probar la conversión de esta manera.
$ cmd //c echo "/CN=Name" "C:/Program Files (x86)/Git/CN=Name"No podemos usar el
echoejecutable que viene con MSYS ya que fue compilado para MSYS, en su lugar usaremos elechoincorporadocmd. Tenga en cuenta que, dado que loscmdinterruptores comienzan con/(común para los comandos de Windows), debemos manejar eso con barras dobles. Como podemos ver en la salida, el argumento se expandió a una ruta de Windows y queda claro por quéopensslafirma esoSubject does not start with '/'..Veamos algunas conversiones más.
$ cmd //c echo "//CN=Name" /CN=NameLas barras dobles hacen que MSYS crea que el argumento es un cambio de estilo de Windows que da como resultado la eliminación de un
/solo (sin conversión de ruta). Pensaría que con esto podríamos usar barras diagonales para agregar más pares clave / valor. Probemos eso.$ cmd //c echo "//O=Org/CN=Name" //O=Org/CN=NameDe repente, las barras dobles al principio no se reducen. Esto se debe a que ahora, con una barra después de las barras dobles iniciales, MSYS cree que estamos haciendo referencia a una ruta UNC (por ejemplo, // servidor / ruta). Si se le pasara
opensslesto, se omitiría la primera clave / valor diciendoSubject Attribute /O has no known NID, skipped.Aquí está la regla relevante de la wiki de MinGW que explica este comportamiento:
En esta regla podemos ver el método que podríamos usar para crear el argumento que queremos. Dado
\que todo lo que sigue en un argumento que comienza con//se convertirá a simple/. Probemos eso.$ cmd //c echo "//O=Org\CN=Name" /O=Org/CN=NameY como podemos ver, funciona.
Espero que esto desmitifique un poco la magia.
fuente
bashscript para generar claves en el entorno Linux? ¿Cómo se interpretaría que las barras dobles y las barras invertidas iniciales en el medio de la línea?casedeclaración yuname -spara detectar el entorno, que luego puede usar con unifpara usar el apropiado barras inclinadas - stackoverflow.com/questions/3466166/…Personalmente, encontré que esto es específico para el binario OpenSSL en uso. En mi sistema que usa msys2 / mingw64, he notado que hay dos binarios OpenSSL diferentes, por ejemplo:
$ 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/opensslCreo que el uso de
/mingw64/bin/openssleso requiere usar un tema que comience con//, sin embargo, no estoy seguro si esto es específico para el paquete / compilación o la versión de OpenSSL, así que para estar seguro, la versión de cada binario está a continuación:$ 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 2018Encontré el siguiente ejemplo de código bash para seleccionar el binario correcto según la versión de OpenSSL cuando utilizo msys / mingw para trabajar en mi máquina:
# 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} versionAdemás de solucionar problemas al pasar la cadena de asunto, también encontré esto para resolver problemas con el tamaño del DN (pasé un openssl.cnf personalizado con una política que no establecía un max_size para ninguno de los campos y que aún tenía problemas al usar
/mingw64/bin/openssl.exe).fuente