ToB企服应用市场:ToB评测及商务社交产业平台

标题: 利用libssh2创建安全的SSH连接:C++开发者的综合指南 [打印本页]

作者: 西河刘卡车医    时间: 2024-8-25 17:18
标题: 利用libssh2创建安全的SSH连接:C++开发者的综合指南
一、介绍

SSH和安全连接的紧张性是不可忽视的。在今天的互联网情况中,保护敏感数据和网络通讯的安全至关紧张。
libssh2是一个用于C/C++开发的开源库,用于实现SSH客户端和服务器的功能。它提供了一组API,使开发者可以或许利用SSH协议创建安全连接,并进行远程下令实验、文件传输等操作。
通过利用libssh2,可以轻松地构建安全的SSH客户端和服务器应用步伐,实现远程管理、主动化使命实验等功能。

二、准备工作

安装和设置libssh2:
SSH密钥和身份验证是在SSH(Secure Shell)协议中用于安满身份验证的关键概念。
SSH密钥:SSH密钥是一对由公钥和私钥组成的加密密钥。公钥用于加密数据,而私钥用于解密数据。在SSH身份验证中,用户将公钥生存在服务器上,而私钥保留在本地。当用户尝试连接到服务器时,服务器会向其发送一个加密的随机挑战,用户利用私钥对其进行解密,并将解密后的挑战发送回服务器以验证身份。SSH密钥的优势在于其安全性和便捷性,由于私钥通常受到暗码保护,而且可以在多个体系之间共享而无需传输暗码。
身份验证方法:SSH支持多种身份验证方法,包罗暗码身份验证、公钥身份验证和基于主机的身份验证。

通过利用SSH密钥和身份验证方法,用户可以实现更强盛的安全性和身份验证控制,以保护远程连接和数据传输。
注意:具体的SSH设置和身份验证方法大概因操作体系、SSH服务器软件和安全战略而有所不同。
三、创建SSH连接

3.1、初始化libssh2库

  1. #include <libssh2.h>
复制代码
  1. int libssh2_init(int flags);
复制代码
该函数担当一个整数参数flags,用于指定初始化的选项。

libssh2_init函数在利用libssh2库之前调用,用于初始化库的状态和资源。调用该函数将为libssh2库分配和设置所需的内存,并在乐成时返回0,表示初始化乐成。假如出现错误或初始化失败,函数将返回一个负值,其中的错误代码用于指示具体的初始化错误。
以下是一个示例,展示怎样利用libssh2_init函数进行libssh2库的初始化:
  1. int rc = libssh2_init(0);
  2. if (rc != 0) {
  3.     // 初始化失败,处理错误
  4.     // ...
  5. }
复制代码
注意:libssh2_init函数只需要在应用步伐启动时调用一次,用于初始化libssh2库。在利用libssh2的其他功能之前,不需要多次调用该函数。
  1. libssh2_exit();
复制代码
这个函数释放库利用的任何资源,并进行须要的清算操作。
3.2、连接到远程主机

libssh2_session_init函数:
  1. LIBSSH2_SESSION *libssh2_session_init(void);
复制代码
该函数用于创建一个libssh2会话对象,并返回指向该对象的指针。它没有担当任何参数,并在创建乐成时返回一个非空指针,否则返回NULL。
利用libssh2_session_init时,利用会话的默认选项,可以调用libssh2_session_set_timeout函数设置超时时间,或者利用libssh2_knownhost_readline函数加载已知主机列表。
libssh2_session_init_ex函数:
  1. LIBSSH2_SESSION *libssh2_session_init_ex(
  2.     libssh2_malloc_func malloc_func,
  3.     libssh2_free_func free_func,
  4.     libssh2_realloc_func realloc_func,
  5.     void *abstract
  6. );
复制代码
该函数也用于创建libssh2会话对象,并返回指向该对象的指针。与libssh2_session_init不同的是,libssh2_session_init_ex答应传递一些额外的参数来指定自定义的内存管理函数和抽象指针。

利用libssh2_session_init_ex可以根据需求自定义内存管理,以便更好地集成libssh2库到本身的应用步伐中。
libssh2_session_set_blocking是libssh2库中的一个函数,用于设置SSH会话的壅闭模式。它的函数签名如下:
  1. void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking);
复制代码
该函数担当一个指向LIBSSH2_SESSION会话对象的指针和一个整数参数,用于指定壅闭模式。下面是对这两个参数的解释:

在壅闭模式下,调用 libssh2 函数时,假如所请求的操作没有立刻完成,函数将不停壅闭(即处于等待状态)直到操作完成或超时。这意味着步伐在等待操作完成时会暂停实验,直到收到相应或操作完成。
在非壅闭模式下,调用 libssh2 函数时,不会等待操作完成。假如调用一个大概壅闭的操作,函数会立刻返回,并根据情况提供适当的错误代码或状态。在非壅闭模式下可以利用独立的方式监控和管理多个会话。
  1. int libssh2_session_handshake(LIBSSH2_SESSION *session, LIBSSH2_SOCKET sock);
复制代码
该函数担当两个参数:

libssh2_session_handshake()函数用于在SSH会话中进行握手操作,它实验以下使命:

函数返回值:

函数调用示例:
  1. int rc = libssh2_session_handshake(session, sock);
  2. if (rc == 0) {
  3.     // 握手成功,可以继续进行其他操作
  4. } else if (rc == LIBSSH2_ERROR_EAGAIN) {
  5.     // 需要进一步读取或写入套接字数据
  6. } else {
  7.     // 握手失败,处理错误
  8. }
复制代码
在利用libssh2库进行SSH连接时,一样平常会在创建SSH会话后立刻调用libssh2_session_handshake()函数进行握手操作。握手乐成后,就可以继承利用libssh2库提供的其他函数实验各种SSH操作,如实验下令、传输文件等。
3.4、完整示例

下面是一个利用libssh2连接到远程主机的完整示例:
  1. #include <stdio.h>#include <stdlib.h>#include <libssh2.h>
  2. int main(){    // 初始化libssh2库    int rc = libssh2_init(0);    if (rc != 0) {        fprintf(stderr, "Failed to initialize libssh2. Error code %d", rc);        return 1;    }    // 创建SSH会话    LIBSSH2_SESSION *session;    session = libssh2_session_init();    if (session == NULL) {        fprintf(stderr, "Failed to create session");        return 1;    }    // 设置会话壅闭模式    libssh2_session_set_blocking(session, 1);    // 创建连接    const char *hostname = "REMOTE_HOST";    const int port = 22;    const char *username = "REMOTE_USERNAME";    const char *password = "REMOTE_PASSWORD";    int socket = socket_connect(hostname, port); // 自定义函数,用于创建socket连接    if (socket < 0) {        fprintf(stderr, "Failed to connect to the remote host");        return 1;    }    rc = libssh2_session_handshake(session, socket);    if (rc != 0) {        fprintf(stderr, "Session handshake failed");        return 1;    }    rc = libssh2_userauth_password(session, username, password);    if (rc != 0) {        fprintf(stderr, "Authentication failed");        return 1;    }    // 实验远程下令    LIBSSH2_CHANNEL *channel = libssh2_channel_open_session(session);    if (channel == NULL) {        fprintf(stderr, "Failed to open a channel");        return 1;    }    rc = libssh2_channel_exec(channel, "REMOTE_COMMAND");    if (rc != 0) {        fprintf(stderr, "Failed to execute remote command");        return 1;    }    // 读取并打印远程下令输出    char buffer[1024];    int nbytes;    while ((nbytes = libssh2_channel_read(channel, buffer, sizeof(buffer) - 1)) > 0) {        buffer[nbytes] = '\0';        printf("%s", buffer);    }    // 断开连接和清算    libssh2_channel_close(channel);    libssh2_channel_free(channel);    libssh2_session_disconnect(session, "Goodbye");    libssh2_session_free(session);    libssh2_exit();
  3.     return 0;}
复制代码
四、文件传输

4.1、上传文件到远程主机

