[Webserver]miniWebserver+https-(9)

๐Ÿ‘‰๐Ÿป ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
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/

Leave a Reply