diff options
author | Andrew Cady <d@jerkface.net> | 2021-10-09 08:50:54 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2021-10-09 08:55:09 -0400 |
commit | e9fed06432ebe404e8e43a6e0abf3a1ec5161dfb (patch) | |
tree | 82a0ff87c3566cf50aeb73c877cea74ac310b650 | |
parent | 204468735750c028641fa6438b956289b573194e (diff) |
locally authenticate cryptonomic.net self-authenticating names
this is pretty sweet
-rwxr-xr-x | cryptonomic-vpn | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/cryptonomic-vpn b/cryptonomic-vpn index d983e60..bdb8f41 100755 --- a/cryptonomic-vpn +++ b/cryptonomic-vpn | |||
@@ -167,8 +167,10 @@ main() | |||
167 | if [ "$NO_ACT" ] | 167 | if [ "$NO_ACT" ] |
168 | then | 168 | then |
169 | exec 2>&1 | 169 | exec 2>&1 |
170 | install_local_private_key | 170 | # Start with the remote public key, to fail early if the server is |
171 | # unavailable. | ||
171 | install_remote_public_key | 172 | install_remote_public_key |
173 | install_local_private_key | ||
172 | test_new_config | 174 | test_new_config |
173 | else | 175 | else |
174 | die unimplemented | 176 | die unimplemented |
@@ -277,11 +279,41 @@ install_local_private_key() | |||
277 | rm -f "$private_key_tmp" | 279 | rm -f "$private_key_tmp" |
278 | } | 280 | } |
279 | 281 | ||
282 | b16_to_b32() | ||
283 | { | ||
284 | printf %s "$1" | basez -x -d | basez -j -l | tr -d = | ||
285 | } | ||
286 | |||
287 | key_to_domain_suffix() | ||
288 | { | ||
289 | [ -f "$1" ] || return | ||
290 | local keytype=1 hashtype=2 sshfp_b16 sshfp_b32 | ||
291 | sshfp_b16=$(ssh-keygen -r . -f "$1" | sed -ne "s/^. IN SSHFP $keytype $hashtype //p") && | ||
292 | [ "$sshfp_b16" ] || die "could not determine ssh client fingerprint" | ||
293 | sshfp_b32=$(b16_to_b32 "$sshfp_b16") | ||
294 | |||
295 | printf %s.%s.%s "$sshfp_b32" "$REMOTE_KEY_TYPE" cryptonomic.net | tail -c64 | ||
296 | } | ||
297 | |||
298 | validate_public_key() | ||
299 | { | ||
300 | local suffix keyfile="$1" name="$2" | ||
301 | [ "$keyfile" ] | ||
302 | [ "$name" ] | ||
303 | suffix=$(key_to_domain_suffix "$keyfile") | ||
304 | |||
305 | case "$name" in | ||
306 | *."$suffix" | "$suffix" ) true ;; | ||
307 | * ) false ;; | ||
308 | esac | ||
309 | } | ||
310 | |||
280 | install_remote_public_key() | 311 | install_remote_public_key() |
281 | { | 312 | { |
282 | trap 'rm -f "$t"' EXIT | 313 | trap 'rm -f "$t"' EXIT |
283 | t=$(mktemp) | 314 | t=$(mktemp) |
284 | keyscan "$REMOTE_IP" | match_and_drop_first_word "$REMOTE_IP" > "$t" | 315 | keyscan "$REMOTE_IP" | match_and_drop_first_word "$REMOTE_IP" > "$t" |
316 | validate_public_key "$t" "$REMOTE_NAME" || die 'cannot authenticate remote public key' | ||
285 | write_successfully /etc/swanctl/pubkey/"$REMOTE_NAME".pub -- write_remote_key "$t" | 317 | write_successfully /etc/swanctl/pubkey/"$REMOTE_NAME".pub -- write_remote_key "$t" |
286 | trap - EXIT | 318 | trap - EXIT |
287 | rm -f "$t" | 319 | rm -f "$t" |
@@ -297,7 +329,7 @@ strongswan_config() | |||
297 | local conn="$1" remote_addrs="$2" local_key="$3" | 329 | local conn="$1" remote_addrs="$2" local_key="$3" |
298 | local public_key_file="$4" private_key_file="$5" | 330 | local public_key_file="$4" private_key_file="$5" |
299 | local remote_ts=0::0/0 vips=:: | 331 | local remote_ts=0::0/0 vips=:: |
300 | id=$(key_to_suffix "$local_key") || return | 332 | id=$(key_to_ip_suffix "$local_key") || return |
301 | sed -e 's/^ //' <<END | 333 | sed -e 's/^ //' <<END |
302 | connections { | 334 | connections { |
303 | ${conn} { | 335 | ${conn} { |
@@ -327,7 +359,7 @@ strongswan_config() | |||
327 | END | 359 | END |
328 | } | 360 | } |
329 | 361 | ||
330 | key_to_suffix() | 362 | key_to_ip_suffix() |
331 | { | 363 | { |
332 | local keytype=1 hashtype=2 | 364 | local keytype=1 hashtype=2 |
333 | ssh-keygen -r . -f "$1" | sed -E -ne 's/^. IN SSHFP '"$keytype $hashtype"' .{48}(.{4})(.{4})(.{4})(.{4})$/\1:\2:\3:\4/p' | 365 | ssh-keygen -r . -f "$1" | sed -E -ne 's/^. IN SSHFP '"$keytype $hashtype"' .{48}(.{4})(.{4})(.{4})(.{4})$/\1:\2:\3:\4/p' |