From 466fcd268e53743ca7414f1fe969a74cd0ac1ee1 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 12 Mar 2021 08:10:42 +0200 Subject: drop old crap --- sshvia | 219 ----------------------------------------------------------------- 1 file changed, 219 deletions(-) delete mode 100755 sshvia (limited to 'sshvia') diff --git a/sshvia b/sshvia deleted file mode 100755 index ea94018..0000000 --- a/sshvia +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/python -# -# Summary -# ======= -# -# ssh user1%foo:2222+user2%bar -# -# This logs in a user2@bar via user1@foo (port 2222). All -# authentication happens locally, not on remote hosts. Private keys -# are only locally, not on foo. -# -# Note that port for the last host must be given using ssh -p, not a -# :22 suffix to the host. This is because this script doesn't get -# called in that case and can't handle it, and ssh itself doesn't -# handle it. -# -# Description -# =========== -# -# This is a helper to allow ssh to be used in a "via this host" -# manner. The user runs "ssh foo+bar" and this effectively logs them -# into bar by first logging into foo and running ssh there. -# -# This is useful when bar is not directly accessible from the local -# machine, but foo is. Authentication (ssh private keys, password -# entry) is done on the local machine, even for the login to bar: -# there is no need to, for example, store ssh private keys on foo. -# -# Example use case: one has a set of virtual machines behind a -# firewall or NAT, and only one of them is accessible from anywhere on -# the Internet. This is called a jump host. You're expected to access -# the other hosts via the jumphost. -# -# Setup -# ===== -# -# User needs to setup their ssh on the local host (via ~/.ssh/config) -# to run this when there is a plus sign in the target hostname: -# -# Host *+* -# ProxyCommand $(sshvia %h %p) -# -# Also, this script should be executable and accessible via $PATH, or -# else the config file should use the full path to this script. -# -# There is no need to configure anything on remote hosts, assuming -# they have a working ssh already. -# -# Implementation -# ============== -# -# This program outputs the magic ssh command line to connect to the -# first target on the command line and to forward its stdin, stdout to -# to that host. In other words, given the following command line: -# -# ssh foo+bar -# -# Each target separated by + has the following form: -# -# [user%]host[:port] -# -# Note the use of % instead of @ to get around the parsing that ssh -# itself does. -# -# Using the above configuration, when the user runs "ssh foo+bar", -# the following happens: -# -# * ssh matches "foo+bar" to the "Host *+*" section, and runs -# the proxy command. -# -# * The proxy command invokes "ssh foo -W bar:22", which means -# it connects to foo and forwards the local stdin/stdout to -# bar's ssh port. The forwarding happens over the secure link -# to foo. -# -# * The ssh started by the user uses the proxy command's -# stdin/stdout to talk to what it thinks is the "foo+bar" -# server. In other words, instead of making a TCP connection -# to the host named "foo+bar" and sets up an encrypted channel -# over that TCP connection, it uses the stdin/stdout of the -# proxy command instead. -# -# In other words, the ssh client started by the user talks to -# the ssh server on bar, but the communication goes via the -# secure channel to foo. -# -# Additionally, this script gives ssh options to set the remote user -# and port for the first host in a chain. - -import re -import sys - -import cliapp - - -def debug(msg): - # Set condition below to true to get debug output to stderr. - if False: - sys.stderr.write('SSHVIA DEBUG: {}\n'.format(msg)) - - -def panic(msg): - sys.stderr.write('SSHVIA ERROR: {}\n'.format(msg)) - sys.exit(1) - - -def extract_last_target(full_target): - # Input is foo+bar. Return foo, bar. - i = full_target.rfind('+') - if i == -1: - return None, full_target - return full_target[:i], full_target[i+1:] - - -def extract_targets(full_target): - targets = [] - remaining = full_target - while remaining: - remaining, target = extract_last_target(remaining) - targets.append(target) - return list(reversed(targets)) - - -def parse_target(target): - # Input is of the form: [user%]host[:port] - # Return user, host, port (None for user, port if missing). - - percent = target.find('%') - colon = target.find(':') - - user = None - port = None - - if percent == -1 and colon == -1: - # It's just the host. - host = target - elif percent >= 0 and colon >= 0 and percent < colon: - # It's user%host:port - user = target[:percent] - host = target[percent+1:colon] - port = target[colon+1:] - elif percent >= 0 and colon >= 0 and percent >= colon: - # it's an error - panic('Do not understand %r' % target) - elif percent >= 0: - # It's user%host - user = target[:percent] - host = target[percent+1:] - elif colon >= 0: - # It's host:port - host = target[:colon] - port = target[colon+1:] - else: - # it's a programming error - panic('Confused by %r' % target) - - return user, host, port - - -# ssh parses its own command line, and extracts target host, target -# port, and target (or remote) username. However, since ssh doesn't -# actually understand the + syntax itself, it gets things muddled: it -# parses user1@host1:8888+user2@host2:2222 in ways that will confuse -# users. Thus, we want the user to use % instead of @ so that ssh -# doesn't get in the way. -# -# ssh also allows the user to provide the remote user with the -l -# option, but we do not need to care about that, since it'll only be -# used to log into the last host in the chain. -# -# We do need to care about ports. ssh's -p option may be used for the -# last host in the chain, but every host in the chain may use : to -# separate a port number. - - -# Parse command line. We expect the full host (%h) and the port for -# thst last host in the chain (%p). That port may be the default 22, -# and will be overriden by the post in the full host if given. - -debug('argv: %r' % sys.argv) -full_target, last_target_default_port = sys.argv[1:] - -targets = extract_targets(full_target) -debug('targets: %r' % targets) -if len(targets) < 2: - panic('ERROR: Must be called with foo+bar syntax!') - -first_target = targets[0] -middle_targets = targets[1:-1] -last_target = targets[-1] - - -# Extract user from first target. -first_user, first_host, first_port = parse_target(first_target) - -# Extract port from last target. Replace with default if missing. -last_user, last_host, last_port = parse_target(last_target) -if last_port is None: - last_port = last_target_default_port - -# Set up the argv array. -argv = ['ssh', '-W', '{}:{}'.format(last_host, last_port)] - -if first_user is not None: - argv.extend(['-l', first_user]) -if first_port is not None: - argv.extend(['-p', first_port]) -all_but_last = [first_host] + middle_targets -argv.append('+'.join(all_but_last)) - - -# Shell-quote everything in argv, to avoid shell metacharacters from -# causing trouble. -argv = [cliapp.shell_quote(x) for x in argv] - - -# Output the command. -debug('result: %r' % argv) -sys.stdout.write(' '.join(argv) + '\n') -- cgit v1.2.1