oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
72.26k stars 2.58k forks source link

ssh2 not working #11947

Open lassejlv opened 1 month ago

lassejlv commented 1 month ago

What version of Bun is running?

1.1.13+bd6a60512

What platform is your computer?

Darwin 23.5.0 arm64 arm

What steps can reproduce the bug?

You can use this code:

import { Client } from "ssh2";

const IP_ADDRESS = process.env.VPS_IP_ADRESS;
const USERNAME = process.env.VPS_USERNAME;
const PASSWORD = process.env.VPS_PASSWORD;

export function runCommand(command) {
  const conn = new Client();

  conn.on("ready", () => {
    console.log("Client :: ready");

    conn.exec(command, (err, stream) => {
      if (err) throw err;

      stream
        .on("close", (code, signal) => {
          console.log(`Stream :: close :: code: ${code}, signal: ${signal}`);
          conn.end();
        })
        .on("data", (data) => {
          console.log(`STDOUT: ${data}`);
        })
        .stderr.on("data", (data) => {
          console.error(`STDERR: ${data}`);
        });
    });
  });

  conn.connect({
    host: IP_ADDRESS,
    port: 22,
    username: USERNAME,
    password: PASSWORD,
  });
}

What is the expected behavior?

I would expect it to connect and run commands. It works with node without any issues.

What do you see instead?

With bun it just exists with this error:

bun src/index.js
dyld[18758]: missing symbol called [1] 18758 abort bun src/index.js

Additional information

Nope, love bun keep up the great work!

Jarred-Sumner commented 1 month ago

~Duplicate of #8228~

BarakBinyamin commented 4 weeks ago

on mac x86 13.5.2 (Ventura) the error was similar when trying launch an ssh2 server

  dyld[26567]: missing symbol called
  Abort trap: 6

on linux x86 ubuntu server

bun: symbol lookup error: /PATH/TO/src/node_modules/cpu-features/build/Release/cpufeatures.node: undefined symbol: node_module_register
Tuanm commented 2 weeks ago
import { readFileSync } from 'fs';
import { Server, type AuthContext } from 'ssh2';
import net from 'net';

/**
 * SSH server's initial configurations.
 */
type ServerConfigurations<T extends AuthContext> = {
    /**
     * Path to the host key file.
     */
    hostKeyPath: string | undefined;
    /**
     * Authenticates an SSH connection.
     */
    authenticate: (context: T) => Promise<boolean>;
    /**
     * Retrieves an assigned port for local forwarding.
     */
    assignPort: (context: T) => Promise<number>;
};

/**
 * Creates an SSH server that supports local port forwarding with authentication.
 */
function createServer<T extends AuthContext>({
    hostKeyPath,
    authenticate,
    assignPort,
}: ServerConfigurations<T>) {
    const hostKeys = [] as string[];
    if (hostKeyPath) {
        hostKeys.push(Buffer.from(readFileSync(hostKeyPath)).toString());
    }
    return new Server(
        {
            hostKeys,
        },
        (client) => {
            client
                .on('authentication', async (ctx) => {
                    if (!(await authenticate(ctx as T))) {
                        return ctx.reject();
                    }
                    (client as any).assignedPort = await assignPort(ctx as T);
                    return ctx.accept();
                })
                .on('ready', () => {
                    client.on('request', (accept, reject, name, info) => {
                        if (name === 'tcpip-forward') {
                            const assignedPort = (client as any)
                                .assignedPort as number;
                            if (assignedPort === info.bindPort) {
                                const server = net
                                    .createServer((socket) => {
                                        socket.setEncoding('utf8');
                                        client.forwardOut(
                                            info.bindAddr,
                                            info.bindPort,
                                            String(socket.remoteAddress),
                                            Number(socket.remotePort),
                                            (err, upstream) => {
                                                if (err) {
                                                    console.log(err);
                                                    socket.end();
                                                    return;
                                                }
                                                upstream
                                                    .pipe(socket)
                                                    .pipe(upstream);
                                            },
                                        );
                                    })
                                    .listen(info.bindPort);
                                (client as any).server = server;
                                return accept && accept();
                            }
                        }
                        return reject && reject();
                    });
                    client.on('close', () => {
                        ((client as any).server as net.Server)?.close();
                    });
                });
        },
    );
}

/**
 * SSH functionalities.
 */
export default {
    createServer,
};

These scripts work well in my python:3.11-slim container with Bun 1.1.17 installed. The only drawback is that I could not build it 😭 by using the bun build command:

error: Could not resolve: "../build/Release/cpufeatures.node"