3
\$\begingroup\$

I've developed a script to set up an encrypted tunnel between two Linux hosts, using iproute2, ssh and setkey. The goal is to allow setting up ad-hoc secure tunnels with minimum of setup and dependencies.

Mirrored here:

#!/bin/bash
# Setup encrypted IPv4 tunnel over IPv4 or IPv6 on two Linux nodes using SSH for tunnel setup.
# Requires only ipsec-tools, iproute2, ssh and necessry kernel modules locally and remotely.
# Warning: it flushes IPsec settings both locally and remotely.
# Don't use with other IPsec tunnnels.
# Sample usage:
# simplevpn -6 fc::1 fc::2 ssh -T root@fc::2
# fc::1 is your IPv6 address
# fc::2 is other peer's IPv6 address
# after successful run it should create tunnel named "simplevpn" locally and remotely
# and set up addresses 192.168.77.1 and 192.168.77.2 locally and remotely respectively
# Note: tested only once in my configuration. This is not a serious production-ready VPN solution.
# Implemented by Vitaly "_Vi" Shukela in 2013, License=MIT
MODE="ipip"
PROT="-4"
if [ "1ドル" == "-6" ]; then
 shift;
 MODE=ipip6
 PROT="-6"
fi
SRC="1ドル"; shift
DST="1ドル"; shift
if [ -z "1ドル" ]; then
 echo Usage: simplevpn [-6] source_ip destination_ip ssh_command_line
 exit 1;
fi
set -e
KEY1=0x`dd if=/dev/urandom count=32 bs=1 2> /dev/null| xxd -p -c 64`
KEY2=0x`dd if=/dev/urandom count=32 bs=1 2> /dev/null| xxd -p -c 64`
true ${LOCALIP:="192.168.77.1"}
true ${REMOTEIP:="192.168.77.2"}
true ${DEVNAME:="simplevpn"}
# 4 is encapsulated IPv4 both in IPv4 an IPv6
setkey -c << EOF
 flush; 
 spdflush; 
 spdadd $SRC $DST 4 -P out ipsec esp/transport//require ah/transport//require; 
 spdadd $DST $SRC 4 -P in ipsec esp/transport//require ah/transport//require;
 add $SRC $DST esp 0x4444 -E rijndael-cbc $KEY1 ; 
 add $DST $SRC esp 0x4444 -E rijndael-cbc $KEY1 ;
 add $SRC $DST ah 0x4445 -A hmac-sha256 $KEY2 ; 
 add $DST $SRC ah 0x4445 -A hmac-sha256 $KEY2 ;
EOF
modprobe ip6_tunnel
ip $PROT tunnel del $DEVNAME || true
ip $PROT tunnel add $DEVNAME mode $MODE local $SRC remote $DST
ip link set $DEVNAME up
ip -4 addr add $LOCALIP/32 dev $DEVNAME
ip -4 route add $REMOTEIP/32 dev $DEVNAME
"$@" << EOF
 set -e
 # the same as above, but "in" and "out" swapped
 setkey -c << EOF2
 flush; 
 spdflush; 
 spdadd $SRC $DST 4 -P in ipsec esp/transport//require ah/transport//require; 
 spdadd $DST $SRC 4 -P out ipsec esp/transport//require ah/transport//require;
 add $SRC $DST esp 0x4444 -E rijndael-cbc $KEY1 ; 
 add $DST $SRC esp 0x4444 -E rijndael-cbc $KEY1 ;
 add $SRC $DST ah 0x4445 -A hmac-sha256 $KEY2 ; 
 add $DST $SRC ah 0x4445 -A hmac-sha256 $KEY2 ;
EOF2
 modprobe ip6_tunnel
 ip $PROT tunnel del $DEVNAME || true
 ip $PROT tunnel add $DEVNAME mode $MODE remote $SRC local $DST
 ip link set $DEVNAME up
 ip -4 addr add $REMOTEIP/32 dev $DEVNAME
 ip -4 route add $LOCALIP/32 dev $DEVNAME
EOF

Are there any glaring errors? Do you have any suggestions (apart from not flushing entire security tables)? I'm primarily interested in security issues.

Jeff Vanzella
4,3182 gold badges24 silver badges33 bronze badges
asked May 22, 2013 at 16:30
\$\endgroup\$
1
  • \$\begingroup\$ Note: filed a bug reproduced with this script. \$\endgroup\$ Commented May 23, 2013 at 15:03

1 Answer 1

1
\$\begingroup\$
  • As far as I can tell, it checks if you provide too many options, but it doesn't check if you provide too few. This should be done before trying to do anything with SRC and DST. set -o errexit -o nounset as the first line would be prudent.
    • set stuff is not inherited by subshells. So to make a failure in the dd command propagate you should start with set -o errexit -o pipefail. A simpler way to achieve the same effect would be to add -o pipefail to set, create a function with the dd | xxd commands, and use this directly instead of assigning to variables.
  • What happens if dd fails, for whatever reason? For example, dd() { echo foo; } will override the command. Use command dd [sic] if you want to make sure it doesn't use shell builtins, aliases or functions.
  • There's no == operator in POSIX [ - AFAIK this only works by accident on some systems. You can either use Bash' [[ or a single =.
  • || true can hide issues with the preceding command. Either check first if the command should be run before trying (and not ignoring the error), or run the command and check if the exit code matches the one you expect.
  • Use More QuotesTM

I can't comment on the safety of the KEYn generation or setkey use.

answered May 28, 2013 at 14:00
\$\endgroup\$
4
  • \$\begingroup\$ Thanks for the advices. The main concern is setkey. Can my tunnel suddenly become uncrypted? Is the encryption applied correctly? \$\endgroup\$ Commented May 28, 2013 at 17:57
  • \$\begingroup\$ Doesn't set -e dig into backticked command? If dd failed I expect the script to exit. \$\endgroup\$ Commented May 28, 2013 at 17:59
  • \$\begingroup\$ @Vi. Updated with tips. \$\endgroup\$ Commented May 29, 2013 at 8:18
  • \$\begingroup\$ @Vi. As I said, I can't really comment on the inner security issues. You may want to strip down to the bare minimum code and ask on security. \$\endgroup\$ Commented May 29, 2013 at 8:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.