I built a simple ipsec between two Linux boxes:
SHAKEY=0xd3413c31c7d19c93d04db1c6ae8d73d9a64910c2e76297129acde44aaa9de5c5
AESKEY=0xcd191fac520878852e15647dce3456ba9857e2dfd6ed56421eb50cb58d7a1e5a
SPI=0x01
if [ "$(hostname -s)" = "host1" ] ;then
SRC=10.0.0.1
DST=10.0.0.3
fi
if [ "$(hostname -s)" = "host3" ] ;then
SRC=10.0.0.3
DST=10.0.0.1
fi
SDIR="src $SRC dst $DST"
DDIR="src $DST dst $SRC"
ip xfrm state add ${SDIR} proto esp spi ${SPI} reqid ${SPI}
mode transport auth sha256 ${SHAKEY} enc aes ${AESKEY}
ip xfrm state add ${DDIR} proto esp spi ${SPI} reqid ${SPI}
mode transport auth sha256 ${SHAKEY} enc aes ${AESKEY}
ip xfrm policy add ${SDIR} dir out priority 0
tmpl ${SDIR} proto esp reqid ${SPI} mode transport
ip xfrm policy add ${DDIR} dir in priority 0
tmpl ${DDIR} proto esp reqid ${SPI} mode transport
This works fine. Now I want to change to a new set of keys without breaking the packet flow. The way I expect this to work is: add an additional key set to the receive path, switch the send path to the new key set, remove the old key set.
Is this the right method? How do I actually do it? Here's what I've tried:
AESKEY2=0x2bdfbfbee5aab7be4f4ccfe202e6f1d5e363503140441fe8aba77c3b784e65bd
SHAKEY2=0xed2ac9c739894c73bae1a9fe477631add20398b0bbc906c5ec486f27ddbb84ac
SPI2=0x02
ip xfrm state add ${SDIR} proto esp spi ${SPI2} reqid ${SPI2}
mode transport auth sha256 ${SHAKEY2} enc aes ${AESKEY2}
ip xfrm state add ${DDIR} proto esp spi ${SPI2} reqid ${SPI2}
mode transport auth sha256 ${SHAKEY2} enc aes ${AESKEY2}
This much seems to work in that packets keep flowing on SPI 1
ip xfrm policy add ${DDIR} dir in \
tmpl ${DDIR} proto esp reqid ${SPI2} mode transport
Fails: RTNETLINK answers: File exists
ip xfrm policy add ${SDIR} dir out priority 5\
tmpl ${SDIR} proto esp reqid ${SPI2} mode transport
ip xfrm policy add ${DDIR} dir in priority 5 \
tmpl ${DDIR} proto esp reqid ${SPI2} mode transport
Allows the new policies to be added but there doesn't seem to be a way to explicitly remove the priority 0 entry. ip xfrm policy del ${SDIR} dir out priority 2
fails with "Error: argument "priority" is wrong: unknown". ip xfrm policy del ${SDIR} dir out
removes the priority 0 entry (a second call would remove the priority 5 entry) and starts traffic sending on SPI 2, but then traffic from the other side on SPI 1 stops being accepted even though the policy dir in entry has not been changed.
What am I missing? How to update the keys without breaking the traffic flow?