AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 439497
Accepted
cemulate
cemulate
Asked: 2018-04-24 06:42:14 +0800 CST2018-04-24 06:42:14 +0800 CST 2018-04-24 06:42:14 +0800 CST

Existe uma maneira de passar dados confidenciais no bash usando um prompt, para qualquer comando?

  • 772

Suponha que eu estivesse usando sha1passpara gerar um hash de alguma senha confidencial na linha de comando. Posso usar sha1pass mysecretpara gerar um hash de mysecretmas isso tem a desvantagem que mysecretagora está no histórico do bash. Existe uma maneira de atingir o objetivo final deste comando, evitando a revelação mysecretem texto simples, talvez usando um passwdprompt -style?

Também estou interessado em uma maneira generalizada de fazer isso para passar dados confidenciais para qualquer comando. O método mudaria quando os dados confidenciais fossem passados ​​como um argumento (como em sha1pass) ou em STDIN para algum comando.

Existe uma maneira de conseguir isso?


Edit : Esta questão atraiu muita atenção e várias boas respostas foram oferecidas abaixo. Um resumo é:

  • De acordo com a resposta de @Kusalananda , idealmente, nunca seria necessário fornecer uma senha ou segredo como argumento de linha de comando para um utilitário. Isso é vulnerável de várias maneiras, conforme descrito por ele, e deve-se usar um utilitário melhor projetado que seja capaz de receber a entrada secreta no STDIN
  • A resposta de @vfbsilva descreve como impedir que as coisas sejam armazenadas no histórico do bash
  • A resposta de @Jonathan descreve um método perfeitamente bom para fazer isso, desde que o programa possa obter seus dados secretos no STDIN. Como tal, decidi aceitar esta resposta. sha1passno meu OP foi apenas um exemplo, mas a discussão estabeleceu que existem ferramentas melhores que coletam dados no STDIN.
  • como @R.. observa em sua resposta , o uso de expansão de comando em uma variável não é seguro.

Portanto, em resumo, aceitei a resposta de @Jonathan, pois é a melhor solução, pois você tem um programa bem projetado e bem-comportado para trabalhar. Embora passar uma senha ou segredo como um argumento de linha de comando seja fundamentalmente inseguro, as outras respostas fornecem maneiras de mitigar as preocupações simples de segurança.

shell security
  • 8 8 respostas
  • 33023 Views

