Bug 1285 - provide fallback options /etc/ssh/ssh_config
Summary: provide fallback options /etc/ssh/ssh_config
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: -current
Hardware: Other All
: P2 enhancement
Assignee: Damien Miller
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-02-14 01:26 AEDT by Joe Wells
Modified: 2021-09-25 02:57 AEST (History)
20 users (show)

See Also:


Attachments
Patch to address fallback options to SendEnv (2.06 KB, patch)
2013-09-17 10:05 AEST, Flavio Poletti
no flags Details | Diff
Add UnSendEnv option (1.71 KB, patch)
2013-11-16 02:03 AEDT, Damien Miller
no flags Details | Diff
SendEnv -PATTERN (2.17 KB, patch)
2018-04-06 15:30 AEST, Damien Miller
no flags Details | Diff
SendEnv -PATTERN (fixed) (2.29 KB, patch)
2018-04-06 15:33 AEST, Damien Miller
dtucker: ok+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joe Wells 2007-02-14 01:26:39 AEDT
If there is a SendEnv setting in the systemwide ssh_config file
(/etc/ssh/ssh_config on my system), there is no way to override this
in the per-user config file.

I'm using OpenSSH 4.2p1 on my machine, but I checked the source code
on WebCVS and the situation is the same in the most recent version.

I have a value for one of the LC_* environment variables that I want
to affect my local ssh client program, but which should _not_ be sent
to the remote server, because the value causes errors on other
machines.  The /etc/ssh/ssh_config file on my system has the line
"SendEnv LANG LC_*".  It seems the only way I can achieve the right
result is to edit /etc/ssh/ssh_config.  However, I do not have root
privileges on all machines where I have this problem, and anyway I do
not want to affect other accounts than my own.

Can a mechanism be added to allow removing patterns from the SendEnv
settings?  Perhaps "SendEnv" with no arguments should remove all
patterns.
Comment 1 Damien Miller 2007-05-18 09:35:10 AEST
The client configuration parsing always uses the first matching option so there are no overrides for things set in the global config. This is intentional: as a matter of policy, the master configuration file should be able to set options that can't be overridden.

Perhaps there should be some way for it to provide default options when none are set in any per-user file too. I'll change this bug to an enhancement request for this (I'm not convinced of the merits of this idea, but it should be tracked).
Comment 2 Joe Wells 2007-05-18 14:01:00 AEST
(In reply to comment #1)
> The client configuration parsing always uses the first matching option
> so there are no overrides for things set in the global config. This is
> intentional: as a matter of policy, the master configuration file
> should be able to set options that can't be overridden.

Some quick investigation reveals that the statement above is
contradicted by the documentation for ssh_config, which says:

     ssh obtains configuration data from the following sources in the following order:
           1.   command-line options
           2.   user's configuration file (~/.ssh/config)
           3.   system-wide configuration file (/etc/ssh/ssh_config)

Notice that the per-user file is consulted _before_ the systemwide
file.

I had not noticed this before.

> Perhaps there should be some way for it to provide default options when
> none are set in any per-user file too. I'll change this bug to an
> enhancement request for this (I'm not convinced of the merits of this
> idea, but it should be tracked).

There is no need to make the systemwide file /etc/ssh/ssh_config
supply defaults.  It turns out that this is already the case.

I now realize that the problem reported in this bug has _only_ to do
with directives where multiple uses of a directive are allowed.  The
problem happens for me because multiple SendEnv directives are used,
and their effect accumulates.  Other directives that allow multiple
uses with accumulating effects are LocalForward, DynamicForward,
IdentityFile, and RemoteForward.

My earlier proposed solution therefore would not work, because
removing items from the SendEnv settings at the time the per-user file
~/.ssh/config is read would not prevent the additional SendEnv
directive in the systemwide file /etc/ssh/ssh_config from modifying
things.

I don't know what to propose, but I think there is still a flaw.

I suggest the bug title be changed to something like this:

  flaw with multiple accumulating config directives in /etc/ssh/ssh_config 
Comment 3 Peter Valdemar Mørch 2009-02-27 03:48:42 AEDT
It is really quite simple. I'll try to be short:

I have an environment var, e.g. LC_PAPER set. I don't want to send it over ssh. This is *only* possible by removing LC_* from the default SendEnv line in /etc/ssh/ssh_config affecting all users and requiring root permissions (unless I'm mistaken).

Please provide non-root means to counter the SendEnv LC_* setting in root's /etc/ssh/ssh_config so the ssh client doesn't send LC_PAPER.
Comment 4 Ron Murray 2009-03-07 04:18:43 AEDT
I'm having problems with this too. I need to connect to a server that's so tightened down that it disconnects you when you send it anything it doesn't like. If OpenSSH has even the smell of SendEnv in a config file, I get a "Received disconnect from xxx.xxx.xxx.xxx: 7: Unsupported request (env).". 

I can, of course, specify a local config file containing that host with the -F option (and with SendEnv undefined), but it would be nice to have everything in the one config file.

Strangely, using the -F option seems to override the SendEnv specification in /etc/ssh/ssh_config.
Comment 5 Simon Vallet 2009-12-07 21:45:07 AEDT
I'm having the same problem here. Note that this potentially affects a large number of systems (e.g. HP iLO management interfaces -- cf. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=343896).
Comment 6 akostadinov 2012-10-10 18:27:53 AEDT
(In reply to comment #1)
...
> config. This is intentional: as a matter of policy, the master
> configuration file should be able to set options that can't be
> overridden.

I think this policy does not make any sense as well it is not executed really because if one supplies on command line -F, then the system wide config is ignored according to man page.

I propose that a new options is added to unset accumulative options like SendEnv such that one can disable them in ~/.ssh/config. Perhaps a special string used as pattern or a separate option, I don't know. But it should be possible.

Regards.
Comment 7 Yury V. Zaytsev 2013-04-16 16:54:11 AEST
I'd really like this implemented too. We have a wealth of Mac OS X hosts that are connecting to Linux machines and sending them bogus locale information, which triggers warnings all over the place.

For now the only possibility is to comment out SendEnv in the /etc/ssh/ssh_config files of the hosts, for which root access is required. It would be nice if we could just tell the users to edit their ~/.ssh/config: they have to customize it anyways to add specific host templates.

Maybe some special value like 'SendEnv none' that would trigger cancelling of all variables will do the trick?
Comment 8 Flavio Poletti 2013-09-17 10:05:50 AEST
Created attachment 2336 [details]
Patch to address fallback options to SendEnv

This patch allows the specification of negated patterns in SendEnv. Hence, you can set e.g.:

Host whatever
   SendEnv !LANG !LC_*

in your ~/.ssh/config file, and this will override (eliminating it) any global option like:

Host *
   SendEnv LANG LC_*

that might be inaccessible to non-root users.

The patch relies on the order of evaluation of the patterns to match. This assumes that the patterns from the user-local files are evaluated before global ones. This assumption is consistent with the behavior described in the documentation and should be safe to consider this as stable. This means that it is possible to set different negations with respect to the "direct" patterns:

Host my host
    SendEnv !*

The example above just disables sending any environment variable.

The patch is straightforward and might be adapted to other similar cases (LocalForward, DynamicForward, IdentityFile, and RemoteForward as pointed out by Joe Wells).
Comment 9 Halil Ozgur 2013-11-15 03:56:42 AEDT
OK. I'm really tired of software (or people?) not caring for the non-Latin languages or the languages that have a Latin alphabet but different rules. Here is a real problem that this bug (or rather, this bad default) has contributed part of it which actually caused production web sites not to respond, more than one time:

# From a host with "tr_TR.UTF-8" locale
ssh some_host
[root@some_host ~]# service php-fpm restart
# Website stops to respond (i.e. fatal error/white screen of death/etc)

This is because PHP also didn't really care about locales until version 5.5: https://bugs.php.net/bug.php?id=18556

The two bugs combined can mess up things real quick if you don't know where to look. OK, this one is actually a bad default rather than a bug IMO. Programs shouldn't try to change settings on remote hosts that can have side effects.

Therefore, the best fix IMO is not sending anything by default. Or should I report this to distribution maintainers? But not having the ability to disable this without editing some system config as root is also a problem.
Comment 10 Damien Miller 2013-11-16 02:03:24 AEDT
Created attachment 2375 [details]
Add UnSendEnv option

This adds an UnSendEnv option that allows cancelling SendEnv. It supports wildcards, so "UnSendEnv LC*" will cancel sending all environment variables starting with "LC".
Comment 11 akostadinov 2014-11-07 23:36:19 AEDT
Is this going to be merged?
Comment 12 Oded Arbel 2015-05-03 23:46:48 AEST
Guys, is this dead? If not, is there any chance to have this feature added to the OpenSSH source?
Comment 13 Nils Toedtmann 2015-08-19 00:09:33 AEST
We are affected as well and would like to see this problem solved, one way or the other, for all the reasons mentioned in this thread.
Comment 14 Damien Miller 2018-04-06 15:30:47 AEST
Created attachment 3138 [details]
SendEnv -PATTERN

Here's an improved diff. It makes it possible to remove previously-set SendEnv variables using "SendEnv -FOO"
Comment 15 Damien Miller 2018-04-06 15:33:49 AEST
Created attachment 3139 [details]
SendEnv -PATTERN (fixed)

improved diff
Comment 16 Darren Tucker 2018-04-06 19:50:54 AEST
Comment on attachment 3139 [details]
SendEnv -PATTERN (fixed)

had to read the "do not increment i" part a couple of times but makes sense now.
Comment 17 Damien Miller 2018-04-06 23:14:33 AEST
I've committed the "SendEnv -PATTERN" patch, but it doesn't resolve the other part of the original request - that there be an easy way to remove configuration that has been set by the system ssh_config after ~/.ssh/config has been set.

I'm not sure how best to do that generally, but it is possible now in a slightly non-obvious way: when CanonicalizeHostname is enabled, the configuration is parsed a second time and "match canonical" blocks are parsed last. It should be possible to use these to clear any environment variables that are undesired. Note that setting CanonicalizeHostname=yes without setting any CanonicalDomains is almost a no-op wrt hostname processing.

The root cause of this is that SendEnv differs from all (?) the other config options by being additive rather than first-match-wins. I'm not sure how fixable that is, since quite a few operating systems include multiple SendEnv in their default configurations and making SendEnv consider only the first matching directive would likely break them.

Maybe a proactive SendEnv ban like Flavio's patch is a good band-aid? Please let me know whether what has been committed will solve your current problems.
Comment 18 Roumen Petrov 2018-06-03 06:27:21 AEST
Proposed solution is not compatible with current configuration rules - quote "For each parameter, the first obtained value will be used." 
SendEnv is multi value keyword but it seems to me proposed correction allows administrator to clear all user settings with SendEnv -*.
As result the only solution is user to bay-pass system configuration using explicit configuration for example alias ssh="ssh -F ~/.ssh/config".

At runtime SendEnv is checked according 'simple' pattern. This model does not supports negated arguments.

There is another implementation "patern-list" with negated arguments.

Using  "patern-list"  user could setup configuration like "SendEnv  LANG,!*" and so first parameter will take precedence. 

May I request change in solution?
Comment 19 Damien Miller 2020-01-26 00:26:28 AEDT
OpenSSH implemented a "Match final" predicate in release 8.0 that supports last-choice fallback configuration.
Comment 20 Damien Miller 2021-04-23 15:10:23 AEST
closing resolved bugs as of 8.6p1 release
Comment 21 Domenico Andreoli 2021-09-24 21:27:24 AEST
It's not clear to me how to use the "Match final" predicate in order to stop /etc/ssh/ssh_config adding SenvEnv with vars that I already banned in my ~/.ssh/config.

Could you please make an example?