Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does it support unix socket for port forwarding? #12

Closed
ieugen opened this issue Jun 6, 2023 · 7 comments
Closed

Does it support unix socket for port forwarding? #12

ieugen opened this issue Jun 6, 2023 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@ieugen
Copy link

ieugen commented Jun 6, 2023

With ssh I have the option of providing a local socket that forwards to a remote proxy.

Does bbssh support unix socket?
One use case is to connect to docker socket via ssh.
I would like to use https://github.com/lispyclouds/contajners over unix socket for a remote host.

man ssh

     -L [bind_address:]port:host:hostport
     -L [bind_address:]port:remote_socket
     -L local_socket:host:hostport
     -L local_socket:remote_socket
             Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote
             side.  This works by allocating a socket to listen to either a TCP port on the local side, optionally bound to the specified bind_address, or to a Unix socket.  Whenever a
             connection is made to the local port or socket, the connection is forwarded over the secure channel, and a connection is made to either host port hostport, or the Unix
             socket remote_socket, from the remote machine.
@ieugen
Copy link
Author

ieugen commented Jun 6, 2023

According to this issue, it seems some unix socket forwarding is supported mwiede/jsch#73 .

I will try it out and see if it works.

Local forwarding to remote:
local tcpip => remote tcpip
Already supported
local tcpip => remote unix domain socket
Already supported

@ieugen
Copy link
Author

ieugen commented Jun 6, 2023

I don't think bbssh works as is with remote sockets but it should be easy to support IMO.
I found the options in jsch:

Also there is an example that does kind of exactly what I want: forward the docker socket .

@ieugen
Copy link
Author

ieugen commented Jun 6, 2023

I tried with:

(session/set-port-forwarding-local
     session
     {:bind-address nil        ;; address to bind to on the local machine
      :local-port  38021              ;; the port to lisen on locally
      :remote-host "/var/run/docker.sock"  ;; host to connect to on the remote network
      :remote-port nil                ;; port to connect to on remote-machine
      :connect-timeout 30000         ;; timeout for the remote connection (ms)
      })

and I got

#error {
 :cause "clojure.lang.PersistentVector cannot be cast to byte[]"
 :via
 [{:type java.lang.ClassCastException
   :message "clojure.lang.PersistentVector cannot be cast to byte[]"
   :at [babashka.pods.impl$bytes__GT_string invokeStatic "impl.clj" 28]}]
 :trace
 [[babashka.pods.impl$bytes__GT_string invokeStatic "impl.clj" 28]
  [babashka.pods.impl$processor invokeStatic "impl.clj" 193]
  [babashka.pods.sci$load_pod$fn__27903 invoke "sci.clj" 122]
  [sci.impl.vars$binding_conveyor_fn$fn__440 invoke "
vars.cljc" 133]
  [clojure.core$binding_conveyor_fn$fn__5823 invoke "core.clj" 2047]
  [clojure.lang.AFn call "AFn.java" 18]
  [java.util.concurrent.FutureTask run "FutureTask.java" 317]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1144]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 642]
  [java.lang.Thread run "Thread.java" 1589]
  [com.oracle.svm.core.thread.PlatformThreads threadStartRoutine "PlatformThreads.java" 775]
  [com.oracle.svm.core.posix.thread.PosixPlatformThreads pthreadStartRoutine "PosixPlatformThreads.java" 203]]}

@ieugen
Copy link
Author

ieugen commented Jun 7, 2023

I tested this code and it works to forward a docker socket.
So there is an issue with how bbssh handles things.

(ns bbssh.socket-forwarding-l
  (:import (com.jcraft.jsch JSch)
           (java.net URL)))

