]> git.corax.cc Git - toolbox/commitdiff
include/ssh: Add functions for handling SSH tunnels and proxies
authorMatthias Kruk <m@m10k.eu>
Wed, 24 Mar 2021 22:26:46 +0000 (07:26 +0900)
committerMatthias Kruk <m@m10k.eu>
Wed, 24 Mar 2021 22:26:46 +0000 (07:26 +0900)
SSH provides a clean way to open and close tunnels and proxies on demand
through control sockets, however keeping track of the control sockets can
be somewhat bothersome. This commit adds functions that provide an easy
way to open and close tunnels and proxies without the caller having to
bother with control sockets.

include/ssh.sh [new file with mode: 0644]

diff --git a/include/ssh.sh b/include/ssh.sh
new file mode 100644 (file)
index 0000000..fe1d32c
--- /dev/null
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+__init() {
+       if ! include "log"; then
+               return 1
+       fi
+
+       declare -xgr __ssh_socket_dir="$TOOLBOX_HOME/ssh"
+
+       return 0
+}
+
+_ssh_get_socket_dir() {
+       if ! mkdir -p "$__ssh_socket_dir" &> /dev/null; then
+               error "Could not create $__ssh_socket_dir"
+               return 1
+       fi
+
+       echo "$__ssh_socket_dir"
+       return 0
+}
+
+_ssh_tunnel_ctrl_socket_name() {
+       local host
+       local port
+       local lport
+
+       local sockdir
+
+       host="$1"
+       port="$2"
+       lport="$3"
+
+       if ! sockdir=$(_ssh_get_socket_dir); then
+               return 1
+       fi
+
+       echo "$sockdir/tunnel-$lport-$host-$port.sock"
+       return 0
+}
+
+_ssh_proxy_ctrl_socket_name() {
+       local host
+       local port
+
+       local sockdir
+
+       host="$1"
+       port="$2"
+
+       if ! sockdir=$(_ssh_get_socket_dir); then
+               return 1
+       fi
+
+       echo "$sockdir/proxy-$host-$port.sock"
+       return 0
+}
+
+ssh_tunnel_open() {
+       local tunnel_host
+       local tunnel_user
+       local remote_addr
+       local remote_port
+       local local_addr
+       local local_port
+
+       tunnel_host="$1"
+       tunnel_user="$2"
+       remote_addr="$3"
+        remote_port="$4"
+       local_addr="$5"
+       local_port="$6"
+
+       local ctrl_sock
+       local addrspec
+       local sshtarget
+
+       if ! ctrl_sock=$(_ssh_tunnel_ctrl_socket_name "$remote_addr" \
+                                                     "$remote_port" \
+                                                     "$local_port"); then
+               return 1
+       fi
+
+       addrspec="$local_addr:$local_port:$remote_addr:$remote_port"
+       sshtarget="$tunnel_user@$tunnel_host"
+
+       if ! ssh -M -S "$ctrl_sock" -fnNT -o "ExitOnForwardFailure=yes" \
+            -L "$addrspec" "$sshtarget" > /dev/null; then
+               return 1
+       fi
+
+       echo "$ctrl_sock"
+       return 0
+}
+
+ssh_tunnel_close() {
+       local tunnel_host
+       local tunnel_user
+       local ctrl_sock
+
+       tunnel_host="$1"
+       tunnel_user="$2"
+       ctrl_sock="$3"
+
+       if ! ssh -S "$ctrl_sock" -O exit "$tunnel_user@$tunnel_host" &> /dev/null; then
+               return 1
+       fi
+
+       return 0
+}
+
+ssh_proxy_open() {
+       local proxy_host
+       local proxy_user
+       local local_addr
+       local local_port
+
+       local ctrl_sock
+       local addrspec
+       local sshtarget
+
+       proxy_host="$1"
+       proxy_user="$2"
+       local_addr="$3"
+       local_port="$4"
+
+       if ! ctrl_sock=$(_ssh_proxy_ctrl_socket_name "$local_addr" "$local_port"); then
+               return 1
+       fi
+
+       addrspec="$local_addr:$local_port"
+       sshtarget="$proxy_user@$proxy_host"
+
+       if ! ssh -M -S "$ctrl_sock" -fnNT -o "ExitOnForwardFailure=yes" \
+            -D "$addrspec" "$sshtarget" > /dev/null; then
+               return 1
+       fi
+
+       echo "$ctrl_sock"
+       return 0
+}
+
+ssh_proxy_close() {
+       local proxy_host
+       local proxy_user
+       local ctrl_sock
+
+       proxy_host="$1"
+       proxy_user="$2"
+       ctrl_sock="$3"
+
+       if ! ssh -S "$ctrl_sock" -O exit "$proxy_user@$proxy_host" &> /dev/null; then
+               return 1
+       fi
+
+       return 0
+}