gnome-keyring-daemon 搭配 openssh

又是一個網路上搜尋到的資訊都不太對的問題。只有提 issue 的這邊寫得好些。

一開始是看著一堆沒加密的 ssh private keys 覺得不太舒服,想把他們通通加密起來。可 是重開機後第一次用要打密碼又很麻煩,就想搭配 gnome-keyring-daemon 使用,自動記 住密碼。本來以為是由於我的桌面環境不是標準的 Ubuntu 桌面才不會動,後來發現用標準 的登入也不行 (20.04 LTS)。

標準環境下

假設用標準環境,/usr/share/xsessions/ubuntu.desktop 長這樣:

1
2
3
4
5
6
7
8
9
[Desktop Entry]
Name=Ubuntu
Comment=This session logs you into Ubuntu
Exec=env GNOME_SHELL_SESSION_MODE=ubuntu /usr/bin/gnome-session --systemd --session=ubuntu
TryExec=/usr/bin/gnome-shell
Type=Application
DesktopNames=ubuntu:GNOME
X-GDM-SessionRegisters=true
X-Ubuntu-Gettext-Domain=gnome-session-3.0

看起來一部份是用 systemd 去跑 session. 看一下 /usr/lib/systemd/ 的確是這樣。 首先 user-preset/90-systemd.preset 裡面有

1
2
3
4
5
# Passive targets: always off by default, since they should only be pulled in
# by dependent units.

disable graphical-session-pre.target
disable graphical-session.target

圖形界面的東西預設是關的,在 user/gnome-session.target 裡面才又開起來:

1
BindsTo=graphical-session.target

接下來是 user/gnome-keyring-ssh.service 重點在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Unit]
Description=Start gnome-keyring as SSH agent
Before=graphical-session-pre.target ssh-agent.service
PartOf=graphical-session-pre.target

<snipped>

ExecStart=/bin/sh -ec 'if [ -z "${SSH_AUTH_SOCK}" ] && \
! grep -s -q X-GNOME-Autostart-enabled=false ~/.config/autostart/gnome-keyring-ssh.desktop /etc/xdg/autostart/gnome-keyring-ssh.desktop; then \
eval $$(/usr/bin/gnome-keyring-daemon --start --components ssh); \
dbus-update-activation-environment --verbose --systemd SSH_AUTH_SOCK=$$SSH_AUTH_SOCK SSH_AGENT_LAUNCHER=gnome-keyring; \
initctl set-env --global SSH_AUTH_SOCK=$$SSH_AUTH_SOCK || true; \
fi'
ExecStopPost=/bin/sh -ec 'if [ "${SSH_AGENT_LAUNCHER}" = gnome-keyring ]; then \
dbus-update-activation-environment --systemd SSH_AUTH_SOCK=; \
initctl unset-env --global SSH_AUTH_SOCK || true; \
fi'

所以要在圖形界面下,檢查 SSH_AUTH_SOCK 沒設定且 autostart 有開才會跑。於是把系 統的 gnome-keyring-ssh.desktop copy 到自家目錄 ~/.config/autostart 底下,並 且把裡面原本的 X-GNOME-Autostart-enabled=false 改為 true, 結果還是一樣不跑,可 見在此之前 ssh-agent 已經跑起來了。到 /etc/X11/Xsession.d 底下看到 90x11-common_ssh-agent 這個會先跑,導致後面進 gnome-session 時 SSH_AUTH_SOCK 已經設定了。這個要改 /etc/X11/Xsession.options 把裡面 use-ssh-agent comment 掉,之後就運作正常。

awesome desktop manager 環境下

沒有 systemd, 自己執行就行了。但內建的 awesome.desktop 就只是直接執行 awesome 而已,沒辦法先跑 gnome-keyring-daemon, 直接新增一個 desktop 檔自己來:

1
2
3
4
$ cat /usr/share/xsessions/xsession.desktop
[Desktop Entry]
Name=Xsession
Exec=/etc/X11/Xsession

注意 Xsession.options 裡面要有 allow-user-xsession. 接下來 ~/.xsession 簡 單寫就好:

1
2
3
4
5
6
7
8
9
#!/bin/bash

# /etc/X11/Xsession.d/55awesome-javaworkaround
_JAVA_AWT_WM_NONREPARENTING=1
export _JAVA_AWT_WM_NONREPARENTING

eval `gnome-keyring-daemon -s`
export SSH_AUTH_SOCK
exec awesome

搭配使用效果

首先把沒加密的 private key 都用 ssh-keygen -p 加密起來,然後實際使用它來連線, 例如 ssh -i .ssh/id_ed25519 之類的,這時 ssh 就會按照 SSH_AUTH_SOCK 裡面的設 定去問 keyring-daemon, daemon 就會跳一個圖形界面出來問密碼:

輸入密碼

把下面那個自動解鎖的選項打勾,密碼就會記到 keyring 裡面了。執行 seahorse 可以 看到目前列管的 ssh keypairs, 注意要在 ~/.ssh 目錄下 xxxxxx.pub 成對的 才會出現。