要利用libssh2上传文件到远程主机,按照以下步调进行操作:
以下是一个简单的C++代码示例:
  1. #include <iostream>#include <libssh2.h>
  2. #include <libssh2_sftp.h>int main() {    // 初始化libssh2库    int rc = libssh2_init(0);    if (rc != 0) {        std::cerr << "Failed to initialize libssh2. Error code: " << rc << std::endl;        return 1;    }    // 创建SSH连接    LIBSSH2_SESSION* session = libssh2_session_init();    if (!session) {        std::cerr << "Failed to create SSH session." << std::endl;        return 1;    }    // 设置远程主机的IP地址和端标语    const char* ip = "remote_host_ip";    int port = 22;    // 连接远程主机    rc = libssh2_session_startup(session, socket);    if (rc != 0) {        std::cerr << "Failed to establish SSH connection. Error code: " << rc << std::endl;        return 1;    }    // 进行身份验证(用户名和暗码)    const char* username = "your_username";    const char* password = "your_password";    rc = libssh2_userauth_password(session, username, password);    if (rc != 0) {        std::cerr << "Failed to authenticate. Error code: " << rc << std::endl;        return 1;    }    // 打开SFTP会话    LIBSSH2_SFTP* sftp_session = libssh2_sftp_init(session);    if (!sftp_session) {        std::cerr << "Failed to initialize SFTP session." << std::endl;        return 1;    }    // 打开本地文件    const char* local_file = "path_to_local_file";    FILE* local_file_handle = fopen(local_file, "rb");    if (!local_file_handle) {        std::cerr << "Failed to open local file: " << local_file << std::endl;        return 1;    }    // 打开远程文件    const char* remote_file = "path_to_remote_file";    LIBSSH2_SFTP_HANDLE* sftp_handle = libssh2_sftp_open(sftp_session, remote_file,                                                        LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC,                                                        LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH);    if (!sftp_handle) {        std::cerr << "Failed to open remote file: " << remote_file << std::endl;        return 1;    }    // 传输文件内容    char buffer[1024];    size_t bytes_read;    ssize_t bytes_written;    while ((bytes_read = fread(buffer, 1, sizeof(buffer), local_file_handle)) > 0) {        bytes_written = libssh2_sftp_write(sftp_handle, buffer, bytes_read);        if (bytes_written != bytes_read) {            std::cerr << "Failed to write to remote file." << std::endl;            return 1;        }    }    // 关闭本地文件和远程文件    fclose(local_file_handle);    libssh2_sftp_close(sftp_handle);    // 关闭SFTP会话和SSH连接    libssh2_sftp_shutdown(sftp_session);    libssh2_session_disconnect(session, "Goodbye");    libssh2_session_free(session);    // 清算libssh2库    libssh2_exit();
  3.         return 0;}
复制代码
4.2、下载文件到本田主机

一个简单的C++代码示例:
  1. #include <iostream>#include <libssh2.h>
  2. #include <libssh2_sftp.h>int main() {    // 初始化libssh2库    int rc = libssh2_init(0);    if (rc != 0) {        std::cerr << "Failed to initialize libssh2. Error code: " << rc << std::endl;        return 1;    }    // 创建SSH连接    LIBSSH2_SESSION* session = libssh2_session_init();    if (!session) {        std::cerr << "Failed to create SSH session." << std::endl;        return 1;    }    // 设置远程主机的IP地址和端标语    const char* ip = "remote_host_ip";    int port = 22;    // 连接远程主机    rc = libssh2_session_startup(session, socket);    if (rc != 0) {        std::cerr << "Failed to establish SSH connection. Error code: " << rc << std::endl;        return 1;    }    // 进行身份验证(用户名和暗码)    const char* username = "your_username";    const char* password = "your_password";    rc = libssh2_userauth_password(session, username, password);    if (rc != 0) {        std::cerr << "Failed to authenticate. Error code: " << rc << std::endl;        return 1;    }    // 打开SFTP会话    LIBSSH2_SFTP* sftp_session = libssh2_sftp_init(session);    if (!sftp_session) {        std::cerr << "Failed to initialize SFTP session." << std::endl;        return 1;    }    // 打开远程文件    const char* remote_file = "path_to_remote_file";    LIBSSH2_SFTP_HANDLE* sftp_handle = libssh2_sftp_open(sftp_session, remote_file, LIBSSH2_FXF_READ, 0);    if (!sftp_handle) {        std::cerr << "Failed to open remote file: " << remote_file << std::endl;        return 1;    }    // 打开本地文件    const char* local_file = "path_to_local_file";    FILE* local_file_handle = fopen(local_file, "wb");    if (!local_file_handle) {        std::cerr << "Failed to open local file: " << local_file << std::endl;        return 1;    }    // 下载文件内容    char buffer[1024];    ssize_t bytes_read;    ssize_t bytes_written;    while ((bytes_read = libssh2_sftp_read(sftp_handle, buffer, sizeof(buffer))) > 0) {        bytes_written = fwrite(buffer, 1, bytes_read, local_file_handle);        if (bytes_written != bytes_read) {            std::cerr << "Failed to write to local file." << std::endl;            return 1;        }    }    // 关闭本地文件和远程文件    fclose(local_file_handle);    libssh2_sftp_close(sftp_handle);    // 关闭SFTP会话和SSH连接    libssh2_sftp_shutdown(sftp_session);    libssh2_session_disconnect(session, "Goodbye");    libssh2_session_free(session);    // 清算libssh2库    libssh2_exit();
  3.         return 0;}
复制代码
五、总结

本文全面介绍了利用libssh2库创建安全的SSH连接的过程。通过对文章的阅读,读者可以了解到怎样利用libssh2库进行SSH连接的准备工作,以及创建SSH连接的具体步调。文章还提供了文件传输的示例,资助读者了解怎样利用libssh2库进行文件上传和下载操作。通过本文的指导,C++开发者可以更好地利用libssh2库来实现安全的SSH连接和远程服务器管理。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4