Subject: How should NATs reject TCP packets? (was:: Re: [Ietf-behave] Next rev on TCP Behavior)

From: Pyda Srisuresh <[email-masked]>
Date: Wed, 20 Apr 2005 18:45:22 -0700 (PDT)

--- Senthil Sivakumar <ssenthil@xxxxxxxxx> wrote:
> 
> >
> >
> >That brings up another question, if a SYN (or any packet) is filtered,
> >what should the response be? 

[suresh] I believe, NAT should simply drop the TCP packets that are not
permitted. Silent discard of unpermitted/erroneous datagrams will prevent
"broadcast storms" and unneeded clutter in the network. 

I believe, it is a BAD idea to generate RST pakets because that gives the
attacker clues when the attacker does port scan on the NAT device. Further, the
attacker could keep the NAT device busy generating RSTs.
 
> >                             Silently dropping the packet opens the NAT
> >up to IP Spoofing attacks where an adversary in the middle of the
> >network spoofs the NATs IP in a SYN, and replies with a spoofed ACK
> >knowing that the SYNACK was dropped silently by the NAT; thus fooling
> >the victim. 

[suresh] Sorry, I donot understand what the problem is.

> >           Generating RST packets seems to violate the semantics of
> >RST, which in my opinion means the host replying can authoritatively say
> >that there is no application expecting to receive the packet.
> >

[suresh] Right. As I said before, I agree, it is not a good idea to send RST.

> >I propose the NAT should respond with ICMP Destination Unreachable
> >(Code: Host unreachable or Port unreachable) much like a router responds
> >with net unreachables. The response would naturally be subject to ICMP
> >rate limiting to prevent reflection attacks. Second, NATs should process
> >incoming ICMP Host or Port Unreachables the same way they would process
> >a RST or FIN/FINACK. Thoughts?
> 
> Does either of these messages cause the originating host to behave
> differently?
> I think sending a RST or ICMP Unreachable would not prevent a host app from 
> retrying
> a number of times (it is programmed to retry), right? Of course, I agree 
> that ICMP
> unreachables are slightly better for the rate limiting reason.
>

[suresh] I believe, the NAT device may optionally send ICMP Destination
unreachable message for the cases where a certain session tuple is not
permitted. However, for diagnostic purposes, the NAT device SHOULD perhaps be
required to log the error and record the event in a statistic counter.

As fo rthe ICMP code, I would recommend using code 10 (Communicaion with
destination host administratively prohibited). It woudl have been nice if we
had another code that would indicate "Communication with destination host port
administratively prohibited". But, we dont. So, I suggest, we use the same code
for host as well as port filtering.

The above logic is not specific to TCP alone and is appliable to UDP. So, we
shoudl capture this in the behave-gen draft.

As you might recall, we talked about capturing ICMP message generation as well
as processng concerning PMTU (i.e., for the cases where framentation is needed
with DF set) in the behave-gen draft in the Minneapolis meeting. We could
extend the coverage to include this as well.

> Senthil
> >Cheers
> >--
> >Saikat
cheers,
suresh

---

From: Saikat Guha <[email-masked]>
Date: Mon, 25 Apr 2005 19:53:46 -0700 (PDT)

On Wed, 2005-04-20 at 18:45 -0700, Pyda Srisuresh wrote:
> permitted. 

I am not in favor of this since this forces the other end to wait for a
TCP timeout on a failed connect. 

> attacker could keep the NAT device busy generating RSTs.

I am not in favor of this either since 1) It forces the other end to
abort immediately. 2) I agree that the NAT could be kept busy generating
RSTs.

> unreachable message [...] I would recommend using code 10 (Communicaion with
> destination host administratively prohibited)

I vote for this one.
1) ICMP rate limiting prevents the NAT being kept busy.
2) Code 10 could be defined with a SHOULD clause to be either hard or
soft giving the endhost the final say on whether to retry or not.

One reason why the endhost may want to consider it a soft error is if it
is expecting (or trying) to trigger a TCP Simultaneous Open. One reason
why the host may want to consider it a hard error is to abort a likely-
to-fail connection request as soon as possible. Using ICMP Dest Unreach,
Code 10 gives the host flexibility to do either. 

Cheers.
-- 
Saikat
Attachment:
signature.asc

