This example shows how to connect a MySQL server over a ssh tunnel.
Put a private key to ~/.ssh
and add setting to ~/.ssh/config
like
Host mybastion
Hostname 50.0.10.10
User your_username
IdentityFile ~/.ssh/private_key
Host mysql.example.local
User your_username
IdentityFile ~/.ssh/private_key
ProxyCommand ssh mybastion -W %h:%p
and mount ~/.ssh
on the host machine to /home/opam/.ssh
on the guest machine:
docker run -it -p 8888:8888 -v $PWD:/notebooks -v ~/.ssh:/home/opam/.ssh akabe/iocaml-datascience
In [1]:
#require "core" ;;
#require "mysql" ;;
In [2]:
open Core ;;
open Core.Caml.Format ;;
In [3]:
let with_ssh_tunnel ~remote_port ~local_port ~bastion ~host ~f =
let ssh_ctrl = sprintf "/tmp/ctrl_ssh.%d" local_port in
let close_ssh () = assert(Unix.system (sprintf "ssh -S %s -O exit %s 2>/dev/null" ssh_ctrl bastion) = Ok ()) in
assert(Unix.system (sprintf "ssh -o ExitOnForwardFailure=yes -MS %s -fNL %d:%s:%d %s" ssh_ctrl local_port host remote_port bastion) = Ok ()) ; (* open ssh tunnel *)
match f () with
| y -> close_ssh () ; y
| exception exn -> close_ssh () ; raise exn
Out[3]:
In [4]:
let exec_sql ~key ~f query =
with_ssh_tunnel
~remote_port:3306
~local_port:3316
~bastion:"mybastion"
~host:"mysql.example.local"
~f:(fun () ->
let dbd = Mysql.quick_connect ~host:"127.0.0.1" ~port:3316 ~user:"myuser" ~password:"mypass" () in
let rows = Mysql.exec dbd query |> Mysql.map_cols ~key ~f in
Mysql.disconnect dbd ;
rows)
Out[4]:
In [5]:
exec_sql
"SELECT 1 AS x"
~key:[|"x"|]
~f:(function [|Some x|] -> x | _ -> assert false)
Out[5]:
In [ ]: