Subject: [secdir] Secdir review of draft-ietf-tsvwg-sctp-udp-encaps-07.txt

From: Tero Kivinen <[email-masked]>
Date: Thu, 10 Jan 2013 16:43:27 +0200

I have reviewed this document as part of the security directorate's
ongoing effort to review all IETF documents being processed by the
IESG.  These comments were written primarily for the benefit of the
security area directors.  Document editors and WG chairs should treat
these comments just like any other last call comments.

This document describes the UDP encapsulation for the SCTP packets.
It seems to be quite similar to other UDP encapsulation documents (for
example RFC3948 for IPsec). The security considerations section points
to the RFC4960 and RFC5061 and says there is no additional security
considerations. I belive this is not true.

The RFC4960 section 11.3 talks about the SCTP Interactions with
firewalls, i.e. how firewalls can do SCTP filtering and how to find
the INIT chunks. This UDP encapsulation can be used to bypass those
checks, by encapsulating the initial INIT chunks with UDP encapsulated
SCTP packets and then after that move to normal SCTP flow (or just
stay in the UDP encapsulated SCTP).

This might allow bypassing the firewall rules set by the site
adminstrator. This also might allow attacks to the hosts inside the
firewall protected domain by bypassing the firewall, which was
supposed to be protecting the hosts.

The document should note that firewalls needs to be updated to
specifically inspect / filter also UDP encapsulated SCTP if they do
normal SCTP inspection / filtering.

Also some other issues.

It is not clear for me how the initiator host finds the port where to
connect, when it is doing initial connection. I.e. if a host A wants
to connect to host B, which port it should use if it needs to use UDP
encapsulated SCTP? Is it assumed that 9899 will be used always? What
about connecting to the hosts which are behind NAT, i.e. if host B is
behind NAT, how does host A find the port number to use (which host B
hopefully somehow already configred to the NAT to be passed to him)?

Also what if host A and B already have one SCTP connection, and now
host B wants to create another, do host B reuse the same UDP
destination port number for host A that was used for the already
existing SCTP connection between them? The section 4.1 says that UDP
port numbers are stored per destination address per SCTP association,
so that would indicate no.

The draft seems to be doing dynamic port number updating based on
finding SCTP association (which includes checking the very weak
verification tag). The current section 4.4 only mentions that port
number is updated. In some cases also the IP-address might change,
i.e. if the NAT box is rebooted or its connection table is cleared,
and the NAT box have multiple IP-addresses, it is completly possible
that the NAT mapping changes so that IP-address and UDP port number
both change. I am not familiar enough with SCTP to know whether this
causes problem with SCTP, i.e. whether it is default SCTP rules to use
the last seen IP-address when sending reply or what.

The section 3.2 do say that if multiple addresses are used, then
RFC5061 (SCTP Dynamic Address Reconfiguration) with RFC4895
(Authentication Chunks for SCTP) MUST be used. With dynamic update for
the UDP port number, the similar hijacking attack described in the
RFC5061 security considerations section is applicable here too. The
RFC5061 requires (without using RFC2119 language) using of
authentication chunks to prevent that attack, so should we require
authentication chunks here too to prevent same attacks even when using
only one IP-address, as we do update the UDP ports based on the
received packets? Also perhaps the requirement of using authentication
chunks should be also mentioned in the security considerations
section, as it is very important for the security point of view of the
protocol. 

The section 4.1 "Architectural Considerations" says correctly that
implementations needs to store remote UDP port per destination address
for each SCTP association, i.e. different SCTP associations can have
different port numbers for same destination address. This is required,
because there might be multiple SCTP clients behind the same NAT box
(having same IP-address), just using different ports. Unfortunately,
section 4.3 "Encapsulation Procedure" does not have the "for each SCTP
association" part, so it would be better to clarify this also in 4.3
that the UDP port number is per destination address per SCTP
association.

The current draft also does not comment anything about NAT keepalives.
For example the RFC3948 (UDP encapsulation for IPsec) does specify
special NAT keepalive packets which are sent by the host behind the
NAT to keep the NAT mapping alive, as quite often NAT boxes remove
mappings after certain time. If the NAT mapping disappears, then
packets might not pass NAT box anymore depending on the direction of
packets and type of NAT box (see RFC2663 for different types of NATs).

The current draft does not seem to answer any of the UNSAF (IAB
Considerations for UNilateral Self-Address Fixing (UNSAF) Across
Network Address Translation, RFC3424) questions. 
-- 
[email-masked]

---

From: Michael Tuexen <[email-masked]>
Date: Fri, 11 Jan 2013 22:23:15 +0100

> these comments just like any other last call comments.
Hi Tero,

thank you very much for your comments. See my answers inline.
> normal SCTP inspection / filtering.
I agree. What about adding the following to the Security Considerations:
<t>Firewalls inspecting SCTP packets must also be aware of the encapsulation
and apply corresponding rules to the encapsulated packets.</t>
> hopefully somehow already configred to the NAT to be passed to him)?
The method for finding the remote port number for the initial packets
is not in the scope of this document. This is something you would do
outside of the SCTP stack. The described API provides the required
interface for the application to set the remote encapsulation
port.
> so that would indicate no.
As stated in the document, each stack uses a single port number
as the destination address of all incoming packets.
> number is updated. In some cases also the IP-address might change,
Correct.
> the last seen IP-address when sending reply or what.
The method described in the document does NOT cover changing the
address. If you want to handle that, you need to use the address
reconfiguration extension (RFC 5061).
> received packets? Also perhaps the requirement of using authentication
I don't think so. The reasoning is the SCTP/UDP/IP does not need
to be more secure than SCTP/IP. SCTP/IP is protected against blind
attackers by the V-tag mechanism. The same applies to SCTP/UDP/IP.
This is described in the second paragraph of the Security Considerations.

The situation is different from changing the IP address.
Assume that there is an association between endpoints A and B.
If A owns IP.A while establishing the association, then looses
it and a node C gets it, B sends packets to C. So C could take
over the association.
> (having same IP-address), just using different ports. Unfortunately,
And there might be multiple peer addresses and the port might be
different. It is even possible that some peer addresses need encapsulation
and some don't.
> that the UDP port number is per destination address per SCTP

What about:
<t>When inserting the UDP header, the source port MUST be the local UDP
encapsulation port number of the SCTP stack,
the destination port MUST be the remote UDP encapsulation port number
stored for the association and the destination address to which the
packet is sent (see <xref target='arch'/>).</t>
> packets and type of NAT box (see RFC2663 for different types of NATs).
SCTP sends on each idle path HEARTBEAT messages which would keep the
NAT state alive.

What about adding the following to section 3.2:

<t>SCTP sends periodically HEARTBEAT chunks on all idle paths. These can
be used to keep the NAT state alive.</t>
> Network Address Translation, RFC3424) questions. 
That is correct. However, the document describes how you encapsulate
SCTP in UDP, not how you build a complete NAT traversal solution
where both ends might be behind NATs. So finding the remote
encapsulation port is not within the scope of the document.

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 29 Jan 2013 16:43:58 +0200

> and apply corresponding rules to the encapsulated packets.</t>

That is good enough.

> interface for the application to set the remote encapsulation

It might be good to say that in the document, i.e. that it is out of
scope of this document. 

> as the destination address of all incoming packets.

The document also says:

   Using a single UDP encapsulation port number per host is not
   possible if the SCTP stack is implemented as part of an
   application.

which indicates that using multiple UDP port numbers is also an
option. Or is implementing SCTP stack as appliction out of scope too?
Section 3.1 seems to indicate that it is not out of scope.

>From the section 3.1 and 4.1 it is not really clear what needs to be
supported. If I have understood correctly that if SCTP is implemented
in kernel then we use one UDP port for the whole host, but if SCTP is
implemented by the application then each application might have
different UDP port, i.e. there will be multiple UDP SCTP encapsulation
ports in the host.

