Discussion:
[Patch] TCP MD5SIG for OpenSSH
(too old to reply)
Thomas ☃ Habets
2016-01-14 08:20:26 UTC
Permalink
The intent of this option is similar to "tls-auth" in openvpn[1]: To
refuse to talk to anyone who doesn't know the shared secret.

You could compare this to port knocking, in that it solves a similar
problem.

This also prevents RST attacks from killing an existing connection,
even when attacker can sniff sequence numbers.

This feature doesn't work through NAT, since the source and
destination are signed. As IPv6 becomes more and more prevalent it'll
become possible to use this in more and more deployments.

The socket option is enabled *after* connection establishment, thus
doesn't protect against SYN floods. This is because server doesn't
know (in userspace) what the address of the peer is until they
connect. Again because signed addresses.

Setting up:
* Add "TCPMD5 foorbarSecret" to sshd_config
* SSH with "-oTCPMD5=foobarSecret"

Patch attached, but it's an ugly patch for 7.1p. I didn't want to put
too much effort into cleaning up and documenting everything if the
concept itself would rejected outright.

It needs formatting, portability, apply to CVS HEAD, and include file
changes at
least. But it works on Linux as is.

Everything signed from fourth packet:

16:32:40.902764 IP 127.0.0.1.51216 > 127.0.0.1.2222: Flags [S], seq
2342692369, win 43690, options [mss 65495,sackOK,TS val 51101999 ecr
0,nop,wscale 7], length 0

16:32:40.902777 IP 127.0.0.1.2222 > 127.0.0.1.51216: Flags [S.], seq
514139093, ack 2342692370, win 43690, options [mss 65495,sackOK,TS val
51101999 ecr 51101999,nop,wscale 7], length 0

16:32:40.902789 IP 127.0.0.1.51216 > 127.0.0.1.2222: Flags [.], ack 1, win
342, options [nop,nop,TS val 51101999 ecr 51101999], length 0

16:32:40.903480 IP 127.0.0.1.51216 > 127.0.0.1.2222: Flags [P.], seq 1:22,
ack 1, win 342, options [nop,nop,md5shared secret not supplied with -M,
can't check - 2daa171c0c342b041da3cb79ecd1d11b,nop,nop,TS val 51101999 ecr
51101999], length 21

So, how about it? Worth cleaning up?

[1] https://community.openvpn.net/openvpn/wiki/Hardening#Useof--tls-auth
--
☢ Thomas ☢
Darren Tucker
2016-01-14 20:57:13 UTC
Permalink
Post by Thomas ☃ Habets
* Add "TCPMD5 foorbarSecret" to sshd_config
* SSH with "-oTCPMD5=foobarSecret"
Have you considered making this a stand-alone tool? Something that
listens and execs sshd -i on the server side and could be used as a
ProxyCommand on the client side. That'd be potentially usable by
other services.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Alex Bligh
2016-01-15 08:48:02 UTC
Permalink
Post by Thomas ☃ Habets
The socket option is enabled *after* connection establishment, thus
doesn't protect against SYN floods. This is because server doesn't
know (in userspace) what the address of the peer is until they
connect. Again because signed addresses.
So could they exchange a secret as part of the session, obviating
the need for any set up?
--
Alex Bligh
Alex Bligh
2016-01-15 12:07:28 UTC
Permalink
Post by Alex Bligh
Post by Thomas ☃ Habets
The socket option is enabled *after* connection establishment, thus
doesn't protect against SYN floods. This is because server doesn't
know (in userspace) what the address of the peer is until they
connect. Again because signed addresses.
So could they exchange a secret as part of the session, obviating
the need for any set up?
They could. Making it part of the protocol does expose more code to be
vulnerable to any preauth attacks though. One of the main benefits is
that if the remote end doesn't have the right key then the data won't
even be parsed. IIRC this has protected OpenVPN installations with its
tls-auth option when there's been OpenSSL and/or OpenVPN bugs.
You could, for example, set the key to SHA256(SSH session key) or
something, since a session key is already negotiated for the
connection. (this is just what comes immediately to mind)
I'm guessing I was thinking of something like this (designed so
neither end reveals its 'inside-NAT' IP address):

1. If configured to be on server side (default is off), server says
"I am capable of TCP-MD5SIG, and here is the address/port pair
I see for you", else proceeds as normal. However, prior to sending
this it sends a TCP ECHO option (option 8).

