Bugzilla – Bug 1202475
ssh: users cannot override default SendEnv of package ssh_config
Last modified: 2022-08-18 10:27:12 UTC
There seems to be an embedded problem with SendEnv config option. The way that config is parsed, is that first encountered settings are taken from config files and the latter are suppose to be ignored. The config files are then parsed in such order 1. command line 2. user options 3. system config 4. package config Unfortunately, the SendEnv can be listed multiple times and options are concatenated. From ssh_config manpage, Multiple environment variables may be separated by whitespace or spread across multiple SendEnv directives. This then results in unable for users to override the default package config, My ~/.ssh/config contains, Host vs2 User adamm ... Host * User amajer SendEnv -* And the system config Host * SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT SendEnv LC_IDENTIFICATION LC_ALL So when I try to connect to vs2, I see this in the connection, debug1: Reading configuration data /home/adamm/.ssh/config debug1: /home/adamm/.ssh/config line 1: Applying options for vs2 debug1: /home/adamm/.ssh/config line 19: Applying options for * debug1: Reading configuration data /usr/etc/ssh/ssh_config debug1: /usr/etc/ssh/ssh_config line 19: include /usr/etc/ssh/ssh_config.d/*.conf matched no files debug1: /usr/etc/ssh/ssh_config line 25: include /etc/ssh/ssh_config.d/*.conf matched no files debug1: /usr/etc/ssh/ssh_config line 27: Applying options for * .... debug1: Sending environment. debug1: channel 0: setting env LANG = "en_US.UTF-8" I cannot seem to override the SendEnv in the system config since it's always going to be applied. Possible fixes for this would be, 1. only allow ONE SendEnv line to be present and take the first, consistent with rest of the configuration file, OR 2. take SendEnv lines from first encountered section that contains them and ignore future sections that have SendEnv In either case, upstream probably will need to be involved here. Affected systems are all SUSE and openSUSE systems as we are by default exporting parts of the environment. Overriding these defaults is impossible on TW as they become part of the package and not config files.
(In reply to Adam Majer from comment #0) > My ~/.ssh/config contains, > SendEnv -* > > > And the system config > > Host * > SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY > LC_MESSAGES The problem is that SendEnv -* clears previously set definitions and user configuration file is processed first. > > In either case, upstream probably will need to be involved here. > I have my doubts upstream is going to do anything, Default is to not send any environment, so if distribution forces SendEnv on users, it is not really upstream issue. The questions "how to override SendEnv" go back for years. What distribution could do - move SendEnv into /usr/etc/ssh/ssh_config.d/env.conf (pick your name) which will at least allow administrator to override it globally in /etc/ssh/ssh_config.d. It will will not allow per-user/per-host overrides though. We cannot even include per-user configuration file from within system wide configuration file to allow overrides. The only thing you really can do is to run "ssh -F" thus bypassing system wide configuration.
Looking at upstream ML, there seems to be some movement on this https://marc.info/?l=openssh-unix-dev&m=153069719521988 but there is opposition too, https://marc.info/?l=openssh-unix-dev&m=153070064923285 so I think the only way forward, is to have some sort of another special syntax where first matched section wins and then next sections are then ignored. Perhaps, SendEnv -* SOME_VAR1 SOME_VAR2 If a line contains -* pattern, then all following SendEnv are ignored and only this one line is then valid.. This would then allow for overrides while keeping almost complete backward compatibility with these multiple SendEnv nonsense.
I'll ask upstream
(In reply to Andrei Borzenkov from comment #1) > What distribution could do - move SendEnv into > /usr/etc/ssh/ssh_config.d/env.conf (pick your name) which will at least > allow administrator to override it globally in /etc/ssh/ssh_config.d. It > will will not allow per-user/per-host overrides though. > Scratch it, it will not work without changing how ssh processes its configuration files.
(In reply to Adam Majer from comment #3) > I'll ask upstream https://bugzilla.mindrot.org/show_bug.cgi?id=1285
(In reply to Andrei Borzenkov from comment #4) > (In reply to Andrei Borzenkov from comment #1) > > What distribution could do - move SendEnv into > > /usr/etc/ssh/ssh_config.d/env.conf (pick your name) which will at least > > allow administrator to override it globally in /etc/ssh/ssh_config.d. It > > will will not allow per-user/per-host overrides though. > > > > Scratch it, it will not work without changing how ssh processes its > configuration files. Sorry, messed up. It will work by allowing "SendEnv -*" in /etc to clear defaults in /usr/etc.
(In reply to Andrei Borzenkov from comment #4) > (In reply to Andrei Borzenkov from comment #1) > > What distribution could do - move SendEnv into > > /usr/etc/ssh/ssh_config.d/env.conf (pick your name) which will at least > > allow administrator to override it globally in /etc/ssh/ssh_config.d. It > > will will not allow per-user/per-host overrides though. > > > > Scratch it, it will not work without changing how ssh processes its > configuration files. I didn't look at the code, but it seems it just concatenates all the files and then parses them in sections that match the target host. This would be why it was relatively easy to adapt it for the /usr/etc/ + /etc/ split. Also, the Match final thing, it doesn't seem to work for this, I've added to local config, Match final SendEnv -LANG And I get, OpenSSH_8.9p1, OpenSSL 1.1.1p 21 Jun 2022 debug1: Reading configuration data /home/adamm/.ssh/config debug1: /home/adamm/.ssh/config line 1: Applying options for vs2 debug1: /home/adamm/.ssh/config line 19: Applying options for * debug1: Reading configuration data /usr/etc/ssh/ssh_config debug1: /usr/etc/ssh/ssh_config line 19: include /usr/etc/ssh/ssh_config.d/*.conf matched no files debug1: /usr/etc/ssh/ssh_config line 25: include /etc/ssh/ssh_config.d/*.conf matched no files debug1: /usr/etc/ssh/ssh_config line 27: Applying options for * debug1: configuration requests final Match pass debug1: re-parsing configuration debug1: Reading configuration data /home/adamm/.ssh/config debug1: /home/adamm/.ssh/config line 19: Applying options for * debug1: Reading configuration data /usr/etc/ssh/ssh_config debug1: /usr/etc/ssh/ssh_config line 19: include /usr/etc/ssh/ssh_config.d/*.conf matched no files debug1: /usr/etc/ssh/ssh_config line 25: include /etc/ssh/ssh_config.d/*.conf matched no files debug1: /usr/etc/ssh/ssh_config line 27: Applying options for * ... debug1: Sending environment. debug1: channel 0: setting env LANG = "en_US.UTF-8"
(In reply to Adam Majer from comment #7) > > Also, the Match final thing, it doesn't seem to work for this, > It works if you do not apply default block on rewrite bor@tw:~> diff -up /usr/etc/ssh/ssh_config /etc/ssh/ssh_config --- /usr/etc/ssh/ssh_config 2022-06-15 06:24:54.000000000 +0300 +++ /etc/ssh/ssh_config 2022-08-17 15:43:27.318585056 +0300 @@ -24,7 +24,7 @@ Include /usr/etc/ssh/ssh_config.d/*.conf # problems. Include /etc/ssh/ssh_config.d/*.conf -Host * +Match host * !final # ForwardAgent no # ForwardX11 no bor@tw:~> cat .ssh/config Match final SendEnv -* bor@tw:~> This may have some unexpected side effects though. https://bugzilla.mindrot.org/show_bug.cgi?id=2906
(In reply to Andrei Borzenkov from comment #8) > -Host * > +Match host * !final > # ForwardAgent no > # ForwardX11 no > > bor@tw:~> cat .ssh/config > Match final > SendEnv -* ok, but this looks very ugly.... the side effect is that configuration will be re-parsed every single time. I will have to test it to see if this will not cause some weird overrides and system defaults are preserved. Road to hell paved with good intentions and all that syntax. :-)
So, we can have the package config like, Host * stuff Match Host * !final SetEnv stuff in the config file. Then this would allow the env to be overriden in the Match final on user end without touching the rest of the config. Side effect it activates this re-parsing. I guess it's not too much overhead these days.
Brief checking on timing for this double parsing, double parsing due to the `Match final` involvement, basically doubles the parsing time of the config files. We go up from about 2ms to 4ms. The connection time to a nearby host (about 4ms away) was about 300ms in total. Actual CPU usage for the connection was about 70ms and it went up by 2ms due to the double parsing. Is this worth it to be able to override system configuration for SendEnv?