Discussion:
Conflicting TERM env var with SetEnv feature.
Raphael Medaer
2018-11-15 16:01:27 UTC
Permalink
Hi,

According to D. Miller's commit "add a SetEnv directive to ssh_config
that allows setting" (7082bb58a) we are now able to set remote
environment var from SSH client.

However I have an issue with env var "TERM". Indeed, ssh client is
already sending term through the session. Thus if I specify an other
TERM thourgh SetEnv (for instance "SetEnv TERM=xterm-256" in my SSH
config), this value will be overridden with my local TERM even if I
added TERM in "AcceptEnv" on server side. I guess because the session
is initialized a little bit later..

Here is some log..
```
$ cat <sshd log>
(...)
sshd[35546]: debug2: Setting env 0: LANG=en_US.UTF-8
sshd[35546]: debug3: receive packet: type 98
sshd[35546]: debug1: server_input_channel_req: channel 0 request env reply 0
sshd[35546]: debug1: session_by_channel: session 0 channel 0
sshd[35546]: debug1: session_input_channel_req: session 0 req env
sshd[35546]: debug2: Setting env 1: TERM=xterm-256color
sshd[35546]: debug3: receive packet: type 98
sshd[35546]: debug1: server_input_channel_req: channel 0 request shell reply 1
sshd[35546]: debug1: session_by_channel: session 0 channel 0
sshd[35546]: debug1: session_input_channel_req: session 0 req shell
sshd[35546]: Starting session: shell on pts/1 for remote-user from
127.0.0.1 port 56081 id 0
(...)

$ echo $TERM
rxvt-unicode-256color

$ cat /etc/ssh/sshd_config
(...)
# Allow client to pass locale environment variables
AcceptEnv LANG LC_* TERM
(...)
```

Don't know if I'm right but I would suggest one of the following fixes:

1. Fix in sshd (server side): I guess we can consider TERM env var
as de facto allowed var for sshd. Then in session we can skip setting
term from "session parameters" and use variable from SetEnv
2. Fix in ssh (client side - probably easier): If the TERM is set in
SetEnv, replace session term. => Not any change needed in server side.

I would enjoy to propose a patch if you agree ... with preference for (2) !

R. Medaer
Raphael Medaer
2018-11-16 14:02:15 UTC
Permalink
I'm not sure that it's wrong to allow an exant environment variable to
override a configuration setenv directive. It's a little like the "-o"
options can also override configuration directives.
Actually if you use "-o" it's also overridden. Looking at sshd
logging, it seems that the env var is overridden because of session
mechanism (aka "not ordering of parameter source").
Thus is it a non-issue due to priority of configuration source ? Does
it mean that the priority is "env var" > "cmd line arguments" >
"configuration directive" ?

If I well understand the logs, I assume it's a bug. Take a look at
this line "sshd[35546]: debug2: Setting env 1: TERM=xterm-256color".
It proves that sshd try to set the env var.

By the way, I'm pretty sure that "SetEnv" (via argument with "-o
SetEnv..." or via the configuration file) should override your local
(aka client) environment variables.

Kind regards,
David Newall
2018-11-16 15:24:10 UTC
Permalink
Post by Raphael Medaer
Actually if you use "-o" it's also overridden. Looking at sshd
logging, it seems that the env var is overridden because of session
mechanism (aka "not ordering of parameter source").
Thus is it a non-issue due to priority of configuration source ? Does
it mean that the priority is "env var" > "cmd line arguments" >
"configuration directive" ?
Tl;dr: you are right, and TERM is special.

Reading the source, I see that TERM is treated specially.  This is
explicit in ssh_config(5), which says, "Note that the TERM environment
variable is always sent whenever a pseudo-terminal is requested as it is
required by the protocol."

Whether or not the configuration should be able to force a different
TERM than the environment is a matter for debate. TERM is used far and
wide, and needs to be consistent with the actual terminal hardware, so
forcing its value in ssh's configuration file seems wrong.

