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
enable ssh connection to a unix socket #435
base: master
Are you sure you want to change the base?
Conversation
a87def5
to
fd0d8b6
Compare
fd0d8b6
to
283d06b
Compare
sshconnect.c
Outdated
error("ssh: connect to host %s port %s: %s", | ||
error("ssh: connect to %s%s: %s", | ||
host, strport, errno == 0 ? "failure" : strerror(errno)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adapt error message for unix paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not needed here. For a UNIX socket, strport
will be an empty string, so %s%s
will just print what's in host
, which contains the path. See:
% /usr/local/bin/ssh okurth@/foo.sock
ssh: connect to /foo.sock: No such file or directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it is broken for IP addresses:
$ ./ssh user@localhost -p 3333
ssh: connect to localhost3333: Connection refused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I missed that, thanks! This is from one of pjd's original changes.
And fixed, with 5e81370
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think pjd's original changes were fine, but later destroyed by my attempts to simplify it :/ Thanks for restoring!
c387c28
to
01454b1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test works but spams a non-fatal error message:
$ make t-exec TEST_SSH_UNSAFE_PERMISSIONS=1
[...]
run test connect-unix.sh ...
/home/chn/repo/openssh-portable/regress/test-exec.sh: 32: kill: No such process
ok simple connect
Thanks a lot for writing a test!
connect through UNIX domain sockets. This is useful in combination with connections forwarding over UNIX domain sockets.
8ce8cde
to
5e25bd6
Compare
5e25bd6
to
0b18af1
Compare
Alright, test is mostly working now, except two jobs:
I don't think it's related.
But I don't know how to fix this. |
regress/connect-unix.sh
Outdated
|
||
start_sshd_unix() | ||
{ | ||
${SUDO} env NC=${NC} SSHD=${SSHD} OBJ=${OBJ} ${SCRIPT_DIR}/sshd-unix.sh& |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One reason for the CI error FATAL: no sshd.socket created
is because if a timing issue. Here we run the whole script sshd-unix.sh
in the background, which first cleans up sshd.socket
before starting netcat to create a new file. This creates a timing window where the wait for creating of sshd.socket
finishes too early. I suggest the following change:
modified regress/connect-unix.sh
@@ -4,7 +4,7 @@ SCRIPT_DIR=`dirname $0`
start_sshd_unix()
{
- ${SUDO} env NC=${NC} SSHD=${SSHD} OBJ=${OBJ} ${SCRIPT_DIR}/sshd-unix.sh&
+ ${SUDO} env NC=${NC} SSHD=${SSHD} OBJ=${OBJ} ${SCRIPT_DIR}/sshd-unix.sh
trace "wait for sshd-unix"
i=0;
modified regress/sshd-unix.sh
@@ -7,7 +7,7 @@ run_sshd_unix() {
rm -f ${OBJ}/sshd.fifo && mkfifo ${OBJ}/sshd.fifo
rm -f ${OBJ}/sshd.socket
touch ${OBJ}/sshd-unix.log ; chmod 0644 ${OBJ}/sshd-unix.log
- cat ${OBJ}/sshd.fifo | ${SSHD} -i -f ${OBJ}/sshd_config "$@" -E ${OBJ}/sshd-unix.log | ${NC} -l -U ${OBJ}/sshd.socket > ${OBJ}/sshd.fifo
+ cat ${OBJ}/sshd.fifo | ${SSHD} -i -f ${OBJ}/sshd_config "$@" -E ${OBJ}/sshd-unix.log | ${NC} -l -U ${OBJ}/sshd.socket > ${OBJ}/sshd.fifo &
}
run_sshd_unix
I haven't been able to run the test suite in full on my own machine, so I can't tell if this fixes the CI error. But at least it should be more logically correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I just pushed a change with that fix.
I found this patch after reading https://tim.siosm.fr/blog/2023/12/19/ssh-over-unix-socket/ and I'm really interested to see it merged. What's the status on this, or is there any help in pushing it forward if needed? |
@svmhdvn I am using this on a daily basis, and I find it very useful (I use it to connect to a VM running under VMware Fusion, without having to bother with the network). Unfortunately, I did not get any response from the maintainers, which has been very disappointing. But maybe I haven't reached out to the right people. |
I agree, I think this is a very useful PR, I'd like to help push this so that we don't have to maintain local patches to security-sensitive software like this. @djmdjm who is the right maintainer to take a look at this? It seems to be in a good working state. |
This is based on PRs #431 and #162 (thanks to @pjd and @kalvdans !) which enables connecting to a unix socket where
getaddrinfo(3)
supportsAF_UNIX
and adds connecting to a unix socket where it is not (which is the case for MacOS and Linux and probably most others). This is achieved by changingresolve_host
to return a faked upstruct addrinfo
for a unix socket, when the "hostname" starts with a/
. The code is partially reused fromchannels.c
/connect_to_helper()
.This also enforces
HashKnownHosts
when a unix socket is used, to prevent corrupting theknown_hosts
file with special characters - file paths can contain spaces,!
,*
and others which are not allowed in host names but do have special meaning inknown_hosts
.Tested successfully with MacOS 13.5 (using gcc 13) and Ubuntu 22.04.
Example usage:
There are multiple ways to set up a ssh server listening on a unix socket. One is setting
in a systemd socket config (for example
/etc/systemd/system/ssh.socket
).Other ways are using
socat
/netcat
, or port forwarding withssh
, using a unix socket on the listening end and TCP on the connecting end.The added test is failing in the github workflow, but works for me locally on both MacOS and Ubuntu 22.04. I haven't figured out why yet, but I will probably refactor it.