sha1pass
명령줄에서 일부 민감한 비밀번호의 해시를 생성하는 데 사용한다고 가정해 보겠습니다 . sha1pass mysecret
생성된 해시를 사용할 수 있지만 이는 이제 bash 기록에 나타나는 mysecret
단점이 있습니다 . 이 명령을 일반 텍스트로 표시하지 않고(아마도 -style 프롬프트를 사용하여 ) mysecret
최종 목표를 달성할 수 있는 방법이 있습니까 ?mysecret
passwd
또한 민감한 데이터를 모든 명령에 전달하는 일반적인 방법에도 관심이 있습니다. 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
을 사용하세요(입력에 줄 바꿈을 원하면 다음을 수행하고 그렇지 않으면 두 번 수행하십시오).cat
somecommand
Ctrl+DReturn
이것은 어떤 쉘을 사용하든 상관없이 작동합니다(Bourne 또는 rc와 같은 쉘이라면).
일부명령 앞에 공백이 있으면 쉘은 입력한 명령을 기록 파일에 저장하지 못할 수 있습니다. 일반적으로 HISTCONTROL
value 로 설정해야 합니다 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