2019/03/26

Automating SSH tunnels

I need a persistent port forwarding configuration between two systems, where there may be more than one SSH jump between the two.  I want systemd to make sure it's running all the time.

A solution:
    # Systemd unit file for an SSH Tunnel service
    #
    [Service]
    Type=simple

    User=tunnel
    ExecStart=/usr/bin/ssh -F /home/tunnel/ssh-config-for-tunnel -vN tunnel.%i

    # On failure, wait 10 seconds to restart
    Restart=always
    RestartSec=10

    # 20 failures within a 10 minute window marks this service as failed.
    StartLimitInterval=600
    StartLimitBurst=20

    [Unit]
    Description="SSH Tunnel to %i"
    Requires=network-online.target

    [Install]
    WantedBy=multi-user.target
From here, I create a trusted keypair with
ssh-keygen -t ed25519
and configure the ssh-config-for-tunnel file:
# Configuration of the SSH tunnel from here to there
# Requirements:
#   This file in /home/tunnel/ssh-config-for-tunnel

#   Service /etc/systemd/system/ssh-tunnel@.service enabled and started
#
#   Additional tunnels can be enabled as ssh-tunnel@elsewhere.service

# Special defaults for tunnels
Host *
    ControlMaster no
    ExitOnForwardFailure yes
    IdentitiesOnly yes

#####################################################################
# Configure Tunnel:
#####################################################################
Host tunnel.myservice
    ### Connection:
    # Private IP of ultimate destination
    HostName 172.31.92.114
    # Identity on the CB master
    IdentityFile ~/.ssh/id_master
    # Public IP of Jump 1 bastion
    ProxyJump 192.168.100.142

    ### Tunnels:
    # Take near port :18443 and send it to master's listener
    LocalForward 8444 localhost:8443
    # Take far port :6100 and bring it back to local listener
    RemoteForward 6100 161.134.130.247:6100

# Jump configurations
Host 192.168.100.142
    # Configuration for the bastion system
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump 10.192.107.33

Host 10.192.107.33
    IdentityFile ~/.ssh/id_ed25519

This example connects from localhost to 10.192.107.33, then from there to 192.168.100.142, then from there to 172.31.92.114, the server that I need the tunnel to, and it sets up port forwarding from end to end, without trying to get the ports on the series of jump servers.

2019/01/11

Create a python virtualenvironment and matching Jupyter kernel

I often work in Jupyter notebook for python scriptlets, and if there's a special package I need, I'd rather not pollute my global python environment. The answer, of course, is virtualenv and a jupyter kernel that references that venv, which I have to look up the command for every time.

 Automation to the rescue-- here's newkernel.cmd:

@echo off
REM newkernel.bat - create a python virtualenv and register it as a
REM Jupyter kernel
REM

SET /P _envname="Name of environment:"
if "%_envname%x" NEQ "x" goto :got_name
@REM else
     set _envname=py-%USERNAME%-%RANDOM%
@REM fi
:got_name

C:\tools\Anaconda3\python.exe -m venv %_envname%.venv

set /P _envkern="Kernel name:"
if "%_envkern%x" NEQ "x" goto :got_kern
@REM else
     set _envkern=py-%_envname%
@REM fi
:got_kern

set /P _envdesc="Kernel Description:"
if "%_envdesc%x" NEQ "x" goto :got_desc
@REM else
     set _envdesc="Python (%_envname%)"
@REM fi
:got_desc

%_envname%.venv\scripts\pip install ipykernel
%_envname%.venv\scripts\python -m ipykernel install --name %_envkern% --display-name "%_envdesc%"