---

From: Pyda Srisuresh <[email-masked]>
Date: Sun, 8 May 2005 23:10:49 -0700 (PDT)

Hi Saikat,

It seems I missed responding to this. Please see my comments inline below.

cheers,
suresh

> TCP timeout on a failed connect. 
[suresh] OK.
 
> abort immediately. 2) I agree that the NAT could be kept busy generating
[suresh] OK. we are in agreement for the same reasons.

> Code 10 gives the host flexibility to do either. 
[suresh] Sounds good.

cheers,
suresh

---

From: Bryan Ford <[email-masked]>
Date: Wed, 11 May 2005 08:06:33 -0700 (PDT)

Joining this discussion a bit late...

> > Code 10 gives the host flexibility to do either.

I am potentially OK with this recommendation providing that it ONLY applies to 
NAT ports that do NOT have an active binding.  For NAT ports that DO have an 
active binding, however, I don't think it NATs should be allowed to respond 
actively with any "hard error" (whether ICMP or TCP RST), because doing so 
could make TCP hole punching unreliable and timing-sensitive.  The standard 
scenario:

1. Clients A and B open TCP connections to rendezvous server S.
2. A asks S to help establish a connection to B.
3. S gives A and B each other's public and private endpoints.
4. A happens to get S's message before B does, so it does a TCP open to B.
5. B's NAT rejects A's attempt with an ICMP error (or RST or whatever).
6. A's NAT sees the error response come back and closes its TCP hole to B.
7. Client B finally gets S's message and attempts to connect to A.
8. B's NAT now opens a hole, but A's NAT has closed its hole, so A's NAT 
rejects B's connection attempt with an ICMP error (or RST or whatever).
9. B's NAT now sees the error and closes its hole.
10. A retries, and if it gets unlucky with the timing the cycle repeats...

Senthil's earlier suggestion of using "host unreachable", on the grounds that 
RFC1122 specifies that it _must_ be treated as soft, would be acceptable if 
it it was actually consistently implemented that way - but he also mentioned 
that Linux for one doesn't treat it as soft for TCP SYNs (which is precisely 
what we're worried about for hole punching purposes).

Suresh's suggestion of using code 10, "communication administratively 
prohibited", worries me even more because not only is it not formally 
specified at all whether it should be treated as a hard or soft error, but it 
seems very likely to me to be commonly interpreted as a hard error most of 
the time.  Think about it: if communication with some host is 
administratively prohibited, then by conventional wisdom it would mean that 
the _system administrator_ set something up to prohibit that communication, 
which means that prohibition isn't going to go away until the system 
administrator "administratively" takes it away.  An "administrative 
prohibition" isn't likely to go away soon on its own - hence it's a hard 
error, not a soft error.

If there was a suitable ICMP response that we knew would always reliably be 
interpreted as a soft error, then I would go along with that.  But as the 
situation stands, I think that a NAT MUST just silently drop any prohibited 
incoming packets directed at a bound port.  Prohibition of packets directed 
at bound NAT ports is by nature a temporary prohibition, not an 
"administrative prohibition" - it's a temporary prohibition that lasts only 
until the internal client punches a hole by sending traffic to the 
appropriate external endpoint.  Such a prohibition MUST elicit either a soft 
error from the NAT or no response at all.  Since there seems to be no 
reliably soft response, the only option seems to be no response at all.

For non-bound NAT ports, I'm OK with any behavior - silently dropping packets, 
sending ICMP errors, or even sending back RSTs as a "real" host would, 
providing that any ICMP errors or RSTs sent back are suitably 
rate-controlled.  Of course, sending back RSTs or ICMP errors for unbound 
ports but not for bound ports could be interpreted as a security weakness 
since it enables a port-scanning attacker to find out which NAT ports are 
bound.  Thus, in situations where this information leakage is deemed 
unacceptable, I think the only acceptable behavior is for the NAT not to 
respond at all on any of its ports.  "A black hole leaks no information."  
It's unfortunate that that means that prohibited connection attempts from 
external hosts will have to time out rather than receiving an immediate 
notification - but then, if all external hosts making "unsolicited" 
connection attempts are assumed to be attackers by default, then again from a 
security perspective, it seems best to make them wait and not hand out any 
information unnecessarily.

Also, for what it's worth, I think that this is an issue that applies to UDP 
just as much as to TCP, with the minor difference that "UDP RST" responses 
aren't an option because they don't exist. :)

Cheers,
Bryan

---

From: Pyda Srisuresh <[email-masked]>
Date: Fri, 13 May 2005 16:31:57 -0700 (PDT)

Bryan,

Please see my comments inline below.

cheers,
suresh
--- Bryan Ford <baford@xxxxxxx> wrote:

> NAT ports that do NOT have an active binding.  

[suresh] I believe, there are principally four kinds of scenarios that could
cause the NAT to reject incoming IP packets.

a) The packet is not the first packet of a session and the packet does not
match any existing NAT Sessions.

b) The packet is the first packet of a session; NAT could permit the session to
go through. However, the NAT device ran out of resources such as memory or NAT
address pool or port pool etc.

c) The packet is the first packet of a session; But, the direction of the first
packet is not permitted by NAT, per the NAT address map; And, there is no
existing BINDing on the NAT device exists for the same dest addres/port.

d) The packet is the first packet of a session. The direction of the first
packet is not permitted by NAT, even though a BINDing exists for the same dest
address/port that permits sessions in the opposite direction.

I believe, we all agree we simply want to drop packets in case (a) above. As
for the remaining 3 cases (b), (c) & (d) - I dont think, there is a good reason
to make a distinction to respond differently in each of these cases. I would
suggest using the same approach for all three cases.

>                                                For NAT ports that DO have an 
[suresh] After step 6 above - I am not sure that A's NAT would simply close the
associated NAT Session. I.e., When you see an ICMP Destination unreachable
message, forward the packet usign the matching NAT Session, but immediately
close the NAT Session right after that? I dont believe that would be the right
thing to do. I believe, the NAT Session should stay alive even after seeing the
ICMP error message, perhaps with a reduced timeout. I would be curious to find
out what the empirical results are on this. 

If the NAT device were to simply delete the NAT Session upon seeign a ICMP Dest
unreachable message, this could be the source of a serious attack on the NAT
device operation. 
 
Same thing after step 9 as well.

> reliably soft response, the only option seems to be no response at all.
[suresh] Well, I wasnt thinking peer-to-peer when I suggested the ICMP Dest.
Unreachable. But, as you say, I agree, ICMP dest unreacable can be problematic
for peer-to-peer hosts, because we want the hosts to retry. Sounds like, the
right thing to do for a NAT is to simply drop the unallowed pkts. I dont see
any ICMP code that woudl be soft and makes sense. However, it seems,  the NAT
device should keep metrics of the various types of pkt drops for diagnostic
purposes.

> rate-controlled.

[suresh] Please see my note earlier. I believe, the same logic  shoudl apply
even here. I woudlnt treat this different from the case where a binding was
pre-existing.

>                  Of course, sending back RSTs or ICMP errors for unbound 

[suresh] Yup.
 
> aren't an option because they don't exist. :)
[suresh] Agreed.

cheers,
suresh

---

From: Cullen Jennings <[email-masked]>
Date: Tue, 17 May 2005 07:35:54 -0700 (PDT)

I suspect that many devices (that are also firewalls) will choose to
silently discard so we probably can't disallow that behavior even if it is
not the preferred approach. I would like to remind folks  that this was
discussed in the last WG meeting. Some notes on the topic were

> "Receive RESET behavior - do we care about this? Greg recommending NATing the
> RESET and starting a short timer (5 seconds) to accommodate packets in
> transit, but this is probably a hint to the NAT implementer. Don't want the
> NAT doing RESET processing unless it's tracking sequence numbers. What if
> RESET gets dropped and retransmitted? This is off to the land of firewalls,
> anyway - do we have to go there? If a NAT knows that RESETs don't open
> connections, it's turning into a firewall anyway."

Anyways, I guess I do wonder if we really need to specify this or not. If
you want STUNT to work and you want to do it on fairly normal OS without
replacing the TCP stacks, what behavior do you need to assume here and how
much can you still leave open? I note that a router would just drop the
packet if it felt like it thought that may not be the right analogy.

I suspect that while making an new ICMP code may have been the right thing
to do long ago, I'm not sure it is that practical to today because of the
large deployment issues in getting OS to change to understand it.

Cullen <not as chair>

On 5/13/05 4:31 PM, "Pyda Srisuresh" <srisuresh@xxxxxxxxx> wrote:

> _______________________________________________
> Ietf-behave mailing list
> Ietf-behave@xxxxxxxxxxxxxxxxxxx
> https://list.sipfoundry.org/mailman/listinfo/ietf-behave

---

From: Saikat Guha <[email-masked]>
Date: Tue, 17 May 2005 15:03:45 -0700 (PDT)

On Tue, 2005-05-17 at 07:35 -0700, Cullen Jennings wrote:
> If you want STUNT to work and you want to do it on fairly normal OS without
> much can you still leave open? 

We studied TCP through existing NATs; the results are under submission:
     http://nutss.gforge.cis.cornell.edu/pub/draft-imc-stunt.pdf

In response to Cullen's question, when it comes to packet filtering, it
would be nice to assume:
1. TCP simultaneous open (or even just SYN-in after a SYN-out) works
2. One of:
        a) NATs don't generate either RSTs or ICMP Unreachables in 
           response to unsolicited SYNs.
  or
        b) NATs don't release the mapping if a) is violated i.e. if they
           receive a RST/ICMP in response to a SYN

Attachment:
signature.asc

---

From: Bryan Ford <[email-masked]>
Date: Wed, 18 May 2005 05:38:17 -0700 (PDT)

Inline...

On Friday 13 May 2005 19:31, Pyda Srisuresh wrote:
> [suresh] I believe, there are principally four kinds of scenarios that
> could cause the NAT to reject incoming IP packets.
>
> b) The packet is the first packet of a session; NAT could permit the
> session to go through. However, the NAT device ran out of resources such as
> memory or NAT address pool or port pool etc.
>
> c) The packet is the first packet of a session; But, the direction of the
> first packet is not permitted by NAT, per the NAT address map; And, there
> is no existing BINDing on the NAT device exists for the same dest
> addres/port.
>
> packet is not permitted by NAT, even though a BINDing exists for the same
> dest address/port that permits sessions in the opposite direction.
>
> I believe, we all agree we simply want to drop packets in case (a) above.
> As for the remaining 3 cases (b), (c) & (d) - I dont think, there is a good
> reason to make a distinction to respond differently in each of these cases.
> I would suggest using the same approach for all three cases.

I agree - I would prefer that they all be the same.  But case (d) is the 
problem - for that case it's really important for hole punching that the 
NAT's response either be a reliably "soft" error response of some kind, or no 
error at all - and since there seems to be no reliable "soft" error response, 
that means no error at all.  Since case (d) demands a soft response, if we 
want consistency across the board, it seems we need a soft response is in 
order across the board for all cases of the NAT rejecting IP packets.

> >                                                For NAT ports that DO have
> > an active binding, however, I don't think it NATs should be allowed to
> > respond actively with any "hard error" (whether ICMP or TCP RST), because
> > doing so could make TCP hole punching unreliable and timing-sensitive. 
> > The standard scenario:
> >
> > 4. A happens to get S's message before B does, so it does a TCP open to
> > B. 5. B's NAT rejects A's attempt with an ICMP error (or RST or
> > whatever). 6. A's NAT sees the error response come back and closes its
> > TCP hole to B. 7. Client B finally gets S's message and attempts to
> > connect to A. 8. B's NAT now opens a hole, but A's NAT has closed its
> > hole, so A's NAT rejects B's connection attempt with an ICMP error (or
> > RST or whatever). 9. B's NAT now sees the error and closes its hole.
> [suresh] After step 6 above - I am not sure that A's NAT would simply close
> the associated NAT Session. I.e., When you see an ICMP Destination
> unreachable message, forward the packet usign the matching NAT Session, but
> immediately close the NAT Session right after that? I dont believe that
> would be the right thing to do. I believe, the NAT Session should stay
> alive even after seeing the ICMP error message, perhaps with a reduced
> timeout. I would be curious to find out what the empirical results are on
> this.

The very nice draft paper Saikat Guha just pointed to on the list has some 
useful results regarding this issue:

Specifically, according to the table on page 8, up to 28% of NATs appear to 
"close the hole" immediately upon receiving an ICMP or RST, depending on the 
exact sequence involved.  Which is fortunately already a minority of NATs 
that will hopefully continue to get smaller in the future, but not 
insignificant.

> If the NAT device were to simply delete the NAT Session upon seeign a ICMP
> Dest unreachable message, this could be the source of a serious attack on
> the NAT device operation.

Good point - another reason such NATs should be considered broken.  But they 
do exist.  I believe the current TCP BEHAVE draft already outlaws this 
behavior, which is good.

So I suppose the upshot is that if a NAT rejects incoming sessions with ICMP 
errors, that won't necessarily cause a serious problem as long as the other 
"facing" NAT is BEHAVE-compliant in its "hole closing" behavior, and as long 
as the end-host application retries outgoing hole punching attempts that fail 
due to those ICMP errors.  I think I would still prefer recommending no 
active response to unsolicited traffic, but I could live with something like 
this for example:

        NATs MUST NOT reject incoming TCP SYNs with a RST.
        NATs SHOULD simply drop incoming SYNs for disallowed sessions.
        NATs MAY alternatively respond with an ICMP error.
        In the latter case, the ICMP error MUST use a "soft error" response code
        (e.g., "destination unreachable"),      and ICMP responses MUST be 
rate-limited.

I could live with the "SHOULD" being weakened to a "MAY", but I'd prefer that 
it be a "SHOULD".

> > RFC1122 specifies that it _must_ be treated as soft, would be acceptable
> > if it it was actually consistently implemented that way - but he also
> > mentioned that Linux for one doesn't treat it as soft for TCP SYNs (which
> > is precisely what we're worried about for hole punching purposes).
> >
> > seems very likely to me to be commonly interpreted as a hard error most
> > of the time.  Think about it: if communication with some host is
> > administratively prohibited, then by conventional wisdom it would mean
> > that the _system administrator_ set something up to prohibit that
> > communication, which means that prohibition isn't going to go away until
> > the system administrator "administratively" takes it away.  An
> > "administrative prohibition" isn't likely to go away soon on its own -
> > hence it's a hard error, not a soft error.
> >
> > If there was a suitable ICMP response that we knew would always reliably
> > be interpreted as a soft error, then I would go along with that.  But as
> > the situation stands, I think that a NAT MUST just silently drop any
> > prohibited incoming packets directed at a bound port.  Prohibition of
> > packets directed at bound NAT ports is by nature a temporary prohibition,
> > not an
> > "administrative prohibition" - it's a temporary prohibition that lasts
> > only until the internal client punches a hole by sending traffic to the
> > appropriate external endpoint.  Such a prohibition MUST elicit either a
> > soft error from the NAT or no response at all.  Since there seems to be
> > no reliably soft response, the only option seems to be no response at
> > all.
>
> [suresh] Well, I wasnt thinking peer-to-peer when I suggested the ICMP
> Dest. Unreachable. But, as you say, I agree, ICMP dest unreacable can be
> problematic for peer-to-peer hosts, because we want the hosts to retry.
> Sounds like, the right thing to do for a NAT is to simply drop the
> unallowed pkts. I dont see any ICMP code that woudl be soft and makes
> sense. However, it seems,  the NAT device should keep metrics of the
> various types of pkt drops for diagnostic purposes.

Agreed.

> [suresh] Please see my note earlier. I believe, the same logic  shoudl
> apply even here. I woudlnt treat this different from the case where a
> binding was pre-existing.

Agreed.

Bryan

---

From: Bryan Ford <[email-masked]>
Date: Wed, 18 May 2005 08:10:36 -0700 (PDT)

On Tuesday 17 May 2005 10:35, Cullen Jennings wrote:
> not the preferred approach.

Agreed.

> I would like to remind folks  that this was 
> > "Receive RESET behavior - do we care about this? Greg recommending NATing
> > the RESET and starting a short timer (5 seconds) to accommodate packets
> > in transit, but this is probably a hint to the NAT implementer. Don't
> > want the NAT doing RESET processing unless it's tracking sequence
> > numbers. What if RESET gets dropped and retransmitted? This is off to the
> > land of firewalls, anyway - do we have to go there? If a NAT knows that
> > RESETs don't open connections, it's turning into a firewall anyway."
>

I think this is precisely the right analogy.  Probably the reason "soft 
errors" aren't very prevalent or supported reliably in ICMP or other Internet 
protocols is because of the strong historical precedent that "soft errors" of 
all kinds are generally treated in the same way: just drop the packet.

Agreed.

Bryan

---

From: Cullen Jennings <[email-masked]>
Date: Wed, 18 May 2005 09:37:26 -0700 (PDT)

>            receive a RST/ICMP in response to a SYN

Yes, I had come to more or less the same conclusion. I note that from the
notes of the last WG meeting we had concluded on 1 and 2a. Some notes are:

    ?     Does NAT allow incoming SYN with simultaneous TCP open?
Recommendation is "yes". What about traditional (outbound-only) NATs?
Qualify this in the recommendation.
    ?     NATs don't send RST when port is unbound and you get a SYN.
Recommendation is "discard silently".

also 

    ?     Receive RESET behavior - do we care about this? Greg recommending
NATing the RESET and starting a short timer (5 seconds) to accommodate
packets in transit, but this is probably a hint to the NAT implementer.
Don't want the NAT doing RESET processing unless it's tracking sequence
numbers. What if RESET gets dropped and retransmitted? This is off to the
land of firewalls, anyway - do we have to go there? If a NAT knows that
RESETs don't open connections, it's turning into a firewall anyway.
    ?     Receiving an external SYN - General nods.

So unless people have some new information of why we would not want to do
the stuff above, this might be a somewhat already decided issue.

I think that we had come to the conclusion that we would allow an inbound
SYN and if there was no where to send it we would silently discard it. We
had also come to the conclusion we were not going to extensively talk about
RST handling because we did not need to and it was a firewall issue.

Cullen <not as chair>

---

From: Pyda Srisuresh <[email-masked]>
Date: Mon, 30 May 2005 12:03:40 -0700 (PDT)

Cullen,

Reset handling is also done in firewalls. That is not to say, Reset handling is
a firewall issue. I disgaree with your remark that reet handling is a firewall
only issue. Reset handlign is covered in draft-sivakumar-behave-nat-tcp-01
draft.

You mention WG meeting notes below. I dont recall seeign one one on the list.
Were the WG meetign minutes mailed to the list already? If so, could you pint
me to the mail that includes this. Thanks.

cheers,
suresh

---

From: Cullen Jennings <[email-masked]>
Date: Wed, 1 Jun 2005 06:23:53 -0700 (PDT)

On 5/30/05 12:03 PM, "Pyda Srisuresh" <srisuresh@xxxxxxxxx> wrote:

> only issue.

That's a fair comment - I did not mean to imply that we say nothing about
RST. What do you think we have to say about RST to make STUNT reliably work?
Are you in agreement with the conclusions that came up in last WG meeting?

> me to the mail that includes this. Thanks.

Not online right now but check around 3/7 or so. You can find them off the
auxiliary web page for the WG and by now I imagine they are in the minutes
from the last IETF.

Cullen <not as chair>

---

From: Pyda Srisuresh <[email-masked]>
Date: Fri, 3 Jun 2005 08:37:56 -0700 (PDT)

--- Cullen Jennings <fluffy@xxxxxxxxx> wrote:

> > Reset handling is also done in firewalls. That is not to say, Reset
> handling
> > is
[suresh] Sure, I agree with the conclusions. We also had discussion on the list
about whether to silently drop the packets or generate RST/ICMP-reject for TCP.
Initially, we agreed that the NAT device SHOULD send ICMP destination
unreachable message, with a code of 10. This is what the ford-behave-gen draft
reflects currently in REQ-9. Later, we agreed to drop the packets silently. We
will revise the text in the next rev of behave-gen draft. 

As for RST processing, below is what the sivakumar-behave-nat-tcp draft says. I
donot see anything in this that impacts STUNT. 

   RST attack is another well known DoS attack. An attacker could
   simply forge a number of RST packets for a variety of Established
   TCP connections and cause the NAT sessions to be reset and freed.
   One technique to defend against this type of attack is to validate
   the RST packet and not let the packet through unless the sequence
   number used in the RST packet is within the expected TCP window
   size of the TCP Session.

cheers,
suresh