Skip to content

Conversation

benzea
Copy link

@benzea benzea commented Jul 27, 2025

We were thinking that having vsock support in dropbear could be useful when having VMs with dropbear. We are considering to use this for OpenWRT/Gluon testing specifically as we could just add a vsock listener by default and then use it in the environment. While on real HW, it would just fail to listen on that socket.

The approach here is to accept AF_VSOCK anywhere where IP sockets are also allowed. Not sure that is a great idea. I am happy to change the approach.

I have tested that listening on the server, connecting the client and port forwarding work.

Examples (just running on the host):

./dropbear -p localhost:22 -p %vsock:22 -E -F -R
./dbclient 1%vsock -p 22 -L %vsock:80:localhost:80

Optionally, one may give the CID to connect to or listen on before the
%vsock. This works both for listening and connecting and also for "TCP"
forwarding.
Copy link
Owner

@mkj mkj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea. I could see it being useful opt-in, though I'm a bit worried if it's enabled by default for special hostnames it could inadvertently be enabled and lead to surprise VM-to-host escapes, etc.

If dropbear server had -o argument parsing I'd suggest adding a -o vsock=on to enable it, but -o isn't supported for server yet (on the todo list).

Maybe it should be an off-by-default compile time option? It would probably be worth being able to disable it regardless to avoid the (small) space increase on platforms not using it.

There's segfault in the build test, I think that's a real failure.
https://github.com/mkj/dropbear/actions/runs/16552516570/job/46809421248#step:17:373

I've noted a few small style issues.

Comment on lines +18 to +19
if (ai && ai->ai_family != AF_VSOCK)
return freeaddrinfo(ai);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All if statements need braces

vsock_res->ai_addrlen = sizeof(*vsockaddr);
vsockaddr->svm_family = AF_VSOCK;
if (vsock != hostname)
vsockaddr->svm_cid = atoi(hostname);
Copy link
Owner

@mkj mkj Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use m_str_to_uint instead of atoi, that has error checking. Though that won't deal with splitting the string.

struct addrinfo *vsock_res;
struct sockaddr_vm *vsockaddr;

vsock_res = calloc(1, sizeof(struct addrinfo) + sizeof(*vsockaddr));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_calloc


for(; ai != NULL;) {
next = ai->ai_next;
free(ai);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_free

Comment on lines +289 to +291
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (strstr(orighost, "%vsock") != NULL) {} else
#endif
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about doing string comparison on the hostname received from the peer here. Does https://libvirt.org/ssh-proxy.html use the same hostname format?

Can the #ifdef and if be done in a nicer way?

Comment on lines +66 to +67
snprintf(ipstring, NI_MAXHOST - 1, "%u%%vsock", vsockaddr->svm_cid);
snprintf(portstring, NI_MAXSERV - 1, "%u", vsockaddr->svm_port);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- 1 shouldn't be needed here?

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

Successfully merging this pull request may close these issues.

2 participants