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


40

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

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

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


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

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

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


6
뿐만 아니라 : 실행중인 프로세스를 나열 할 수있는 권한을 가진 동일한 시스템에있는 모든 사용자는 해당 프로세스 sha1pass mysecret가 실행중인 것을 볼 수 있으므로 현재 상태를 알 수 mysecret있습니다. (물론 프로그램이 실제로 실행되는 동안 몇 초 동안 만 작동합니다 ...)
MathematicalOrchid

@MathematicalOrchid 개인 가상 머신에서 실행하면이를 피할 수 있습니다. 그러나 그것은 하나의 암호 만 생성하기 위해 설정하기에는 너무 많은 작업 일 수 있습니다 ... :-)
Kusalananda

5
@Kusalananda 내 요점은 "명령 기록을 해제하는 방법을 알아 내더라도 명령 줄에 민감한 데이터를 넣지 마십시오"입니다.
MathematicalOrchid

2
아시다시피 SHA-1은 몇 년 전부터 키 또는 비밀번호 해시로 더 이상 사용되지 않습니다.
David Foerster

2
시스템이 감사 데몬을 실행중인 경우 모든 사용자의 모든 명령과 모든 인수가 루트로 중앙에 기록되므로 해당 로그에 액세스 할 수있는 사람이면 누구나 볼 수 있습니다.
랜달

답변:


20

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

IFS= read -rs VARIABLE < /dev/tty

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

sha1pass <<<"$VARIABLE"

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

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


sha1pass표준 입력 스트림을 사용하지 않는 것으로 설정했습니다 .
Kusalananda

@Kusalananda 그래,하지만이 방법은 stdin에서 읽은 프로그램에서 작동합니다.
Jonathan

따라서 유틸리티가 STDIN에서 비밀 입력을 취할 수 있다고 가정하면 보안 측면에서 안전하고 안전한 솔루션입니까?
cemulate

잘 설계 된 프로그램을 가지고있는 것이 최선의 해결책이라는 것을 감안할 때이 답변을 수락하기로 결정했습니다 . sha1pass내 OP의 예일 뿐이며 이것에 가장 적합한 선택은 아닙니다.
21:00에

1
@cemulate, ... 명령 행에서 안전하지 않습니다 . heredoc 또는 herestring (여기서 답변에서와 같이)의 맥락에서 노출되지 ps않지만 임시 파일에 기록 될 수 있습니다-피하기를 원한다면 sshpass < <(printf '%s\n' "$VARIABLE")고려 될 수 있습니다 printf. 외부 명령으로 전달되지 않으며 ) execv를 통해 액세스 할 수 없습니다 ps.
Charles Duffy

35

이상적으로는 명령 행에서 일반 텍스트 암호를 명령의 인수로 입력하지 않는 것이 이상적입니다. 그렇게하면 암호가 명령의 인수가되며 프로세스 테이블에서 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 직접 입력하거나 명령 대체 형식을 사용하여 명령 행에 비밀번호가 필요합니다.

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


11
이것은 올바르지 않습니다. 명령 확장의 결과는 명령 $(...)줄의 일부이며 ps강화 된 / proc가있는 시스템을 제외하고 출력에 표시됩니다 .
R ..

3
@Kusalananda, 당신이 시작한 후에 argv를 덮어 쓰기는 덮어 쓰기가 일어나기 전에 취약한 창을 남깁니다. 수정이 아니라 완화입니다.
Charles Duffy

5
@Kusalananda, 암호 해싱을위한 잘 설계된 프로그램은 명령 줄에 입력을 요구하지 않으므로 조건부가 기본적으로 주어집니다. 그렇지 않으면 다른 도구를 선택해야합니다.
Charles Duffy

4
@CharlesDuffy :이 도구는 근본적으로 고장난 것 같습니다. sha1pass명령 줄에서 암호없이 실행하면 아무 것도 읽지 않고 출력이 생성되는 것 같습니다. 따라서 OP는 다른 도구를 선택해야합니다.
R ..

8
이 답변은 보안 관점에서 안전하지 않으며 유일한 장점은 암호가 쉘 기록에 표시되지 않지만 명령 앞에 공백을 포함하면이 이점을 쉽게 달성 할 수 있다는 것입니다.
Ferrybig

25

이렇게 설정 한 경우 HISTCONTROL:

HISTCONTROL=ignorespace

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

~$  mycommand

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


10

파이프 또는 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)

내가 찾고 있는 것은 비밀 출력 command_with_secret_output입력 할 수 있는 실제 명령 입니다 . 여기서 대체 할 수있는 그러한 명령이 있습니까?
cemulate

대화 형 bash 세션 에서 여기 문서를 입력 하면 문서가 기록 파일에 저장됩니다.
Kusalananda

@cemulate : 쉘 내장을 사용하십시오 ( read예 :) read -r secret. 그럼 당신의 비밀은입니다 $secret. 원하는 경우 입력 전후로 stty를 실행할 수 있습니다.
R ..

3
@ Kusalananda : sha1passstdin 또는 파일에서 암호를 읽을 수 없으므로 근본적으로 고장 났거나 사용할 수 없거나 안전하지 않은 것 같습니다. 문제를 해결하려면 다른 유틸리티가 필요하다고 생각합니다.
R ..

1
@cemulate R에 대한 마지막 의견은 바로 그 자리에 있습니다. 그것이 도움이되지 않는 이유입니다. read -rs작업을 수행 -r하지만 (백 슬래시가있는 비밀번호 를 포함 하는 경우 포함 ) 프로세스 목록에서 비밀번호가 표시 될 가능성이 있습니다 (프로세스 계정이 설정되어 있는지 여부 및 구성 방법에 따라 다름). , 프로세스 계정 로그에서도).
Kusalananda

6

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

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

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

head -c-1 mysecret | sha1pass 

2
첫 번째 예제에서 암호를 디스크에 쓰는 이유는 cat | sha1pass무엇입니까? cat mysecret | sha1pass그리고 sha1pass < mysecret마지막 줄 바꿈에 대한 동일한 동작을합니다. cat개행을 추가하지 않습니다. 어쨌든 sha1pass표준 입력을 통해 암호를 전달하는 것이 지원되면 최종 줄 바꿈 자체를 무시할 것으로 예상됩니다. 줄 바꿈으로 끝나지 않은 줄이있는 파일은 결국 유닉스에서 부자연 스럽기 때문에 줄 바꿈으로 끝나지 않은 파일을 기대하기가 어색합니다.
JoL

@JoL i) 나는 그것을 생각하지 않았기 때문에 : /하지만 어떻게 작동합니까? 입력을 입력 할 수있는 기회를주기 전에 cat | sha1pass실행되는 것 같습니다 sha1pass. II) 아니, 물론 cat mysecret줄 바꿈을 추가하지 않습니다, 나는 말했다 결코 cat그것은 단지 것을, 그것을 추가 포함 을.
terdon

알지만 그것을 < mysecret제거하는 것과는 다릅니다. :)
JoL

신경 쓰지 마. 다시 읽었으므로 나중에 제안하겠다고 말씀하셨습니다 head -c-1. 나는 왜 사용 cat mysecret | sha1pass하고 나중에 제안 하는지에 대해 혼란스러워 한 것 같습니다 sha1pass < mysecret. 걱정은 sha1pass가 stdin의 일반 파일에 대해 불평 할 수 있다는 것입니다. 왜 그런지 잘 모르겠습니다.
JoL

@JoL 더 이상 사용하지 않았고 검색하는 데 몇 분 동안 sha1pass매뉴얼이나 -h다른 형식의 문서를 찾을 수 없었기 때문에 입력 문자열 또는 입력 파일로 sha1pass foo처리 된 경우 알아낼 수 없었습니다. foo. 따라서 각 가능성을 처리 할 수있는 옵션을 제공했습니다.
terdon

1

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

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

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


0

나는 사용할 것이다

sha1pass "$(cat)"

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


3
R ..의 답변은 왜 이것이 안전하지 않은지를 설명합니다.
hvd April
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.