8 respostas

  • Voted
  1. Kusalananda
    2018-04-24T07:12:29+08:002018-04-24T07:12:29+08:00

    Idealmente, você nunca digita uma senha de texto não criptografado na linha de comando como um argumento para um comando. Fazer isso torna a senha um argumento para o comando, e os argumentos da linha de comando podem ser vistos na tabela de processos usando ferramentas simples como psou registrados em alguns logs de auditoria.

    Dito isto, certamente existem maneiras de ocultar a senha real do histórico de comandos do shell.

    sha1pass "$( head -n 1 )"
    

    Em seguida, digite a senha e pressione Enter. O headcomando usado aqui aceita exatamente uma linha de entrada e a última nova linha que você digitar não fará parte dos dados que são passados ​​para sha1pass.

    Para evitar que os caracteres ecoem:

    sha1pass "$( stty -echo; head -n 1; stty echo )"
    

    O stty -echocomando desativa o eco dos caracteres digitados no terminal. O eco é então restaurado com stty echo.

    Para transmitir a entrada padrão, esse último comando pode ser alterado (você teria feito isso se sha1passaceitasse dados na entrada padrão, mas aparece como se este utilitário específico estivesse ignorando sua entrada padrão):

    { stty -echo; head -n 1; stty echo; } | somecommand
    

    Se você precisar de entrada de várias linhas (o acima assume que uma única linha deve ser passada, sem caractere de nova linha no final), substitua todo o headcomando cate encerre a entrada (supondo que somecommandele seja lido até o final do arquivo) com Ctrl+D( seguinte Returnse desejar incluir um caractere de nova linha na entrada ou duas vezes se não quiser).

    Isso funcionaria independentemente do shell que você estivesse usando (desde que fosse um shell do tipo Bourne ou rc).

    Alguns shells podem ser feitos para não salvar os comandos digitados em seus arquivos de histórico se o comando for precedido por um espaço. Isso geralmente envolve ter que definir HISTCONTROLo valor ignorespace. Isso é suportado pelo menos por bashe kshno OpenBSD, mas não por, por exemplo, ksh93ou dash. zshos usuários podem usar a histignorespaceopção ou sua HISTORY_IGNOREvariável para definir um padrão a ser ignorado.

    Em shells que suportam leitura readsem ecoar caracteres para o terminal, você também pode usar

    IFS= read -rs password     # -s turns off echoing in bash or zsh
                               # -r for reading backslashes as-is,
                               # IFS= to preserve leading and trailing blanks
    sha1pass "$password"
    

    mas isso obviamente ainda tem o mesmo problema com a revelação potencial da senha na tabela de processos.

    Se o utilitário ler da entrada padrão e se o shell suportar "here-strings", o acima poderá ser alterado para

    IFS= read -rs password
    somecommand <<<"$password"
    

    Resumo dos comentários abaixo:

    • A execução de um comando com uma senha fornecida na linha de comando, que todos os comandos acima fazem, exceto aquele que canaliza os dados para o comando, tornará a senha potencialmente visível para qualquer pessoa executando psao mesmo tempo. No entanto, nenhum dos comandos acima salvará a senha digitada no arquivo de histórico do shell se executado a partir de um shell interativo.

    • Programas bem comportados que lêem senhas de texto não criptografado fazem isso lendo de sua entrada padrão, de um arquivo ou diretamente do terminal.

    • sha1passrequer a senha na linha de comando, digitada diretamente ou usando alguma forma de substituição de comando.

    • Se possível, use outra ferramenta.

    • 42
  2. vfbsilva
    2018-04-24T06:59:05+08:002018-04-24T06:59:05+08:00

    Se você definir HISTCONTROLassim:

    HISTCONTROL=ignorespace
    

    e inicie o comando com um espaço:

    ~$  mycommand
    

    não será armazenado no histórico.

    • 26
  3. Best Answer
    Jonathan
    2018-04-24T11:37:56+08:002018-04-24T11:37:56+08:00

    Se estiver usando o shell zshou bash, use a opção -s para o readshell integrado para ler uma linha do dispositivo terminal sem que ela seja repetida.

    IFS= read -rs VARIABLE < /dev/tty
    

    Então você pode usar algum redirecionamento sofisticado para usar a variável como stdin.

    sha1pass <<<"$VARIABLE"
    

    Se alguém executar ps, tudo o que verá é "sha1pass".

    Isso pressupõe que sha1passlê a senha do stdin (em uma linha, ignorando o delimitador de linha) quando não recebe nenhum argumento.

    • 26
  4. R.. GitHub STOP HELPING ICE
    2018-04-24T07:44:22+08:002018-04-24T07:44:22+08:00

    Passe dados confidenciais por meio de um pipe ou here-doc:

    command_with_secret_output | command_with_secret_input
    

    ou:

    command_with_secret_input <<EOF
    $secret
    EOF
    

    É bom que os segredos estejam em variáveis ​​de shell (não exportadas), mas você nunca pode usar essas variáveis ​​em linhas de comando, apenas em here-documents e shell internals.

    Conforme observado por Kusalananda em um comentário, se você estiver inserindo comandos em um shell interativo, as linhas inseridas para um documento here serão armazenadas no histórico do shell, portanto, não é seguro digitar uma senha lá, mas ainda deve ser seguro usar variáveis ​​shell contendo segredos; o histórico conterá o texto $secretem vez de qualquer coisa $secretexpandida.

    O uso de expansões de comando não é seguro :

    command_with_secret_input "$(command_with_secret_output)"
    

    porque a saída será incluída na linha de comando e visível na pssaída (ou leitura manual de /proc), exceto em sistemas com /proc endurecido.

    A atribuição a uma variável também é aceitável:

    secret=$(command_with_secret_output)
    
    • 10
  5. terdon
    2018-04-24T07:09:47+08:002018-04-24T07:09:47+08:00

    Basta escrever o valor em um arquivo e passar o arquivo:

    $ cat > mysecret
    Big seecreeeet!
    $ cat mysecret | sha1pass 
    

    Não tenho certeza de como sha1passfunciona, se puder receber um arquivo como entrada, você pode usar sha1pass < mysecret. Caso contrário, usar catpode ser um problema, pois inclui a nova linha final. Se for esse o caso, use (se o seu headsuporte -c):

    head -c-1 mysecret | sha1pass 
    
    • 6
  6. JoL
    2018-04-24T07:56:09+08:002018-04-24T07:56:09+08:00

    Se o que o terdon fez for possível, então essa é a melhor solução, passando pela entrada padrão. O único problema que resta é que ele escreveu a senha no disco. Podemos fazer isso em vez disso:

    stty -echo
    echo -n "password: "
    head -1 | sha1pass
    stty echo
    

    Como Kusalananda disse, stty -echogarante que o que você digita não seja visto até que você o faça stty echonovamente. head -1obterá uma linha da entrada padrão e a passará para sha1pass.

    • 1
  7. oktupol
    2018-04-26T01:23:20+08:002018-04-26T01:23:20+08:00

    eu usaria

    sha1pass "$(cat)"
    

    catleria de stdin até EOF, o que pode ser causado pressionando Ctrl+D. Então, o resultado seria passado como argumento parasha1pass

    • 1
  8. Ronald Duncan
    2021-06-22T04:24:28+08:002021-06-22T04:24:28+08:00

    Se você está passando informações confidenciais e as usa regularmente, provavelmente é melhor criptografá-las.

    Colocando algo como

    #create key as follows - will prompt for password
    #echo -n 'secret you want encrypted' | openssl enc -aes-256-cbc  -a -salt -pbkdf2|base64
    export MY_SECRET='VTJGc2RHVmtYMTlzVnBGWXNYUitLWlpYT3BWdStaQXJXeUVwc1JORnFsNWswZXJKT1dkRWpsWkxLWVFnK1hONQo='
    

    Em seu .bashrc, você terá uma variável de ambiente criptografada que você pode acessar sempre que precisar de um segredo, e será solicitada a senha/senha que você usou ao criar a variável de ambiente.

    No exemplo acima é 'secret'

    Você acessa é um comando da seguinte forma

    `echo $MY_SECRET|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2 `
    

    por exemplo

    xfreerpd /parameters.... /p:`echo $MY_SECRET|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2` 
    

    Para sua consulta usando sha1pass. Você pode criar e passar da seguinte forma

    MY_SECRET=`echo -n 'secret you want encrypted' | openssl enc -aes-256-cbc  -a -salt -pbkdf2|base64`
    

    Então use da seguinte forma

    sha1pass `echo $MY_SECRET|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2 `
    

    A parte base64 é para que você possa definir a variável

    MY_SECRET='VTJGc2RHVmtYMTlzVnBGWXNYUitLWlpYT3BWdStaQXJXeUVwc1JORnFsNWswZXJKT1dkRWpsWkxLWVFnK1hONQo='
    

    E não deixe seu segredo preso no histórico de comandos etc etc.

    Quando você gera o segredo, às vezes, a saída base64 terá várias linhas, então você precisa fazer as quebras de linha para sua variável.

    echo -n 'secret you want encrypted' | openssl enc -aes-256-cbc  -a -salt -pbkdf2|base64
    enter aes-256-cbc encryption password:
    Verifying - enter aes-256-cbc encryption password:
    VTJGc2RHVmtYMTlzVnBGWXNYUitLWlpYT3BWdStaQXJXeUVwc1JORnFsNWswZXJKT1dkRWpsWkxL
    WVFnK1hONQo=
    
    #take the above line break out 
    MY_SECRET='VTJGc2RHVmtYMTlzVnBGWXNYUitLWlpYT3BWdStaQXJXeUVwc1JORnFsNWswZXJKT1dkRWpsWkxLWVFnK1hONQo='
    

    O openssh solicitará uma senha para criptografar e descriptografar a cada vez, você pode fornecer uma como parte do comando, mas estará apenas ocultando coisas do histórico, etc. Dê uma olhada em https://www.tecmint.com/ generate-encrypt-decrypt-random-passwords-in-linux/ para obter algumas informações sobre como usar o openssh para isso. https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-base64-encode-and-decode-from-command-line/ para base64 e https://stackoverflow.com/questions/16072351 /how-to-assign-an-output-to-a-shellscript-variable para diferentes opções na substituição de comando que usei back-tick ` acima

    • 0

relate perguntas

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

  • Existe um daemon syslog que implementa RFC 5848 "Signed Syslog Messages"?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve