5

I configured a small network on a cloud virtual machine. This virtual machine has a static IP address assigned to eth0 interface that I'll call $EXTIP. mydomain.com points to $EXTIP. Inside, I have some linux containers, that get their ip through DHCP in the Subnet 10.0.0.0/24 (i called the virtual interface nat ). They run some services that can be reached through DNAT. Then I wanted to connect to these containers through an IPSec tunnel, so I configured StrongSwan.

ipsec.conf:

conn %default
        dpdaction=none
        rekey=no

conn remote
        keyexchange=ikev2
        ike=########
        left=[$EXTIP]
        leftsubnet=10.0.1.0/24,10.0.0.0/24
        leftauth=pubkey
        lefthostaccess=yes
        leftcert=########.pem
        leftfirewall=yes
        leftid="#########"
        right=%any
        rightsourceip=10.0.1.0/24
        rightauth=########
        rightid=%any
        rightsendcert=never
        eap_identity=%any
        auto=add
        type=tunnel

Everything works fine, IPSec clients get IPs of the 10.0.1.0/24 subnet and can reach the containers subnet. My problem is that I'm not able to get SSH connections over the tunnel. It simply does not work, ssh client does not produce any output. Sniffing with tcpdump gives:

tcpdump:

09:50:29.648206 ARP, Request who-has 10.0.0.1 tell mydomain.com, length 28
09:50:29.648246 ARP, Reply 10.0.0.1 is-at 00:ff:aa:00:00:01 (oui Unknown), length 28
09:50:29.648253 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [S], seq 4007849772, win 29200, options [mss 1460,sackOK,TS val 1151153 ecr 0,nop,wscale 7], length 0
09:50:29.648296 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [S.], seq 2809522632, ack 4007849773, win 14480, options [mss 1460,sackOK,TS val 11482992 ecr 1151153,nop,wscale 6], length 0
09:50:29.677225 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [.], ack 2809522633, win 229, options [nop,nop,TS val 1151162 ecr 11482992], length 0
09:50:29.679370 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [P.], seq 0:23, ack 1, win 229, options [nop,nop,TS val 1151162 ecr 11482992], length 23
09:50:29.679403 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [.], ack 24, win 227, options [nop,nop,TS val 11483002 ecr 1151162], length 0
09:50:29.684337 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [P.], seq 1:32, ack 24, win 227, options [nop,nop,TS val 11483003 ecr 1151162], length 31
09:50:29.685471 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [.], seq 32:1480, ack 24, win 227, options [nop,nop,TS val 11483003 ecr 1151162], length 1448
09:50:29.685519 IP mydomain.com > 10.0.0.1: ICMP mydomain.com unreachable - need to frag (mtu 1422), length 556
09:50:29.685567 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [.], seq 32:1402, ack 24, win 227, options [nop,nop,TS val 11483003 ecr 1151162], length 1370
09:50:29.685572 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [.], seq 1402:1480, ack 24, win 227, options [nop,nop,TS val 11483003 ecr 1151162], length 78
09:50:29.714601 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [.], ack 32, win 229, options [nop,nop,TS val 1151173 ecr 11483003], length 0
09:50:29.714642 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [P.], seq 1480:1600, ack 24, win 227, options [nop,nop,TS val 11483012 ecr 1151173], length 120
09:50:29.723649 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [P.], seq 1393:1959, ack 32, win 229, options [nop,nop,TS val 1151174 ecr 11483003], length 566
09:50:29.723677 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [.], ack 24, win 227, options [nop,nop,TS val 11483015 ecr 1151173,nop,nop,sack 1 {1394:1960}], length 0
09:50:29.725688 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [.], ack 1480, win 251, options [nop,nop,TS val 1151177 ecr 11483003], length 0
09:50:29.952394 IP 10.0.0.1.ssh > 10.0.1.2.54869: Flags [P.], seq 1480:1600, ack 24, win 227, options [nop,nop,TS val 11483084 ecr 1151173,nop,nop,sack 1 {1394:1960}], length 120
09:50:29.981056 IP mydomain.com.54869 > 10.0.0.1.ssh: Flags [.], ack 1600, win 251, options [nop,nop,TS val 1151253 ecr 11483084,nop,nop,sack 1 {1480:1600}], length 0

If you need it this is my iptables configuration file:

iptables:

*filter
:INPUT ACCEPT [144:9669]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [97:15649]
:interfacce-trusted - [0:0]
:porte-trusted - [0:0]
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j interfacce-trusted
-A FORWARD -j porte-trusted
-A FORWARD -j REJECT --reject-with icmp-host-unreachable
-A FORWARD -d 10.0.0.1/32 -p tcp -m tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -d 10.0.0.1/32 -p tcp -m tcp --dport 443 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -d 10.0.0.3/32 -p tcp -m tcp --dport 1234 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A interfacce-trusted -i nat -j ACCEPT
-A porte-trusted -d 10.0.0.1/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A porte-trusted -d 10.0.0.1/32 -p tcp -m tcp --dport 443 -j ACCEPT
-A porte-trusted -d 10.0.0.3/32 -p tcp -m tcp --dport 1234 -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [10:600]
:INPUT ACCEPT [10:600]
:OUTPUT ACCEPT [4:268]
:POSTROUTING ACCEPT [18:1108]
-A PREROUTING -d [$EXTIP] -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.1:80
-A PREROUTING -d [$EXTIP] -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.0.1:443
-A PREROUTING -d [$EXTIP] -p tcp -m tcp --dport 8069 -j DNAT --to-destination 10.0.0.3:1234
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
-A POSTROUTING -s 10.0.1.0/24 -o nat -j MASQUERADE
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
COMMIT

Probably I'm missing something stupid... Thanks in advance for helping :))

PattPatel
  • 131
  • 1
  • 5
  • I tried to connect to remote server two clients from the same network (my laptops). They ping each other, but they can't ssh themselves. From Windows Phone 8.1, using an SSH app I can SSH as well so I think it's a StrongSwan related problem. Here is my StrongSwan client config `conn %default keyexchange=ikev2 ike=###### dpdaction=none rekey=no conn remote leftsourceip=%config leftauth=######## lefthostaccess=yes right=$EXTIP rightid=%mydomain.com rightsubnet=0.0.0.0/0 rightauth=pubkey eap_identity=####### auto=add type=tunnel` – PattPatel Jun 02 '14 at 09:05
  • Putty works fine, native SSH and Sublime don't – PattPatel Jun 02 '14 at 10:10
  • What sort of MTU do you have set up, encrypted traffic doesn't always deal with packet fragmentation very well.. – NickW Jun 02 '14 at 10:10
  • @NickW mtu on eth0 is 1500, i'm encapsulating ipsec traffic over udp – PattPatel Jun 02 '14 at 10:17
  • @NickW the problem was packet fragmentation. With a simple rule in the mangle table to manage MSS I solved my problem :) Thank you `-A FORWARD -s 10.0.1.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360` – PattPatel Jun 02 '14 at 10:31
  • Sweet! Glad you got it fixed! – NickW Jun 02 '14 at 10:34

2 Answers2

8

The problem was packet fragmentation. With a simple rule in the mangle table to manage MSS I solved my problem :)

iptables -t mangle -A FORWARD -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
PattPatel
  • 131
  • 1
  • 5
  • Please accept your own answer, so others know this has been solved. It helped me for sure! – Martin Feb 24 '15 at 15:14
  • Using the following answer, I was also able to create tcpdump on both site. [Link](https://serverfault.com/questions/1020685/how-can-i-capture-ipsec-packets-on-my-vpn-server/1069111#1069111) It turns out in my cast the messages with larger packet size don't arrive on remote. Both hosts are behind NAT. Interestingly SSH in one direction and telnet in both direction went through. Similar solution is also suggested [here](https://docs.strongswan.org/docs/5.9/howtos/forwarding.html#_mtumss_issues) :) – SchLx May 22 '23 at 13:34
0

In my case it was also a fragmentation issue. It was not easy to find out. My symptoms were the following:

  • ping worked in boot direction
  • ssh only worked in one direction from host2 to host1

I found the answer here and was able to set up tcpdump on boot host with the following commands:

# configure filter log group:
sudo iptables -I INPUT -m addrtype --dst-type LOCAL -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5
sudo iptables -I OUTPUT -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

# verify configuration:
sudo iptables -L --line-numbers
...
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    NFLOG      all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL policy match dir in pol ipsec nflog-group 5
...
Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    NFLOG      all  --  anywhere             anywhere             policy match dir out pol ipsec nflog-group 5

# observe the logs (use you own setting for the grep):
sudo tcpdump -s 0 --print -n -i nflog:5 -w ./ipsec_ssh.pcap \
  grep  "{ip_address_to_check}.{port}" | tee -a host1_ssh.log

# remove roles:
sudo iptables -D INPUT 1
sudo iptables -D OUTPUT 1

I did this for both hosts and compared the output from them. Only the smaller packages had arrived on the host2.

Also, the diagram here was quite helpful and with the documentation from here I tried to guess the location where I had to insert the mss limitation.

In my case the following rule on host1 had solved the issue:

sudo iptables -t mangle -A PREROUTING -m policy --pol ipsec -p tcp -m tcp --dir in --tcp-flags SYN,RST SYN -m tcpmss --mss 1360:1535 -j TCPMSS --set-mss 1360
SchLx
  • 129
  • 1
  • 4