Public-key listing server

Lists unsigned public-key offers without asking your agent or password manager to sign.

Port 30024Auth: anonymous fallback

Connect

Inspect your agent

ssh -p 30024 demo@modernssh-examples.manaf.ch

Offer one key

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 -p 30024 demo@modernssh-examples.manaf.ch
server.ts
import { once } from "node:events"
import { Server, SessionChannel, type PublicKey, type ServerClient } from "@bunkerch/modernssh"

const hostKey = process.env.SSH_HOST_KEY_PRIVATE_KEY
if (!hostKey) throw new Error("SSH_HOST_KEY_PRIVATE_KEY is required")

const keys = new WeakMap<ServerClient, Map<string, PublicKey>>()
const server = new Server({ hostKeys: [hostKey], maxAuthenticationAttempts: 256 })

server.hooker.hook("noneAuthentication", (_hook, _context, decision) => {
  decision.allowLogin = false
})
server.hooker.hook("publicKeyAuthentication", (_hook, context, decision, client) => {
  const advertised = keys.get(client) ?? new Map<string, PublicKey>()
  advertised.set(context.publicKey.hash("sha256"), context.publicKey)
  keys.set(client, advertised)

  // Reject the probe without SSH_MSG_USERAUTH_PK_OK, so the agent never signs.
  decision.requestSignature = false
  decision.allowLogin = false
})
server.hooker.hook("keyboardInteractiveAuthentication", (_hook, _context, decision) => {
  // OpenSSH reaches this fallback after it has offered every public key.
  decision.allowLogin = true
})
server.hooker.hook("channelOpenRequest", (_hook, channel, decision) => {
  decision.allowOpen = channel instanceof SessionChannel
})

server.on("connection", (connection) => {
  keys.set(connection, new Map())
  connection.on("channel", (channel) => {
    if (!(channel instanceof SessionChannel)) return
    channel.hooker.hook("shellRequest", (_hook, decision) => {
      decision.success = true
    })
    channel.events.on("shell", (shell) => {
      const output = [...(keys.get(connection) ?? [])]
        .map(([fingerprint, key]) => fingerprint + "\n" + key.toString())
        .join("\n\n")

      void (async () => {
        await shell.writeStdout(output + "\n")
        const closed = once(shell, "close")
        shell.exit(0).close()
        await closed
        await connection.close()
      })().catch((error: unknown) => shell.destroy(error as Error))
    })
  })
})

server.listen({ host: "0.0.0.0", port: Number(process.env.PORT ?? 2224) })