The secureSocket option, enabled by default, results in TMUX_TMPDIR being set to /run/user/$(id -u) — literally, with the command substitution not taking place. This prevents tmux from running, as /run/user/$(id -u) does not exist and the user does not have permission to create it.
Set programs.tmux.enable = true; in a plain nixos config. Log in as a regular user and try running tmux.
The tmux module doesn't really do anything a wrapper can't accomplish, so I personally think it should be removed and replaced with some wrapper generator that can be used on non-NixOS systems as well. Thoughts and feedback on this solution welcome! Do we have a general policy on this sort of thing?
Advantages of nixos module:
Advantages of wrapper generator:
"x86_64-linux"Linux 4.15.7, NixOS, 17.09.3129.1dcd022f01b (Hummingbird)yesyesnix-env (Nix) 2.0pre5889_c287d731"nixos-17.09.3129.1dcd022f01b"""/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgsThe only advantage of modules I see is typechecking though.
NixOS modules are super useful; the options are discoverable, documented, there's one config syntax for everything and users can be given some sane defaults and suggestions in the form of options on common settings they may want to change. They can be browsed on nixos.org by users before even installing.
To me it's a big selling point of NixOS, although I admit, I don't know much about the alternative you describe. Where do I find information about wrappers, how is a user meant to know one exists and does this type of wrapper have a more specific name that is more easily searched for, like "configuration wrapper"?
But back to the real issue.
How are you running tmux? Do you SSH, log on graphically or sudo to another user? You should not have permission to create /run/user/$(id -u), pam_systemd should do it for you, but that doesn't happen if you use su/sudo.
https://github.com/systemd/systemd/issues/7451#issuecomment-346787237
My set-environment has export TMUX_TMPDIR="${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"}" as intended and when I SSH to a user or log on graphically /run/user/$(id -u) is created. In this case everything works as expected:
$ ls /run/user
1000 1001
$ echo $TMUX_TMPDIR
/run/user/1001
$tmux
<tmux opens>
However when using su, it does not.
[root@nixos]$ su - user
[user@nixos:~]$ id -u
1000
[user@nixos:~]$ ls /run/user
0
[user@nixos:~]$ echo $TMUX_TMPDIR
/run/user/$(id -u)
[user@nixos:~]$ tmux
can't create socket: No such file or directory
Maybe rather the TMUX_TMPDIR envvar being set to XDG_RUNTIME_DIR option should be removed or not be default? As the description of secureSocket says:
Store tmux socket under /run, which is more secure than /tmp, but as a downside it doesn't survive user logout.
Just how insecure is using /tmp anyway? Is it worth the inconvenience of breaking normal use with su/sudo and having tmux sessions killed due to the deletion of /run/user/$(id -u) when the user session is closed? I'm sure both are the opposite of what users expect as a default from tmux running on Linux.
Using XDG_RUNTIME_DIR has been controversial with tmux developers and security was not cited as a reason even once.
https://github.com/tmux/tmux/issues/142
The problem is that in the absence of XDG_RUNTIME_DIR, ${XDG_RUNTIME_DIR:-"/run/user/\$(id -u)"} expands to /run/user/$(id -u), not to /run/user/1000. I don't really care about the details of how we solve it.
As for the module vs wrapper thing, I'm in favour of removing the module and replacing it with some machinery to generate a wrapper. So rather than
programs.tmux = {
enable = true;
extraConfig = ''
bind-key foo bar baz
set -g quux quuux
'';
};
You'd do
environment.systemPackages = [(
pkgs.tmux.withConfig {
extraConfig = ''
bind-key foo bar baz
set -g quux quuux
'';
})];
(modulo some changes with naming?)
This pattern already exists with programs such as vim and emacs.
The wrapper should also has some documentation somewhere, because wrapper are not self-documenting at the moment.
@lheckemann how did you fix this?
@jpotier as a workaround, set programs.tmux.secureSocket = false
Just how insecure is using /tmp anyway?
@yesbox systemd already creates private directories in /tmp, so if using /tmp with umask 077 is insecure, then tmux would be the least of our concerns. Principle of least surprise would dictate that programs.tmux.secureSocket = false by default.
[lemmarathon@nixos:~]$ ls -l /tmp
drwx------ 3 root root 60 Jun 25 22:00 systemd-private-cf199b0f312047138ef3c83ed3a3f878-systemd-timesyncd.service-aEyyKe
drwx------ 2 root root 60 Jun 25 23:14 tmux-0
drwx------ 2 lemmarathon lemmarathon 60 Jun 25 23:25 tmux-1004
@dguibert FYI, as a member of the nixos org, you can close issues with commits… Even if the commits aren't in the relevant repo, apparently >_< thanks github
@dguibert FYI, as a member of the nixos org, you can close issues with commits… Even if the commits aren't in the relevant repo, apparently >_< thanks github
Oups, yes thanks github...
BTW thanks for reopening this.
wasn't this fixed by https://github.com/NixOS/nixpkgs/pull/62136?
wasn't this fixed by #62136?
yes this fix the issue for me.
well, closing then :-)
Most helpful comment
@yesbox systemd already creates private directories in /tmp, so if using /tmp with umask 077 is insecure, then tmux would be the least of our concerns. Principle of least surprise would dictate that
programs.tmux.secureSocket = falseby default.