I.e. if host A is connected to two different applications on host B.
Host B is such host that it does not support SCTP on kernel, the SCTP
is implemented on the application itself, and that means each
application has separate UDP encapsulation port. Now what you said
before I assume that it is outside the scope of this document for host
A know how to connect to host B, i.e. how to get the UDP port numbers
where to connect, and also whether to use the UDP encapsulation at
all?

Is there any work ongoing on this? I.e. how is this going to be solved
in practice? Or is it assumed that the SCTP applications which do not
have direct access to IP-layer, which need to use UDP encapsulation
because of that, are always only initiators, i.e. nobody ever connects
to them, they always initiate the connection to the known services?

> > number is updated. 

> > In some cases also the IP-address might change,

Then you need to say that in the draft. Note, that hosts A and B do
not have any way of knowing when the IP-address changes, or whether it
is going to change. For normal TCP (and most likely also SCTP) this
IP-address change will usually result the connection to be reset, as
the NAT box does not have the mapping for the connection anymore, but
for UDP that does not happen. The NAT box will just create new
mapping.

I.e. the situation is as follows. Host A is behind NAT, and talks to
host B using UDP encapsulated SCTP. Now the NAT box is rebooted, and
it looses state. When Host A sends next UDP encapsulated SCTP packet
to Host B that UDP packet might get new source IP address by the NAT
box. What should happen at that point?

Should the SCTP implementation notice that IP-address of the
association has changed, and send some kind of reset or what? Or does
the SCTP implementation just drop all packets because they do not
match association and then connection is dropped after timeout?

How do you plan to use RFC 5061 to solve that situation? I do not know
enough of RFC 5061 to say how it can be used to solve this kind of
situation, where the peer A whose IP-address was changed does not even
know that his IP-address was changed.

> it and a node C gets it, B sends packets to C. So C could take

And that same thing can happen with UDP encapsulation when NAT box is
rebooted. I.e host A owns IP.NAT.port-X, and then nat box is rebooted
and that port-X is given to host C, now packets sent by host B to
IP.NAT.port-X end up to host C who will be able to take over the
association.

Of course as the NAT mappings are usually remote IP + remote port +
protocol + NAT IP + NAT port, this means that changes for host C to
get exactly same 5-tuple are small... On the other hand host C can
most likely know remote IP and remote port as they are well known
based on the service. The NAT IP is most likely going to be same all
the time, so only thing host C needs to be doing is to cause NAT to
loose state (i.e. cause it to either reboot, or run out of mappings),
and then start filling up the NAT mappings until it gets the NAT port
host A used earlier.

One way to cause NAT to loose state, is to start flooding NAT with new
UDP packets each destinationed to remote host + port and having
UDP different source port. NAT will allocate new NAT port for each of
them until it runs out of port numbers, in which case it starts
reusing port numbers. Now depending on the NAT implementation, flood
guarding, SCTP heartbeat intervals etc NAT might reuse the host A's
port in which case host C managed to get the session.

> packet is sent (see <xref target='arch'/>).</t>

That seems to be ok.

> SCTP sends on each idle path HEARTBEAT messages which would keep the

Which ways those HEARTBEAT messages are sent? For NAT mappings to stay
alive, the messages quite often needs to be coming from inside of the
NAT, i.e. from the host which is behind the NAT, and if both ends are
behind NAT, they need to be coming from both ends. Do HEARTBEATs cover
that possibility. Also some NAT boxes are known to require as small
keepalive intervals as 20 seconds... How often do you send HEARTBEATS?

For example RFC3948 section 4 recommends that default value for
keepalive interval is 20 seconds for UDP Encapsulation of ESP
connections. 

> be used to keep the NAT state alive.</t>

That is ok, provided HEARTBEATS are able to solve this issue.

> encapsulation port is not within the scope of the document.

So is having both ends behind NAT out of scope? This should then be
mentioned in section 3.2. Note, that similar problems also arise when
you need to connect to host which is behind NAT, i.e. even if it is
only one host behind NAT, but if the connection is coming from the
outside, you have similar problems than what you have when both ends
are behind NAT.

So if the scope only covers the case where the SCTP initiator is
behind NAT, then that needs to be mentioned in this document.

Also RFC3424 do also cover other cases than just those where both ends
are behind NAT... 
-- 
[email-masked]

---

From: Michael Tuexen <[email-masked]>
Date: Wed, 30 Jan 2013 12:59:52 +0100

>> and apply corresponding rules to the encapsulated packets.</t>
Included in revision -09.
> It might be good to say that in the document, i.e. that it is out of
What about adding
<t>Please note that this document does not provide all techniques necessary
for building a complete NAT-capable application using SCTP. This document
focuses on the functionality required within the SCTP stack and making
this available via an API.</t>
to the Abstract?
> Section 3.1 seems to indicate that it is not out of scope.
No, you can implement SCTP in the kernel (which means that the stack
is unique on the host) or in the application (which means there
can me multiple, one stack per association for example).
Correct.
> where to connect, and also whether to use the UDP encapsulation at
Correct. Finding the remote UDP number for the initial packets is
out of scope.
> to them, they always initiate the connection to the known services?
As said above, a complete solution is out of scope of this document.
> Then you need to say that in the draft. Note, that hosts A and B do
It is mentioned in the last paragraph of section 4.7
> is going to change. For normal TCP (and most likely also SCTP) this
Well, that depends.
If the address change is local on the host, SCTP kernel implementations (at
least FreeBSD and Linux) will get notified when addresses are added or
removed. For example, on FreeBSD you can add an address using
ifconfig and the address changes will happen on all association which use
a wildcard bound SCTP socket, it is allowed system-wide via the
net.inet.sctp.auto_asconf sysctl and the application didn't disabled
it via the SCTP_AUTO_ASCONF socket option.
On the other hand, if the address change is not local, the peer will
respond to a packet with an ABORT chunk having the T-bit set. This
could be interpreted as an indication of an address change. 
> for UDP that does not happen. The NAT box will just create new
Which is fine.
> box. What should happen at that point?
As described above, host B will respond with an ABORT chunk and host A
can use this as an indication that it has to update its address.
So it can send a ASCONF chunk adding the wildcard address and removing
the wildcard address which will result in the possibility to continue
the association.
> know that his IP-address was changed.
I hope the above makes it clearer. We can add at the end of section 4.7
text like:

If an SCTP end-point receives an ABORT with the T-bit set, it MAY
use this as an indication that the addresses seen by the peer might
have changed.</t>
> IP.NAT.port-X end up to host C who will be able to take over the
Sure, this can happen.
> port in which case host C managed to get the session.
Yes, that is possible. What can the attacker do? The attacker can't
insert any DATA or SACK chunks, since it would have to guess the V-tag.
However, the attacker can ABORT the association with sending an ABORT with the
V-tag set. But this is not better or worse than attacking the NAT box.
So most likely the attacker can receive an RWND of user data.
If sent unprotected, I would assume that his is acceptable.
Using DTLS/SCTP would protect against it.
>> packet is sent (see <xref target='arch'/>).</t>
Included in rev-09.
> keepalive intervals as 20 seconds... How often do you send HEARTBEATS?
Both sides send HEARTBEATs, the standard time between them is 30 seconds
plus RTO plus/minus 50%. However, the application can change the 30 seconds
to other values using the standard socket API.
> That is ok, provided HEARTBEATS are able to solve this issue.
Included in rev -09.
> outside, you have similar problems than what you have when both ends
I think the point is that finding the remote port number for initial
packets is out of scope of the this document.
> behind NAT, then that needs to be mentioned in this document.
Again finding the remote port for initial packets is out of scope. However,
in this scenario the initiator could try 9899...

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 31 Jan 2013 12:37:38 +0200

> this available via an API.</t>

I think it would be better to add more explicit notice what is left
outside of the scope. 

> can me multiple, one stack per association for example).

That was my understanding, and thats why it was bit odd to see text
that says that you have one UDP port only, and it is not possible to
do that if SCTP stack is in the application.

This seems to give bit mixed signals what is supported and what is
not. 

> Correct. Finding the remote UDP number for the initial packets is

