bollard icon indicating copy to clipboard operation
bollard copied to clipboard

Connect to socket over ssh?

Open muqshots opened this issue 2 years ago • 5 comments

Hi is it possible to connect to a remote socket over ssh?

for context here is how to do it on the docker cli, docker -H ssh://user@hostname ps

Is there any supported/alternate way to do this?

muqshots avatar Jul 16 '22 19:07 muqshots

This isn't supported right now, but happy to accept a PR for this feature.

fussybeaver avatar Jul 18 '22 15:07 fussybeaver

@fussybeaver

This isn't supported right now, but happy to accept a PR for this feature.

Any tips on how this could be achieved? I am gonna investigate, but if you could provide any helpful stuff, that would be great.

Rutherther avatar Jul 04 '23 20:07 Rutherther

Hi,

I'm not at a computer this week, but can give the situation at present.

~IIRC Connecting via an SSH URL to the buildkit server is a buildkit feature. Support for that particular feature directly is not yet supported, since I think it needs some additional protobuf dialogue in Bollard.~ However, we did add building images through buildkit, so if your intent is to access data behind SSH, you can try to build with the RUN --mount=type=ssh which should work.

Hope that brings you further.

fussybeaver avatar Jul 05 '23 14:07 fussybeaver

@Rutherther so after some further looking into it, this is more about creating an SSH remote port forward, perhaps you could use the thrussh crate/library for this? Perhaps as an initial POC you can create an example without Bollard that just does a remote tunneled port forward, and test it with the docker cli by connecting to the local port.

From the Bollard/Docker plumbing side, this can follow separately, because it only needs to connect to the local port that you're using..

fussybeaver avatar Jul 11 '23 14:07 fussybeaver

This is something I've done before with the openssh crate, might be helpful

        let mut tempfile = NamedTempFile::new().context("Could not create tempfile for ssh key")?;
        tempfile
            .write_all(self.ssh_key.as_bytes())
            .context("Could not write ssh key to tempfile")?;
        let keyfile = tempfile.into_temp_path();

        let session = SessionBuilder::default()
            .user(self.user.clone())
            .keyfile(keyfile)
            .port(self.port as u16)
            .known_hosts_check(KnownHosts::Accept)
            .control_directory(std::env::temp_dir())
            .connect_timeout(Duration::from_secs(5))
            .connect_mux(&self.ip)
            .await
            .context("Could not connect to remote host")?;

        // get a random open port from the OS
        let local_addr = {
            let listener = TcpListener::bind("127.0.0.1:0").await?;
            listener.local_addr()?
        };

        let connect_socket = Path::new("/var/run/docker.sock");
        session
            .request_port_forward(ForwardType::Local, local_addr, connect_socket)
            .await
            .context("Could not request port forward")?;

        let docker = Docker::connect_with_http(&local_addr.to_string(), 120, API_DEFAULT_VERSION)?;
        docker
            .version()
            .await
            .context("Could not fetch docker version")?;

alakhpc avatar Jul 11 '23 20:07 alakhpc