Note, also, /etc/ssh/ssh_config is not *the* ssh configuration, merely
the default.  Any user can replace it with a file of their own choosing.
Philipp Marek
2018-11-22 11:39:45 UTC
Permalink
Post by David Newall
Post by Raphael Medaer
Actually if you use "-o" it's also overridden. Looking at sshd
logging, it seems that the env var is overridden because of session
mechanism (aka "not ordering of parameter source").
Thus is it a non-issue due to priority of configuration source ? Does
it mean that the priority is "env var" > "cmd line arguments" >
"configuration directive" ?
Tl;dr: you are right, and TERM is special.
Reading the source, I see that TERM is treated specially.  This is
explicit in ssh_config(5), which says, "Note that the TERM environment
variable is always sent whenever a pseudo-terminal is requested as it
is required by the protocol."
Whether or not the configuration should be able to force a different
TERM than the environment is a matter for debate. TERM is used far and
wide, and needs to be consistent with the actual terminal hardware, so
forcing its value in ssh's configuration file seems wrong.
Note, also, /etc/ssh/ssh_config is not *the* ssh configuration, merely
the default.  Any user can replace it with a file of their own choosing.
Yes.
But even ~/.ssh/config is not enough to override $TERM;
and if it happens that your local terminal emulation is not available
on the remote machine(s), what would be the right place to fix it?

Forcing the local commands to run with the minimum compatible terminal
emulation is bad; needing an alias or so to fix that isn't right either;
and having to change ~/.profile (or .bashrc etc.) on _all_ remote
machines doesn't sound like a nice solution, too.

For me, the sweet spot would be a "Match" block in ~/.ssh/config with a
"SetEnv" directive in it - but exactly that isn't possible right now...
David Newall
2018-11-23 00:03:56 UTC
Permalink
Post by Philipp Marek
if it happens that your local terminal emulation is not available
on the remote machine(s), what would be the right place to fix it?
Is it a trick question?  Isn't the remote machine the only place that
you can fix ?  Setting TERM on the local machine won't magically make a
Wyse 60 understand VT220 control codes.

Why not wrap ssh with a shell script to do what you want?
Philipp Marek
2018-11-23 06:32:02 UTC
Permalink
Post by David Newall
Post by Philipp Marek
if it happens that your local terminal emulation is not available
on the remote machine(s), what would be the right place to fix it?
Is it a trick question? 
No.

Modern "tmux" has a terminal type "tmux" (similar to screen),
but when SSHing into eg. a CentOS7 box this type is not available
- and so ncurses things (like an editor) get severely messed up.
Post by David Newall
Isn't the remote machine the only place that
you can fix ?
No. I offered several different ways to deal with that.
Post by David Newall
  Setting TERM on the local machine won't magically make
a Wyse 60 understand VT220 control codes.
No, but it's the easiest thing to do for mostly-compatible
terminals like screen, xterm, tmux, etc.
Post by David Newall
Why not wrap ssh with a shell script to do what you want?
Because that's another point that has to know which machine
I deal with. That means argument parsing compatible to SSH,
perhaps even knowing about SSH host aliases/redirects via
~/.ssh/config, and so on.
Having an SSH "Match" block seems to be the best solution
to me, followed by a check in the remote's .bashrc (which
would have to be duplicated on all affected hosts, and
removed again when an CentOS update allows to use "tmux"
there).

Furthermore, that "SetEnv" in ssh_config works for all but
one environment variable violates the principle of least
surprise, and so I'd consider that a bug in SSH.
Yeah, $TERM is special - but why not let the user override it?
Nicholas Marriott
2018-11-23 07:05:49 UTC
Permalink
Hi

terminfo and termcap database dissemination times are notoriously slow
so it is common for TERM to be set locally to something that doesn't
exist or doesn't work properly on a remote host.

For many years this was the case with OpenBSD which had ncurses 5.1 and
so an old xterm entry with no colour capabilities; xterm-new was needed
instead. Old versions of Solaris can be as bad if not worse, not to
mention embedded boxes which may have little more than dumb and vt220.

