bollard
bollard copied to clipboard
Connect to socket over ssh?
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?
This isn't supported right now, but happy to accept a PR for this feature.
@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.
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.
@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..
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")?;