최근에 나는 자동 시작(KDE)에 다음 스크립트를 추가했습니다:
eval `ssh-agent`
ssh-add
스크립트는 로그인 시 시작되어 비밀번호를 요청하고 키를 로드해야 합니다. 효과는 거의 완벽합니다. 스크립트가 올바르게 실행되고, 에이전트가 시작되고, 환경 변수가 모두 설정되고, 비밀번호를 묻는 메시지가 나타납니다. 유일한 문제는 이후에 키가 로드되지 않는다는 것입니다. 그러나 터미널에 ssh-add를 입력하면 비밀번호를 묻는 메시지가 나타나고 나머지 X 세션 동안 키가 저장됩니다.
내가 뭘 잘못했나요? 비밀번호를 입력하라는 요청에도 불구하고 키가 로드되지 않는 이유는 무엇입니까?
추신: 저는 Debian jessie를 사용하고 있습니다.
답변1
이 문제를 일으킬 수 있는 두 가지 시나리오를 생각해 볼 수 있습니다.
둘 다 많은 데스크탑 관리자가 자체 SSH 키 에이전트를 출시한다는 사실에서 비롯됩니다. 내보낸 변수를 가져오려면 데스크톱 관리자(터미널 에뮬레이터)에서 시작한 응용 프로그램이 데스크톱 관리자보다 먼저 에이전트를 시작해야 하기 때문에 이 작업이 수행됩니다.
데스크탑 관리자를 시작하면 데스크탑 관리자가 자체 SSH 에이전트를 시작하고 결국 이를 대체합니다.
SSH 에이전트를 언제 어떻게 시작하는지 잘 모르겠지만, 에이전트 다음에 Desktop Manager가 시작되면 내보낸 변수가 생성한 변수보다 우선 적용됩니다.
데스크탑 관리자는 사용자가 시작하기 전에 자체 SSH 에이전트를 시작하며 데스크탑 관리자는 유지되지 않습니다.
터미널 창을 시작하고 실행하면 터미널 창을 닫은 후에는
eval $(ssh-agent); ssh-add
내보낸 변수가 유지되지 않습니다 .ssh-agent
새 터미널 창을 시작하면 데스크탑 관리자가 시작한 SSH 에이전트가 설정한 변수를 얻게 됩니다.
작동 방식은 ssh-agent
백그라운드에서 데몬 프로세스를 시작한 다음 설정해야 하는 여러 변수를 인쇄하는 것입니다.
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-JLbBwVBP4754/agent.4754; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4755; export SSH_AGENT_PID;
echo Agent pid 4755;
따라서 을 설정할 때 eval $(ssh-agent)
이러한 변수를 모두 설정하면 됩니다.
이제 변수는 자식에게만 상속될 수 있으므로 데스크탑 관리자에서 변수를 유지하려면 데스크탑 관리자가 시작되기 전에 설정해야 합니다. 이는 올바르게 수행하기 어려울 수 있으며 배포판마다 다릅니다. 이것이 바로 많은 데스크톱 관리자가 스스로 이 작업을 수행하는 이유입니다.
이는 pam 스택 초기화 중에도 수행되는 경우가 있습니다.
답변2
Patrick이 지적했듯이 ssh-agent
데스크톱 환경에서 생성된 인스턴스와 경쟁할 수 있습니다. 글쎄, "경쟁"은 아마도 올바른 단어가 아닐 것입니다. 다른 애플리케이션이 에이전트와 대화할 수 있도록 하는 변수는 해당 환경에 있어야 합니다. 데스크톱 세션의 모든 애플리케이션은 데스크톱 환경의 일부(세션 관리자라고 가정)에 의해 어떤 방식으로든 생성되므로 먼저 변수를 세션 관리자의 환경 목록에 넣어야 합니다. 이는 두 가지 방법으로 발생할 수 있습니다.
세션 관리자는 이 작업을 내부적으로 수행합니다(어딘가에 설정한 일부 옵션에 따라 다름). 여기에는 PAM 모듈(로그인/세션 관리자에서 호출)에 의해 생성된 프록시가 포함됩니다.
귀하와 같은 사용자 스크립트를 통해. 그러나 이는 보기만큼 간단하지 않습니다. 세션 관리자가 스크립트를 실행할 때 스크립트 인터프리터라는 새로운 프로세스를 생성합니다. 변수는 해당 환경에 설정되어 있지만 세션 관리자(상위 프로세스)로 다시 쉽게 내보낼 수 없습니다. 이는 셸에서 동일한 작업을 수행하는 것과 동일합니다. 스크립트를 실행해도 현재 셸 환경에는 아무런 영향이 없습니다. 이렇게 해야 합니다
source
. 그러면 현재 셸에서 명령이 실행되어 업데이트/생성된 변수에 액세스할 수 있습니다. 세션 관리자에서 이 작업을 수행하는 것은 매우 복잡합니다(셸 인터프리터가 아니기 때문에). 그래서 당신ssh-agent
은 실제로 경쟁하고 있지 않습니다. 단지ssh-add
스크립트에서 로드된 ID 와 함께 거기에 있을 뿐이고 실제로 그것에 대해 아는 사람은 아무도 없습니다.
무슨 일이 일어나고 있는지 이해하려면 1의 출력을 확인하세요.
ps fax | grep -E "(ssh|gpg)-[a]gent"
스크립트를 다음으로 변경하십시오.
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > ~/ssh-agent.stdout
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> ~/ssh-agent.stdout
eval `ssh-agent | tee -a ~/ssh-agent.stdout`
이는 변수의 내용을 파일로 인쇄한 다음 ~/ssh-agent.stdout
처리하기 전에 해당 위치에 출력을 추가합니다 ssh-agent
(따라서 변수를 내보냅니다) . 파일 내용을 새로 생성된 쉘 터미널과 같은 환경 변수 SSH_AUTH_SOCK
와 비교합니다. SSH_AGENT_PID
대부분의 경우 PID가 (주기적으로) 단조롭게 증가하기 때문에 어느 것이 먼저 시작되었는지 알 수 있습니다. 이 섹션은 일부 DE가 gpg-agent
SSH 프록시 서비스를 제공하는 기능도 사용하기 때문에 존재합니다.gpg-agent
라인 호출을 완전히 제거 할 수도 있습니다 ssh-agent
. SSH 에이전트가 데스크탑 환경을 생성한 후 스크립트가 실행되면 환경 변수가 있기 때문에 비밀번호 대화 상자(올바른 에이전트에 대한)가 표시됩니다. 그렇지 않은 경우 스크립트가 DE의 프록시 인스턴스보다 먼저 실행 중이므로 프록시에 전혀 액세스할 수 없음을 의미합니다.
1개의 괄호는영리한 트릭grep
프로세스 목록에서 자신을 제거합니다.