[unix] 자식 프로세스에 암호를 전달하는 방법은 무엇입니까?

ps 명령을 사용하면 다른 사용자도 볼 수 있기 때문에 명령 줄에서 암호를 전달하는 것은 (프로그램에서 시작한 자식 프로세스에) 안전하지 않은 것으로 알려져 있습니다. 대신 환경 변수로 전달해도됩니까?

그것을 전달하기 위해 다른 무엇을 사용할 수 있습니까? (환경 변수 제외) 가장 쉬운 솔루션은 파이프를 사용하는 것처럼 보이지만이 가장 쉬운 솔루션은 쉽지 않습니다.

나는 Perl에서 프로그램한다.



답변

프로세스 인수는 모든 사용자에게 표시되지만 환경은 동일한 사용자에게만 표시됩니다 ( 적어도 Linux 에서는 모든 유닉스 유닉스 변형에 대해 생각합니다). 따라서 환경 변수를 통해 암호를 전달하는 것이 안전합니다. 누군가가 환경 변수를 읽을 수 있다면 프로세스를 실행할 수 있으므로 이미 게임입니다.

예를 들어 ps공공 장소에서 기밀 환경 변수를 포함한 결과를 실수로 복사하여 붙여 넣는 등 환경의 내용은 간접적으로 누출 될 위험이 있습니다. 또 다른 위험은 환경 변수를 필요로하지 않는 프로그램 (비밀번호가 필요한 프로세스의 하위 포함)에 환경 변수를 전달하고 해당 프로그램은 환경 변수가 기밀로 예상되지 않기 때문에 환경 변수를 노출시키는 것입니다. 이러한 2 차 누출 위험이 얼마나 나쁜지는 암호를 사용하는 프로세스가 수행하는 작업 (얼마나 오래 실행됩니까? 하위 프로세스를 실행합니까?)에 따라 다릅니다.

파이프와 같이 도청되도록 설계되지 않은 채널을 통해 암호를 실수로 유출하지 않도록하는 것이 더 쉽습니다. 보내는 쪽에서 수행하기가 매우 쉽습니다. 예를 들어, 쉘 변수에 비밀번호가 있다면,

echo "$password" | theprogram

theprogram표준 입력에 비밀번호가 필요한 경우 . echo내장되어 있기 때문에 안전합니다 . 인수가 ps출력에 노출되므로 외부 명령으로 안전하지 않습니다 . 동일한 효과를 얻는 또 다른 방법은 here 문서를 사용하는 것입니다.

theprogram <<EOF
$password
EOF

암호가 필요한 일부 프로그램은 특정 파일 디스크립터에서 암호를 읽도록 지시 할 수 있습니다. 다른 것에 표준 입력이 필요한 경우 표준 입력 이외의 파일 디스크립터를 사용할 수 있습니다. 예를 들면 다음과 gpg같습니다.

get-encrypted-data | gpg --passphrase-fd 3 --decrypt … 3<<EOP >decrypted-data
$password
EOP

프로그램이 파일 디스크립터에서 읽도록 지시 할 수 없지만 파일에서 읽도록 지시받을 수 있다면`/ dev / fd / 3와 같은 파일 이름을 사용하여 파일 디스크립터에서 읽도록 지시 할 수 있습니다.

theprogram --password-from-file=/dev/fd/3 3<<EOF
$password
EOF

ksh, bash 또는 zsh에서는 프로세스 대체를 통해보다 간결하게 수행 할 수 있습니다.

theprogram --password-from-file=<(echo "$password")


답변

인수 또는 환경 변수를 통해 비밀번호를 직접 전달하는 대신

#!/bin/bash
#filename: passwd_receiver
echo "The password is: $1"

동일한 인수 또는 환경 변수를 사용하여 파일 이름 을 전달하십시오 .

#!/bin/bash
#filename: passwd_receiver
echo "The password is: $(< "$1")"

그런 다음 당신은 하나 통과 할 수 있는 권한 보호 일반 파일을 (즉, 동일한 사용자로 실행중인 다른 프로세스에서 당신을 보호하지 않지만), 또는 /dev/stdin파이프 그것을 (AFAIK가 동일한 사용자로 실행중인 다른 프로세스에서 당신을 보호 할 수있는)에서 :

 echo PASSWORD | ./passwd_receiver /dev/stdin

/dev/stdin여기서 사용한다면 반드시 pipe 입니다. 터미널 인 경우 동일한 사용자로 실행되는 다른 프로세스에서 읽을 수 있습니다.

이미 /dev/stdin다른 용도로 사용해야 하는 경우 파이프를 지원하는 쉘에 해당하는 경우 프로세스 대체를 사용할 수 있습니다 .

./passwd_receiver <(echo PASSWORD)

명명 된 파이프 (FIFO)는 동일 해 보이지만 가로 챌 수 있습니다.

이러한 솔루션은 완벽하게 안전 하지는 않지만 메모리 스왑 시스템이 많지 않으면 충분히 근접 할 수 있습니다.

이상적으로는 mlock (2) 가 스왑 불가능으로 표시된 메모리에 이러한 파일 (파이프도 파일 임) 을 읽습니다. 이는 일반적으로 gnupg와 같은 비밀번호 처리 프로그램입니다.

노트:

  1. FileDescriptor에 번호를 전달하면 파일 이름을 전달하는 것과 같은 파일로 이론적으로 단지 훌륭하지만 때문에 파일 이름은 더 실용적인 <()당신에게 파일 이름이 아닌 FileDescriptor에 번호를 부여 (와 coproc의 당신이 표시 filedescriptors 제공 FD_CLOEXEC 그 filedescriptors이 컨텍스트에서 사용할 수 없게한다).

  2. /proc/sys/kernel/yama/ptrace_scope로 설정된 Linux 시스템 인 경우 0AFAIK 인 경우 동일한 사용자로 실행중인 다른 프로세스로부터 자신을 보호하는 방탄 방법은 없습니다 (ptrace를 사용하여 프로세스에 연결하고 메모리를 읽을 수 있음)

  3. 다른 (루트가 아닌) 사용자로 실행중인 프로세스에서 비밀번호를 멀리 유지해야하는 경우 인수, 환경 변수, 파이프 및 권한 보호 파일이 모두 수행됩니다.


답변

아니요, 환경 변수도 쉽게 읽을 수 있으며 자식 프로세스로 누출됩니다. 파이프를 사용하여 전달하십시오.


답변

다른 방법이 없다면 Linux Key Retention 서비스 (커널 키링)를 고려하십시오.

security / keys.txt 에서 시작하십시오 . 부모와 자식 프로세스간에 기본 키링 중 하나를 복제 할 수 있습니다.

가장 간단한 솔루션은 아니지만 유지 관리 및 사용되는 것처럼 보입니다 (작년에는 Android 버그에도 영향을 미쳤습니다).

나는 그것의 “정치적”지위에 대해 모른다. 그러나 나는 비슷한 요구를 가지고 있었고, Guile 바인딩 작업을 시작했다. 기존의 Perl 지원을받지 못했습니다.


답변