I think it would be much more convenient for users with multiple older
machines to put some Match sections in .ssh/config rather than modifying
their shell profiles on every host individually or faffing around with
scripts to wrap ssh.
Post by Philipp Marek
if it happens that your local terminal emulation is not available
on the remote machine(s), what would be the right place to fix it?
Is it a trick question?  Isn't the remote machine the only place that you
can fix ?  Setting TERM on the local machine won't magically make a Wyse 60
understand VT220 control codes.
Why not wrap ssh with a shell script to do what you want?
_______________________________________________
openssh-unix-dev mailing list
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Gert Doering
2018-11-23 07:15:30 UTC
Permalink
Hi,
Post by David Newall
Post by Philipp Marek
if it happens that your local terminal emulation is not available
on the remote machine(s), what would be the right place to fix it?
Is it a trick question?  Isn't the remote machine the only place that
you can fix ?  Setting TERM on the local machine won't magically make a
Wyse 60 understand VT220 control codes.
Stuff like TERM=screen can be substituted reasonably well with TERM=xterm,
for example. (I regularily run into this when ssh'ing to AIX boxes, which
do not know about "screen" - and since these are not mine, fixing all their
termcap/terminfo DBs is not trivially done).

So far I've never bothered to look into ssh automatically changing this
for me when I ssh to "these boxes", but I'm following the discussion with
interest :-)

gert
--
"If was one thing all people took for granted, was conviction that if you
feed honest figures into a computer, honest figures come out. Never doubted
it myself till I met a computer with a sense of humor."
Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany ***@greenie.muc.de
Jochen Bern
2018-11-23 12:41:57 UTC
Permalink
Post by Gert Doering
Stuff like TERM=screen can be substituted reasonably well with TERM=xterm,
for example. (I regularily run into this when ssh'ing to AIX boxes, which
do not know about "screen" - and since these are not mine, fixing all their
termcap/terminfo DBs is not trivially done).
If the problem is *that* systematic, wouldn't it be a better approach to
distribute something along the lines of



# Belt&suspenders in case we get executed from a *non*-interactive shell
if [ "$TERM" != "" -a "$TERM" != "dumb" ]; then
# Doublecheck that the termcap *still* hasn't been updated
tput init >/dev/null 2>&1
EXIT=$?
if [ $EXIT -ne 0 ]; then
# Non-understood $TERM. Try to switch to a working one.
# (*This* machine's "working ones" are hardcoded here!)
case $TERM in
screen) export TERM="xterm" ;;
# ... more ...
*) export TERM="dumb" ;;
esac
fi
fi



into the target accounts'/machines' ~/.bash_profile's, /etc/profile's,
/etc/profile.d/TERMfix.sh's, or what-have-you's?

Regards,
--
Jochen Bern
Systemingenieur

www.binect.de
www.facebook.de/binect
Raphael Medaer
2018-11-23 13:22:22 UTC
Permalink
TL;DR: I understand TERM is special but ... it should be special in a
sense that **by default** it uses the local TERM value ! Without
overriding it if I intentionally decide to change it in my config.
distribute something along the lines of (...) into the target accounts'/machines'
IMHO I don't think it's realistic to distribute/install your
"switching TERM procedure" on each remote host. It probably works if
you have 5-10 machines... not with thousands.

As Nicholas Marriott said,

it's
much more convenient for users with multiple older
machines to put some Match sections in .ssh/config rather than modifying
their shell profiles on every host individually or faffing around with
scripts to wrap ssh.
I fully agree with him. Furthermore, if your TERM is not recognized
remotely, it doesn't mean it is not compatible ! Thank's Gert Doering
for the example of TERM "screen" which can indeed be
substituted/simplified using "xterm". Btw, this is exactly the same
use-case in my first email.

My feeling is that your terminal is living locally on your local
machine. It has its own TERM value with its own feature set. When you
open a session on remote host, you always have the same terminal, with
same feature set. However if this TERM value is not recognized, bad
luck, you cannot use any feature even if a subset of them are
supported (with a compatible TERM value). You probably know that your
remote host is too old, so you should be able to set another
(compatible) TERM.

As far as I know you can do it with following tricks:

1. Changing your TERM locally then establish your SSH connection
-> you could automate it with an alias ... but you cannot switch
on target host ...

2. Establishing your SSH connection and then change your TERM.
If you do it in the remote shell...
-> I think it's hard to "automate" when you have a lot of host

If you do it though an argument of ssh command (for instance `ssh
host 'export TERM=...'`)
-> I think it's hard to "automate" when you often wrap the ssh command

3. Using SetEnv ?? ... without bug ?
Tl;dr: you are right, and TERM is special.
I understand TERM is special but ... it should be special in a sense
that **by default** it uses the local TERM value ! Without overriding
it if I intentionally decide to change it in my config.

Loading...