Mehrere Login-Sessions auf einem Rechner: einen gemeinsamen gpg-agent oder pro Session einen eigenen? (was: Wie kann ich dem ssh-agent mitteilen, dass er sich beenden soll?)

Helmut Waitzmann nn.throttle at xoxy.net
Mo Dez 15 02:32:13 CET 2014


Mathias Bauer <mbauer at mailbox.org> writes:

> * Helmut Waitzmann schrieb am So, 14. Dez 2014, um 02:48 (+0100):
>
>> Mathias Bauer <mbauer at mailbox.org> writes:
>>
>> > * Helmut Waitzmann schrieb am Fr, 12. Dez 2014, um 20:18 (+0100):
>> >
>> > hier läuft
>> >   $ gpg-agent --version
>> >   gpg-agent (GnuPG) 2.0.19
>>
>> Bei mir ist es
>> $ gpg-agent --version
>> gpg-agent (GnuPG) 2.0.14
>>
>> > Ein TERM beendet den Agenten; bei drei TERMs oder einem INT
>> > geschieht das sofort (ohne Rücksicht auf Verluste).  Die
>> > Prozessnummer ist Teil von GPG_AGENT_INFO:
>> >   /path/to/socket/S.gpg-agent:12345:1
>>
>> [...]  und auch nicht, was geschieht, wenn im Socketnamen ein
>> Doppelpunkt enthalten ist.
>
> Was meinst Du damit?  

Mit Socketnamen meinte ich „/path/to/socket/S.gpg-agent“, nicht nur die
Komponente nach dem letzten „/“.

> Den Namen des Sockets, S.gpg-agent, kannst Du nicht vorgeben und er
> enthält auch nie einen Doppelpunkt.

Ja, ist mir klar. "${GNUPGHOME:-"${HOME}"/.gnupg}" kann aber
Doppelpunkte enthalten.

>> Mein ssh-agent weigert sich, das Socket anzulegen, wenn ich ihm
>> das Option „--use-standard-socket“ mitgebe und GNUPGHOME einen
>> „:“ enthält.  Soweit also keine Gefahr für mehr als 2 „:“ in
>> GPG_AGENT_INFO.  Nur das Handbuch schweigt halt dazu.
>
> Ich ordne mal ein wenig:
> - Du verwendest einen separaten SSH-Agenten und *nicht* gpg-agent
>   mit der Option --enable-ssh-support.
> - Was der SSH-Agent macht oder nicht, lassen wir jetzt erstmal
>   außen vor.

Autsch!  Das war ein Fehler von mir, habe ich doch tatsächlich „ssh-agent“
geschrieben, aber „gpg-agent“ gemeint.  Keine Ahnung, wie ich dazu kam,
wahrscheinlich, weil im gpg-agent‐Manual auch vom ssh-agent die Rede
ist.  Ich bitte um Verzeihung für die Verwirrung, die ich gestiftet
habe.  (Mir ist klar, dass man den gpg-agent auch die Dienste des
ssh-agent übernehmen lassen kann, wenn man --enable-ssh-support
verwendet.  Das habe ich aber nicht vor.)

> Wo kommen bei Dir denn Doppelpunkte in Pfaden oder Namen vor?

Momentan nicht.  Solange aber im gpg‐Manual nicht explizit steht, dass
"${GNUPGHOME:-"${HOME}"/.gnupg}" keinen „:“ enthalten darf, muss ich
damit rechnen, dass eines Tages jemand auf die Idee kommt, in eine der
Variablen HOME oder GNUPGHOME aus irgend einem Grund einen „:“ zu
stecken.  Jeder Account‐Inhaber ist frei, etwa HOME umzusetzen und
GNUPGHOME sowieso.  Und dann ergibt sich die Frage:  Wie wird
"${GNUPGHOME:-"${HOME}"/.gnupg}"/S.gpg-agent:12345:1 interpretiert, wenn
darin mehr als 2 „:“ enthalten sind?

> Welches OS/Distribution verwendest Du denn?  

Debian/Linux

> Startet man den gpg-agent mit der Option --use-standard-socket, erhält
> man
>
>    GPG_AGENT_INFO=/home/you/.gnupg/S.gpg-agent:12345:1
>
> Das kann man *nicht* machen, wenn das HOME-Verzeichnis per NFS
> importiert wird, was auch so dokumentiert ist:
>
>    This option may not be used if the home directory is mounted
>    on a remote file system...

