[Openswan dev] Problems with openswan and bridging

Rene Mayrhofer rene.mayrhofer at gibraltar.at
Mon Jun 4 14:46:26 EDT 2007


Hi Paul, Ken, and Michael,

I am currently facing a rather weird issue with openswan U2.4.5/K2.4.6 on 
kernel 2.4.34 in combination with bridging. The setup is as follows:

10: int: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0a:0b:0a:56:50 brd ff:ff:ff:ff:ff:ff
11: ext: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 10
    link/ether 00:0a:0b:0a:56:51 brd ff:ff:ff:ff:ff:ff
12: br_ext: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
    link/ether 00:0a:0b:0a:56:51 brd ff:ff:ff:ff:ff:ff
    inet 80.120.3.120/25 scope global br_ext
13: br_int: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
    link/ether 00:0a:0b:0a:56:50 brd ff:ff:ff:ff:ff:ff
    inet 192.168.13.1/24 scope global br_int
14: ipsec0: <NOARP,UP> mtu 16260 qdisc pfifo_fast qlen 10
    link/ether 00:0a:0b:0a:56:51 brd ff:ff:ff:ff:ff:ff
    inet 80.120.3.120/25 scope global ipsec0

br_int is a bridge that only uses int as its physical interface, br_ext only 
uses ext. Openswan is bound to br_ext with 
        interfaces="ipsec0=br_ext"

This works in principle, and the tunnels can be established. Thetwo bridges 
are also fine, as e.g. traffic from a client in br_int to a server in br_ext 
works. Now, for a connection from br_int through the tunnel at ipsec0, things 
become more interesting:

master:~# tcpdump -nevx -i br_int icmp
tcpdump: listening on br_int, link-type EN10MB (Ethernet), capture size 96 
bytes
20:28:40.014663 00:01:4a:a0:2c:cb > 00:0a:0b:0a:56:50, ethertype IPv4 
(0x0800), length 74: IP (tos 0x0, ttl 128, id 22153, offset 0, flags [none], 
length: 60) 192.168.13.110 > 192.168.10.130: icmp 40: echo request seq 18188
        0x0000:  4500 003c 5689 0000 8001 4af7 c0a8 0d6e  E..<V.....J....n
        0x0010:  c0a8 0a82 0800 0450 0200 470c 6162 6364  .......P..G.abcd
        0x0020:  6566 6768 696a 6b6c 6d6e 6f70 7172 7374  efghijklmnopqrst
        0x0030:  7576 7761 6263 6465 6667 6869            uvwabcdefghi
20:28:40.040088 00:0a:0b:0a:56:50 > 00:01:4a:a0:2c:cb, ethertype IPv4 
(0x0800), length 74: IP (tos 0x0, ttl  62, id 34928, offset 0, flags [none], 
length: 60) 192.168.10.130 > 192.168.13.110: icmp 40: echo reply seq 18188
        0x0000:  4500 003c 8870 0000 3e01 5b10 c0a8 0a82  E..<.p..>.[.....
        0x0010:  c0a8 0d6e 0000 0c50 0200 470c 6162 6364  ...n...P..G.abcd
        0x0020:  6566 6768 696a 6b6c 6d6e 6f70 7172 7374  efghijklmnopqrst
        0x0030:  7576 7761 6263 6465 6667 6869            uvwabcdefghi

master:~# tcpdump -nevx -i ipsec0 icmp
tcpdump: listening on ipsec0, link-type EN10MB (Ethernet), capture size 96 
bytes
20:28:56.514806 00:0a:0b:0a:56:51 > 00:0a:0b:0a:56:51, ethertype IPv4 
(0x0800), length 74: IP (tos 0x0, ttl 127, id 22159, offset 0, flags [none], 
length: 60) 192.168.13.110 > 192.168.10.130: icmp 40: echo request seq 18956
        0x0000:  4500 003c 568f 0000 7f01 4bf1 c0a8 0d6e  E..<V.....K....n
        0x0010:  c0a8 0a82 0800 0150 0200 4a0c 6162 6364  .......P..J.abcd
        0x0020:  6566 6768 696a 6b6c 6d6e 6f70 7172 7374  efghijklmnopqrst
        0x0030:  7576 7761 6263 6465 6667 6869            uvwabcdefghi
20:28:56.544647 00:1a:6d:7e:28:72 > 00:0a:0b:0a:56:51, ethertype IPv4 
(0x0800), length 74: IP (tos 0x0, ttl  63, id 34931, offset 0, flags [none], 
length: 60) 192.168.10.130 > 192.168.13.110: icmp 40: echo reply seq 18956
        0x0000:  4500 003c 8873 0000 3f01 5a0d c0a8 0a82  E..<.s..?.Z.....
        0x0010:  c0a8 0d6e 0000 0950 0200 4a0c 6162 6364  ...n...P..J.abcd
        0x0020:  6566 6768 696a 6b6c 6d6e 6f70 7172 7374  efghijklmnopqrst
        0x0030:  7576 7761 6263 6465 6667 6869            uvwabcdefghi

As you can see, the ping comes in through br_int, goes out through ipsec0, 
gets a reply from the server that comes back in through ipsec0 and is sent to 
br_int. So far, so good. Alas,

master:~# tcpdump -nevx -i int icmp
tcpdump: WARNING: int: no IPv4 address assigned
tcpdump: listening on int, link-type EN10MB (Ethernet), capture size 96 bytes
20:29:40.515145 00:01:4a:a0:2c:cb > 00:0a:0b:0a:56:50, ethertype IPv4 
(0x0800), length 74: IP (tos 0x0, ttl 128, id 22173, offset 0, flags [none], 
length: 60) 192.168.13.110 > 192.168.10.130: icmp 40: echo request seq 21004
        0x0000:  4500 003c 569d 0000 8001 4ae3 c0a8 0d6e  E..<V.....J....n
        0x0010:  c0a8 0a82 0800 f94f 0200 520c 6162 6364  .......O..R.abcd
        0x0020:  6566 6768 696a 6b6c 6d6e 6f70 7172 7374  efghijklmnopqrst
        0x0030:  7576 7761 6263 6465 6667 6869            uvwabcdefghi

The underlying physical interface (of course) sees the incoming request, but 
never sees the reply. This is quite understable, given that

DROP IN=br_ext OUT=br_int PHYSIN=ext PHYSOUT=int SRC=192.168.10.130 
DST=192.168.13.110 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=34955 PROTO=ICMP 
TYPE=0 CODE=0 ID=512 SEQ=25356

netfilter decides to DROP the packet. And this is actually the interesting 
part, because

master:~# iptables -L FORWARD -vn
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               
destination 
   0     0 ACCEPT     all  --  *      br_int  0.0.0.0/0            0.0.0.0/0           
MARK match 0x32
    0     0 ACCEPT     all  --  br_ext br_int  0.0.0.0/0            0.0.0.0/0           
MARK match 0x33
    0     0 ACCEPT     all  --  br_ext br_int  0.0.0.0/0            0.0.0.0/0           
MARK match 0x32
    0     0 ACCEPT     all  --  ipsec0 br_int  0.0.0.0/0            0.0.0.0/0   
 5489 2032K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
state RELATED,ESTABLISHED
  938 56280 ACCEPT     all  --  int    ipsec0  0.0.0.0/0            0.0.0.0/0   
  750 45000 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           
LOG flags 0 level 5 prefix `DROP '
  750 45000 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0   

That is, RELATED and ESTABLISHED connections are actually allowed from 
anywhere to anywhere. This rule does not hit, because connection tracking 
does not seem to recognize the replies:

master:~# cat /proc/net/ip_conntrack | grep icmp
icmp     1 27 src=192.168.13.110 dst=192.168.10.130 type=8 code=0 id=512 
[UNREPLIED] src=192.168.10.130 dst=192.168.13.110 type=0 code=0 id=512 use=1 
mark=51

And this seems to be the main problem. Do you have any idea why connection 
tracking may not recognize the ICMP replies, although source and destination 
addresses match (there are no NAT rules on ipsec0, br_int, or int)? It is 
also quite funny that, as you can see in the syslog output above, that the 
packet is marked is coming from br_ext instead of from ipsec0. On br_ext, it 
is only visible as ESP (which is correct).

Right now, we can only get connections through the tunnel to work when 
globally allowing traffic from br_ext to br_int, even without the possibility 
to check if it came in via ipsec0, much less being able to use stateful 
filtering.

I'd happy about any advice. The changelog between 2.4.6 (that's the KLIPS 
version currently in use) and 2.4.8 does not hint that this issue would be 
solved, and recompiling that particular kernel would be a major hassle, so 
I'd prefer to do it only sparingly.

with best regards,
Rene

-- 
-------------------------------------------------
Gibraltar firewall       http://www.gibraltar.at/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.openswan.org/pipermail/dev/attachments/20070604/cc00a008/attachment.bin 


More information about the Dev mailing list