@c -*-texinfo-*- @c This file is part of Guile-SSH Reference Manual. @c Copyright (C) 2015 Artyom V. Poptsov @c See the file guile-ssh.texi for copying conditions. @node Tunnels @section Tunnels @cindex Tunnels The following procedures from @code{(ssh tunnel)} module are a high-level API built upon the basic port forwarding facilities for managing port forwards. @deffn {Scheme Procedure} make-tunnel session [#:bind-address=''127.0.0.1''] #:port #:host [#:host-port=port] [#:reverse?=#f] Make a new SSH tunnel using @var{session} from @var{bind-address} and @var{port} to a @var{host} and @var{host-port}. The procedure is capable of creating both direct and reverse port forwarding tunnels; the type of a tunnel is determined by @var{reverse?} argument. If @var{reverse?} is set to @code{#f} then a reverse port forwarding tunnel will be created. Setting @var{reverse?} to @code{#t} changes the direction of the tunnel and a reverse port forwarding tunnel will be created. In this case a server allocates a socket to listen to @var{port} on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to @var{host} and @var{host-port} from the local machine. @var{host} can be set to @code{#f} to tell the server to listen on all addresses and known protocol families. Setting a @var{port} to 0 tells the server to bind the first unprivileged port. The procedure does not binds ports nor transfers data to the port (in case of reverse port forwarding), you should start port forwarding by means of the procedures that operate on a object -- e.g. @code{start-forward} or @code{call-with-ssh-forward}. Return a new tunnel object. @end deffn @deffn {Scheme Procedure} tunnel? x Return @code{#t} if @var{x} is an Guile-SSH tunnel, @code{#f} otherwise. @end deffn @deffn {Scheme procedure} tunnel-reverse? x Check if @var{x} is a reverse port forwarding tunnel. @end deffn @deffn {Scheme procedure} tunnel-session tunnel Get a session associated with a @var{tunnel}. @end deffn @deffn {Scheme Procedure} tunnel-bind-address tunnel Get a source host of a @var{tunnel}. @end deffn @deffn {Scheme Procedure} tunnel-port tunnel Get a local port of a @var{tunnel}. @end deffn @deffn {Scheme Procedure} tunnel-host tunnel Get a remote host of a @var{tunnel}. @end deffn @deffn {Scheme Procedure} tunnel-host-port tunnel Get a remote port of a @var{tunnel}. @end deffn @deffn {Scheme Procedure} start-forward tunnel Start port forwarding on @var{tunnel}. The procedure actually binds tunnel ports and forwards data. @end deffn @deffn {Scheme Procedure} call-with-ssh-forward tunnel proc Open a new @var{tunnel} and start port forwarding. @var{proc} is called with a socket as an argument. All I/O on the socket will be forwarded to the remote host and port of a @var{tunnel}. Return the result the @var{proc} call. As a practical example, let's say you want to use @url{https://www.gnu.org/software/guile-rpc/, Guile-RPC} over SSH. Here's how you can implement an RPC call using @code{call-with-ssh-forward}: @lisp (let ((t (make-tunnel session #:port 12345 ;; Suppose a Guile-RPC server listens on ;; 127.0.0.1:23456 on the remote host: #:host "127.0.0.1" #:host-port 23456))) (call-with-ssh-forward t (lambda (socket) (RPC-PROGRAM-proc some-data #x123 socket)))) @end lisp The full example of an RPC client that uses a SSH tunnel is in @file{$prefix/share/guile-ssh/examples/rpc} directory. @end deffn @subsection Example Here is a simple Guile program that connects to ``www.example.org'' and starts port forwading from the local port 8080 to the port 80 on the remote host: @lisp #!/usr/bin/guile \ -e main !# (use-modules (ssh session) (ssh auth) (ssh key) (ssh tunnel)) (define (main args) (let ((s (make-session #:user "alice" #:host "localhost" #:port 22 #:log-verbosity 'nolog)) (k (private-key-from-file "/home/alice/.ssh/id_rsa"))) (connect! s) (userauth-public-key! s k) (let ((t (make-tunnel s #:port 8080 #:host "www.example.org" #:host-port 80))) (start-forward t)))) @end lisp @c Local Variables: @c TeX-master: "guile-ssh.texi" @c End: