You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于libssh库建立中转SSH隧道并执行服务器脚本的技术问询

Solution for Multi-Hop SSH with libssh (PC → Gateway → Server)

Alright, since you've already got the initial SSH connection from your PC to the gateway (as user1 with password auth) sorted, let's focus on extending that to reach the target server as the www user (passwordless auth) and run your script. Here's how to do it with libssh:

Step 1: Ensure Gateway-to-Server Auth is Set Up

First, double-check that the www user on the gateway has passwordless SSH access to the server. That means:

  • The gateway's www user has an SSH key pair (usually ~www/.ssh/id_rsa and ~www/.ssh/id_rsa.pub).
  • The server's www user has the gateway's public key added to ~www/.ssh/authorized_keys (with proper permissions: chmod 700 ~www/.ssh and chmod 600 ~www/.ssh/authorized_keys).
    This is non-negotiable for passwordless auth—key-based authentication is the way to go here.

Step 2: Use libssh to Extend the Connection to the Server

You have two solid options depending on your needs:

Option A: Run Script via Gateway Channel (Simpler)

If you just need to execute the script and grab output without a full interactive session, this is the quickest approach. Here's a code snippet:

#include <libssh/libssh.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    // Assume gateway_session is already connected and authenticated as user1
    ssh_session gateway_session = ...; // Your existing session setup

    // Create a channel on the gateway
    ssh_channel channel = ssh_channel_new(gateway_session);
    if (channel == NULL) {
        fprintf(stderr, "Failed to create channel: %s\n", ssh_get_error(gateway_session));
        return 1;
    }

    // Open a session channel
    if (ssh_channel_open_session(channel) != SSH_OK) {
        fprintf(stderr, "Failed to open session: %s\n", ssh_get_error(gateway_session));
        ssh_channel_free(channel);
        return 1;
    }

    // Command to connect to server as www and run your script
    const char* cmd = "ssh www@server /path/to/your/target_script.sh";
    if (ssh_channel_request_exec(channel, cmd) != SSH_OK) {
        fprintf(stderr, "Failed to execute command: %s\n", ssh_get_error(gateway_session));
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        return 1;
    }

    // Read and print the script's output
    char buffer[256];
    int bytes_read;
    while ((bytes_read = ssh_channel_read(channel, buffer, sizeof(buffer)-1, 0)) > 0) {
        buffer[bytes_read] = '\0';
        printf("%s", buffer);
    }

    // Cleanup resources
    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    ssh_disconnect(gateway_session);
    ssh_free(gateway_session);

    return 0;
}

Option B: Full Nested SSH Session (More Control)

If you need advanced functionality like multiple commands, file transfers, or persistent interactions with the server, set up a proxy jump using libssh to route the server session through your existing gateway connection:

#include <libssh/libssh.h>

int main() {
    // Existing gateway session (connected as user1)
    ssh_session gateway_session = ...;

    // Create a new session for the target server
    ssh_session server_session = ssh_new();
    if (server_session == NULL) {
        fprintf(stderr, "Failed to create server session\n");
        return 1;
    }

    // Configure server session options
    ssh_options_set(server_session, SSH_OPTIONS_HOST, "server");
    ssh_options_set(server_session, SSH_OPTIONS_USER, "www");
    // Use the gateway as a proxy jump
    ssh_options_set(server_session, SSH_OPTIONS_PROXY_JUMP, gateway_session);

    // Connect to the server
    if (ssh_connect(server_session) != SSH_OK) {
        fprintf(stderr, "Failed to connect to server: %s\n", ssh_get_error(server_session));
        ssh_free(server_session);
        return 1;
    }

    // Authenticate with passwordless key auth
    if (ssh_userauth_publickey_auto(server_session, NULL, NULL) != SSH_OK) {
        fprintf(stderr, "Failed to authenticate as www: %s\n", ssh_get_error(server_session));
        ssh_disconnect(server_session);
        ssh_free(server_session);
        return 1;
    }

    // Execute your script on the server
    ssh_channel channel = ssh_channel_new(server_session);
    if (channel == NULL) {
        fprintf(stderr, "Failed to create server channel: %s\n", ssh_get_error(server_session));
        ssh_disconnect(server_session);
        ssh_free(server_session);
        return 1;
    }

    if (ssh_channel_open_session(channel) != SSH_OK) {
        fprintf(stderr, "Failed to open server session: %s\n", ssh_get_error(server_session));
        ssh_channel_free(channel);
        ssh_disconnect(server_session);
        ssh_free(server_session);
        return 1;
    }

    const char* script_cmd = "/path/to/your/target_script.sh";
    if (ssh_channel_request_exec(channel, script_cmd) != SSH_OK) {
        fprintf(stderr, "Failed to run script: %s\n", ssh_get_error(server_session));
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        ssh_disconnect(server_session);
        ssh_free(server_session);
        return 1;
    }

    // Read script output
    char buffer[256];
    int bytes_read;
    while ((bytes_read = ssh_channel_read(channel, buffer, sizeof(buffer)-1, 0)) > 0) {
        buffer[bytes_read] = '\0';
        printf("%s", buffer);
    }

    // Cleanup all resources
    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    ssh_disconnect(server_session);
    ssh_free(server_session);
    ssh_disconnect(gateway_session);
    ssh_free(gateway_session);

    return 0;
}

Step 3: Add Robust Error Handling

Don't skip error checking for each libssh call—ssh_get_error() provides detailed messages that can help debug issues like auth failures, connection timeouts, or permission errors on the gateway/server.

Quick Compilation Tip

When building your code, link against libssh with the -lssh flag:

gcc your_tunnel_code.c -o ssh_multi_hop -lssh

内容的提问来源于stack exchange,提问作者Simo Elmou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:25:03