From d4acd873b02e7f0a2d2695309a3b2790fe12984e Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 6 Mar 2020 16:21:29 +0200 Subject: Add: first version --- ssh-config.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ssh-config.py | 21 ++++++++++++++++++++ ssh-config.yaml | 5 +++++ 3 files changed, 87 insertions(+) create mode 100644 ssh-config.md create mode 100644 ssh-config.py create mode 100644 ssh-config.yaml diff --git a/ssh-config.md b/ssh-config.md new file mode 100644 index 0000000..96dc320 --- /dev/null +++ b/ssh-config.md @@ -0,0 +1,61 @@ +--- +title: SSH client config for WMF +author: Lars Wirzenius +bindings: ssh-config.yaml +functions: ssh-config.py +... + +# Introduction + +I need to access certain servers for my work at WMF using SSH. For +this to work, I need an SSH client config that uses the right SSH keys +and routes access via a "bastion" server. This document has acceptance +criteria for my config. + +My configuation is based on the one [on +wikitech](https://wikitech.wikimedia.org/wiki/Production_access#Setting_up_your_SSH_config): + +~~~ +# Configure the initial connection to the bastion host, with the one HostName closest to you +Host bast + User your_username_here + HostName bast1002.wikimedia.org + IdentityFile ~/.ssh/your_production_ssh_key + ForwardAgent no + IdentitiesOnly yes + +# Proxy all connections to internal servers through the bastion host +Host *.wmnet + User your_username_here + ProxyCommand ssh -W %h:%p bast + IdentityFile ~/.ssh/your_production_ssh_key + ForwardAgent no + IdentitiesOnly yes +~~~ + +# Acceptance criteria + +For my work I need to access production servers. Most of them don't +allow direct SSH access and I need to go through a bastion server. + +There are also two keys: a "lab" key and a "production" key. The SSH +config ensures the right key is used. + +## Bastion access + +This scenario ensures I can access the bastion host directly. + +~~~scenario +when I run ssh bast hostname +then the output matches /^bast\d+$/ +~~~ + +## Deployment server access + +This scenario ensures I can access the deployment host for running the +train. + +~~~scenario +when I run ssh deploy1001.eqiad.wmnet hostname +then the output matches /^deploy\d+$/ +~~~ diff --git a/ssh-config.py b/ssh-config.py new file mode 100644 index 0000000..bea1453 --- /dev/null +++ b/ssh-config.py @@ -0,0 +1,21 @@ +import os +import re +import subprocess + +def run_ssh(ctx, host=None, cmd=None): + _runcmd(ctx, ['ssh', host, cmd]) + if ctx.get('exit') != 0: + print('context:', ctx.as_dict()) + assert_eq(ctx.get('exit'), 0) + +def stdout_matches(ctx, regex): + stdout = ctx.get('stdout', '') + assert_ne(re.search(regex, stdout), None) + +def _runcmd(ctx, argv): + p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate("") + ctx['argv'] = argv + ctx['stdout'] = stdout.decode('utf-8') + ctx['stderr'] = stderr.decode('utf-8') + ctx['exit'] = p.returncode diff --git a/ssh-config.yaml b/ssh-config.yaml new file mode 100644 index 0000000..376fe44 --- /dev/null +++ b/ssh-config.yaml @@ -0,0 +1,5 @@ +- when: I run ssh (?P\S+) (?P.+) + function: run_ssh + +- then: the output matches /(?P.+)/ + function: stdout_matches -- cgit v1.2.1