[GH-ISSUE #3884] ssh profile blocks access to ssh-agent with non-default socket location #2440

Closed
opened 2026-05-05 09:07:36 -06:00 by gitea-mirror · 8 comments
Owner

Originally created by @scruloose on GitHub (Jan 12, 2021).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3884

Bug and expected behavior

I have just installed firejail and run the auto-configurator with sudo firecfg. I have ssh-agent running (with a nonstandard socket location — which I believe is relevant). When I run ssh <host>, I'm prompted for the passphrase for my key every time, even though ssh-add -l shows the key is loaded, env shows the SSH-AUTH_SOCK variable is correctly set, and I have verified that the socket "file" exists. If I provide the passphrase, ssh connects as expected.

No profile and disabling firejail

  • What changed calling firejail --noprofile /path/to/program in a terminal?
    • When I call firejail --noprofile /usr/bin/ssh <host>, it uses the key from ssh-agent with no passphrase prompt and immediately presents the remote system's shell prompt, as expected.
  • What changed calling the program by path?
    • When I call ssh directly with /usr/bin/ssh <host>, it uses the key from ssh-agent with no passphrase prompt and immediately presents the remote system's shell prompt, as expected.

Reproduce

Steps to reproduce the behavior:

  1. With ssh-agent running and listening on a non-default socket location…
  2. Install Firejail
  3. Run sudo firecfg
  4. ssh-add your key if it's not already loaded
  5. In a bash terminal, try to ssh to a host that has public-key authentication set up

Environment

  • Linux distribution and version:
    Debian Bullseye, kernel 5.10.4
  • Firejail version:
    0.9.64

Additional context

  • When I try it with ssh -vvv, the output includes the following line:
    debug1: pubkey_prepare: ssh_get_authentication_socket: No such file or directory
  • It appears that the default ssh.profile includes an exception hardcoded to the default socket location:
    noblacklist /tmp/ssh-*
    But I don't see anything that takes the SSH_AUTH_SOCK environment variable and adds an exception for it.
  • My ssh-agent currently is not sandboxed. My existing configuration calls it by full path and I haven't yet updated that to point to the firejail symlink.

Checklist

  • [ ?] The upstream profile (and redirect profile if exists) have no changes fixing it.
    I don't actually know how to check this. I can tell you I haven't made any local changes to the profile.
  • [ Y] The program has a profile.
  • [ ?] A short search for duplicates was performed.
    Sorry, duplicates of what? Duplicate profiles for ssh? This is a perfectly stock install, with nothing customized yet.
  • [ N/A] If it is a AppImage, --profile=PROFILENAME is used to set the right profile.
    It's the official Debian repo ssh package, not an AppImage.
  • [ Y] Used LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 PROGRAM to get english error-messages.
    English UTF-8 is my system default language.
  • [ N/A] I'm aware of browser-allow-drm yes/browser-disable-u2f no in firejail.config to allow DRM/U2F in browsers.
    Never heard of it. However, I think DRM is a cancer, I already have it disabled in my browser, and my problem is not browser related. So I think we can safely rule this out.

debug output

I'll happily provide this if it's needed, but I'm reasonably sure the relevant details are already in "Additional Context" above.

Originally created by @scruloose on GitHub (Jan 12, 2021). Original GitHub issue: https://github.com/netblue30/firejail/issues/3884 **Bug and expected behavior** I have just installed firejail and run the auto-configurator with `sudo firecfg`. I have ssh-agent running (with a nonstandard socket location — which I believe is relevant). When I run `ssh <host>`, I'm prompted for the passphrase for my key every time, even though `ssh-add -l` shows the key is loaded, `env` shows the `SSH-AUTH_SOCK` variable is correctly set, and I have verified that the socket "file" exists. If I provide the passphrase, ssh connects as expected. **No profile and disabling firejail** - *What changed calling `firejail --noprofile /path/to/program` in a terminal?* * When I call `firejail --noprofile /usr/bin/ssh <host>`, it uses the key from ssh-agent with no passphrase prompt and immediately presents the remote system's shell prompt, as expected. - *What changed calling the program by path?* * When I call ssh directly with `/usr/bin/ssh <host>`, it uses the key from ssh-agent with no passphrase prompt and immediately presents the remote system's shell prompt, as expected. **Reproduce** *Steps to reproduce the behavior:* 1. With ssh-agent running and listening on a non-default socket location… 1. Install Firejail 2. Run `sudo firecfg` 3. `ssh-add` your key if it's not already loaded 4. In a bash terminal, try to ssh to a host that has public-key authentication set up **Environment** - *Linux distribution and version:* Debian Bullseye, kernel 5.10.4 - *Firejail version:* 0.9.64 **Additional context** * When I try it with `ssh -vvv`, the output includes the following line: `debug1: pubkey_prepare: ssh_get_authentication_socket: No such file or directory` * It appears that the default `ssh.profile` includes an exception hardcoded to the default socket location: `noblacklist /tmp/ssh-*` But I don't see anything that takes the `SSH_AUTH_SOCK` environment variable and adds an exception for it. * My `ssh-agent` currently is *not* sandboxed. My existing configuration calls it by full path and I haven't yet updated that to point to the firejail symlink. **Checklist** - [ ?] *The upstream profile (and redirect profile if exists) have no changes fixing it.* I don't actually know how to check this. I can tell you I haven't made any local changes to the profile. - [ Y] *The program has a profile.* - [ ?] *A short search for duplicates was performed.* Sorry, duplicates of what? Duplicate profiles for ssh? This is a perfectly stock install, with nothing customized yet. - [ N/A] *If it is a AppImage, `--profile=PROFILENAME` is used to set the right profile.* It's the official Debian repo `ssh` package, not an AppImage. - [ Y] *Used `LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 PROGRAM` to get english error-messages.* English UTF-8 is my system default language. - [ N/A] *I'm aware of `browser-allow-drm yes`/`browser-disable-u2f no` in `firejail.config` to allow DRM/U2F in browsers.* Never heard of it. However, I think DRM is a cancer, I already have it disabled in my browser, and my problem is not browser related. So I think we can safely rule this out. **debug output** I'll happily provide this if it's needed, but I'm reasonably sure the relevant details are already in "Additional Context" above.
Author
Owner

@kmk3 commented on GitHub (Jan 12, 2021):

Additional context

  • When I try it with ssh -vvv, the output includes the following line:
    debug1: pubkey_prepare: ssh_get_authentication_socket: No such file or directory

  • It appears that the default ssh.profile includes an exception hardcoded
    to the default socket location: noblacklist /tmp/ssh-* But I don't see
    anything that takes the SSH_AUTH_SOCK environment variable and adds an
    exception for it.

Indeed, ssh.profile only has an exception for the default path. If you use a
custom path, the usual way to allow it is to add an exception for it on
/etc/firejail/ssh.local or ~/.config/firejail/ssh.local. Example:

noblacklist /path/to/ssh_auth_sock

I don't think that there is any functionality implemented to create exceptions
based on the contents of a given environment variable (other than the ones that
are explicitly supported, such as ${HOME}. Though I must say that this would
be nice to have for things like $XDG_CONFIG_HOME.

Checklist

  • [ ?] The upstream profile (and redirect profile if exists) have no changes
    fixing it.
    I don't actually know how to check this. I can tell you I
    haven't made any local changes to the profile.

I think it means to check on the master branch if it has already been fixed:

https://github.com/netblue30/firejail/blob/master/etc/profile-m-z/ssh.profile

  • [ ?] A short search for duplicates was performed. Sorry, duplicates of
    what? Duplicate profiles for ssh? This is a perfectly stock install, with
    nothing customized yet.

It means to check for existing issues before potentially opening a duplicate.

<!-- gh-comment-id:759073908 --> @kmk3 commented on GitHub (Jan 12, 2021): > **Additional context** > > * When I try it with `ssh -vvv`, the output includes the following line: > `debug1: pubkey_prepare: ssh_get_authentication_socket: No such file or > directory` > > * It appears that the default `ssh.profile` includes an exception hardcoded > to the default socket location: `noblacklist /tmp/ssh-*` But I don't see > anything that takes the `SSH_AUTH_SOCK` environment variable and adds an > exception for it. Indeed, ssh.profile only has an exception for the default path. If you use a custom path, the usual way to allow it is to add an exception for it on /etc/firejail/ssh.local or ~/.config/firejail/ssh.local. Example: ```firejail noblacklist /path/to/ssh_auth_sock ``` I don't think that there is any functionality implemented to create exceptions based on the contents of a given environment variable (other than the ones that are explicitly supported, such as `${HOME}`. Though I must say that this would be nice to have for things like `$XDG_CONFIG_HOME`. > **Checklist** > > * [ ?] _The upstream profile (and redirect profile if exists) have no changes > fixing it._ I don't actually know how to check this. I can tell you I > haven't made any local changes to the profile. I think it means to check on the master branch if it has already been fixed: <https://github.com/netblue30/firejail/blob/master/etc/profile-m-z/ssh.profile> > * [ ?] _A short search for duplicates was performed._ Sorry, duplicates of > what? Duplicate profiles for ssh? This is a perfectly stock install, with > nothing customized yet. It means to check for existing issues before potentially opening a duplicate.
Author
Owner

@scruloose commented on GitHub (Jan 13, 2021):

Thanks for your quick response!

I don't know if it's obvious to everyone but me, or if it might be good to update the template to specify "duplicate issues"…?

Adding that line to ~/.config/firejail/ssh.local had no effect on its own. After also adding a whitelist rule (similar to the ones that get included via whitelist-runuser-common.inc) now ssh seems to be working as expected.

When I saw ${USER} and ${HOME} in that profile file, I kind of assumed that reading from arbitrary environment variables was supported. I can already see that it would be helpful to have that capability.

<!-- gh-comment-id:759528185 --> @scruloose commented on GitHub (Jan 13, 2021): Thanks for your quick response! I don't know if it's obvious to everyone but me, or if it might be good to update the template to specify "duplicate issues"…? Adding that line to `~/.config/firejail/ssh.local` had no effect on its own. After also adding a whitelist rule (similar to the ones that get included via `whitelist-runuser-common.inc`) *now* ssh seems to be working as expected. When I saw `${USER}` and `${HOME}` in that profile file, I kind of assumed that reading from arbitrary environment variables was supported. I can already see that it would be helpful to have that capability.
Author
Owner

@kmk3 commented on GitHub (Jan 14, 2021):

Thanks for your quick response!

No problem.

I don't know if it's obvious to everyone but me, or if it might be good to
update the template to specify "duplicate issues"…?

Will do that.

Adding that line to ~/.config/firejail/ssh.local had no effect on its own.
After also adding a whitelist rule (similar to the ones that get included via
whitelist-runuser-common.inc) now ssh seems to be working as expected.

Nice, I'm glad it worked.

When I saw ${USER} and ${HOME} in that profile file, I kind of assumed
that reading from arbitrary environment variables was supported.

Yeah, I was bit by this before as well. Not sure what is the best place for
documenting that though, so if anyone has any suggestions...

I can already see that it would be helpful to have that capability.

Agreed, though I'm not sure about the security/code complexity implications of
that. I'd suggest opening a feature request.

On a related note: Not sure if this helps the case, but the profiles are
currently able to set environment variables:

$ man firejail-profile | grep env
              Blacklist  /tmp/.X11-unix  directory,  ${HOME}/.Xauthority  and  file specified in ${XAUTHORITY} environment variable.  Remove DISPLAY and XAUTHORITY environment variables.
       env name=value
              Set environment variable. Examples:
              env LD_LIBRARY_PATH=/opt/test/lib
              env CFLAGS="-W -Wall -Werror"
<!-- gh-comment-id:759907751 --> @kmk3 commented on GitHub (Jan 14, 2021): > Thanks for your quick response! No problem. > I don't know if it's obvious to everyone but me, or if it might be good to > update the template to specify "duplicate issues"…? Will do that. > Adding that line to `~/.config/firejail/ssh.local` had no effect on its own. > After also adding a whitelist rule (similar to the ones that get included via > `whitelist-runuser-common.inc`) _now_ ssh seems to be working as expected. Nice, I'm glad it worked. > When I saw `${USER}` and `${HOME}` in that profile file, I kind of assumed > that reading from arbitrary environment variables was supported. Yeah, I was bit by this before as well. Not sure what is the best place for documenting that though, so if anyone has any suggestions... > I can already see that it would be helpful to have that capability. Agreed, though I'm not sure about the security/code complexity implications of that. I'd suggest opening a feature request. On a related note: Not sure if this helps the case, but the profiles are currently able to set environment variables: ```console $ man firejail-profile | grep env Blacklist /tmp/.X11-unix directory, ${HOME}/.Xauthority and file specified in ${XAUTHORITY} environment variable. Remove DISPLAY and XAUTHORITY environment variables. env name=value Set environment variable. Examples: env LD_LIBRARY_PATH=/opt/test/lib env CFLAGS="-W -Wall -Werror" ```
Author
Owner

@Lesstat commented on GitHub (Jan 14, 2021):

I just encountered the same bug and the whitelist rule explained above did fix it 👍 so kudos to you. Unfortunately, If the connection includes a Proxyjump I still get asked for my ssh passphrase. Any ideas how to fix this?

<!-- gh-comment-id:760050484 --> @Lesstat commented on GitHub (Jan 14, 2021): I just encountered the same bug and the whitelist rule explained above did fix it :+1: so kudos to you. Unfortunately, If the connection includes a Proxyjump I still get asked for my ssh passphrase. Any ideas how to fix this?
Author
Owner

@kmk3 commented on GitHub (Jan 14, 2021):

firejail's default ssh profile breaks my ssh-agent

@scruloose Could you change the title to something more specific? Example:

default ssh profile can't see my ssh-agent's custom auth socket path

@Lesstat commented 10 hours ago:

I just encountered the same bug and the whitelist rule explained above did
fix it +1 so kudos to you.

Since custom auth socket paths seem to be a thing, I'll add a comment about
them on ssh.profille (and possibly on allow-ssh.inc; see #3885). Would you
mind giving an example path and/or saying what is your use case for it?

Related to that, we are discussing1 2 further hardening ssh (TBD), so I'm
very interested in custom setups and whether that would break them. I'll
mention you both when the relevant PR is created.

Unfortunately, If the connection includes a Proxyjump I still get asked for
my ssh passphrase. Any ideas how to fix this?

This is a different problem, so please open a new issue.

<!-- gh-comment-id:760412503 --> @kmk3 commented on GitHub (Jan 14, 2021): > firejail's default ssh profile breaks my ssh-agent @scruloose Could you change the title to something more specific? Example: > default ssh profile can't see my ssh-agent's custom auth socket path @Lesstat commented 10 hours ago: > I just encountered the same bug and the whitelist rule explained above did > fix it +1 so kudos to you. Since custom auth socket paths seem to be a thing, I'll add a comment about them on ssh.profille (and possibly on allow-ssh.inc; see #3885). Would you mind giving an example path and/or saying what is your use case for it? Related to that, we are discussing[1] [2] further hardening ssh (TBD), so I'm very interested in custom setups and whether that would break them. I'll mention you both when the relevant PR is created. > Unfortunately, If the connection includes a Proxyjump I still get asked for > my ssh passphrase. Any ideas how to fix this? This is a different problem, so please open a new issue. [1]: https://github.com/netblue30/firejail/pull/3885#pullrequestreview-566865571 [2]: https://github.com/netblue30/firejail/pull/3885#issuecomment-759866475
Author
Owner

@scruloose commented on GitHub (Jan 17, 2021):

For my part, I'm using a systemd user service to manage my ssh-agent, mostly so it's available independent of my desktop environment and I don't have to worry about duplicate agent processes. As long as I continue to have at least one logged-in session — be it X11, Wayland, VT1, ssh in from remote, whatever — the same ssh-agent process stays available, even if the initial login session that triggered it has since logged out.

AFAIK, the expected location for ephemeral runtime files and sockets associated with systemd user services is $XDG_RUNTIME_DIR, which on my Debian systems is /run/user/$UID/, so that's where I put my ssh-agent's socket.

<!-- gh-comment-id:761717737 --> @scruloose commented on GitHub (Jan 17, 2021): For my part, I'm using a systemd user service to manage my ssh-agent, mostly so it's available independent of my desktop environment and I don't have to worry about duplicate agent processes. As long as I continue to have at least one logged-in session — be it X11, Wayland, VT1, ssh in from remote, whatever — the same ssh-agent process stays available, even if the initial login session that triggered it has since logged out. AFAIK, the expected location for ephemeral runtime files and sockets associated with systemd user services is `$XDG_RUNTIME_DIR`, which on my Debian systems is `/run/user/$UID/`, so that's where I put my ssh-agent's socket.
Author
Owner

@kmk3 commented on GitHub (Jan 20, 2021):

@scruloose changed the title

Thanks.

For my part, I'm using a systemd user service to manage my ssh-agent, mostly
so it's available independent of my desktop environment and I don't have to
worry about duplicate agent processes. As long as I continue to have at least
one logged-in session — be it X11, Wayland, VT1, ssh in from remote, whatever
— the same ssh-agent process stays available, even if the initial login
session that triggered it has since logged out.

Nice, I never thought about making user daemons survive session termination.

AFAIK, the expected location for ephemeral runtime files and sockets
associated with systemd user services is $XDG_RUNTIME_DIR, which on my
Debian systems is /run/user/$UID/, so that's where I put my ssh-agent's
socket.

That makes sense; I would also rather put sockets in there. Better user
isolation and less /tmp pollution. I wish that more tools would use
$XDG_RUNTIME_DIR for these things by default on Linux...

<!-- gh-comment-id:763315180 --> @kmk3 commented on GitHub (Jan 20, 2021): > @scruloose changed the title Thanks. > For my part, I'm using a systemd user service to manage my ssh-agent, mostly > so it's available independent of my desktop environment and I don't have to > worry about duplicate agent processes. As long as I continue to have at least > one logged-in session — be it X11, Wayland, VT1, ssh in from remote, whatever > — the same ssh-agent process stays available, even if the initial login > session that triggered it has since logged out. Nice, I never thought about making user daemons survive session termination. > AFAIK, the expected location for ephemeral runtime files and sockets > associated with systemd user services is `$XDG_RUNTIME_DIR`, which on my > Debian systems is `/run/user/$UID/`, so that's where I put my ssh-agent's > socket. That makes sense; I would also rather put sockets in there. Better user isolation and less /tmp pollution. I wish that more tools would use `$XDG_RUNTIME_DIR` for these things by default on Linux...
Author
Owner

@scruloose commented on GitHub (Jan 25, 2021):

Nice, I never thought about making user daemons survive session termination.

It does make some things much simpler. The behaviour I described, where user services persist as long as the user continues to have at least one active login session, is the systemd default. There's also a setting you can apply to users via the system systemctl instance, which IIRC is called "enable-linger", that allows that user's user systemd services to start at boot and survive until shutdown just like system services. I'm not sure whether it's possible for the user to then turn the lingering behaviour on and off for individual units, though, and generally I use system services that drop privileges via the User= and Group= directives for that kind of use-case.

I wish that more tools would use $XDG_RUNTIME_DIR for these things by default on Linux...

Yeah, me too. How does that old joke go? "The great thing about standards is there are so many to choose from, you can do whatever you want"…

<!-- gh-comment-id:767124099 --> @scruloose commented on GitHub (Jan 25, 2021): > Nice, I never thought about making user daemons survive session termination. It does make some things much simpler. The behaviour I described, where user services persist as long as the user continues to have at least one active login session, is the systemd default. There's also a setting you can apply to users via the system systemctl instance, which IIRC is called "enable-linger", that allows that user's user systemd services to start at boot and survive until shutdown just like system services. I'm not sure whether it's possible for the user to then turn the lingering behaviour on and off for individual units, though, and generally I use system services that drop privileges via the `User=` and `Group=` directives for that kind of use-case. > I wish that more tools would use `$XDG_RUNTIME_DIR` for these things by default on Linux... Yeah, me too. How does that old joke go? "The great thing about standards is there are so many to choose from, you can do whatever you want"…
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#2440
No description provided.