From 1e20926763855b24f0474bdf65bf9b4a593eb731 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Fri, 8 Oct 2021 22:27:10 -0400 Subject: implement options --- connect-vpn.sh | 244 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file 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 @@ -#!/bin/sh -ROUTER_IP=68.48.18.140 -ROUTER_NAME=andy +#!/bin/bash +[ "$UID" = 0 ] || exec sudo -- "$0" "$@" || exit -CLIENT_KEY_BASENAME=ssh_host_rsa_key -CLIENT_KEY_DIRNAME=/etc/ssh -CLIENT_KEY=${CLIENT_KEY_DIRNAME}/${CLIENT_KEY_BASENAME} - -ssh2der() +help() { - ssh-keygen -e -f "$1" -m PEM | openssl rsa -RSAPublicKey_in -outform DER + prefixU="Usage: $0 " + prefix0=" $0 " + prefix1=${prefix0//?/ } + cat <...cryptonomic.net + +Synopsis: + +$prefix0 --remote-ip \\ +$prefix1 --remote-name + + +Usage: + +$prefix0 --remote-ip \\ +$prefix1 --remote-name \\ +$prefix1 [--remote-key-type rsa] \\ +$prefix1 [--local-key ] + + +Options: + + --remote-ip + --remote-name + + Remote IP and NAME are MANDATORY. + + --remote-key + + Remote key, if specified, must be 'rsa'. + + --local-key + + The specified key must be an RSA key. + + The filename is considered relative to /etc/ssh if it has no slashes. + + The default is 'ssh_host_rsa_key'. + +EOF } +die() { printf 'Error: %s\n' "$*"; exit 1; } + +REMOTE_IP=68.48.18.140 +REMOTE_NAME=andy +REMOTE_KEY_TYPE=rsa +LOCAL_KEY=ssh_host_rsa_key + +LOCAL_KEY_DEST_BASENAME=ssh_host_rsa_key +LOCAL_PRIVATE_KEY_DEST=/etc/swanctl/private/$LOCAL_KEY_DEST_BASENAME +LOCAL_PUBLIC_KEY_DEST=/etc/swanctl/pubkey/$LOCAL_KEY_DEST_BASENAME.pub + +OPTS=$(getopt \ + --options 'h' \ + --longoptions 'help,remote-ip:,remote-name:,remote-key-type:,local-key:' \ + -n connect-vpn \ + -- "$@") +eval set -- "$OPTS" +unset OPTS + +while true +do + case "$1" in + -h|--help) help; exit;; + --remote-ip) REMOTE_IP=$2; shift 2;; + --remote-name) REMOTE_NAME=$2; shift 2;; + --remote-key-type) REMOTE_KEY_TYPE=$2; shift 2;; + --local-key) LOCAL_KEY=$2; shift 2;; + --) shift; break;; + esac + shift +done + +if [ $# != 0 ] +then + help + exit 1 +fi + +[ "$REMOTE_IP" ] || die 'remote ip' # todo parse IP +[ "$REMOTE_NAME" ] || die 'remote name' # todo parse valid hostname +[ "$REMOTE_KEY_TYPE" = rsa ] + +case "$LOCAL_KEY" in + */*) ;; + *) LOCAL_KEY=/etc/ssh/$LOCAL_KEY ;; +esac + +[ -f "$LOCAL_KEY" -a -r "$LOCAL_KEY" ] || die "local key ($LOCAL_KEY)" + match_and_drop_first_word() { - expect=$1 - while read word rest - do - if [ "$word" = "$expect" ] - then - printf '%s\n' "$rest" - return - fi - done - false + expect=$1 + while read word rest + do + if [ "$word" = "$expect" ] + then + printf '%s\n' "$rest" + return + fi + done + false } keyscan() { - if [ -e keyscan.cache ] - then - cat keyscan.cache - else - ssh-keyscan -t rsa "$1" - fi + if [ -e keyscan.cache ] + then + cat keyscan.cache + else + semi_quietly ssh-keyscan -t "${REMOTE_KEY_TYPE}" "$1" + fi } write_successfully() @@ -45,7 +131,16 @@ write_successfully() then if [ "$NO_ACT" ] then - echo "mv $f $out" >&2 + ( + exec >&2 + echo "Write $out:" + case "$(file --mime-encoding "$f")" in + *': binary') xxd "$f" ;; + *) cat "$f" ;; + esac | sed 's/^/ /' + echo + ) + rm -f "$f" else mv "$f" "$out" fi @@ -55,36 +150,70 @@ write_successfully() fi } +semi_quietly() +{ + local t=$(mktemp) + if "$@" 2>"$t" + then + rm -f "$t" + else + cat "$t" >&2 + fi +} + +openssl() +{ + semi_quietly command openssl "$@" +} + +write_public_key() +{ + openssl rsa -in "$1" -outform DER +} +write_private_key() +{ + openssl rsa -in "$1" -outform DER -pubout +} + +write_remote_key() +{ + case "$REMOTE_KEY_TYPE" in + rsa) ssh-keygen -e -f "$1" -m PEM | openssl rsa -RSAPublicKey_in -outform DER ;; + *) echo "Unsupported key type." >&2; exit 1 ;; + esac +} + keycopy() { - private_key_tmp="$(mktemp)" || return - cp "$CLIENT_KEY" "$private_key_tmp" - ssh-keygen -N '' -P '' -p -m PEM -f "$private_key_tmp" + private_key_tmp=$(mktemp) || return + cp "$LOCAL_KEY" "$private_key_tmp" + ssh-keygen -N '' -p -m PEM -f "$private_key_tmp" >/dev/null 2>&1 trap 'rm -f "$private_key_tmp"' EXIT - write_successfully /etc/swanctl/private/"$CLIENT_KEY_BASENAME" -- openssl rsa -in "$private_key_tmp" -outform DER - write_successfully /etc/swanctl/pubkey/"$CLIENT_KEY_BASENAME".pub -- openssl rsa -in "$private_key_tmp" -outform DER -pubout + write_successfully "$LOCAL_PRIVATE_KEY_DEST" -- write_private_key "$private_key_tmp" + write_successfully "$LOCAL_PUBLIC_KEY_DEST" -- write_public_key "$private_key_tmp" trap - EXIT rm -f "$private_key_tmp" - t=$(mktemp) - keyscan "$ROUTER_IP" | match_and_drop_first_word "$ROUTER_IP" > "$t" - write_successfully /etc/swanctl/pubkey/"$ROUTER_NAME".pub -- ssh2der "$t" - rm -f "$t" + trap 'rm -f "$t"' EXIT + t=$(mktemp) + keyscan "$REMOTE_IP" | match_and_drop_first_word "$REMOTE_IP" > "$t" + write_successfully /etc/swanctl/pubkey/"$REMOTE_NAME".pub -- write_remote_key "$t" + trap - EXIT + rm -f "$t" } nocomments() { - sed 's/#.*//; /^ *$/d' + sed 's/#.*//; /^ *$/d' } - config() { local conn="$1" remote_addrs="$2" id="$3" + local public_key_file="$4" private_key_file="$5" local remote_ts=0::0/0 vips=:: - local public_key_file="${CLIENT_KEY_BASENAME}.pub" private_key_file="${CLIENT_KEY_BASENAME}" sed -e 's/^ //' <&1 set -e keycopy test_new_config - -- cgit v1.2.3