Skip to content

Instantly share code, notes, and snippets.

@iBug
Created November 24, 2020 16:41
Show Gist options
  • Select an option

  • Save iBug/08d84346b95ef4cda810858109410325 to your computer and use it in GitHub Desktop.

Select an option

Save iBug/08d84346b95ef4cda810858109410325 to your computer and use it in GitHub Desktop.
Setup IPsec encryption on Linux using `ip xfrm` (No additional software required)

Setup IPsec encryption on Linux using ip xfrm

Using Linux builtin IP XFRM object, no additional software (like StrongSwan) is required.

Usage

Put both shell scripts under /etc/ipsec and the service file under /etc/systemd/system. Make sure /etc/ipsec/keys exists and is a directory (where keys will be generated and stored). Do this on both hosts. Note that the IP addresses should be swapped (and possibly replaced by its local address - the one behind any NAT present) on the remote host.

Edit all.sh to include all links you want to encrypt. Run all.sh once to produce keys, and copy the corresponding keys to the remote host. Run the edited all.sh on the remote host again.

To make things loaded on system boot automatically, run systemctl enable ipsec.service. You'll have to adopt the script for your init system if it isn't systemd.

#!/bin/sh
# File: /etc/ipsec/all.sh
cd "$(dirname "$0")"
ACTION="${1:-start}"
./ipsec.sh 192.168.0.1 172.16.0.1 "$ACTION"
exit 0
[Unit]
Description=Setup IPsec pointopoint encryption
After=network.target
[Service]
Type=oneshot
ExecStart=/etc/ipsec/all.sh start
ExecStop=/etc/ipsec/all.sh stop
[Install]
WantedBy=multi-user.target
#!/bin/bash
if [ $# -lt 2 ]; then
echo "Missing arguments!" >&2
exit 1
fi
SRC="$1"
DST="$2"
MODE="${MODE:-$3}"
BASEDIR="$(dirname "$0")"
cd "$BASEDIR/keys"
if [ -e "${SRC}-${DST}" ]; then
KEY_FILE="${SRC}-${DST}"
elif [ -e "${DST}-${SRC}" ]; then
KEY_FILE="${DST}-${SRC}"
else
KEY_FILE="${SRC}-${DST}"
echo KEY1="0x$(head -c 32 /dev/urandom | xxd -p -c 64)" >> "$KEY_FILE"
echo KEY2="0x$(head -c 32 /dev/urandom | xxd -p -c 64)" >> "$KEY_FILE"
echo ID="0x$(head -c 4 /dev/urandom | xxd -p -c 8)" >> "$KEY_FILE"
fi
source $KEY_FILE
if [ "$MODE" = start ]; then
ip xfrm state add src $SRC dst $DST proto esp spi $ID reqid $ID mode transport auth sha256 $KEY1 enc aes $KEY2
ip xfrm state add src $DST dst $SRC proto esp spi $ID reqid $ID mode transport auth sha256 $KEY1 enc aes $KEY2
ip xfrm policy add src $SRC dst $DST dir out tmpl src $SRC dst $DST proto esp reqid $ID mode transport
ip xfrm policy add src $DST dst $SRC dir in tmpl src $DST dst $SRC proto esp reqid $ID mode transport
elif [ "$MODE" = stop ]; then
ip xfrm state delete src $SRC dst $DST proto esp spi $ID
ip xfrm state delete src $DST dst $SRC proto esp spi $ID
ip xfrm policy delete src $SRC dst $DST dir out
ip xfrm policy delete src $DST dst $SRC dir in
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment