명령에 대한 프롬프트를 사용하여 bash에서 민감한 데이터를 전달하는 방법이 있습니까?

명령에 대한 프롬프트를 사용하여 bash에서 민감한 데이터를 전달하는 방법이 있습니까?

sha1pass명령줄에서 일부 민감한 비밀번호의 해시를 생성하는 데 사용한다고 가정해 보겠습니다 . sha1pass mysecret생성된 해시를 사용할 수 있지만 이는 이제 bash 기록에 나타나는 mysecret단점이 있습니다 . 이 명령을 일반 텍스트로 표시하지 않고(아마도 -style 프롬프트를 사용하여 ) mysecret최종 목표를 달성할 수 있는 방법이 있습니까 ?mysecretpasswd

또한 민감한 데이터를 모든 명령에 전달하는 일반적인 방법에도 관심이 있습니다. sha1pass이 방법은 민감한 데이터가 특정 명령에 매개변수(예: ) 또는 STDIN으로 전달될 때 변경됩니다.

이를 수행할 수 있는 방법이 있습니까?


편집하다: 이 질문은 많은 관심을 받았고, 아래에 몇 가지 훌륭한 답변이 있습니다. 요약은 다음과 같습니다.

  • ~에 따르면@Kusalananda의 답변, 이상적으로는 유틸리티에 대한 명령줄 인수로 암호나 비밀을 제공할 필요가 없습니다. 그가 설명했듯이 이는 여러 면에서 취약하므로 STDIN에 대한 비밀 입력을 얻을 수 있도록 더 잘 설계된 유틸리티를 사용해야 합니다.
  • @vfbsilva의 답변bash 기록에 항목이 저장되는 것을 방지하는 방법을 설명합니다.
  • @Jonathan의 답변프로그램이 STDIN에서 비밀 데이터를 얻을 수 있는 한 이를 달성하는 완벽한 방법을 설명합니다. 그래서 나는 이 대답을 받아들이기로 결정했다. sha1pass내 OP의 예일 뿐이지만 토론 결과 STDIN에 대한 데이터를 얻기 위한 더 나은 도구가 존재한다는 것이 결정되었습니다.
  • ~처럼@아르 자형..댓글 달기그의 대답, 변수에 대한 명령 확장을 사용하는 것은아니요안전한.

그래서 전체적으로 받아들인다.@Jonathan의 답변잘 설계되고 제대로 작동하는 프로그램이 있으므로 이것이 최고의 솔루션이기 때문입니다. 암호나 비밀을 명령줄 인수로 전달하는 것은 근본적으로 안전하지 않지만 다른 답변은 간단한 보안 문제를 완화할 수 있는 방법을 제공합니다.

답변1

이상적으로는 명령줄의 명령에 대한 인수로 일반 텍스트 암호를 입력해서는 안 됩니다. 이렇게 하면 암호가 명령에 대한 인수가 되고 명령줄 인수는 일부 감사 로그에 기록 하거나 간단한 도구를 사용하여 ps프로세스 테이블에서 볼 수 있습니다 .

하지만 쉘의 명령 기록에서 실제 비밀번호를 숨기는 방법이 확실히 있습니다.

sha1pass "$( head -n 1 )"

그런 다음 비밀번호를 입력하고 를 누르세요 Enter. 여기에 사용된 명령은 head한 줄의 입력만 허용하며, 입력한 마지막 개행 문자는 전달된 데이터의 일부가 되지 않습니다 sha1pass.

문자가 반향되는 것을 방지하려면 다음을 수행하십시오.

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

stty -echo명령은 터미널에 입력된 문자의 반향을 끕니다. 그런 다음 복원 에코를 사용하십시오 stty echo.

표준 입력을 전달하려면 마지막 명령을 변경할 수 있습니다( sha1pass표준 입력의 데이터가 허용된 경우 수행할 작업이지만 이 특정 유틸리티는 표준 입력을 무시하는 것처럼 보입니다).

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

여러 줄 입력이 필요한 경우(위에서는 끝에 개행 문자 없이 단일 줄을 전달해야 한다고 가정함) 다음 head을 사용하세요(입력에 줄 바꿈을 원하면 다음을 수행하고 그렇지 않으면 두 번 수행하십시오).catsomecommandCtrl+DReturn

이것은 어떤 쉘을 사용하든 상관없이 작동합니다(Bourne 또는 rc와 같은 쉘이라면).

일부명령 앞에 공백이 있으면 쉘은 입력한 명령을 기록 파일에 저장하지 못할 수 있습니다. 일반적으로 HISTCONTROLvalue 로 설정해야 합니다 ignorespace. 적어도 OpenBSD에서는 bash이를 지원 ksh하지만 예를 들어 ksh93그렇지 않을 수도 있습니다 dash. zsh사용자는 histignorespace옵션이나 해당 변수 사용을 HISTORY_IGNORE무시하도록 패턴을 정의 할 수 있습니다.

read문자를 터미널에 에코하지 않고 읽기를 지원하는 쉘에서는 다음을 사용할 수도 있습니다.

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"

그러나 이는 여전히 프로세스 테이블에서 비밀번호가 유출될 가능성이 있는 동일한 문제를 갖고 있는 것으로 보입니다.

유틸리티가 표준 입력에서 읽고 쉘이 "here-strings"를 지원하는 경우 위의 내용을 다음으로 변경할 수 있습니다.

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

의견을 요약하면 다음과 같습니다.

  • ps명령줄에 제공된 암호를 사용하여 명령을 실행하면(데이터를 명령에 파이프하는 명령 제외) 위의 모든 명령이 이 작업을 수행하므로 잠재적으로 동시에 실행하는 모든 사람에게 암호가 표시됩니다 . 그러나 대화형 셸에서 실행되는 경우 위 명령 중 어느 것도 입력한 비밀번호를 셸의 기록 파일에 저장하지 않습니다.

  • 일반 텍스트 암호를 읽는 정상적으로 작동하는 프로그램은 표준 입력, 파일 또는 터미널에서 직접 읽어서 읽습니다.

  • sha1pass직접 또는 명령 대체 형식을 사용하여 명령줄에 비밀번호를 입력해야 합니다.

  • 가능하다면 다른 도구를 사용하십시오.

답변2

zsh또는 쉘을 사용하는 경우 bash쉘 내장 -s 옵션을 사용하여 read에코하지 않고 터미널 장치에서 행을 읽습니다.

IFS= read -rs VARIABLE < /dev/tty

그런 다음 멋진 리디렉션을 사용하여 해당 변수를 표준 입력으로 사용할 수 있습니다.

sha1pass <<<"$VARIABLE"

누군가가 실행하면 ps"sha1pass"만 표시됩니다.

sha1pass인수가 지정되지 않은 경우 stdin에서(줄 구분 기호를 무시하고 한 줄로) 비밀번호를 읽는다고 가정합니다 .

답변3

HISTCONTROL다음과 같이 설정 하면 :

HISTCONTROL=ignorespace

그리고 공백으로 명령을 시작합니다.

~$  mycommand

히스토리에 저장되지 않습니다.

답변4

파일에 값을 쓰고 파일을 전달하면 됩니다.

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

어떻게 작동하는지 잘 모르겠습니다 sha1pass. 파일을 입력으로 사용할 수 있으면 사용할 수 있습니다 sha1pass < mysecret. 그렇지 않은 경우 cat마지막 개행 문자가 포함되어 있기 때문에 사용하는 데 문제가 있을 수 있습니다. 이 경우 다음을 사용하세요( head지원하는 경우 -c).

head -c-1 mysecret | sha1pass 

관련 정보