I'm trying to set up an IPsec connection manually from the console with iproute2. What I need is a virtual interface (at best, a virtual IP address could also be sufficient) that IPsec-transforms everthing ingressing (ESP/TUNNEL MODE) and hands it over to eth0 (on my system called em1). On the other set a peer takes the packet from its own eth deciphers it and hands it over to a virtual interface a the other side. So I want do establish a "normal" IPsec tunnel.
I've got no problem with the policy and SA, and configuring that was easy using the normal ethernet addresses of the systems in transport mode, i.e.
ip xfrm policy add src 198.51.100.1 dst 198.51.100.2 dir out tmpl proto esp ip xfrm state add src 198.51.100.1 dst 198.51.100.2 spi 24501 proto esp enc des 0xAABBCCDDEEFF0011 ip xfrm state add src 198.51.100.2 dst 198.51.100.1 spi 24501 proto esp enc des 0xAABBCCDDEEFF0022
and an adversary configuration on the peer works quite well.
Now I tried to set up a virtual IP and a route to the other system with
ip address add 10.0.0.0 dev em1 ip route add to 10.0.0.2 via 10.0.0.1
and again vice versa on the other side. This again works well. Then I altered the IPsec policy and SA to
ip xfrm policy add src 10.0.0.1 dst 10.0.0.2 dir out tmpl src 198.51.100.1 dst 198.51.100.2 proto esp mode tunnel ip xfrm state add src 10.0.0.1 dst 10.0.0.2 spi 24501 proto esp enc des 0xAABBCCDDEEFF0011 ip xfrm state add src 10.0.0.2 dst 10.0.0.1 spi 24501 proto esp enc des 0xAABBCCDDEEFF0022
When I now try to
tcping the peer I get no answer and
setkey -PD tells me, that the security policy was never triggered. Now I'm trying to fabricate a working virtual interface to handle the IPsec tunnel, but I don't know how to bind it to the physical interface and how I get the kernel to apply the security policy.
It is vital for me that I can solve this with iproute2, as I ultimately want to do this out of a C++ program and I have already the appropriate classes that drop Netlink commands the same style the
ip command does (what I can do with
ip, I also can do within my code). In fact, the first part already works out of my program and I want to use the same Netlink API functions for the rest.
Update I figured out that the state needed to be set up with the tunnel addresses so the working SAs are
ip xfrm state add src 10.0.0.1 dst 10.0.0.2 spi 24501 proto esp enc des 0xAABBCCDDEEFF0011 ip xfrm state add src 10.0.0.2 dst 10.0.0.1 spi 24501 proto esp enc des 0xAABBCCDDEEFF0022
while the policy remains the same. Now the policy is triggered and I see a transformed packet on a sniffing port. Also iptables on the other machine blocked the packet and I disabled it for testing.
So, the one direction seems to work now, but I still get no answer. I also don't know if the problem is yet somehow the transform, the routing or the interface part. My prefered solution would still be one including a virtual interface, but I don't have any idea how to bind it to a physical one, let alone if the transform would work that way.