summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@cryptonomic.net>2021-10-08 22:27:10 -0400
committerAndrew Cady <d@cryptonomic.net>2021-10-08 22:27:10 -0400
commit1e20926763855b24f0474bdf65bf9b4a593eb731 (patch)
treec9e9485d7da64de1b65cf04ece8d2145f8417369
parent448cab6d8f073558a3f4c3a85652d3fcbf03c100 (diff)
implement optionsHEADmaster
-rwxr-xr-xconnect-vpn.sh244
1 files changed, 193 insertions, 51 deletions
diff --git a/connect-vpn.sh b/connect-vpn.sh
index f4f302c..6292979 100755
--- a/connect-vpn.sh
+++ b/connect-vpn.sh
@@ -1,38 +1,124 @@
1#!/bin/sh 1#!/bin/bash
2ROUTER_IP=68.48.18.140 2[ "$UID" = 0 ] || exec sudo -- "$0" "$@" || exit
3ROUTER_NAME=andy
4 3
5CLIENT_KEY_BASENAME=ssh_host_rsa_key 4help()
6CLIENT_KEY_DIRNAME=/etc/ssh
7CLIENT_KEY=${CLIENT_KEY_DIRNAME}/${CLIENT_KEY_BASENAME}
8
9ssh2der()
10{ 5{
11 ssh-keygen -e -f "$1" -m PEM | openssl rsa -RSAPublicKey_in -outform DER 6 prefixU="Usage: $0 "
7 prefix0=" $0 "
8 prefix1=${prefix0//?/ }
9 cat <<EOF
10
11Synopsis:
12
13$prefix0 <hostname>.<keystring>.<keytype>.cryptonomic.net
14
15Synopsis:
16
17$prefix0 --remote-ip <IP address> \\
18$prefix1 --remote-name <hostname>
19
20
21Usage:
22
23$prefix0 --remote-ip <IP address> \\
24$prefix1 --remote-name <hostname> \\
25$prefix1 [--remote-key-type rsa] \\
26$prefix1 [--local-key <filename>]
27
28
29Options:
30
31 --remote-ip
32 --remote-name
33
34 Remote IP and NAME are MANDATORY.
35
36 --remote-key
37
38 Remote key, if specified, must be 'rsa'.
39
40 --local-key
41
42 The specified key must be an RSA key.
43
44 The filename is considered relative to /etc/ssh if it has no slashes.
45
46 The default is 'ssh_host_rsa_key'.
47
48EOF
12} 49}
50die() { printf 'Error: %s\n' "$*"; exit 1; }
51
52REMOTE_IP=68.48.18.140
53REMOTE_NAME=andy
54REMOTE_KEY_TYPE=rsa
55LOCAL_KEY=ssh_host_rsa_key
56
57LOCAL_KEY_DEST_BASENAME=ssh_host_rsa_key
58LOCAL_PRIVATE_KEY_DEST=/etc/swanctl/private/$LOCAL_KEY_DEST_BASENAME
59LOCAL_PUBLIC_KEY_DEST=/etc/swanctl/pubkey/$LOCAL_KEY_DEST_BASENAME.pub
60
61OPTS=$(getopt \
62 --options 'h' \
63 --longoptions 'help,remote-ip:,remote-name:,remote-key-type:,local-key:' \
64 -n connect-vpn \
65 -- "$@")
66eval set -- "$OPTS"
67unset OPTS
68
69while true
70do
71 case "$1" in
72 -h|--help) help; exit;;
73 --remote-ip) REMOTE_IP=$2; shift 2;;
74 --remote-name) REMOTE_NAME=$2; shift 2;;
75 --remote-key-type) REMOTE_KEY_TYPE=$2; shift 2;;
76 --local-key) LOCAL_KEY=$2; shift 2;;
77 --) shift; break;;
78 esac
79 shift
80done
81
82if [ $# != 0 ]
83then
84 help
85 exit 1
86fi
87
88[ "$REMOTE_IP" ] || die 'remote ip' # todo parse IP
89[ "$REMOTE_NAME" ] || die 'remote name' # todo parse valid hostname
90[ "$REMOTE_KEY_TYPE" = rsa ]
91
92case "$LOCAL_KEY" in
93 */*) ;;
94 *) LOCAL_KEY=/etc/ssh/$LOCAL_KEY ;;
95esac
96
97[ -f "$LOCAL_KEY" -a -r "$LOCAL_KEY" ] || die "local key ($LOCAL_KEY)"
98
13 99
14match_and_drop_first_word() 100match_and_drop_first_word()
15{ 101{
16 expect=$1 102 expect=$1
17 while read word rest 103 while read word rest
18 do 104 do
19 if [ "$word" = "$expect" ] 105 if [ "$word" = "$expect" ]
20 then 106 then
21 printf '%s\n' "$rest" 107 printf '%s\n' "$rest"
22 return 108 return
23 fi 109 fi
24 done 110 done
25 false 111 false
26} 112}
27 113
28keyscan() 114keyscan()
29{ 115{
30 if [ -e keyscan.cache ] 116 if [ -e keyscan.cache ]
31 then 117 then
32 cat keyscan.cache 118 cat keyscan.cache
33 else 119 else
34 ssh-keyscan -t rsa "$1" 120 semi_quietly ssh-keyscan -t "${REMOTE_KEY_TYPE}" "$1"
35 fi 121 fi
36} 122}
37 123
38write_successfully() 124write_successfully()
@@ -45,7 +131,16 @@ write_successfully()
45 then 131 then
46 if [ "$NO_ACT" ] 132 if [ "$NO_ACT" ]
47 then 133 then
48 echo "mv $f $out" >&2 134 (
135 exec >&2
136 echo "Write $out:"
137 case "$(file --mime-encoding "$f")" in
138 *': binary') xxd "$f" ;;
139 *) cat "$f" ;;
140 esac | sed 's/^/ /'
141 echo
142 )
143 rm -f "$f"
49 else 144 else
50 mv "$f" "$out" 145 mv "$f" "$out"
51 fi 146 fi
@@ -55,36 +150,70 @@ write_successfully()
55 fi 150 fi
56} 151}
57 152
153semi_quietly()
154{
155 local t=$(mktemp)
156 if "$@" 2>"$t"
157 then
158 rm -f "$t"
159 else
160 cat "$t" >&2
161 fi
162}
163
164openssl()
165{
166 semi_quietly command openssl "$@"
167}
168
169write_public_key()
170{
171 openssl rsa -in "$1" -outform DER
172}
173write_private_key()
174{
175 openssl rsa -in "$1" -outform DER -pubout
176}
177
178write_remote_key()
179{
180 case "$REMOTE_KEY_TYPE" in
181 rsa) ssh-keygen -e -f "$1" -m PEM | openssl rsa -RSAPublicKey_in -outform DER ;;
182 *) echo "Unsupported key type." >&2; exit 1 ;;
183 esac
184}
185
58keycopy() 186keycopy()
59{ 187{
60 private_key_tmp="$(mktemp)" || return 188 private_key_tmp=$(mktemp) || return
61 cp "$CLIENT_KEY" "$private_key_tmp" 189 cp "$LOCAL_KEY" "$private_key_tmp"
62 ssh-keygen -N '' -P '' -p -m PEM -f "$private_key_tmp" 190 ssh-keygen -N '' -p -m PEM -f "$private_key_tmp" >/dev/null 2>&1
63 trap 'rm -f "$private_key_tmp"' EXIT 191 trap 'rm -f "$private_key_tmp"' EXIT
64 192
65 write_successfully /etc/swanctl/private/"$CLIENT_KEY_BASENAME" -- openssl rsa -in "$private_key_tmp" -outform DER 193 write_successfully "$LOCAL_PRIVATE_KEY_DEST" -- write_private_key "$private_key_tmp"
66 write_successfully /etc/swanctl/pubkey/"$CLIENT_KEY_BASENAME".pub -- openssl rsa -in "$private_key_tmp" -outform DER -pubout 194 write_successfully "$LOCAL_PUBLIC_KEY_DEST" -- write_public_key "$private_key_tmp"
67 195
68 trap - EXIT 196 trap - EXIT
69 rm -f "$private_key_tmp" 197 rm -f "$private_key_tmp"
70 198
71 t=$(mktemp) 199 trap 'rm -f "$t"' EXIT
72 keyscan "$ROUTER_IP" | match_and_drop_first_word "$ROUTER_IP" > "$t" 200 t=$(mktemp)
73 write_successfully /etc/swanctl/pubkey/"$ROUTER_NAME".pub -- ssh2der "$t" 201 keyscan "$REMOTE_IP" | match_and_drop_first_word "$REMOTE_IP" > "$t"
74 rm -f "$t" 202 write_successfully /etc/swanctl/pubkey/"$REMOTE_NAME".pub -- write_remote_key "$t"
203 trap - EXIT
204 rm -f "$t"
75} 205}
76 206
77nocomments() 207nocomments()
78{ 208{
79 sed 's/#.*//; /^ *$/d' 209 sed 's/#.*//; /^ *$/d'
80} 210}
81 211
82
83config() 212config()
84{ 213{
85 local conn="$1" remote_addrs="$2" id="$3" 214 local conn="$1" remote_addrs="$2" id="$3"
215 local public_key_file="$4" private_key_file="$5"
86 local remote_ts=0::0/0 vips=:: 216 local remote_ts=0::0/0 vips=::
87 local public_key_file="${CLIENT_KEY_BASENAME}.pub" private_key_file="${CLIENT_KEY_BASENAME}"
88 sed -e 's/^ //' <<END 217 sed -e 's/^ //' <<END
89 connections { 218 connections {
90 ${conn} { 219 ${conn} {
@@ -116,10 +245,17 @@ END
116 245
117get_my_mac() 246get_my_mac()
118{ 247{
119 iface=$(ip -oneline route get "$1" | sed -ne 's/.* dev \([^ ]*\) .*/\1/p') 248 iface=$(ip -oneline route get "$1" | sed -ne 's/.* dev \([^ ]*\) .*/\1/p')
120 [ "$iface" ] || return 249 [ "$iface" ] || return
121 my_mac=$(ip -oneline -6 addr show dev "$iface" | sed -ne 's/.* inet6 fe80::\([^/]*\)\/.*/\1/p') 250 my_mac=$(ip -oneline -6 addr show dev "$iface" | sed -ne 's/.* inet6 fe80::\([^/]*\)\/.*/\1/p')
122 [ "$my_mac" ] 251 [ "$my_mac" ]
252}
253
254crypto_get_my_mac()
255{
256 my_mac=$(ssh-keygen -r . -f "$LOCAL_KEY" |
257 sed -E -ne 's/^[^ ]+ IN SSHFP [^ ]+ 2 .{48}(.{4})(.{4})(.{4})(.{4})$/\1:\2:\3:\4/p')
258 [ "$my_mac" ]
123} 259}
124 260
125NO_ACT() 261NO_ACT()
@@ -129,25 +265,31 @@ NO_ACT()
129 265
130write_config() 266write_config()
131{ 267{
132 get_my_mac "$ROUTER_IP" || return 268 crypto_get_my_mac "$REMOTE_IP" || return
133 write_successfully /etc/swanctl/conf.d/"$ROUTER_NAME".conf -- config "$ROUTER_NAME" "$ROUTER_IP" "$my_mac" 269 write_successfully /etc/swanctl/conf.d/"$REMOTE_NAME".conf -- \
270 config \
271 "$REMOTE_NAME" \
272 "$REMOTE_IP" \
273 "$my_mac" \
274 "$LOCAL_PUBLIC_KEY_DEST" \
275 "$LOCAL_PRIVATE_KEY_DEST"
134} 276}
135 277
136test_new_config() 278test_new_config()
137{ 279{
138 NO_ACT ipsec stop 280 NO_ACT ipsec stop
139 281
140 write_config 282 write_config
141 283
142 NO_ACT ipsec start 284 NO_ACT ipsec start
143 NO_ACT sleep 2 285 NO_ACT sleep 2
144 NO_ACT swanctl -c 286 NO_ACT swanctl -c
145 NO_ACT ipsec listpubkeys 287 NO_ACT ipsec listpubkeys
146 NO_ACT ipsec up ${ROUTER_NAME} 288 NO_ACT ipsec up "${REMOTE_NAME}"
147} 289}
148 290
149NO_ACT=y 291NO_ACT=y
292exec 2>&1
150set -e 293set -e
151keycopy 294keycopy
152test_new_config 295test_new_config
153