(comment

  (let [jsch (doto (JSch.)
               (.addIdentity "/home/ieugen/.ssh/id_ed25519"))
        session (-> jsch
                    (.getSession "ubuntu" "dev1.REDACTED" 22))
        session (doto session
                  (.setConfig "StrictHostKeyChecking", "no")
                  .connect)
        port (-> session
                 (.setSocketForwardingL nil 0 "/var/run/docker.sock" nil 1000))
        my-url (URL. (str "http://localhost:" port "/_ping"))
        _ (println "Connecting to" my-url)
        c (-> my-url .openConnection)]
    (println "Docker Ping http response code ("
             my-url "): "
             (-> c .getResponseCode))
    (def session session)
    (-> session .disconnect))
 
  )

@retrogradeorbit
Copy link
Member

I tried with:

(session/set-port-forwarding-local
     session
     {:bind-address nil        ;; address to bind to on the local machine
      :local-port  38021              ;; the port to lisen on locally
      :remote-host "/var/run/docker.sock"  ;; host to connect to on the remote network
      :remote-port nil                ;; port to connect to on remote-machine
      :connect-timeout 30000         ;; timeout for the remote connection (ms)
      })

and I got

#error {
 :cause "clojure.lang.PersistentVector cannot be cast to byte[]"
 :via
 [{:type java.lang.ClassCastException
   :message "clojure.lang.PersistentVector cannot be cast to byte[]"
   :at [babashka.pods.impl$bytes__GT_string invokeStatic "impl.clj" 28]}]
 :trace
 [[babashka.pods.impl$bytes__GT_string invokeStatic "impl.clj" 28]
  [babashka.pods.impl$processor invokeStatic "impl.clj" 193]
  [babashka.pods.sci$load_pod$fn__27903 invoke "sci.clj" 122]
  [sci.impl.vars$binding_conveyor_fn$fn__440 invoke "
vars.cljc" 133]
  [clojure.core$binding_conveyor_fn$fn__5823 invoke "core.clj" 2047]
  [clojure.lang.AFn call "AFn.java" 18]
  [java.util.concurrent.FutureTask run "FutureTask.java" 317]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1144]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 642]
  [java.lang.Thread run "Thread.java" 1589]
  [com.oracle.svm.core.thread.PlatformThreads threadStartRoutine "PlatformThreads.java" 775]
  [com.oracle.svm.core.posix.thread.PosixPlatformThreads pthreadStartRoutine "PosixPlatformThreads.java" 203]]}

This will be an issue with the serialisation across the pod boundary. I will have a look at it a little later. Should be pretty easy to fix.

@ieugen
Copy link
Author

ieugen commented Jun 12, 2023

Downloaded new release, replaced it on path at /home/ieugen/.babashka/pods/repository/epiccastle/bbssh/0.4.0/linux/x86_64

Ran the script bellow and it works.

Thank you!

Are you planning on doing a release soon?

(ns bb-ssh
  (:require [babashka.pods :as pods]
            [babashka.deps :as deps]))

(pods/load-pod 'epiccastle/bbssh "0.4.0")
(deps/add-deps '{:deps {org.clojars.lispyclouds/contajners {:mvn/version "1.0.0"}}})

(require '[pod.epiccastle.bbssh.core :as bbssh]
         '[contajners.core :as c])

(comment

  (let [port 38021
        session (bbssh/ssh "dev1.example.com"
                           {:username "ubuntu"
                            :identity "/home/ieugen/.ssh/id_ed25519"
                            :bind-address "127.0.0.1"        ;; address to bind to on the local machine
                            :local-port  port              ;; the port to lisen on locally
                            :remote-unix-socket "/var/run/docker.sock"  ;; host to connect to on the remote network
                            :connect-timeout 30000         ;; timeout for the remote connection (ms)
                            })
        images-docker (c/client {:engine   :docker
                                 :category :images
                                 :version  "v1.42"
                                 :conn     {:uri (str "http://127.0.0.1:" port)}})]
    (println "Remote unix socket available as TCP port" port)
    ;; (println images-docker)
    (println (c/invoke images-docker {:op :ImageList})))
  )

@retrogradeorbit
Copy link
Member

released in 0.5.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants