Supongamos que estaba usando sha1pass
para generar un hash de alguna contraseña sensible en la línea de comando. Puedo usar sha1pass mysecret
para generar un hash de mysecret
pero esto tiene la desventaja que mysecret
ahora está en el historial de bash. ¿Hay alguna manera de lograr el objetivo final de este comando mientras se evita revelar mysecret
en texto plano, tal vez utilizando un passwd
indicador de estilo?
También estoy interesado en una forma generalizada de hacer esto para pasar datos confidenciales a cualquier comando. El método cambiaría cuando los datos confidenciales se pasan como un argumento (como en sha1pass
) o en STDIN a algún comando.
¿Hay alguna manera de lograr esto?
Editar : Esta pregunta atrajo mucha atención y se han ofrecido varias buenas respuestas a continuación. Un resumen es:
- Según la respuesta de @ Kusalananda , idealmente uno nunca tendría que dar una contraseña o secreto como argumento de línea de comandos a una utilidad. Esto es vulnerable de varias maneras según lo descrito por él, y uno debería usar una utilidad mejor diseñada que sea capaz de tomar la entrada secreta en STDIN
- La respuesta de @ vfbsilva describe cómo evitar que las cosas se almacenen en el historial de bash
- La respuesta de @ Jonathan describe un método perfectamente bueno para lograr esto siempre que el programa pueda tomar sus datos secretos en STDIN. Como tal, he decidido aceptar esta respuesta.
sha1pass
en mi OP fue solo un ejemplo, pero la discusión ha establecido que existen mejores herramientas que toman datos sobre STDIN. - Como @R .. señala en su respuesta , el uso de la expansión de comandos en una variable no es seguro.
En resumen, acepté la respuesta de @ Jonathan ya que es la mejor solución dado que tiene un programa bien diseñado y con buen comportamiento para trabajar. Aunque pasar una contraseña o un secreto como argumento de la línea de comandos es fundamentalmente inseguro, las otras respuestas proporcionan formas de mitigar las preocupaciones simples de seguridad.
sha1pass mysecret
está ejecutando y, por lo tanto, saber quémysecret
es. (Esto solo funciona durante unos segundos mientras el programa se está ejecutando, por supuesto ...)Respuestas:
Si usa el shell
zsh
obash
, use la opción -s en elread
shell incorporado para leer una línea del dispositivo terminal sin que se repita.Luego puede usar una redirección elegante para usar la variable como stdin.
Si alguien corre
ps
, todo lo que verá es "sha1pass".Eso supone que
sha1pass
lee la contraseña de stdin (en una línea, ignorando el delimitador de línea) cuando no se le da ningún argumento.fuente
sha1pass
no utiliza su flujo de entrada estándar.sha1pass
fue solo un ejemplo en mi OP, y claramente no es la mejor opción para esto.ps
, pero puede escribirse en un archivo temporal; si uno quiere evitar eso, entoncessshpass < <(printf '%s\n' "$VARIABLE")
podría considerarse (porqueprintf
es un incorporado, no un comando externo, no se pasaexecv
y no se puede acceder a través deps
).Idealmente, nunca escriba una contraseña de texto sin cifrar en la línea de comando como argumento para un comando. Al hacerlo, la contraseña se convierte en un argumento para el comando, y los argumentos de la línea de comando se pueden ver en la tabla de procesos mediante el uso de herramientas simples como
ps
o iniciar sesión en algunos registros de auditoría.Dicho esto, ciertamente hay formas de ocultar la contraseña real del historial de comandos del shell.
Luego ingrese la contraseña y presione Enter. El
head
comando utilizado aquí acepta exactamente una línea de entrada y la última línea nueva que escriba no formará parte de los datos a los que se pasasha1pass
.Para evitar que los caracteres hagan eco:
El
stty -echo
comando desactiva el eco de los caracteres escritos en el terminal. El eco se restaura constty echo
.Para pasar la entrada estándar, ese último comando podría modificarse (lo habría hecho si hubiera
sha1pass
aceptado los datos en la entrada estándar, pero parece que esta utilidad en particular está ignorando su entrada estándar):Si necesita una entrada de varias líneas (lo anterior supone que se debe pasar una sola línea, sin caracteres de nueva línea al final), reemplace todo el
head
comando concat
y termine la entrada (suponiendo quesomecommand
se lea hasta el final del archivo) con Ctrl+D( siguiente Returnsi desea incluir un carácter de nueva línea en la entrada, o dos veces si no).Esto funcionaría independientemente de qué shell estuviera utilizando (siempre que fuera un shell tipo Bourne o rc).
Se pueden hacer algunos shells para no guardar los comandos escritos en sus archivos de historial si el comando está precedido por un espacio. Esto generalmente implica tener que establecer
HISTCONTROL
el valorignorespace
. Esto es apoyado por al menosbash
yksh
en OpenBSD, pero no por ejemploksh93
odash
.zsh
los usuarios pueden usar lahistignorespace
opción o suHISTORY_IGNORE
variable para definir un patrón a ignorar.En los shells que admiten la lectura con
read
caracteres sin eco en el terminal, también puede usarpero esto obviamente todavía tiene el mismo problema al revelar potencialmente la contraseña en la tabla de procesos.
Si la utilidad lee de la entrada estándar y el shell admite "here-strings", lo anterior podría cambiarse a
Resumen de comentarios a continuación:
Ejecutar un comando con una contraseña dada en la línea de comando, lo que hace todos los comandos anteriores, excepto el que canaliza los datos al comando, hará que la contraseña sea visible para cualquiera que se ejecute
ps
al mismo tiempo. Sin embargo, ninguno de los comandos anteriores guardará la contraseña ingresada en el archivo de historial del shell si se ejecuta desde un shell interactivo.Los programas que se comportan bien y que leen contraseñas de texto sin cifrar lo hacen leyendo desde su entrada estándar, desde un archivo o directamente desde el terminal.
sha1pass
requiere la contraseña en la línea de comando, ya sea ingresada directamente o usando alguna forma de sustitución de comando.Si es posible, use otra herramienta.
fuente
$(...)
será parte de la línea de comando y será visible en laps
salida, excepto en un sistema con hard / proc.sha1pass
ejecutar sin contraseña en la línea de comando parece producir una salida sin leer nada ... Por lo tanto, OP debe elegir una herramienta diferente.Si configuras
HISTCONTROL
así:e inicie el comando con un espacio:
No se almacenará en el historial.
fuente
Pase datos confidenciales a través de una tubería o here-doc:
o:
Está bien que los secretos estén en variables de shell (no exportadas), pero nunca puede usar esas variables en líneas de comando, solo en documentos aquí y componentes internos de shell.
Como señaló Kusalananda en un comentario, si está ingresando comandos en un shell interactivo, las líneas que ingrese para un documento aquí se almacenarán en el historial del shell, por lo que no es seguro escribir una contraseña allí, pero aún así debería estar seguro para usar variables de shell que contienen secretos; el historial contendrá el texto en
$secret
lugar de lo que se haya$secret
expandido.El uso de expansiones de comandos no es seguro :
porque la salida se incluirá en la línea de comando y será visible en la
ps
salida (o lectura manual desde / proc) excepto en sistemas con endurecido / proc.La asignación a una variable también está bien:
fuente
command_with_secret_output
que me permita escribir la salida secreta. ¿Existe tal comando que pueda ser sustituido aquí?bash
sesión interactiva guardará el documento en el archivo de historial.read
, por ejemploread -r secret
. Entonces tu secreto está adentro$secret
. Puede ejecutar stty antes / después para ocultar la entrada si lo desea.sha1pass
parece fundamentalmente roto / inutilizable / inseguro ya que no puede leer la contraseña de stdin o un archivo. Creo que se necesita una utilidad diferente para resolver el problema.read -rs
hará el trabajo (si incluye-r
poder tener contraseñas con barras diagonales invertidas), pero luego puede volver a mostrar la contraseña en la lista de procesos (y dependiendo de si la contabilidad de procesos está activada y cómo está configurada) , en el proceso también registros de contabilidad).Simplemente escriba el valor en un archivo y pase el archivo:
No estoy seguro de cómo
sha1pass
funciona, si puede tomar un archivo como entrada, puede usarlosha1pass < mysecret
. Si no, el usocat
podría ser un problema ya que incluye la nueva línea final. Si ese es el caso, use (si eshead
compatible-c
):fuente
cat | sha1pass
?cat mysecret | sha1pass
ysha1pass < mysecret
tener el mismo comportamiento con respecto a las nuevas líneas finales.cat
no agrega nuevas líneas. De todos modos, sisha1pass
admite pasar la contraseña a través de la entrada estándar, esperaría que ignore la nueva línea final por sí misma. Los archivos con líneas que no terminan con nuevas líneas no son naturales en Unix después de todo, por lo que sería incómodo esperar un archivo que no termina con una nueva línea.cat | sha1pass
parece corrersha1pass
antes de darme la oportunidad de ingresar cualquier entrada. ii) No, por supuestocat mysecret
, no agrega una nueva línea, nunca dije que lacat
agregue, solo que la incluye .< mysecret
eliminara. :)head -c-1
. Supongo que me confundí en cuanto a por qué usarcat mysecret | sha1pass
y luego proponersha1pass < mysecret
. Supongo que la preocupación es que sha1pass podría quejarse de los archivos regulares para stdin; No estoy seguro de por qué.sha1pass
y no pude encontrar un manual o-h
cualquier otra forma de documentación en los pocos minutos que pasé buscando y, por lo tanto, no pude averiguar si se ejecutasha1pass foo
tratadofoo
como una cadena de entrada o como un archivo de entrada . Por lo tanto, di opciones para lidiar con cada posibilidad.Si lo que hizo terdon es posible, entonces esa es la mejor solución, pasando por la entrada estándar. El único problema que queda es que escribió la contraseña en el disco. Podemos hacer esto en su lugar:
Como dijo Kusalananda,
stty -echo
asegura que lo que escribes no se vea hasta que lo vuelvas a hacerstty echo
.head -1
obtendrá una línea de entrada estándar y la pasará asha1pass
.fuente
yo usaría
cat
leería desde stdin hastaEOF
, que puede ser causado presionando Ctrl + D. Luego, el resultado se pasaría como argumento asha1pass
fuente