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 -vx
se está ejecutando para esta línea al agregar al principio del script?set -vx
es ú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.com
que muestra la-subj
cadena sin comillas . Pero no puedo averiguar cómo hacer esto en una forma citada del guión.-vx
salida 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
-subj
argumento 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
openssl
en la forma esperada:"/O=Org/CN=Name"
Entonces, para responder la pregunta específica, debe cambiar la
-subj
lí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
openssl
en 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 usoopenssl
desde 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
echo
ejecutable que viene con MSYS ya que fue compilado para MSYS, en su lugar usaremos elecho
incorporadocmd
. Tenga en cuenta que, dado que loscmd
interruptores 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éopenssl
afirma esoSubject does not start with '/'.
.Veamos algunas conversiones más.
$ cmd //c echo "//CN=Name" /CN=Name
Las 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=Name
De 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
openssl
esto, 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=Name
Y como podemos ver, funciona.
Espero que esto desmitifique un poco la magia.
fuente
bash
script 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?case
declaración yuname -s
para detectar el entorno, que luego puede usar con unif
para 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/openssl
Creo que el uso de
/mingw64/bin/openssl
eso 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 2018
Encontré 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} version
Ademá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