명령에 대해 프롬프트를 사용하여 bash에서 중요한 데이터를 전달하는 방법이 있습니까? Kusalananda의 대답 @

sha1pass명령 행에서 민감한 비밀번호의 해시를 생성하는 데 사용했다고 가정하십시오 . sha1pass mysecret해시를 생성하는 데 사용할 수 mysecret있지만 mysecret현재 bash 기록에있는 단점이 있습니다 . -style 프롬프트 mysecret를 사용하여 일반 텍스트로 표시 하지 않고이 명령의 최종 목표를 달성 할 수있는 방법이 passwd있습니까?

또한 민감한 데이터를 모든 명령에 전달하기 위해이를 수행하는 일반적인 방법에 관심이 있습니다. 민감한 데이터가 인수 (예 : in sha1pass) 또는 STDIN에서 일부 명령 으로 전달되면 메소드가 변경됩니다 .

이것을 달성 할 수있는 방법이 있습니까?


편집 :이 질문은 많은 관심을 끌었으며 아래에 몇 가지 좋은 답변이 있습니다. 요약은 다음과 같습니다.

  • 당으로 Kusalananda의 대답 @ , 이상적으로 하나는 유틸리티 명령 줄 인수로 암호 나 비밀을 줄 필요가 없을 것입니다. 이것은 그에 의해 설명 된 여러 가지 방법으로 취약하며 STDIN에서 비밀 입력을 취할 수있는 더 잘 설계된 유틸리티를 사용해야합니다
  • @vfbsilva의 답변 은 bash 기록에 물건이 저장되는 것을 방지하는 방법을 설명합니다
  • @Jonathan의 답변 은 프로그램이 STDIN에서 비밀 데이터를 취할 수있는 한 이것을 달성하기위한 완벽하게 좋은 방법을 설명합니다. 따라서이 답변을 수락하기로 결정했습니다. sha1pass내 OP의 예는 하나의 예이지만 STDIN에 대한 데이터를 가져 오는 더 나은 도구가 존재한다는 논의가있었습니다.
  • @R .. 메모 그의 대답 변수에 명령 확장의 사용은 하지 안전합니다.

요약하자면, @Jonathan의 대답 은 귀하가 잘 설계되고 올바르게 작동하는 프로그램이 있다는 점에서 가장 좋은 해결책이기 때문에 받아 들였습니다 . 암호 나 암호를 명령 줄 인수로 전달하는 것은 근본적으로 안전하지 않지만 다른 답변은 간단한 보안 문제를 완화하는 방법을 제공합니다.



답변

은 USING 경우 zsh또는 bash쉘은 상기 -s 옵션을 사용하여 read그것을 반향 않고 상기 단말 장치로부터의 라인을 읽을 쉘 내장.

IFS= read -rs VARIABLE < /dev/tty

그런 다음 멋진 리디렉션을 사용하여 변수를 stdin으로 사용할 수 있습니다.

sha1pass <<<"$VARIABLE"

누군가 실행하면 ps“sha1pass”만 보입니다.

sha1pass인수가 주어지지 않으면 stdin에서 암호 를 읽습니다 (한 줄에서 줄 구분 기호 무시).


답변

이상적으로는 명령 행에서 일반 텍스트 암호를 명령의 인수로 입력하지 않는 것이 이상적입니다. 그렇게하면 암호가 명령의 인수가되며 프로세스 테이블에서 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와 명령 cat및 입력을 종료 (가정 somecommand자체가 파일의 마지막에이를 때까지 읽는) Ctrl+D( Return줄 바꿈 문자를 입력에 포함하려면 다음을 따르십시오 .

이것은 Bourne과 같은 쉘이거나 rc와 같은 쉘이라면 어떤 쉘을 사용하든 작동합니다.

명령 앞에 공백이 있으면 일부 쉘은 입력 된 명령을 히스토리 파일에 저장하지 않을 수 있습니다. 여기에는 보통 HISTCONTROL값 으로 설정 해야합니다 ignorespace. 이것은 적어도에서 지원 bash하고 ksh오픈 BSD에 있지만 예에 의해 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 직접 입력하거나 명령 대체 형식을 사용하여 명령 행에 비밀번호가 필요합니다.

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


답변

이렇게 설정 한 경우 HISTCONTROL:

HISTCONTROL=ignorespace

공백으로 명령을 시작하십시오.

~$  mycommand

기록에 저장되지 않습니다.


답변

파이프 또는 here-doc을 통해 민감한 데이터를 전달하십시오.

command_with_secret_output | command_with_secret_input

또는:

command_with_secret_input <<EOF
$secret
EOF

비밀은 (내보내기되지 않은) 셸 변수에있는 것이 좋지만 명령 행에서는 절대로 여기 변수와 문서 내부 및 셸 내부에서만 사용할 수 없습니다.

주석에서 Kusalananda가 언급했듯이 대화 형 쉘에 명령을 입력하면 here 문서에 입력 한 줄이 쉘 기록에 저장되므로 암호를 입력하는 것이 안전하지 않지만 여전히 암호를 입력해야합니다 비밀을 포함하는 쉘 변수를 사용하는 것이 안전합니다. 역사는 확장 된 $secret것이 아니라 텍스트를 포함 할 것 $secret입니다.

명령 확장 사용은 안전하지 않습니다 .

command_with_secret_input "$(command_with_secret_output)"

ps/ proc이 강화 된 시스템을 제외하고 는 출력 이 명령 줄에 포함되어 출력 (또는 / proc에서 수동으로 읽음)에 표시되기 때문 입니다.

변수에 할당해도 괜찮습니다.

secret=$(command_with_secret_output)

답변

값을 파일에 쓰고 파일을 전달하십시오.

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

어떻게 sha1pass작동 하는지 잘 모르겠습니다 . 파일을 입력으로 사용할 수 있다면을 사용할 수 있습니다 sha1pass < mysecret. 그렇지 않은 경우 cat마지막 줄 바꿈이 포함되어있어 사용 에 문제가있을 수 있습니다. 이 경우 ( head지원 하는 경우)를 사용하십시오 -c.

head -c-1 mysecret | sha1pass 

답변

terdon이 수행 한 것이 가능하다면 표준 입력을 통과하는 가장 좋은 솔루션입니다. 남은 유일한 문제는 암호를 디스크에 썼다는 것입니다. 대신이 작업을 수행 할 수 있습니다.

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

Kusalananda가 말했듯 stty -echostty echo다시 입력 할 때까지 입력 한 내용이 보이지 않도록 합니다. head -1표준 입력에서 한 줄을 가져 와서 전달합니다 sha1pass.


답변

나는 사용할 것이다

sha1pass "$(cat)"

catstdin에서까지 읽을 때 EOFCtrl + D를 누르면 발생할 수 있습니다. 그런 다음 결과는 인수로 전달됩니다.sha1pass