sshでPermission denined
普段Mac内でiTermなどターミナルを立ち上げて作業を行ってる時には問題ないんですが、
cronで予約しておいたジョブの中や
Macに外からsshで入って作業したりするときに、
gitコマンドを使ったりすると、
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
こんな感じのエラーが。 同時にMacの方でターミナルなどを立ち上げて直接試してみると問題なく接続できます。
GitHub関連で調べていたらこんなページを見つけたので
これに従い取り敢えずMacの中でssh -vT [email protected]してみると
$ ssh -vT [email protected]
...
debug1: identity file /Users/user/.ssh/id_dsa type 2
debug1: identity file /Users/user/.ssh/id_dsa-cert type -1
...
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /Users/user/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug1: Authentication succeeded (publickey).
...
と。何故かdsa鍵しか最初にみてませんが、最終的にrsa鍵で認証を通してます。
一方、外からssh(内部でssh localで入っても一緒の状態になりました)してからみると
$ ssh -vT [email protected]
...
debug1: identity file /Users/user/.ssh/id_dsa type 2
debug1: identity file /Users/user/.ssh/id_dsa-cert type -1
...
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /Users/user/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug1: Authentication succeeded (publickey).
な感じで失敗。
~/.ssh/にはid_rsaもあるのを確認した上で、~/.ssh/configを見ると
Host github
HostName github.com
IdentityFile ~/.ssh/id_rsa
User rcmdnk
Compression yes
の記述はあり、GitHubではrsa鍵を使ってたので良いと思ったんですが、
追記: 2014/04/30
そもそもこれも間違い。
Hostがgithubだけだとgithub.comに接続したときにこの部分も適用されません。
適用させるにはHost github.comとするかHost github*みたいにワイルドカードを使って
接続先のホスト名とマッチさせないといけません。
実際、上の状態でid_rsaをgithub_rsaとかに変更し、ファイルも移動させて試してみると
$ ssh -vT github.com
OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
debug1: Reading configuration data /Users/USER/.ssh/config
debug1: Reading configuration data /etc/ssh_config
Debug1: /etc/ssh_config line 20: Applying options for *
...
debug1: Trying private key: /Users/USER/.ssh/id_rsa
debug1: Trying private key: /Users/USER/.ssh/id_dsa
debug1: No more authentication methods to try.
Permission denied (publickey).
みたいな感じで~/.ssh/configからは何も読み取ってないし
キーもid_rsaの方を使ってます。
上の例では単にid_rsaとデフォルトのものを使ってたので通ってただけでした。。。
Host githubで通したいなら普段ssh接続するときも
git clone git@github:rcmdnk/...みたいにしないといけません(逆にこのようにalias的にできる)。
ついでに、普段はこの様にgitというユーザーで使いますし、
githu.comで指定してたらHostNameの意味はないので
Host github.com
IdentityFile ~/.ssh/github_rsa
だけでOK。id_rsaを使うならgithub自体の設定をconfigに書く必要もありません。
Compressionのオプションも環境によりますが、
よほど遅いネットワークでない限り気にすることないし
外しておいて良いかと。
(むしろ遅くなることもあるので)
追記ここまで
よく見たらその上の方に
Host *
Protocol 2
IdentityFile ~/.ssh/id_dsa
こんな記述が。。。昔どこかで使ったか、少なくとも今使っては居ないので、 なんかのテストで少し使っていたか、全く覚えてないですが、取り敢えずコメントアウト。 これが、ssh時にdsa鍵を強制してたのでいけなかったみたいで、 コメントアウトしたら外からsshした場合も
$ ssh -vT [email protected]
...
debug1: identity file /Users/user/.ssh/id_rsa type 1
debug1: identity file /Users/user/.ssh/id_rsa-cert type -1
debug1: identity file /Users/user/.ssh/id_dsa type 2
debug1: identity file /Users/user/.ssh/id_dsa-cert type -1
...
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /Users/user/.ssh/id_rsa
debug1: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
Enter passphrase for key '/Users/user/.ssh/id_rsa':
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
...
こんな感じでrsaキーを使ってOKに。 ただ、鍵にパスフレーズを入れてたみたいでこの場合パスフレーズを要求されました。 Mac内で行うときは聞かれない。
取り敢えずこれに関しては自分がおかしな設定残してただけで使えるようにはなったんですが、 なぜMac内で直接立ち上げたときは問題なかったのか意味不明だったのでちょっと調べてみることに。
Macでのssh-agent: launchdで立ち上げ
ssh-agentは特に気にしてなかったんですが、
Macではlaunchd
を採用していてこれでssh-agentも管理されています。
設定ファイルは
/System/Library/LaunchAgents/org.openbsd.ssh-agent.plist
ターミナルを起動するとSSH_AUTH_SOCKが
$ echo $SSH_AUTH_SOCK
/tmp/launchd-XXXXXX/Listeners
(XXXXXXの部分はランダムな文字列)と設定されてます。
追記: 2014/10/20
Mac OS X 10.10 Yosemiteからこのlaunchdのテンポラリーディレクトリの位置が変更されました。
追記ここまで
これでsshとかでこの値にアクセスしようとすると
ssh-agentが起動するようになってるようです
1。
さらに、この時に一度使った鍵のパスフレーズはKeyChainに保存される?ため
2
3
4
、
次回から起動した時は一度登録したパスフレーズは聞かれません。
で、上の場合Mac内ではssh-agentに鍵を最初の時に登録してあったのでパスフレーズも聞かれず上手く行ってた模様。
一方、外部からsshしたりしてSSH_AUTH_SOCKの値を見ると設定されてません。
これがどの部分で設定されてるかは結局良くわからなかったんですが、
取り敢えずこれが原因。
Macの方でこの値を取得して値だけ
$ export SSH_AUTH_SOCK=/tmp/launchd-XXXXXX/Listeners
とすれば、sshなどするときにssh-agentが自動で起動するようになりました。
SSH_AUTH_SOCKを自動で設定する
一番単純には/tmp/launchd*/Listenersを探して設定すればOK
5。
export SSH_AUTH_SOCK=`ls -tr /tmp/launchd*/Listeners|tail -n1`
たまに該当するファイルが複数できてる事があるので 時間的に最後の物を選択。
この辺、どこで設定されてるか探し当てられませんでしたが、Macでログインした時に 新しいものが出来る模様。(launchdを勉強すれば分かるのだろうか。。。? SSH_AUTH_SOCKもMacでログインした時に 全体の環境変数として設定されてる?ログアウトしてログインし直したり 6すると新しい物が出来る。単に時間が経っても出来る?)
さらに、たまに上の方法で探した最後の物が間違ってる場合もあり(他の物様に作られたもの?)、上手く行かない時があるんですが、
webで探すとssh-agentで使われてる物を直接探して
psから取ってきたり
7、
export SSH_AUTH_SOCK=`ps auxeww | grep ssh-agent | grep SSH_AUTH_SOCK | sed 's/.*SSH_AUTH_SOCK=//' | cut -f 1 -d ' '`
lsofで探してきたり
8
export SSH_AUTH_SOCK=`/usr/sbin/lsof | grep Listeners | grep ssh-agent | awk '{print $8}'`
するものがありましたが、
ssh-agentが走ってないと駄目なので、例えばMacでログインだけして、
一度もMac内のターミナルからsshなどを実行してない状況で
他からsshしてくるとこれらは使えません。
なので、
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
みたいな事を書いておくと正しい物を拾えます。
ただ、これでも、Macを起動しただけで一度もログインしてない状態だと
うまくいかないので、その時は自分で別途ssh-agentを立ち上げるように
すれば良いかも。
.bashrcを読み込んでるスクリプト起動時等に立ち上がるとパスフレーズを聞かれて止まってしまうので
.bash_profileの方に
1 2 3 4 5 6 7 8 9 | |
と、.bashrc読み込み後にSSH_AUTH_SOCKが設定されてない時に限り
ssh-agentを起動するように。
これだとssh-agentが増え続けるので、
1 2 3 | |
と言った感じでログアウト時にkillするようにしておきます。
ただ、Macをサーバーの様に外から再起動させてそのまま置いておく、
ということはまず無いので、後半はやり過ぎで
Listenersを探す程度にしておいて、
もし後半の様な状況で必要ならば手でssh-agentを起動する、
程度で良いかも。
ただし、
ssh-agent -lというMac特有のオプション?付きで起動: MacOSX & ssh-agent -l ↩普段ログインし直す必要なんて無いわけですが、LogMeInを使っていて、たまに調子悪いと勝手にログアウトしてしまうことがある。。。 ↩
where is SSH_AUTH_SOCK set?、
lsofの方は0.1秒程かかってちょっと遅い ↩
