Search code examples
socketssshopensshsshd

Identify incoming SSHD processes by forwarded socket file


I have a Docker container running SSHD which receives SSH connections from multiple remote machines. I need to identify and terminate the connection coming from one particular machine.

The connections:

  • Each incoming connection is from a different machine.
  • Each incoming connection forwards a Unix socket file on the container to a TCP port on the remote machine. Each remote machine forwards a different container.
  • Forwarding that one port is the only thing these connections do; they do not start an interactive session or run any commands.
  • Every incoming connection logs in as the same user.
  • Each remote machine has a different auth key which it uses to log in.
  • The code which executes the SSH connection on the remote machines is under my control, so if there is some option I can pass to ssh or set in ssh_config which will make it easier to ID the connections, I have the option to do that.

What I know:

  • I know the serial number of the machine whose connection I need to kill.
  • I know which socket file that connection will be forwarding.
  • I know which SSH auth key the connection will have logged in with.
  • I do not know what IP address or hostname the connection will be coming from.

What I've tried so far:

  • ps -aux will show me the SSHD processes for all the incoming connections. However, I cannot tell which incoming connection comes from which remote machine.
  • If I could identify which process corresponded to which SSH auth key, that would suffice, but there's no obvious way to even begin with that.
  • The most promising option would seem to be identifying which process has the corresponding socket file open, but I haven't been able to do that yet:
    • cat /proc/net/unix tells me which socket files are open, but not what processes each one is opened by
    • lsof is supposed to list which processes have which files open. However, when I tested it by running it when I had a single incoming connection:
      • The output did not list the socket file I knew to be open anywhere
      • The output for the SSHD processes in question (there were two of them, one running as root and the other as the log-in user) showed their only open files to be /proc/${PID}/cwd, /proc/${PID}/root, /proc/${PID}/exe, and 6-8 numbered files in /proc/${PID}/fd/

Solution

  • Found the solution: lsof can tell you which processes have a given socket file open. However, Docker, by default, restricts containers such that processes inside the container cannot read /proc/${PID}/fd/${FD_NUM}, even if the process trying to do the reading is running as root, which is why lsof couldn't tell what processes had what files opened.

    Running the SSHD container with --cap-add=SYS_PTRACE tells Docker not to block such operations, allowing lsof to work correctly.

    More specifically: lsof -t "${SOCKET_FILE}" will return a list of PIDs which have the given socket file open.