2. If configured to be on client side (default is off), client
examines address/port pair, and checks it against its own
version, to detect SNAT at client side. If it wants it says
"I am also capable of TCP-MD5SIG, and here is the address/port
pair I see for you", else proceeds as normal. But before sending
the response, it ensures the TCP ECHO reply (option 9) has been
sent.

3. Server compares supplied address/port pair with what it sees
(to detect DNAT like Amazon elastic IPs), and if they are the
same, it waits for the TCP ECHO reply, and if it gets it
says "Excellent, let's apply TCP-MD5SIG, here is a
random key", and from that point on TCP-MD5SIG is applied
both times, else proceeds as normal.

I don't see the advantage in hashing a session key (which should
be kept private) over using a random key. The random key could
be hashed with the session key I suppose if the concern was
entropy.

The idea would be for this to detect NAT (without revealing private
IP addresses) and avoid TCP-MD5SIG if it's in use, but for TCP-MD5SIG
to be off by default anyway. The reason for this is that it might not
detect middleboxen (e.g. firewalls) that effectively proxy the TCP
session or strip the packets. A couple of dummy ECHO/ECHO REPLY TCP
options are used in order to detect such stripping.

Ray Bellis did some work on analysing all the evil things NAT devices
and other middleboxen might do in a different context (DNS/UDP),
https://www.icann.org/committees/security/sac035.pdf
and detecting NAT. There's this draft:
https://tools.ietf.org/html/draft-bellis-behave-natpresent-00
but I don't think it got anywhere. So we are left with heuristics.

Lastly I think you are using TCP-MD5SIG aka RFC2385. This has been
obsoleted by RFC5925 (TCP-AO) though I'm not sure how wide support
that has. I suspect some of the above may be reinvention of wheels
already within RFC5925.
--
Alex Bligh
Malcolm
2016-01-15 11:27:19 UTC
Permalink
Post by Alex Bligh
So could they exchange a secret as part of the session, obviating
the need for any set up?
If by set up, you mean "the rest of the SSH authentication", then surely not.
MD5 pre-shared secrets are probably fine for "port-knocking" or even
RST-proofing purposes, but not for authenticating SSH sessions to servers.

=M=
Thomas ☃ Habets
2016-01-15 11:44:00 UTC
Permalink
Post by Alex Bligh
Post by Thomas ☃ Habets
The socket option is enabled *after* connection establishment, thus
doesn't protect against SYN floods. This is because server doesn't
know (in userspace) what the address of the peer is until they
connect. Again because signed addresses.
So could they exchange a secret as part of the session, obviating
the need for any set up?
They could. Making it part of the protocol does expose more code to be
vulnerable to any preauth attacks though. One of the main benefits is
that if the remote end doesn't have the right key then the data won't
even be parsed. IIRC this has protected OpenVPN installations with its
tls-auth option when there's been OpenSSL and/or OpenVPN bugs.

You could, for example, set the key to SHA256(SSH session key) or
something, since a session key is already negotiated for the
connection. (this is just what comes immediately to mind)

It'd be hard to automate and make default though, since if done when
the connection goes through NAT it will fail the connection. You could
work around that by only enabling it for IPv6, and hope that nobody's
doing IPv6 NAT.

It'd still protect against other attacks like third parties fiddling
with an already established connection, be it by RSTing because they
know the accepted RST window or more sophisticated attacks.

But again, only solves a subset of the problems.
--
☢ Thomas ☢
Thomas ☃ Habets
2016-01-15 11:54:52 UTC
Permalink
Post by Darren Tucker
Post by Thomas ☃ Habets
* Add "TCPMD5 foorbarSecret" to sshd_config
* SSH with "-oTCPMD5=foobarSecret"
Have you considered making this a stand-alone tool? Something that
listens and execs sshd -i on the server side and could be used as a
ProxyCommand on the client side. That'd be potentially usable by
other services.
No I hadn't. Good idea.

I think there may be some aspects you'd be missing out on (or
reimplement, or outsource to e.g. inetd), such as (account) password
brute force protection. I haven't tried it, but I suspect sshd -i
can't limit to 10 concurrent preauth sessions each getting one attempt
per second which sshd otherwise does by default.
--
☢ Thomas ☢
Alex Bligh
2016-01-15 12:45:41 UTC
Permalink
Post by Malcolm
Post by Alex Bligh
So could they exchange a secret as part of the session, obviating
the need for any set up?
If by set up, you mean "the rest of the SSH authentication", then surely not.
MD5 pre-shared secrets are probably fine for "port-knocking" or even
RST-proofing purposes, but not for authenticating SSH sessions to servers.
No not at all. I meant obviating the need for separately presharing
an MD5SIG key. Clearly this is additional to the existing authentication
and encryption and not in any way a substitution. It's designed to
prevent (e.g.) RST attacks.
--
Alex Bligh
Thomas ☃ Habets
2016-01-15 13:34:56 UTC
Permalink
Post by Alex Bligh
1. If configured to be on server side (default is off), server says
"I am capable of TCP-MD5SIG, and here is the address/port pair
I see for you", else proceeds as normal. However, prior to sending
this it sends a TCP ECHO option (option 8).
2. If configured to be on client side (default is off), client
examines address/port pair, and checks it against its own
version, to detect SNAT at client side. If it wants it says
"I am also capable of TCP-MD5SIG, and here is the address/port
pair I see for you", else proceeds as normal. But before sending
the response, it ensures the TCP ECHO reply (option 9) has been
sent.
What is the point of the TCP ECHO?
[ah… middleboxes]
Post by Alex Bligh
3. Server compares supplied address/port pair with what it sees
(to detect DNAT like Amazon elastic IPs), and if they are the
same, it waits for the TCP ECHO reply, and if it gets it
says "Excellent, let's apply TCP-MD5SIG, here is a
random key", and from that point on TCP-MD5SIG is applied
both times, else proceeds as normal.
I don't see the advantage in hashing a session key (which should
be kept private) over using a random key.
Are you saying the random key should be sent in the clear? Or are you
saying this negotiation should be done after the encryption has
already been established? I'll assume the latter, in which case sure,
you can have a new random key. IIRC the session key is DH-negotiated
though, which means neither side gets to *choose* the key. If the
server just chooses a "random" key it could actually be a backdoored
key. I don't see a harmful attack here, but it would allow one side of
the connection to deceive the other about how secure their connection
is, and leaking key material, even if it's only for this outer layer
of auth. Hopefully DH is also more secure in the face of passive
attackers so that *both* sides need to have bad RNG to leak the
session key as opposed to just one side.

The bigger problem here is still though that it assumes the normal
crypto negotiation has already taken place, and any security problems
with it are not helped by this MD5 signature. Compare again to port
knocking. (I consider port knocking to be the wrong implementation,
personally, since what almost all implementations do is "send a
password in the clear", but are pretending that's not what they're
doing because it's supposedly more stealthy (security through
obscurity). This is a separate topic though)

Putting the negotiation later and under crypto could make it harder to
sync exactly when to turn it on, because TCP segments may contain
partial crypto blocks and may already be sent before the setsockopt()
call on the receiver.
Post by Alex Bligh
The random key could
be hashed with the session key I suppose if the concern was
entropy.
That probably fixes the concerns I just mentioned with RNG etc.
Post by Alex Bligh
The idea would be for this to detect NAT (without revealing private
IP addresses)
Except for those who do SNAT/DNAT to "bounce" a connection, where it
would leak other addresses.
Post by Alex Bligh
and avoid TCP-MD5SIG if it's in use, but for TCP-MD5SIG
to be off by default anyway. The reason for this is that it might not
detect middleboxen (e.g. firewalls) that effectively proxy the TCP
session or strip the packets. A couple of dummy ECHO/ECHO REPLY TCP
options are used in order to detect such stripping.
Is this assuming that a middlemox that strips MD5 would also strip
ECHO? Seems plausible to me, but I don't have the data. If this
assumption is incorrect it would break SSH through these by default,
which would be bad.

I don't have enough experience with these boxes to know if they do this.
Post by Alex Bligh
Lastly I think you are using TCP-MD5SIG aka RFC2385.
Yes.
Post by Alex Bligh
This has been
obsoleted by RFC5925 (TCP-AO) though I'm not sure how wide support
that has.
My crystal ball says TCP-AO will not happen. 2385 was implemented so
that Unix boxes could play BGP, so that's a *need*. But anyone who
implements 5925 will also support 2385, and it's "good enough" (heavy
quotes here, I'm not defending it), so it's not a *need* for anyone.
I'm sure someone will implement it eventually in OSS stuff of course.

It's from 2010 and I've been unable to find any spec sheet (that love
to list RFCs they support) that list 5925. I did find a brief mention
of a patch in FreeBSD[1], but it was unclear if it was just "skip this
option" handling or part of a bigger set of patches actually handling
it. Author

In my opinion 5925 implements some trivial parts of key management,
while leaving the big parts completely unaddressed. Maybe the hardest
part of crypto is key management, and TCP-AO provides a hook for some,
but just hand waves the hardest part of cryptography. Yes, it has
better hooks if application layer (e.g. SSH protocol) wants to rotate
keys, and has better replay protection for really long lived
connections (in terms of bytes). But really both of these are much
more important for a plaintext protocol than for SSH. Except for a
possible future preimage attack on MD5 TCP-MD5SIG is just fine for
SSH. (disclaimer: IANACryptographer)

In any case my patch, and the suggested external tool and your
post-encryption negotiation, are not in any way blocking future TCP-AO
implementation, and could be used in parallel. And because of OS
support, *if* we want TCP-AO then I'd say we *also* want TCP-MD5SIG.
Maybe in 20 years the latter can be dropped, if that's the case. But
today TCP-AO can't perhaps even be implemented since it's blocked on
kernel implementations.
Post by Alex Bligh
I suspect some of the above may be reinvention of wheels already within RFC5925.
No, my reading doesn't find anything like that. In fact it explicitly
states that "NAT breaks this" (section 9.2), so NAT is not handled.

[1] http://lists.freebsd.org/pipermail/svn-src-user/2013-March/006156.html
--
☢ Thomas ☢
Alex Bligh
2016-01-15 14:07:06 UTC
Permalink
Thomas,
Post by Thomas ☃ Habets
Are you saying the random key should be sent in the clear?
No!
Post by Thomas ☃ Habets
Or are you
saying this negotiation should be done after the encryption has
already been established? I'll assume the latter,
Yes
Post by Thomas ☃ Habets
in which case sure,
you can have a new random key. IIRC the session key is DH-negotiated
though, which means neither side gets to *choose* the key. If the
server just chooses a "random" key it could actually be a backdoored
key. I don't see a harmful attack here, but it would allow one side of
the connection to deceive the other about how secure their connection
is, and leaking key material, even if it's only for this outer layer
of auth. Hopefully DH is also more secure in the face of passive
attackers so that *both* sides need to have bad RNG to leak the
session key as opposed to just one side.
OK, I now understand why you are proposing that. So use a hash
of the DH session key and a randomly generated nonce sent in
plaintext? And then turn it on before crypto is negotiated for
the reasons you suggest.
Post by Thomas ☃ Habets
Post by Alex Bligh
The idea would be for this to detect NAT (without revealing private
IP addresses)
Except for those who do SNAT/DNAT to "bounce" a connection, where it
would leak other addresses.
I don't /think/ it does. It's only

a) leaking to the client the IP address the server thinks the client has,
which the client can already discover from the SSH_CONNECTION
variable. This is only if the option is switched on at the server side.

b) leaking to the server the IP address the client thinks the server has,
which is only if the option is switched on at both the server and the
client side, and I find it difficult to see why that would be a problem.

IE if you turn it on server side, you leak something you'd leak already
if a connection fully establishes. If you turn it on both ends, the client
leaks the IP it's trying to connect to.

