Bug 1202475 - ssh: users cannot override default SendEnv of package ssh_config
Summary: ssh: users cannot override default SendEnv of package ssh_config
Status: NEW
Alias: None
Product: openSUSE Tumbleweed
Classification: openSUSE
Component: Basesystem (show other bugs)
Version: Current
Hardware: Other Other
: P5 - None : Normal (vote)
Target Milestone: ---
Assignee: Hans Petter Jansson
QA Contact: E-mail List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-17 09:21 UTC by Adam Majer
Modified: 2022-08-18 10:27 UTC (History)
1 user (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Majer 2022-08-17 09:21:11 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.
Comment 1 Andrei Borzenkov 2022-08-17 10:28:02 UTC
(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.
Comment 2 Adam Majer 2022-08-17 10:56:29 UTC
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.
Comment 3 Adam Majer 2022-08-17 11:25:53 UTC
I'll ask upstream
Comment 4 Andrei Borzenkov 2022-08-17 12:08:27 UTC
(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.
Comment 5 Andrei Borzenkov 2022-08-17 12:17:26 UTC
(In reply to Adam Majer from comment #3)
> I'll ask upstream

https://bugzilla.mindrot.org/show_bug.cgi?id=1285
Comment 6 Andrei Borzenkov 2022-08-17 12:18:12 UTC
(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.
Comment 7 Adam Majer 2022-08-17 12:34:14 UTC
(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"
Comment 8 Andrei Borzenkov 2022-08-17 12:46:50 UTC
(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
Comment 9 Adam Majer 2022-08-17 12:57:16 UTC
(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. :-)
Comment 10 Adam Majer 2022-08-17 13:01:29 UTC
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.
Comment 11 Adam Majer 2022-08-18 10:27:12 UTC
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?