Bug 1630166 - crypto-policies trump post-canonicalization ssh settings
Summary: crypto-policies trump post-canonicalization ssh settings
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: openssh
Version: 28
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jakub Jelen
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-09-18 06:21 UTC by Maciej Żenczykowski
Modified: 2019-02-13 11:26 UTC (History)
11 users (show)

Fixed In Version: openssh-7.9p1-4.fc29
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-02-13 02:47:10 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Maciej Żenczykowski 2018-09-18 06:21:48 UTC
# rpm -q --whatprovides /etc/ssh/ssh_config
openssh-clients-7.8p1-2.fc28.x86_64

# rpm -q --whatprovides /etc/ssh/ssh_config.d/05-redhat.conf
openssh-clients-7.8p1-2.fc28.x86_64

# rpm -q --whatprovides /etc/crypto-policies/back-ends/openssh.config
crypto-policies-20180425-5.git6ad4018.fc28.noarch

# cat ~/.ssh/config 
Host *
  CanonicalizeHostname always
  CanonicalizeMaxDots 0
  CanonicalizeFallbackLocal no
  CanonicalDomains foo.org
  VerifyHostKeyDNS yes

Host router.foo.org
  KexAlgorithms +diffie-hellman-group1-sha1

# egrep -v '^#|^$' < /etc/ssh/ssh_config
Include /etc/ssh/ssh_config.d/*.conf

# egrep -v '^#|^$' < /etc/ssh/ssh_config.d/05-redhat.conf 
Include /etc/crypto-policies/back-ends/openssh.config

Host *
        GSSAPIAuthentication yes
        ForwardX11Trusted yes
        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 LANGUAGE
        SendEnv XMODIFIERS

# egrep -v '^#|^$' < /etc/crypto-policies/back-ends/openssh.config
Ciphers aes256-gcm,chacha20-poly1305,aes256-ctr,aes256-cbc,aes128-gcm,aes128-ctr,aes128-cbc
MACs hmac-sha2-256-etm,hmac-sha1-etm,umac-128-etm,hmac-sha2-512-etm,hmac-sha2-256,hmac-sha1,umac-128,hmac-sha2-512
GSSAPIKexAlgorithms gss-gex-sha1-,gss-group14-sha1-
KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1

# ssh -v router
OpenSSH_7.8p1, OpenSSL 1.1.0h-fips  27 Mar 2018
debug1: Reading configuration data /root/.ssh/config
debug1: /root/.ssh/config line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/05-redhat.conf
debug1: Reading configuration data /etc/crypto-policies/back-ends/openssh.config
debug1: /etc/ssh/ssh_config.d/05-redhat.conf line 8: Applying options for *
debug1: Canonicalized hostname "router" => "router.foo.org"
debug1: Re-reading configuration after hostname canonicalisation
debug1: Reading configuration data /root/.ssh/config
debug1: /root/.ssh/config line 1: Applying options for *
debug1: /root/.ssh/config line 11: Applying options for router.foo.org
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/05-redhat.conf
debug1: Reading configuration data /etc/crypto-policies/back-ends/openssh.config
debug1: /etc/ssh/ssh_config.d/05-redhat.conf line 8: Applying options for *
debug1: Connecting to router.foo.org [192.168.1.2] port 22.
debug1: Connection established.
...
debug1: Local version string SSH-2.0-OpenSSH_7.8
debug1: Remote protocol version 2.0, remote software version dropbear_0.51
debug1: no match: dropbear_0.51
debug1: Authenticating to router.foo.org:22 as 'root'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: (no match)
Unable to negotiate with 192.168.1.2 port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1

So as you can see the cryptopolicy 'KexAlgorithms' for * took effect prior to canonicalization and the custom override.
As a result connection failed to establish.

Should 'Host *' actually be 'Match canonical all' ?

Comment 1 Tomas Mraz 2018-09-18 06:29:39 UTC
Jakub, can you please look at this?

Comment 2 Maciej Żenczykowski 2018-09-18 06:33:26 UTC
btw. I've verified that:

# egrep -v '^#|^$' < /etc/ssh/ssh_config.d/05-redhat.conf
Match canonical all
Include /etc/crypto-policies/back-ends/openssh.config
Match canonical all
        GSSAPIAuthentication yes
        ForwardX11Trusted yes
        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 LANGUAGE
        SendEnv XMODIFIERS

fixes the problem if canonicalization is turned on.
(not clear if it should be 'Match canonical' or 'Match canonical all')

But I'm not sure if it triggers correctly, and I'm not sure if it triggers at all if canonicalization is off.

Perhaps this is less a crypto-policies problem and more an openssh config parsing problem...

Perhaps the real problem is how it handles:
  keyword +opt
and
  keyword -opt
which you would expect to append/remove even after prior matches...

Obviously I can fix this via:

# cat ~/.ssh/config 
...
Host router router.foo.org
  KexAlgorithms +diffie-hellman-group1-sha1

but then I'm probably no longer getting the crypto-policy + diffie-hellman-group1-sha1 and am instead probably getting ssh's builtin + diffie-hellman-group1-sha1 instead...

Comment 3 Maciej Żenczykowski 2018-09-18 06:43:40 UTC
Or maybe there should be a keyword to do canonicalization right now and not parse any more files?

ie. perhaps we should have:

# cat /etc/ssh/ssh_config:
IfFirstPassOfCanonicalizationThenStartFromScratch
Include /etc/ssh/ssh_config.d/*.conf


or perhaps we need a

Match canonical_or_not_canonicalizing

instead of 'Host *'

Comment 4 Jakub Jelen 2018-09-18 08:11:36 UTC
> Perhaps the real problem is how it handles:
>   keyword +opt
> and
>   keyword -opt
> which you would expect to append/remove even after prior matches...

Unfortunately, this is a limitation of the ssh_config parser in openssh, which works for most common cases, but there are some corner cases.

Personally, I do not use the canonicalization, but I know it is very cumbersome in many cases

Your proposed solution with `Match canonical all`, will probably not work, since this will avoid matching with canonicalization turned off:

> The canonical keyword matches only when the configuration file is being re-parsed after hostname canonicalization [...]

And we really do not want to turn the canonicalization by default, since it brings many unexpected issues out of the box.

> Obviously I can fix this via:

> # cat ~/.ssh/config 
> ...
> Host router router.foo.org
>   KexAlgorithms +diffie-hellman-group1-sha1

> but then I'm probably no longer getting the crypto-policy + diffie-hellman-group1-sha1 and am instead probably getting ssh's builtin + diffie-hellman-group1-sha1 instead...

I would say that this is preferred way -- you basically create an exception from crypto policy for this device, since the per-user configuration file has higher priority.

Introducing different canonicalization options would make it even more complicated than it is now.

Let me know if there is anything I can do for you in this way.

Comment 5 Maciej Żenczykowski 2018-09-18 09:04:37 UTC
Seems like there really should be a 'Match finalpass' to replace the 'Host *'.  But I guess that would be an upstream openssh feature request?

Comment 6 Jakub Jelen 2018-09-18 09:16:58 UTC
Yes. If you can summarize the issue about the canonization in the upstream bugzilla https://bugzilla.mindrot.org/ it would be best since you have the first-hand experience with the canonicalization.

Comment 7 Maciej Żenczykowski 2018-09-18 09:28:05 UTC
Done: https://bugzilla.mindrot.org/show_bug.cgi?id=2906

Comment 8 Fedora Update System 2018-10-19 11:07:34 UTC
openssh-7.9p1-1.fc29 has been submitted as an update to Fedora 29. https://bodhi.fedoraproject.org/updates/FEDORA-2018-5be740cab4

Comment 9 Fedora Update System 2018-10-20 19:24:10 UTC
openssh-7.9p1-1.fc29 has been pushed to the Fedora 29 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-5be740cab4

Comment 10 Jakub Jelen 2018-10-22 10:29:48 UTC
oh .. this did not make it to the release. Reverting the state back.

Comment 11 Maciej Żenczykowski 2018-11-23 06:50:24 UTC
https://bugzilla.mindrot.org/show_bug.cgi?id=2906 is marked resolved.

Damien Miller 2018-11-23 16:09:45 EST
This has been committed and, barring catastrophe, will be in OpenSSH 8.0.

commit 9e34e0c59ab04514f9de9934a772283f7f372afe (HEAD -> master, origin/master, origin/HEAD)
Author: djm <djm>
Date:   Fri Nov 23 05:08:07 2018 +0000

    upstream: add a ssh_config "Match final" predicate
    
    Matches in same pass as "Match canonical" but doesn't require
    hostname canonicalisation be enabled. bz#2906 ok markus
    
    OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa

Comment 12 Jakub Jelen 2018-11-23 09:13:04 UTC
Did you verify that the applied patch solves your problem? If so, I can try to backport it to the current version.

Comment 13 Maciej Żenczykowski 2018-11-24 09:37:44 UTC
Yes, I confirm it works.

Now running:
  openssh.x86_64 7.9p1-2mz.fc29
  openssh-clients.x86_64 7.9p1-2mz.fc29
  openssh-server.x86_64 7.9p1-2mz.fc29

Built via:
  mkdir -p /root/rpmbuild/openssh
  cd /root/rpmbuild/openssh

  git clone https://github.com/openssh/openssh-portable.git
  cd openssh-portable/
  git show 9e34e0c59ab04514f9de9934a772283f7f372afe > ../openssh-7.9p1-final-pass.patch
  cd ..
  rm -rf openssh-portable/

# apply the spec file diff below, and manually remove the $Id$ chunks out of the patch

  cd /root/rpmbuild/SPECS
  rpmbuild -ba openssh.spec

# Finally fixup /etc/crypto-policies/back-ends/openssh.config to look like:

Match final
  Ciphers ...  
  MACs ...
  ...etc...

[root@sky SPECS]# diff -Naur openssh.spec_ openssh.spec
--- openssh.spec_       2018-11-23 23:28:32.365065119 -0800
+++ openssh.spec        2018-11-23 23:33:05.296161170 -0800
@@ -66,7 +66,7 @@
 
 # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
 %global openssh_ver 7.9p1
-%global openssh_rel 2
+%global openssh_rel 2mz
 %global pam_ssh_agent_ver 0.10.3
 %global pam_ssh_agent_rel 6
 
@@ -226,6 +226,10 @@
 # Allow to disable RSA signatures with SHA-1 in server
 # https://bugzilla.mindrot.org/show_bug.cgi?id=2746
 Patch954: openssh-7.9p1-disable-sha1.patch
+# Add support for 'match final' predicate
+# https://bugzilla.redhat.com/show_bug.cgi?id=1630166
+# https://bugzilla.mindrot.org/show_bug.cgi?id=2906
+Patch999: openssh-7.9p1-final-pass.patch
 
 License: BSD
 Group: Applications/Internet
@@ -450,6 +454,7 @@
 %patch953 -p1 -b .scp-ipv6
 %patch808 -p1 -b .gsskex-method
 %patch954 -p1 -b .disable-sha1
+%patch999 -p1 -b .patch-final
 
 %patch200 -p1 -b .audit
 %patch201 -p1 -b .audit-race

Comment 14 Jakub Jelen 2019-01-14 10:47:43 UTC
*** Bug 1438326 has been marked as a duplicate of this bug. ***

Comment 15 Fedora Update System 2019-01-14 16:07:50 UTC
openssh-7.9p1-3.fc29 has been submitted as an update to Fedora 29. https://bodhi.fedoraproject.org/updates/FEDORA-2019-f6ff819834

Comment 16 Fedora Update System 2019-01-15 02:23:33 UTC
openssh-7.9p1-3.fc29 has been pushed to the Fedora 29 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2019-f6ff819834

Comment 17 Maciej Żenczykowski 2019-01-15 08:49:39 UTC
Unfortunately:

  dnf --enablerepo updates-testing upgrade openssh\*

doesn't find anything to upgrade (and I'm thus still at openssh-clients-7.9p1-2.fc29.x86_64).

Do note though that at *least* the /etc/ssh/ssh_config.d/05-redhat.conf file needs to be changed from 'Host *' to 'Match final'.

Comment 18 Jakub Jelen 2019-01-15 09:48:16 UTC
It was not clear to me that the /etc/ssh/ssh_config.d/05-redhat.conf needs to be changed to Match final too. I will do that with the next update. I will drop this bug from the bodhi update for now. Sorry for a delay.

Comment 19 Rob Foehl 2019-01-16 05:22:22 UTC
Changing the "Host *" in /etc/ssh/ssh_config.d/05-redhat.conf alone won't help with the separate issue of bare directives in /etc/crypto-policies/back-ends/openssh.config as currently used.  Two separate changes are necessary to solve the two separate problems in this bug and bug 1438326.

To do this without changes to crypto-policies, the 05-redhat.conf file needs to be updated like this, in its entirety:

# Uncomment this if you want to use .local domain
# Host *.local
#   CheckHostIP no

Match final all
	GSSAPIAuthentication yes

# If this option is set to yes then remote X11 clients will have full access
# to the original X11 display. As virtually no X11 client supports the untrusted
# mode correctly we set this to yes.
	ForwardX11Trusted yes

# Send locale-related environment variables
	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 LANGUAGE
	SendEnv XMODIFIERS

# Follow system-wide Crypto Policy, if defined:
	Include /etc/crypto-policies/back-ends/openssh.config



The two important changes are replacing "Host *" with "Match final all" (which is not the same thing as "Match final", please stop conflating the two) and moving the crypto policy include to within that group of directives.  See ssh_config(5) for descriptions of the order in which directives apply, and for use of Include following Host/Match directives.

Comment 20 Maciej Żenczykowski 2019-01-16 12:46:30 UTC
Care to explain how 'Match final' and 'Match final all' differ? I'm confused.

Comment 21 Jakub Jelen 2019-01-23 17:34:33 UTC
Rob, I would be also interested in hearing what is difference between `Match final` and `Match final all`. The manual page is not very clear in this way, but from my testing so far, it looks like they both behave the same way (you can run it with -vvv to get more information what is going on in the background):

$ cat /tmp/ssh_config 
Match final all
  GSSAPIAuthentication yes
$ ssh -F /dev/null -G test@test | grep gssapiauthentication
gssapiauthentication no
$ ssh -F /tmp/ssh_config -G test@test | grep gssapiauthentication
gssapiauthentication yes
$ vim /tmp/ssh_config
$ cat /tmp/ssh_config 
Match final
  GSSAPIAuthentication yes
$ ssh -F /tmp/ssh_config -G test@test | grep gssapiauthentication
gssapiauthentication yes

If I understand it right, the "final" keyword invokes the second pass through the configuration file and the "all" after that is already implicit (automatically matches in case there is no other option following).

Comment 22 Fedora Update System 2019-02-06 17:00:50 UTC
openssh-7.9p1-4.fc29 has been submitted as an update to Fedora 29. https://bodhi.fedoraproject.org/updates/FEDORA-2019-0576ad8060

Comment 23 Fedora Update System 2019-02-10 04:27:32 UTC
openssh-7.9p1-4.fc29 has been pushed to the Fedora 29 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2019-0576ad8060

Comment 24 Fedora Update System 2019-02-13 02:47:10 UTC
openssh-7.9p1-4.fc29 has been pushed to the Fedora 29 stable repository. If problems still persist, please make note of it in this bug report.

Comment 25 Maciej Żenczykowski 2019-02-13 10:14:10 UTC
$ rpm -q --whatprovides /etc/ssh/ssh_config
openssh-clients-7.9p1-4.fc29.x86_64

$ cat /etc/ssh/ssh_config | egrep 'Host '

# Host *

Think this comment should perhaps be changed to '# Match final all' ?

(btw. still not clear on what if any diff there is between Match final & Match final all)

Comment 26 Maciej Żenczykowski 2019-02-13 10:28:59 UTC
(btw. afaict this works perfectly now.  thank you!)

Comment 27 Jakub Jelen 2019-02-13 11:26:23 UTC
Yes, that is the default example in the configuration file. I don't think it needs a change

From my understanding, the "final" itself is just a prefix defining when the matching should be done (in the initial pass or in the final pass). After that, any other match condition follows that should be a valid argument to match. In our case we want to "match all". But from my reading of the code, omitting the "all" does not hurt since the result is set to 1 and after the final, no argument is needed. But clearly, the "match final all" is more correct according to the description in manual page.


Note You need to log in before you can comment on or make changes to this bug.