ssh-agent

GNU screen で ssh-agentを使うとおかしくなる問題から色々やってみた

新しくウィンドウを開くとssh-agentのソケット名が変わったりパスワードを入力するのが難しかったり期限切れにできなかったりと、色々大変である。

^A c でウィンドウ開いてssh host、直接screen ssh hostなどで、生存期間内ならパスフレーズなし、期限切れならそこで入力、としたい。

とりあえずssh-agentを使う方法とgpg-agentを使う方法があり、それぞれにsystemdを使う方法と.bashrcなどで自力でやる方法があったが、結局ssh-agentにした。

openssh-client=1:8.2p1-4
systemd=245.5-2

ssh-agent

生存期間を指定すると毎度ssh-addを動かさないといけなくなる。
色々悩んだ結果、sshのラッパー書くことにした。

#!/bin/sh
ssh-add -l > /dev/null || ssh-add -t 600
/usr/bin/ssh @$

ssh-agentをどこで起動するか、だが openssh-client パッケージにssh-agent.serviceがあるので利用する。
systemctl enable --user ssh-agent.service
すると、[Install]がないためenableにできない。
なので
systemctl edit --user ssh-agent.service

[Install]
WantedBy=default.target

を追加する。(新規ファイル)
その後
systemctl enable --user ssh-agent.service
で追加。新しくユーザーセッションが始まれば起動される。

あとは、SSH_AUTH_SOCKを固定にするため、.bashrcで指定する。

...
[ -z ”$PS1” ] && return
...
export SSH_AUTH_SOCK=/run/user/$(id -u)/openssh_agent
if [[ ! $TERM =~ screen*|dumb ]]; then
~/bin/ssh -V 2> /dev/null
screen -RR -D
fi

これで普通にログインするとssh-add用のパスワードを聞いてきた後、screenが立ち上がり、既にセッションがあればアタッチする。(-RDDオプション)
欠点はscreen動かしたくない時(コンソールとか)にも動いてしまうこと。
生存期間が過ぎていればパスワード入力時にctrl-Cで止めることは可能。

loginctl

テストしているとssh-agentがいっぱい動いたりキャッシュがあったりなかったりでよくわからなくなってくる。
そこで、
sudo loginctl terminate-user username
とすると、usernameのプロセスがまとめて消える。
(もちろんログアウトされる)

gpg-agent

gpg-agentはsudoのように認証後しばらく保持して、10分後に使うときは再度パスワードの入力を求める、などができるんだけど、このパスワード入力がpinentryを使用するのだが、これに問題がある。
どこに表示するか、をGPG_TTYに登録する必要があるのだが、screen上で
screen ssh server
などとやると新しい窓が開いてsshしようとするのだが、GPG_TTYが前の窓のままなので戻ってパスワードを入力する必要があったりする。
かつこのパスワード入力はCtrl-Cとか押すとその後表示がおかしくなったりそもそも中止できなかったり、どの窓で入力待ちをしているのかわからなくなったりで非常に使いづらい。
一応、やったことを残しておく。

...
[ -z ”$PS1” ] && return
...
if [ -x /usr/bin/gpg-agent ]; then
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye
export SSH_AUTH_SOCK=”$(gpgconf --list-dirs agent-ssh-socket)”
fi
pinentry-program /usr/bin/pinentry-tty
enable-ssh-support
default-cache-ttl       600
max-cache-ttl-ssh       1800

5月11日追記
~/bin/ssh みたいなことをしなくても、
~/.ssh/config に
AddKeysToAgent yesと書けばよかったみたい。
有効期限はssh-agentに-t 有効期限でいいようだ。

ssh-agent.serviceは、システムの物を再利用するより新しく作った方が良さげ。

[Unit]
Description=OpenSSH Agent
Documentation=man:ssh-agent(1)
Wants=dbus.socket
After=dbus.socket

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/openssh_agent
ExecStart=/usr/bin/ssh-agent -D -t 600 -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です