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.
-
\$\begingroup\$ Note: filed a bug reproduced with this script. \$\endgroup\$Vi.– Vi.2013年05月23日 15:03:09 +00:00Commented May 23, 2013 at 15:03
1 Answer 1
- 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
andDST
.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 thedd
command propagate you should start withset -o errexit -o pipefail
. A simpler way to achieve the same effect would be to add-o pipefail
toset
, create a function with thedd | 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. Usecommand 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.
-
\$\begingroup\$ Thanks for the advices. The main concern is
setkey
. Can my tunnel suddenly become uncrypted? Is the encryption applied correctly? \$\endgroup\$Vi.– Vi.2013年05月28日 17:57:18 +00:00Commented May 28, 2013 at 17:57 -
\$\begingroup\$ Doesn't
set -e
dig into backticked command? Ifdd
failed I expect the script to exit. \$\endgroup\$Vi.– Vi.2013年05月28日 17:59:39 +00:00Commented May 28, 2013 at 17:59 -
\$\begingroup\$ @Vi. Updated with tips. \$\endgroup\$l0b0– l0b02013年05月29日 08:18:13 +00:00Commented May 29, 2013 at 8:18
-