SSH tonnel deur bastion dmv. JSch, in Clojure.
Afgeleë Verbindige deur 'n Tonnel
Ek het nou al 'n geruime tyd wat ek 'n BASH script gebruik om 'n SSH tonnel deur 'n bastion gasheer te skep. Hoewel dit werk, is dit elke keer 'n eksterne aktiwiteit wat nie noodwendig seepglad verloop saam met die vloei van die werk nie.
'n Ander pyn-punt het die week te voorskyn gekom nadat ek 'n kollega moes help om 'n ontwikkelings-omgewing op te stel op Windows 10 en WSL.
Die normale werkvloei was om heeltyd sekuriteit-groepe op te dateer met die nuutse IP-adresse. Gewoonlik is 'n databasis konfigurasie opgestel met 'n private sleutel (PEM key) direk na die adres van die databasis bediener.
In die ontwikkelingsproses gebruik ek 'n verwysing na localhost
en dan 'n poort wat plaaslik dan 'n spesifieke
omgewing teiken. Deur van hierdie metode gebruik te maak, kan 'n mens dan byvoorbeeld enige aantal verbindinge
maak met die bediener as localhost
en dan spesifieke poort nommers, 3307, 3308, 3309 ens.
Ek het dit nodig geag om dierdie proses in die kode in te bring, sodat 'n mens nie heeltyd rond hoef te spring nie.
So maklik soos 1, 2 3!
Hieronder is die basiese wat nodig is, die afhanklikheid op com.jcraft/jsch
weergawe 0.1.55
vanaf
JCraft. Daar is 'n hele paar intressante projekte, maar ek is spesifiek geïntresseerd
in JSch. Die bestaande dokumentasie en voorbeelde is in Java en daar is baie ekstra geraas rondom die kruks van wat
nodig is. Die voorbeeld is 155 lyntjies Java kode. Ek moet sê, daar is baie eksta kode om die GUI aan die gang
te kry.
Die werkende implementering in Clojure is minder as 27 lyne.
Reg, so kom ons begin met die deps.edn
dokument wat die bibloteek waarvan dit afhanklik is aandui:
;; deps.edn
{:paths ["src"]
:deps
{com.jcraft/jsch {:mvn/version "0.1.55"}}}
En dan die Clojure kode om 'n SSH tonnel te skep deur 'n bastion:
(ns user
(:import [com.jcraft.jsch JSch]))
;; ssh -L 3307:my-db.my-domain:3306 -i identity-file.pem user@bastion.my-domain
(defn tunnel-to
"Establish an SSH Tunnel through a Bastion Host
Returns the session established."
[{:keys [identity-file user host known-hosts-location] :as bastion}
{:keys [lport rhost rport] :as remote}]
(let [jsch (doto (JSch.)
(.addIdentity identity-file)
(.setKnownHosts known-hosts-location))
session (.getSession jsch user host)]
(println "SSH Connect...")
(.connect session)
(println "Forwarding port...")
(.setPortForwardingL session lport rhost rport)
session))
Die gebruik van hierdie funksie is as volg:
(def tonnel-sessie
(tunnel-to
;; bastion+local config
{:identity-file "~/some-dir/my.pem"
:user "user"
:host "bastion.my-domain"
:known-hosts-location "~/.ssh/known_hosts"}
;; remote config from bastion
{:lport 3307
:rhost "my-db.my-domain"
:rport 3306}))
;; doen wat nodig is...
;; laastens:
(.close tonnel-sessie)
Ek het uiteindelik goeie JavaDoc opgespoor, wat nogal baie gehelp het, by epaul.github.io/jsch-documentation