Genau.  Und leider ist es auch nicht möglich, das Socket per symbolic
link oder gpg‐Konfiguration auf ein lokales Dateisystem umzusetzen, wenn
„--use-standard-socket“ verwendet werden soll.  Dann scheidet
„--use-standard-socket“ wohl aus und damit auch, wenn es nicht noch
andere Kniffe gibt, pro Rechner für alle Login‐Sessions eines Benutzers
dasselbe gpg-agent zu verwenden, dessen Start ich gpg2 überlassen könnte
und das ich nie beenden müsste.

>> > Das ganze Vorgehen ist abhängig davon, wie Deine Sessions
>> > gestartet werden, ob Konsole und/oder X, ob mehrere parallel,
>> > etc.
>>
>> Einen gpg-agent möchte ich bei jedem Einloggen zur Verfügung
>> haben, egal, ob auf der Konsole oder mit X11.
>
> Das funktioniert und ist auch kein Problem.  Starte einfach bei
> jeder Anmeldung einen neuen Agenten.  Schwierig wird es in den
> beiden folgenden Situationen:
>
> - Es soll ein und derselbe Agenten benutzt werden.
>
> - Für mehrere, auch parallel benutzte X- oder Konsole-Sessions
>   soll der Agent der *ersten* gestarteten Session für alle
>   anderen ebenfalls verwendet werden.
>
> Da muss man ganz genau analysieren an welcher Stelle, X und
> Konsole, der Agent jeweils gestartet wird, wo die
> Environment-Variablen wirken, etc. und das Ganze dann
> entsprechend modifizieren.

Ich gehe davon aus, dass es unmöglich ist, Umgebungsvariablen von einer
Sitzung zu einer anderen zu übermitteln, richtig?.  Dann erzwingt – so,
wie ich das verstehe – ein gemeinsames gpg-agent für alle Sitzungen auf
demselben Rechner, dass „--use-standard-socket“ verwendet wird, was aber
wegen NFS‐HOME ausgeschlossen ist, richtig?

> Du bist Dir im Klaren darüber, dass
> das u. U. tiefgreifende Änderungen im (Linux-)System erfordert?

Das möchte ich nach Möglichkeit vermeiden.

> Wenn ja, kannst Du beide Probleme mit der Option --write-env-file
> beheben.  Das wird sehr schnell sehr umfangreich werden...

> Mein Rat: Beschränke Dich auf die Skripte des jeweiligen
> Benutzers und lass die Finger von /etc/X11/Xsession.d/* - wenn Du
> Linux verwendest.  

Das sowieso.  gpg-Konfiguration sollte Benutzersache sein und deshalb
unter "${HOME}", nicht unter /etc stattfinden.

>> Ich hätte nichts dagegen, wenn es machbar wäre, auf jedem
>> Rechner, der das gemeinsame NFS‐HOME‐Verzeichnis nutzt, nur
>> einen gpg-agent für alle Sessions zu nutzen.
>
> Auf jedem Rechner jeweils pro Benutzer für alle Sessions jeweils
> nur einen Agenten zu verwenden funktioniert.  

Da wäre ich an Einzelheiten interessiert.

> NFS hat damit nichts zu tun.

NFS verbietet nur ein einfaches „--use-standard-socket“.

>> Das hätte den Vorteil, dass ich diesen einen gpg-agent nicht
>> beenden muss: Er soll ja sowieso für alle weitere Sessions
>> (egal, ob augenblickliche oder zukünftige) verwendet werden.
>> Das bedeutet aber, dass ich beim Einloggen nicht einfach einen
>> gpg-agent starten kann, denn es könnte ja bereits einer laufen.
>
> Ja.
>
>> Deswegen kann dann der Fall eintreten (wenn doch noch kein
>> gpg-agent läuft), dass gpg2 selber einen startet.  Weil ich
>> dabei aber keine Möglichkeit habe, "${GPG_AGENT_INFO}" an
>> andere bereits laufende Prozesse (etwa ein Mailerprogramm)
>> weiterzugeben,
>
> Doch, die hast Du, wenn Du früh genug in den Sessions eingreifst.

Wenn gpg2 (z.B. von Thunderbird aus) einen gpg-agent selber gestartet
hat, wie kommt dann ein zweites gpg2, das anschließend (z.B. von
Gnus/Emacs) gestartet wird, an die "${GPG_AGENT_INFO}"‐Daten des bereits
gestarteten Agents heran?

Oder gibt es die Möglichkeit, zu prüfen, ob bereits ein Agent läuft,
damit man beim Sessionstart genau dann einen startet, wenn noch keiner
läuft, um zu vermeiden, dass gpg2 selber einen startet?

Der Hinweis im Manual

   Note that by running gpg-agent without arguments you may test whether
   an agent is already running; however such a test may lead to a race
   condition, thus it is not suggested.

legt mir nahe, das sei nicht möglich.

>> müsste das Socket des von gpg2 gestarteten gpg-agents dann
>> immer an derselben Stelle im Dateisystem zu finden sein,
>
> Der Socket befindet sich immer auf dem jeweiligen Rechner in
> /tmp, nicht irgendwo per NFS.  (Ausnahme: --use-standard-socket)
> Du hast Recht, das Verzeichnis des Sockets ist nicht fix.  

Um es zu finden, könnte man „--write-env-file“ verwenden und hat aber dann
das Problem, dass die dort angegebene Datei für jeden Rechner an für ihn
individueller, aber fester, Stelle sein muss, weil auf jedem Rechner ein
eigenes gpg-agent laufen muss und daher eine eigene solche Datei
benötigt wird.

In der Datei "${GNUPGHOME:-"${HOME}"/.gnupg}"/gpg-agent.conf müsste dann
auf jedem Rechner, der diese Datei per NFS erhält, beim Option

   write-env-file FILE

für „FILE“ ein Dateiname stehen, der entweder in einem lokalen Dateisystem
liegt oder – wenn im NFS enthalten – den Rechnernamen enthält.

Können in "${GNUPGHOME:-"${HOME}"/.gnupg}"/gpg-agent.conf
Umgebungsvariable verwendet werden?  Ich habe dazu im Manual nichts
gefunden.

>> Also bleibt wohl nur die Vorgehensweise „für jedes
>> Login‐Session einen eigenen gpg-agent“: Weil dabei bei jedem
>> Login in jedem Fall ein gpg-agent gestartet wird, kann die von
>> ihm herausgegebene Umgebungsvariable GPG_AGENT_INFO einfach an
>> alle weiteren Prozesse des Sessions vererbt werden und es
>> entsteht auch nicht das Problem, dass gpg2 selber einen
>> gpg-agent startet.
>
> Entweder so (Du hast dann mehrere Agenten) 

und das Problem, die Agenten nicht vollständig race‐condition‐frei
beenden zu können

> oder Du prüfst beim Start jeder Session, ob bereits ein Socket läuft

Wie?

> und startetst ggf. einen neuen mit der Option --write-env-file.
>
> Wie schon oben angedeutet, ist diese Prüfung des springende
> Punkt.  Dafür musst man an mehreren Stellen des Startprozeders
> (Shell-Skripte!) eingreifen.  

Allen Login‐Vorgängen, egal, ob per login/getty oder Xsession, ist
gemeinsam, dass ein Login‐Shell gestartet wird.  Wäre damit
"${HOME}"/.profile nicht ein möglicher Startpunkt?

>> Ich habe durch Ausprobieren festgestellt: Die mit dem Option
>> „--write-env-file“ vom Agent erzeugte Umgebungsvariablen‐Datei
>> wird weder geleert noch entfernt, wenn sich der Agent nach
>> Empfang eines TERM‐Signals beendet.  Das Socket aber wird
>> entfernt.
>>
>> Kann ich daran, ob das in "${GPG_AGENT_INFO%:*:*}" genannte
>> Socket vorhanden ist, sehen, ob ein gpg-agent läuft?
>
> Ja, mit zusätzlichen Prüfungen wie meiner letzten E-Mail erwähnt.
> Die genügen für das XXL-Szenario (mehrere Sessions, parallel,
> etc.) natürlich nicht.

Traditionell sind mehrere Login‐Sessions in Unix kein Problem; auch X11
kommt damit zurecht.  Das soll, wenn irgend möglich, auch mit gpg-agent
nicht anders sein.

Das bedeutet:  Mehrere Sessions, die ich auf einem oder verschiedenen
Rechnern mit gemeinsamem, per NFS importiertem, HOME‐Verzeichnis
parallel starte, haben entweder pro Session oder pro Rechner einen
eigenen Agenten.

> Ich beende hier weder unter X noch auf der Konsole den Agenten
> automatisch.  Wenn man alle relevanten Möglichkeiten
> ausfallsicher abdecken möchte, ist das Starten dieses einen
> Agenten ausreichend umfangreich...

D.h., du verwendest für alle Sessions, die du auf einem Rechner
startest, einen gemeinsamen Agenten?  Wie findest du heraus, ob er
bereits läuft, wenn du ein Session startest?

Grüße, und vielen Dank für deine Mühe,

Helmut




Mehr Informationen über die Mailingliste Gnupg-de