#include #include #include #include #include #include #include #include #include #include #include #include #include const int PORT = 7271; const char* SERVER_CERT_FILE = "server.crt"; const char* SERVER_KEY_FILE = "server.key"; const char* CA_CERT_FILE = "ca.crt"; volatile sig_atomic_t server_running = 1; void signal_handler(int sig) { std::cout << "\n收到信号 " << sig << ",正在关闭服务器..." << std::endl; server_running = 0; } void print_openssl_errors() { BIO* bio = BIO_new_fp(stderr, BIO_NOCLOSE); ERR_print_errors(bio); BIO_free(bio); } void init_openssl() { SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); } void cleanup_openssl() { #if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_cleanup(); #endif } SSL_CTX* create_context() { const SSL_METHOD* method = TLS_server_method(); SSL_CTX* ctx = SSL_CTX_new(method); if (!ctx) { std::cerr << "无法创建SSL上下文" << std::endl; print_openssl_errors(); exit(EXIT_FAILURE); } SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION); return ctx; } int verify_callback(int preverify_ok, X509_STORE_CTX* ctx) { if (!preverify_ok) { int err = X509_STORE_CTX_get_error(ctx); if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) { return 1; } } return preverify_ok; } void configure_context(SSL_CTX* ctx) { if (SSL_CTX_use_certificate_file(ctx, SERVER_CERT_FILE, SSL_FILETYPE_PEM) <= 0) { std::cerr << "无法加载服务器证书" << std::endl; print_openssl_errors(); exit(EXIT_FAILURE); } if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_FILE, SSL_FILETYPE_PEM) <= 0) { std::cerr << "无法加载服务器私钥" << std::endl; print_openssl_errors(); exit(EXIT_FAILURE); } if (!SSL_CTX_check_private_key(ctx)) { std::cerr << "证书和私钥不匹配" << std::endl; exit(EXIT_FAILURE); } if (SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, nullptr) <= 0) { std::cerr << "无法加载CA证书" << std::endl; print_openssl_errors(); exit(EXIT_FAILURE); } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); SSL_CTX_set_verify_depth(ctx, 4); // 关键优化:简化SSL选项 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-GCM-SHA256"); } void graceful_ssl_close(SSL* ssl, int fd) { if (!ssl || fd < 0) return; // 简化的关闭逻辑 SSL_shutdown(ssl); SSL_free(ssl); close(fd); } void handle_connection(SSL* ssl, int client_fd, const char* client_ip, uint16_t client_port) { std::cout << "\n处理连接 " << client_ip << ":" << client_port << std::endl; std::cout << "协议: " << SSL_get_version(ssl) << std::endl; // 验证客户端证书 X509* client_cert = SSL_get_peer_certificate(ssl); if (!client_cert) { std::cerr << "客户端未提供证书" << std::endl; graceful_ssl_close(ssl, client_fd); return; } X509_free(client_cert); // 设置TCP_NODELAY int optval = 1; setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)); // 设置60秒读取超时 struct timeval timeout = {60, 0}; setsockopt(client_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); std::cout << "等待客户端数据..." << std::endl; // 读取客户端数据 char buffer[4096]; int bytes = SSL_read(ssl, buffer, sizeof(buffer)); if (bytes > 0) { std::cout << "收到数据: " << bytes << "字节" << std::endl; // 发送响应 const char* response = "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Connection: close\r\n" "\r\n" "Hello from TLS server!"; SSL_write(ssl, response, strlen(response)); std::cout << "已发送响应" << std::endl; } else if (bytes == 0) { std::cout << "客户端关闭连接" << std::endl; } else { std::cout << "客户端未发送数据(超时)" << std::endl; } graceful_ssl_close(ssl, client_fd); } int main() { signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); init_openssl(); SSL_CTX* ctx = create_context(); configure_context(ctx); int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); exit(EXIT_FAILURE); } int optval = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); sockaddr_in addr{}; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = INADDR_ANY; if (bind(sockfd, (sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind"); exit(EXIT_FAILURE); } if (listen(sockfd, 10) < 0) { perror("listen"); exit(EXIT_FAILURE); } std::cout << "服务器监听端口 " << PORT << std::endl; while (server_running) { sockaddr_in client_addr{}; socklen_t client_len = sizeof(client_addr); int client_fd = accept(sockfd, (sockaddr*)&client_addr, &client_len); if (client_fd < 0) { if (server_running) perror("accept"); continue; } char client_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN); uint16_t client_port = ntohs(client_addr.sin_port); SSL* ssl = SSL_new(ctx); SSL_set_fd(ssl, client_fd); if (SSL_accept(ssl) <= 0) { std::cerr << "SSL握手失败: "; print_openssl_errors(); SSL_free(ssl); close(client_fd); continue; } handle_connection(ssl, client_fd, client_ip, client_port); } close(sockfd); SSL_CTX_free(ctx); cleanup_openssl(); return 0; }