And of course you'd have to select a non-default option for this to
happen.
Post by Thomas ☃ Habets
Post by Alex Bligh
and avoid TCP-MD5SIG if it's in use, but for TCP-MD5SIG
to be off by default anyway. The reason for this is that it might not
detect middleboxen (e.g. firewalls) that effectively proxy the TCP
session or strip the packets. A couple of dummy ECHO/ECHO REPLY TCP
options are used in order to detect such stripping.
Is this assuming that a middlemox that strips MD5 would also strip
ECHO?
Yes
Post by Thomas ☃ Habets
Seems plausible to me, but I don't have the data. If this
assumption is incorrect it would break SSH through these by default,
which would be bad.
It would only break such connections *IF* it were turned on on both
client and server (which I am not suggesting would be the default) AND
there was no NAT in the path AND the middlebox in question stripped
some TCP options but not others.
Post by Thomas ☃ Habets
I don't have enough experience with these boxes to know if they do this.
Summary of Ray's work: middleboxen do every possible bad thing under the
sun, to the extent it is inadvisable to work around the worst of them.
Post by Thomas ☃ Habets
Post by Alex Bligh
This has been
obsoleted by RFC5925 (TCP-AO) though I'm not sure how wide support
that has.
My crystal ball says TCP-AO will not happen. 2385 was implemented so
that Unix boxes could play BGP, so that's a *need*. But anyone who
implements 5925 will also support 2385, and it's "good enough" (heavy
quotes here, I'm not defending it), so it's not a *need* for anyone.
I'm sure someone will implement it eventually in OSS stuff of course.
...
Post by Thomas ☃ Habets
In any case my patch, and the suggested external tool and your
post-encryption negotiation, are not in any way blocking future TCP-AO
implementation, and could be used in parallel. And because of OS
support, *if* we want TCP-AO then I'd say we *also* want TCP-MD5SIG.
Maybe in 20 years the latter can be dropped, if that's the case. But
today TCP-AO can't perhaps even be implemented since it's blocked on
kernel implementations.
Agree
Post by Thomas ☃ Habets
Post by Alex Bligh
I suspect some of the above may be reinvention of wheels already within RFC5925.
No, my reading doesn't find anything like that. In fact it explicitly
states that "NAT breaks this" (section 9.2), so NAT is not handled.
[1] http://lists.freebsd.org/pipermail/svn-src-user/2013-March/006156.html
OK. I admit I should have read that one more carefully.
--
Alex Bligh
Roland Mainz
2016-01-15 16:27:19 UTC
Permalink
[snip]
Post by Alex Bligh
3. Server compares supplied address/port pair with what it sees
(to detect DNAT like Amazon elastic IPs), and if they are the
same, it waits for the TCP ECHO reply, and if it gets it
says "Excellent, let's apply TCP-MD5SIG, here is a
random key", and from that point on TCP-MD5SIG is applied
both times, else proceeds as normal.
I don't see the advantage in hashing a session key (which should
be kept private) over using a random key. The random key could
be hashed with the session key I suppose if the concern was
entropy.
The idea would be for this to detect NAT (without revealing private
IP addresses) and avoid TCP-MD5SIG if it's in use, but for TCP-MD5SIG
to be off by default anyway. The reason for this is that it might not
detect middleboxen (e.g. firewalls) that effectively proxy the TCP
session or strip the packets. A couple of dummy ECHO/ECHO REPLY TCP
options are used in order to detect such stripping.
Don't these extra roundtrips further increase the latency of ssh
connection setup (e.g. imagine a high-bandwidth&&high-latency satelite
link) ? ssh is already a *PAIN* in that area, killing it's usefullness
for applications like "Distributed make" because the time to setup the
connection can be much longer than the command executed on the remote
side.

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) ***@nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Alex Bligh
2016-01-15 17:09:09 UTC
Permalink
Post by Roland Mainz
Don't these extra roundtrips further increase the latency of ssh
connection setup (e.g. imagine a high-bandwidth&&high-latency satelite
link) ? ssh is already a *PAIN* in that area, killing it's usefullness
for applications like "Distributed make" because the time to setup the
connection can be much longer than the command executed on the remote
side.
They would, but only when this non-default option was enabled.
--
Alex Bligh
Roland Mainz
2016-01-15 17:26:41 UTC
Permalink
Post by Alex Bligh
Post by Roland Mainz
Don't these extra roundtrips further increase the latency of ssh
connection setup (e.g. imagine a high-bandwidth&&high-latency satelite
link) ? ssh is already a *PAIN* in that area, killing it's usefullness
for applications like "Distributed make" because the time to setup the
connection can be much longer than the command executed on the remote
side.
They would, but only when this non-default option was enabled.
OK... are there any good ideas how to mitigate the latency effect ([1]) ?

[1]=Long on my wishlist is something like a SSH3 protocol which
somehow can rival Kerberised rsh (yes, yes, I know, it's comparing
apples with pears) in connection setup latency and better handles
socket/pipe buffer boundaries (sort of |SOCK_SEQPACKET|-style) ...
(But this is now going waaaay off-topic from the original subject...
so either drop or rename subject of the thread...)

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) ***@nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Loading...