2

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?

Bill
  • 51

1 Answers1

2

Figured it out:

ip xfrm state add ${DDIR} proto esp spi ${SPI2} reqid ${SPI} \
  mode transport auth sha256 ${SHAKEY2} enc aes ${AESKEY2}

On both nodes to allow receipt with the new SPI and associated with the OLD reqid. The reqid continues to tie this SA to the associated "policy."

Then add the new SPI and key for sending. Node will start using the new key immediately.

ip xfrm state add ${SDIR} proto esp spi ${SPI2} reqid ${SPI} \
  mode transport auth sha256 ${SHAKEY2} enc aes ${AESKEY2}

Finally, once both sides are using the new key, stop using the old one.

ip xfrm state del ${SDIR} proto esp spi ${SPI}
ip xfrm state del ${DDIR} proto esp spi ${SPI}
Bill
  • 51