[Swan] NAT issues

Phil Nightowl phil.nightowl at gmail.com
Thu Aug 26 14:53:42 UTC 2021


Hello everyone!

I am having (probably) NAT issues with connection setup failing. I tried 
several modifications to my config and maybe ended up not seeing the 
obvious.


The network topology:
---------------------
10.9.8.0/24 -- NATbox1 (10.9.8.254/10.0.a.b) -- ISP/Internet -- NATbox2 -- 10.0.0.98

On both ends, the public IPs are fixed. NATbox1 is configured - apart 
from the usual NAT - to forward inbound traffic on udp/500, udp/4500, 
esp and ah directly to 10.9.8.123.


Desired configuration:
----------------------
Server on 10.9.8.123 responding in host-to-host mode to connections from 
10.9.8.0/24

AND (simultaneously)

the same server responding in host-to-host mode to connections from 
10.0.0.98 (and maybe couple more, but not many hosts) behind NATbox2


The config so far:
------------------
all involved hosts running 3.27, the first part is working fine with the 
following config:

conn mainnet
     left=%defaultroute
     right=%group
     auto=ondemand
     authby=rsasig
     ikev2=insist
     leftid=%fromcert
     rightid=%fromcert
     leftrsasigkey=%cert
     rightrsasigkey=%cert
     leftcert=server-certname
     leftsendcert=always
     rightsendcert=always
     pfs=yes
     aggressive=no
     salifetime=1h
     negotiationshunt=hold
     failureshunt=drop

(together with similar passthrough config for ssh traffic, again with 
left=%defaultroute and right=%group)

The corresponding /etc/ipsec.d/policies/mainnet contains only one line of 

10.9.8.0/26

(yes, all hosts talking to 10.9.8.123 are from this range).

As mentioned, this part of the config works fine. However, when I add 
configuration for the connection originating from 10.0.0.98, no 
connection is established. In order to rule out other problems, I tried 
to make the second part of the config as easy as possible, temporarily 
even switching to PSK. Right now, I ended up with the following:

---- on 10.9.8.123:

conn branch
     left=%defaultroute
     right=<public-ip-of-natbox2>
     auto=add
     ikev2=insist
     authby=secret
     pfs=yes
     aggressive=no
     salifetime=1h
     negotiationshunt=hold
     failureshunt=drop
     rekey=no


---- and on 10.0.0.98:
conn mainnet
     left=%defaultroute
     right=<public-ip-of-natbox1>
     auto=ondemand
     ikev2=insist
     authby=secret
     pfs=yes
     aggressive=no
     salifetime=1h
     negotiationshunt=hold
     failureshunt=drop
     fragmentation=yes

(plus the SSH passthrough part).


When initiating the connection from 10.0.0.98 to 10.9.8.123 (using 
<public-ip-of-natbox1>, of course), I get only four packets through (as 
seen from the initiator, i. e. 10.0.0.98):

1  10.0.0.98                <public-ip-of-natbox1>    ISAKMP   822    IKE_SA_INIT MID=00 Initiator Request
2  <public-ip-of-natbox1>   10.0.0.98                 ISAKMP   474    IKE_SA_INIT MID=00 Responder Response
3  10.0.0.98                <public-ip-of-natbox1>    ISAKMP   439    IKE_AUTH MID=01 Initiator Request
4  <public-ip-of-natbox1>   10.0.0.98                 ISAKMP   111    IKE_AUTH MID=01 Responder Response


On the responder, I can see the following in the pluto logfile (tried to 
quote the relevant part, please tell me if I am looking at the wrong 
place):

pluto[6203]: | Now let's proceed with state specific processing
pluto[6203]: | calling processor Respond to IKE_SA_INIT
pluto[6203]: | anti-DDoS cookies not required (and no cookie received)
pluto[6203]: | find_host_connection me=10.9.8.123:500 him=<public-ip-of-natbox2>:500 policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 10.9.8.1:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | find_next_host_connection policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | found policy = PSK+ENCRYPT+TUNNEL+PFS+FAIL1+DONT_REKEY+IKEV2_ALLOW+IKEV2_PROPOSE+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO (branch)
pluto[6203]: | find_next_host_connection returns empty
pluto[6203]: | find_host_connection me=10.9.8.123:500 him=%any:500 policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 10.9.8.1:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[6203]: | find_next_host_connection policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUP+GROUTED (mainnet-ssh)
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#10.9.8.0/24-(22--6--0))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#10.9.8.0/24-(22--6--0) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#10.9.8.0/24-(0--6--22))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#10.9.8.0/24-(0--6--22) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#<public-ip-of-natbox2>/32-(0--6--22))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#<public-ip-of-natbox2>/32-(0--6--22) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=ECDSA+IKEV2_ALLOW
pluto[6203]: | found policy = RSASIG+ENCRYPT+TUNNEL+PFS+FAIL1+GROUP+GROUTED+IKEV2_ALLOW+IKEV2_PROPOSE+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO (mainnet)
pluto[6203]: | found policy = RSASIG+ENCRYPT+TUNNEL+PFS+FAIL1+GROUPINSTANCE+IKEV2_ALLOW+IKEV2_PROPOSE+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO (mainnet#10.9.8.0/26)
pluto[6203]: | find_next_host_connection returns empty
pluto[6203]: | initial parent SA message received on 10.9.8.123:500 for "mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0)" 0.0.0.0 with kind=CK_INSTANCE dropped
pluto[6203]: | find_host_connection me=10.9.8.123:500 him=<public-ip-of-natbox2>:500 policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = PSK+ENCRYPT+TUNNEL+PFS+FAIL1+DONT_REKEY+IKEV2_ALLOW+IKEV2_PROPOSE+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO (branch)
pluto[6203]: | find_next_host_connection returns empty
pluto[6203]: | find_host_connection me=10.9.8.123:500 him=%any:500 policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUP+GROUTED (mainnet-ssh)
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#10.9.8.0/24-(22--6--0))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#10.9.8.0/24-(22--6--0) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#10.9.8.0/24-(0--6--22))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#10.9.8.0/24-(0--6--22) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = AUTH_NEVER+SHUNT0+GROUPINSTANCE (mainnet-ssh#<public-ip-of-natbox2>/32-(0--6--22))
pluto[6203]: | find_next_host_connection returns mainnet-ssh#<public-ip-of-natbox2>/32-(0--6--22) 0.0.0.0
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = RSASIG+ENCRYPT+TUNNEL+PFS+FAIL1+GROUP+GROUTED+IKEV2_ALLOW+IKEV2_PROPOSE+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO (mainnet)
pluto[6203]: | find_next_host_connection returns mainnet
pluto[6203]: | find_next_host_connection policy=RSASIG+IKEV2_ALLOW
pluto[6203]: | found policy = RSASIG+ENCRYPT+TUNNEL+PFS+FAIL1+GROUPINSTANCE+IKEV2_ALLOW+IKEV2_PROPOSE+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO (mainnet#10.9.8.0/26)
pluto[6203]: | find_next_host_connection returns mainnet#10.9.8.0/26
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | connect_to_host_pair: 10.9.8.123:500 <public-ip-of-natbox2>:500 -> hp:branch
pluto[6203]: | rw_instantiate() instantiated "mainnet#10.9.8.0/26"[2] <public-ip-of-natbox2> for <public-ip-of-natbox2>
pluto[6203]: | found connection: mainnet#10.9.8.0/26[2] <public-ip-of-natbox2> with policy RSASIG+IKEV2_ALLOW
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | found connection: mainnet#10.9.8.0/26[2] <public-ip-of-natbox2> with policy RSASIG+IKEV2_ALLOW
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to <public-ip-of-natbox2>:500
pluto[6203]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[6203]: | passthrough conn mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0) also matches - check which has longer prefix match
pluto[6203]: | passthrough conn mainnet-ssh#<public-ip-of-natbox2>/32-(0--6--22) also matches - check which has longer prefix match
pluto[6203]: | selecting default constructed local IKE proposals for connection mainnet#10.9.8.0/26 (IKE SA responder matching remote proposals)
pluto[6203]: packet from <public-ip-of-natbox2>:500: constructed local IKE proposals for mainnet#10.9.8.0/26 (IKE SA responder matching remote proposals): 1:IKE:ENCR=AES_GCM_C_256;>


In order to deal with the confusion (for a reason unknown to me, pluto 
is apparently assigning the incoming packet <public-ip-of-natbox2> to 
the mainnet conn instead of branch, which is what I supposed it to do), 
I tried to remove the mainnet config temporarily. However, this did not 
improve things either. After this attempt (conn mainnet removal), the 
pluto logfile says:

pluto[10077]: | selected state microcode Responder: process AUTH request
pluto[10077]: | Now let's proceed with state specific processing
pluto[10077]: | calling processor Responder: process AUTH request
pluto[10077]: | state #1 NAT-T: new mapping <public-ip-of-natbox2>:4500
pluto[10077]: | processing: [RE]START state #1 connection "branch" <public-ip-of-natbox2>:500 (in for_each_state() at state.c:1600)
pluto[10077]: | new NAT mapping for #1, was <public-ip-of-natbox2>:500, now <public-ip-of-natbox2>:4500
pluto[10077]: | processing: stop state #1 connection "branch" <public-ip-of-natbox2>:4500 (in for_each_state() at state.c:1600)
pluto[10077]: | serialno table: hash serialno #1 to head 0x5d8404
pluto[10077]: | serialno table: hash serialno #1 to head 0x5d8404
pluto[10077]: | processing: resume state #1 connection "branch" <public-ip-of-natbox2>:4500 (in for_each_state() at state.c:1600)
pluto[10077]: | NAT-T: updating local port to 4500
pluto[10077]: | NAT-T connection has wrong interface definition 10.9.8.123:4500 vs 10.9.8.123:500
pluto[10077]: | NAT-T: updated to use interface eth2:4500
pluto[10077]: | X509: no CERT payloads to process
pluto[10077]: | refine_host_connection for IKEv2: starting with "branch"
pluto[10077]: |    match_id a=10.0.0.98
pluto[10077]: |             b=<public-ip-of-natbox2>
pluto[10077]: |    results  fail
pluto[10077]: | refine_host_connection: checking "branch" against "branch", best=(none) with match=0(id=0/ca=1/reqca=1)
pluto[10077]: | Warning: not switching back to template of current instance
pluto[10077]: | No IDr payload received from peer
pluto[10077]: | skipping because peer_id does not match
pluto[10077]: | refine going into 2nd loop allowing instantiated conns as well
pluto[10077]: | find_host_pair: comparing 10.9.8.123:500 to 0.0.0.0:500
pluto[10077]: |    match_id a=10.0.0.98
pluto[10077]: |             b=(none)
pluto[10077]: |    results  matched
pluto[10077]: | refine_host_connection: checking "branch" against "mainnet-ssh", best=(none) with match=1(id=1/ca=1/reqca=1)
pluto[10077]: | Warning: not switching back to template of current instance
pluto[10077]: | No IDr payload received from peer
pluto[10077]: | skipping group connection
pluto[10077]: |    match_id a=10.0.0.98
pluto[10077]: |             b=(none)
pluto[10077]: |    results  matched
pluto[10077]: | refine_host_connection: checking "branch" against "mainnet-ssh#10.9.8.0/24-(22--6--0)" 0.0.0.0, best=(none) with match=1(id=1/ca=1/reqca=1)
pluto[10077]: | Warning: not switching back to template of current instance
pluto[10077]: | No IDr payload received from peer
pluto[10077]: | skipping because mismatching IKE version
pluto[10077]: |    match_id a=10.0.0.98
pluto[10077]: |             b=(none)
pluto[10077]: |    results  matched
pluto[10077]: | refine_host_connection: checking "branch" against "mainnet-ssh#10.9.8.0/24-(0--6--22)" 0.0.0.0, best=(none) with match=1(id=1/ca=1/reqca=1)
pluto[10077]: | Warning: not switching back to template of current instance
pluto[10077]: | No IDr payload received from peer
pluto[10077]: | skipping because mismatching IKE version
pluto[10077]: |    match_id a=10.0.0.98
pluto[10077]: |             b=(none)
pluto[10077]: |    results  matched
pluto[10077]: | refine_host_connection: checking "branch" against "mainnet-ssh#<public-ip-of-natbox2>/32-(22--6--0)" 0.0.0.0, best=(none) with match=1(id=1/ca=1/reqca=1)
pluto[10077]: | Warning: not switching back to template of current instance
pluto[10077]: | No IDr payload received from peer
pluto[10077]: | skipping because mismatching IKE version
pluto[10077]: |    match_id a=10.0.0.98
pluto[10077]: |             b=(none)
pluto[10077]: |    results  matched
pluto[10077]: | refine_host_connection: checking "branch" against "mainnet-ssh#<public-ip-of-natbox2>/32-(0--6--22)" 0.0.0.0, best=(none) with match=1(id=1/ca=1/reqca=1)
pluto[10077]: | Warning: not switching back to template of current instance
pluto[10077]: | No IDr payload received from peer
pluto[10077]: | skipping because mismatching IKE version
pluto[10077]: | returning since no better match then original best_found
pluto[10077]: | no suitable connection for peer '10.0.0.98'
pluto[10077]: "branch" #1: Peer ID '10.0.0.98' mismatched on first found connection and no better connection found
pluto[10077]: | ikev2_parent_inI2outR2_continue_tail returned STF_FAIL+v2N_AUTHENTICATION_FAILED
pluto[10077]: | processing: [RE]START state #1 connection "branch" <public-ip-of-natbox2>:4500 (in complete_v2_state_transition() at ikev2.c:2788)
pluto[10077]: | #1 complete v2 state transition from STATE_PARENT_R1 with STF_FAIL+v2N_AUTHENTICATION_FAILED
pluto[10077]: | sending a notification reply
pluto[10077]: "branch" #1: responding to AUTH message (ID 1) from <public-ip-of-natbox2>:4500 with encrypted notification AUTHENTICATION_FAILED


At this poing, I got stuck. Can anyone see what am I doing wrong? If 
not, where should I continue debugging?

Many thanks,

Phil


More information about the Swan mailing list