Which is again one thing that should be explictly mentioned. It makes
hard to understand what this document is for, as you would expect this
kind of things to be solved here, or at least pointed to a pointer
telling where they are solved, but this document is silent about the
issue. 

> As said above, a complete solution is out of scope of this document.

That is fine, but it should mention what is out of scope. 

> It is mentioned in the last paragraph of section 4.7

I would be very suprised if someone can really combine RFC5061 and
this document to get interoperable implementation with just that one
reference, in the cases where the NAT box is rebooted and the outer
IP-addresses change because of that.

> > is going to change. For normal TCP (and most likely also SCTP) this

No, it really does not. We are not talking about local IP address
changes, we are talking the NAT box rebooting and loosing state, and
allocating new IP address for the UDP encapsulated SCTP packets. The
local host does not know anything about that. 

> it via the SCTP_AUTO_ASCONF socket option.

We are not talking about local changes.

> could be interpreted as an indication of an address change. 

Ok, so this is already handled in the SCTP internally, i.e. remote
node notices that other end changed IP-address and indicates that to
the other end. Mentioning this in the draft would most likely help for
implementors to understand what they need to do in this cases.

NAT boxes loosing state is something that should be explained in the
draft, as that is quite common situation and if this is supposed to
work on environments where there are NATs, then what happens when NAT
box looses state should be explained.

> the wildcard address which will result in the possibility to continue

Adding section explaining the thing above would most likely help to
understand that this issue needs to be handled in the implementations.
This for example makes it quite clear that using udp encapsulation
through NAT without supporting RFC 5061 is just not going to work. 

> use this as an indication that the addresses seen by the peer might

I would like think it would be better to add new section explaining
how this is supposed to interact with NAT boxes loosing state. I.e.
the text what you explained above to me. Until now I had only assumed
that if I would be implementing that, I do not need to care about
RFC5061 unless I want to support IP-addresses changing. After your
explination it is clear that all implementations who want to work
through NATs do need to support it.

> insert any DATA or SACK chunks, since it would have to guess the
> V-tag. However, the attacker can ABORT the association with sending
> an ABORT with the V-tag set. But this is not better or worse than
> attacking the NAT box. So most likely the attacker can receive an
> RWND of user data. If sent unprotected, I would assume that his is
> acceptable. Using DTLS/SCTP would protect against it.

It can do exactly same things it can do in the other case where the IP
address got reused. It will receive all packets that were supposed to
be received by original host A, so it can see all traffic going to
host A. As there is no cryptographic checksums there, it can add data
to the packets it receive and might send them to host A depending on
the network layout. At least as far as I know.

> to other values using the standard socket API.

Ok, so that is ok. 

> packets is out of scope of the this document.

The dynamic port fixup is UNSAF operation, already described in the
draft.

The use if RFC5061 with wildcard addresses is similar operation. Both
of those are solutions which get around the fact that peers do not
know the actual addresses, i.e. are trying to "determine or fix the
addresses by which it is known to another endpoint".

UNSAF operations are not only the cases where you try to find out the
initial address, it covers also all cases where the protocol tries to
fix things caused by NATs. From RFC3424:

   o  proposed workarounds include the use of "ping"-like address
      discovery requests sent from the UNSAF client (initiator) to the
      UNSAF server (listener), to which the listener responds with the
      transport address of the initiator - in the address realm of the
      listener.  However, with connection-less transports, e.g. UDP,
      IPsec ESP, etc., an UNSAF process must take care to react to
      changes in NAT bindings for a given application flow, since it may
      change unpredictably.

just covers this loosing NAT bindings and the:

   o  limiting the scope to outbound requests for service (or service
      initiation) in order to prevent unacceptable security exposures.

Is just what this document does, i.e. limits the scope so that only
outbound ocnnections are allowed or similar constraints, but does not
mention what those constraints are.

What you are trying to say is that UNSAF considerations do not apply
as you have scoped them out, but that is exactly one UNSAF
consideration. In real world case those problems do need to be solved,
and this document is not really that useful if it cannot be used in
real world...
-- 
[email-masked]