๐๐ป ์ฃผ์ ๋ณ๊ฒฝ์ฌํญ์ ์๋์ ๊ฐ์ต๋๋ค.
The major changes are as follows.
โ๏ธ โ๏ธ ํ์๋ ๋ถ๋ถ์ด ๋ณ๊ฒฝ์ฌํญ์
๋๋ค.
The parts marked with โ๏ธ are the changes.
โ๏ธ http,https ๋ค์์คํ์ด์ค ์ ์ฉ
Apply http, https namespaces
# Server.h
namespace http{
class Server { ... };
}
# HttpsServer.cpp
namespace https {
class Server { ... };
}
โ๏ธ httpsํ๋กํ ์ฝ ์ ์ฉ / Apply HTTPS protocol
๐๐ป openssl ์ ์ฉํ๊ธฐ / Apply openssl
โ๏ธ openssl ์ค์น / install openssl
brew install openssl
โ๏ธ openssl ์ค์น ๊ฒฝ๋ก ํ์ธ / Check the openssl installation path
MacBookAir build % brew --prefix openssl
/opt/homebrew/opt/openssl@3
โ๏ธ CMakeLists.txt ํ์ผ์ openssl ์ ์ฉ
Apply openssl to the CMakeLists.txt file
# cmake์ต์๋ฒ์ ์ง์ / Specify minimum CMake version
cmake_minimum_required(VERSION 3.10)
# ํ๋ก์ ํธ ์ด๋ฆ๊ณผ ๋ฒ์ ์ค์ / Project name and version settings
project(mini_webserver_9 VERSION 1.0)
# C++ ํ์ค ๋ฒ์ ์ง์ (c++20) / C++ Standard Version Specification (C++20)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Opensslโ๏ธ
include_directories(/opt/homebrew/opt/openssl@3/include)
link_directories(/opt/homebrew/opt/openssl@3/lib)
# โ๏ธ ์คํ ํ์ผ ์์ฑ ๋์ ์์ค ํ์ผ ๋์ด / List source files to be used for creating executable files
add_executable(main
Main.cpp
Router.cpp
Server.cpp
HttpsServer.cpp
)
# Openssl + main ๋งํฌ / linkโ๏ธ
target_link_libraries(main ssl crypto)
โ๏ธ ํ
์คํธ์ฉ ์ธ์ฆ์ ์์ฑ (key.pem, cert.pem)
Generate a certificate for testing(key.pem, cert.pem)
— ์ธ์ฆ์ ์์ฑ ๋ช ๋ น / Certificate creation command
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
- req : ์์ฒด ์๋ช ์ธ์ฆ์๋ฅผ ์์ฑ / Generate a self-signed certificate
- x509 : x.509ํ์์ผ๋ก ์์ฑ / Created in x.509 format
- newkey rsa:4096 :
์ 4096๋นํธ RSA ๊ฐ์ธํค์ ์ธ์ฆ์ ์์ฒญ์ ํจ๊ป ์์ฑ
Generate a new 4096-bit RSA private key and a certificate request together
- keyout key.pem : ๊ฐ์ธํค๊ฐ ์ ์ฅ๋ ํ์ผ๋ช / filename where the private key will be stored
- out cert.pem : ์์ฑ๋ ์ธ์ฆ์ ํ์ผ๋ช / Certificate filename to be generated
- days 365 : ์ธ์ฆ์ ์ ํจ๊ธฐ๊ฐ / Certificate validity period
- nodes: ์ํธํํ์ง์์(๋น๋ฐ๋ฒํธ ์์ด ์ฌ์ฉ๊ฐ๋ฅ) / Unencrypted (can be used without a password)
— ์ง๋ฌธ์ ๊ทธ๋ฅ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ๋ชจ๋ ์ํฐ๋ฅผ ์
๋ ฅํฉ๋๋ค.
For the questions, just press Enter for all default values.
MacBookAir cert % openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
..+.........+.+.....+...+.+..+..........+.....+....+++++++++++++++++++++++++++++++++++++++++++++*.....+.....+............+.+..............+...+...+++++++++++++++++++++++++++++++++++++++++++++*...........+.....+.+......
... ์ค๋ต/skipping the middle ...
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
MacBookAir cert %
๐๐ป์ฝ๋ / Code
โ๏ธ httpsServer.h ,httpsServer.cppํ์ผ์ด ์ถ๊ฐ๋์์ต๋๋ค.
โ๏ธ์ธ์ฆ์ ๊ฒ์ฌ ๋ฐ ๋ฑ๋ก(httpsServer.cpp,main.cpp)
— httpsServer.cpp
bool https::Server::initialize_ssl(const std::string& cert_file, const std::string& key_file) { ... }
— main.cpp
if (!server3.initialize_ssl("../cert/cert.pem", "../cert/key.pem")) {
std::cerr << "SSL initialization failed. Exiting.\n";
return -1;
}
โ๏ธ ์์ผ์ ์ ์ฉ / Apply to socket
void https::Server::handle_client(int client_socket) {
// https์ค์ ์ถ๊ฐ / Add https settingsโ๏ธ
SSL* ssl = SSL_new(ssl_ctx);
if (!ssl) {
std::cerr << "[SSL] SSL_new() failed\n";
close(client_socket);
return;
}
// client_socket์ ssl์ ์ฉ / Apply SSL to client_socketโ๏ธ
SSL_set_fd(ssl, client_socket);
if (SSL_accept(ssl) <= 0) {
ERR_print_errors_fp(stderr);
SSL_free(ssl);
close(client_socket);
return;
}
... ์ค๋ต / skipping the middle...
// http์ค์ / http setting
//write(client_socket, response.c_str(), response.size());
//
// https์ค์ . https setting โ๏ธ
SSL_write(ssl, response.c_str(), static_cast<int>(response.size()));
}
โ๏ธ stopํจ์์์ ์์ผ,SSL/TLS ,openssl ์ข
๋ฃ
Terminate socket, SSL/TLS, and openssl in the stop function
— httpsServer.cpp
void https::Server::stop() {
if (running.load() && server_fd != -1) { //
// ํ๋๊ทธ๋ฅผ false๋ก ์ค์ ํ์ฌ ๋ฃจํ ์ข
๋ฃ ์ ํธ ์ ์ก
// Set flag to false to send loop termination signal
running.store(false);
//close(server_fd); //โ๏ธ -
// ์ค์ ๋ก๋ ์ฌ๊ธฐ์ ์์ผ์ ๋ซ๊ฑฐ๋ ๋ฆฌ์์ค ํด์ ๋ฅผ ์ํํฉ๋๋ค.
// In practice, close the socket or release resources here.
//server_fd = -1; // ๋ซ์์ผ๋ฏ๋ก ์ด๊ธฐํ / Initialize to -1 after closing
// โ๏ธ -> ๋ณ๊ฒฝ๋ ์ฝ๋ / changed code
// ์๋ฒ ์์ผ ๋ซ๊ธฐ (์ด๋ ค์๋ค๋ฉด) / Close server socket (if open)
if (server_fd != -1) {
close(server_fd);
server_fd = -1;
}
// SSL ์ปจํ
์คํธ ํด์ (์กด์ฌํ๋ค๋ฉด) Release SSL context (if any) โ๏ธ
if (ssl_ctx) {
SSL_CTX_free(ssl_ctx);
ssl_ctx = nullptr;
}
// OpenSSL ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋ฆฌ / OpenSSL Library Cleanup โ๏ธ
EVP_cleanup();
std::cout << "[Server] Shutdown initiated." << std::endl;
}
}
๐๐ป๋น๋ / Build
cd build
cmake ..
make
๐๐ป์คํ / Run
./main
๐๐ป ๋ธ๋ผ์ฐ์ ์ ์ / Access Browser
https://localhost:6443/