<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ethan</title>
    <description>The latest articles on DEV Community by Ethan (@ethan_ac5ca38abc559d950c9).</description>
    <link>https://dev.to/ethan_ac5ca38abc559d950c9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3556864%2F64607dbd-8db0-4269-a17f-d4a69d9b617e.jpeg</url>
      <title>DEV Community: Ethan</title>
      <link>https://dev.to/ethan_ac5ca38abc559d950c9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ethan_ac5ca38abc559d950c9"/>
    <language>en</language>
    <item>
      <title>Building a Cybersecurity Lab: Project Overview 🗺️</title>
      <dc:creator>Ethan</dc:creator>
      <pubDate>Sat, 25 Oct 2025 23:13:28 +0000</pubDate>
      <link>https://dev.to/ethan_ac5ca38abc559d950c9/building-a-cybersecurity-lab-project-overview-58gp</link>
      <guid>https://dev.to/ethan_ac5ca38abc559d950c9/building-a-cybersecurity-lab-project-overview-58gp</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3eh7hvj5um18r7bgtu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3eh7hvj5um18r7bgtu5.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Throughout my cybersecurity journey I've heard the saying "hands-on experience beats theory," about a hundred times. I've always followed this principle when learning something new. Whether it be CTFs or small security related projects, I've had a blast taking on new challenges. However, there's one challenge that I've been eagerly waiting to take on until now.&lt;/p&gt;

&lt;p&gt;After purchasing an old refurbished Dell tower desktop and installing Proxmox as my main OS, I'll finally be able to take on the unique challenge of building a home lab. To fully understand what it takes to secure a network, you've gotta do the real thing, and I have a feeling I'll end up learning a lot from this. Whether it be setting up a SIEM for SOC related purposes, simulating attacks, or practicing incident response, there's so much to learn when building and tinkering with a home lab.&lt;/p&gt;

&lt;h2&gt;
  
  
  📁 Cybersecurity Lab Architecture
&lt;/h2&gt;

&lt;p&gt;Within this lab environment I plan on building out 5 separate networks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Management Network - This is where my Proxmox administration and Internet access will sit. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Corporate Network - This will be a "production" environment with Active Directory. My main aim is to emulate a real corporate environment consisting of domain controllers, workstations, file servers, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Tools Network - This is where most or all of my security tools will live. This network will include a SIEM, network monitoring, and my security infrastructure. I plan on incorporating tools such as Splunk, Wazuh, TheHive, MISP, and many more.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DMZ - This network segment will consist of vulnerable applications and exposed services. I'm thinking of introducing Metasploitable, DVWA, and exploitable web applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Red Team Network - This will be my isolated attack infrastructure, consisting of Kali Linux, attack tools, and C2 servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ⚡ Data Flow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyrirzp7eht192a7a8pn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyrirzp7eht192a7a8pn0.png" alt=" " width="486" height="993"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Project Goals
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Technical Skills&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure enterprise security tools from scratch&lt;/li&gt;
&lt;li&gt;Write detection rules (Sigma, SPL, YARA)&lt;/li&gt;
&lt;li&gt;Analyze logs and network traffic for threats&lt;/li&gt;
&lt;li&gt;Conduct digital forensics investigations&lt;/li&gt;
&lt;li&gt;Automate security workflows with Python&lt;/li&gt;
&lt;li&gt;Understand common attack techniques and how to detect them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📚 Analytical Skills&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Threat hunting methodology and process&lt;/li&gt;
&lt;li&gt;Incident investigation procedures&lt;/li&gt;
&lt;li&gt;Root cause analysis and prioritization&lt;/li&gt;
&lt;li&gt;Pattern recognition in security data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🤝 Soft Skills&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Technical documentation and report writing&lt;/li&gt;
&lt;li&gt;Communication of technical concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⭐ Next Steps
&lt;/h2&gt;

&lt;p&gt;So far I've installed Proxmox and created network bridges for each of my segmented networks. Ontop of that, I've also downloaded the necessary ISOs for each operating system I plan on using in the lab. &lt;/p&gt;

&lt;p&gt;Next up, I'll be installing pfsense for my firewall, which will allows me to understand how these segmented networks will communicate with each other. &lt;/p&gt;

&lt;p&gt;If you'd like to follow along with my cybersecurity lab journey, please check out the &lt;a href="https://github.com/EthanMartin123/cyber-lab" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repository I created for this project. There's not much in there right now, but I do plan on adding more as the project develops.&lt;/p&gt;




&lt;p&gt;If you have any suggestions please leave them in the comments below!&lt;br&gt;
Thanks for reading! 👋&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>proxmox</category>
      <category>security</category>
      <category>networking</category>
    </item>
    <item>
      <title>Encrypting my HTTP server with OpenSSL in C 🔒</title>
      <dc:creator>Ethan</dc:creator>
      <pubDate>Wed, 15 Oct 2025 01:41:49 +0000</pubDate>
      <link>https://dev.to/ethan_ac5ca38abc559d950c9/encrypting-my-http-server-with-openssl-in-c-34bj</link>
      <guid>https://dev.to/ethan_ac5ca38abc559d950c9/encrypting-my-http-server-with-openssl-in-c-34bj</guid>
      <description>&lt;h1&gt;
  
  
  Implementing TLS in My C HTTP Server
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;After building my HTTP server in C, I was eager to start securing the site's traffic. I had heard a lot about SSL/TLS from studying for the CompTIA Security+ certification, but implementing it gave me a unique and more developed understanding of how it's actually integrated with network protocols.&lt;/p&gt;

&lt;h2&gt;
  
  
  How TLS Works
&lt;/h2&gt;

&lt;p&gt;Before I dive into the code, it's important that we first understand the fundamentals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdxw5qaco44ucogdmnl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdxw5qaco44ucogdmnl5.png" alt="TLS Handshake Diagram" width="590" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The TLS handshake comes into play after the TCP three-way handshake and before any HTTP pages are served.&lt;/p&gt;

&lt;p&gt;Here's a step-by-step overview of how the TLS 1.3 handshake unfolds:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Client Hello Message.&lt;/strong&gt; The client initiates the handshake by sending a "hello" message to the server. In this message the server will find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The TLS version the client supports&lt;/li&gt;
&lt;li&gt;The cipher suites supported&lt;/li&gt;
&lt;li&gt;A string of random bytes known as "client random"&lt;/li&gt;
&lt;li&gt;Parameters for calculating the premaster secret&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Server Generates Master Secret.&lt;/strong&gt; Server now has the following to create the master secret:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client random&lt;/li&gt;
&lt;li&gt;Client's parameters&lt;/li&gt;
&lt;li&gt;Cipher suites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Server Hello/Finished Message.&lt;/strong&gt; The server's hello and finished messages include the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server's certificate&lt;/li&gt;
&lt;li&gt;Digital signature&lt;/li&gt;
&lt;li&gt;Server random&lt;/li&gt;
&lt;li&gt;Chosen cipher suite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Client Finished.&lt;/strong&gt; The client verifies the validity of the signature and certificate, then generates the master secret, and sends a "Finished" message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Last thing to note before we jump into the code implementation...
&lt;/h3&gt;

&lt;p&gt;The TLS handshake utilizes &lt;strong&gt;asymmetric encryption&lt;/strong&gt;. Asymmetric encryption is defined as a process of encryption that uses a pair of mathematically linked keys: a public key and a private key.&lt;/p&gt;

&lt;p&gt;After the TLS handshake is completed, future traffic is encrypted using &lt;strong&gt;symmetric encryption&lt;/strong&gt;. Symmetric encryption uses the same secret key to encrypt and decrypt data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Implementation
&lt;/h2&gt;

&lt;p&gt;OpenSSL is an open-source toolkit for cryptographic and secure communication. With OpenSSL we get access to two important libraries: &lt;strong&gt;libcrypto&lt;/strong&gt; and &lt;strong&gt;libssl&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cryptographic library (libcrypto):&lt;/strong&gt; Contains a variety of cryptographic functions for symmetric encryption (like AES), asymmetric encryption (like RSA), as well as cryptographic hashing (like SHA256).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLS/SSL library (libssl):&lt;/strong&gt; Gives us access to the SSL and TLS protocols, which are used for secure connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;openssl/ssl.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;    // libssl&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;openssl/err.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;    // openssl errors&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;openssl/crypto.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // libcrypto&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  OpenSSL in Action
&lt;/h3&gt;

&lt;p&gt;Before, my HTTP server used POSIX functions to establish a basic connection. In order to create a secure connection, we'll need some additional functionality working around those POSIX functions.&lt;/p&gt;

&lt;h4&gt;
  
  
  setup_tls()
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;SSL_CTX&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;setup_tls&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SSL_library_init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;OpenSSL_add_all_algorithms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;SSL_load_error_strings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;SSL_CTX&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SSL_CTX_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TLS_server_method&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to create SSL context"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_set_cipher_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DEFAULT:!aNULL:!eNULL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"failed to set cipher list&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_set_ciphersuites&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Failed to set TLS 1.3 cipher suites&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_use_certificate_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"certs/cert.pem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SSL_FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to use cert file"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_use_PrivateKey_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"certs/key.pem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SSL_FILETYPE_PEM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to use private key file"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_check_private_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Private Key does not match certificate&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ TLS Configured Successfully&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a lot to unpack here. Let me break down the key components:&lt;/p&gt;

&lt;h4&gt;
  
  
  Initialization Functions
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;SSL_library_init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;OpenSSL_add_all_algorithms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;SSL_load_error_strings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These three function calls initialize the OpenSSL library, register all available encryption algorithms, and load human-readable error messages that we can use for debugging.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating the SSL Context
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;SSL_CTX&lt;/code&gt; structure holds all the configuration for our TLS implementation. We create it using &lt;code&gt;TLS_server_method()&lt;/code&gt;, which automatically selects the highest TLS version supported by both client and server.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuring Cipher Suites
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_set_cipher_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DEFAULT:!aNULL:!eNULL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"failed to set cipher list&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_CTX_set_ciphersuites&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Failed to set TLS 1.3 cipher suites"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first function configures cipher suites for TLS 1.2 and earlier, excluding any that don't provide authentication or encryption. The second function specifically sets cipher suites for TLS 1.3, prioritizing AES-256 for maximum security.&lt;/p&gt;

&lt;h4&gt;
  
  
  Loading Certificates and Private Keys
&lt;/h4&gt;

&lt;p&gt;The certificate and private key are essential for the TLS handshake. The certificate contains the server's public key and is sent to clients during the handshake. The private key remains on the server and is used to decrypt data encrypted with the public key. The &lt;code&gt;SSL_CTX_check_private_key()&lt;/code&gt; function verifies that the private key corresponds to the certificate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrating TLS into the Server Loop
&lt;/h3&gt;

&lt;p&gt;With our TLS context set up, we need to modify how we handle client connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// After accepting a connection&lt;/span&gt;
    &lt;span class="n"&gt;client_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;new_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockfd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;client_len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accept"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// TLS handshake per connection&lt;/span&gt;
    &lt;span class="n"&gt;SSL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SSL_new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl_ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TLS handshake failed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_set_fd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to set fd with SSL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Performing TLS handshake...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSL_accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SSL_accept failed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;ERR_print_errors_fp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;SSL_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Now use SSL_read() and SSL_write() instead of read() and write()&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;bytes_received&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SSL_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// ... process request ...&lt;/span&gt;

&lt;span class="n"&gt;SSL_write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Clean up&lt;/span&gt;
&lt;span class="n"&gt;SSL_shutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;SSL_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key difference is that we wrap the standard socket file descriptor with an SSL structure using &lt;code&gt;SSL_new()&lt;/code&gt; and &lt;code&gt;SSL_set_fd()&lt;/code&gt;. The &lt;code&gt;SSL_accept()&lt;/code&gt; function performs the entire TLS handshake we discussed earlier. After that, we use &lt;code&gt;SSL_read()&lt;/code&gt; and &lt;code&gt;SSL_write()&lt;/code&gt; instead of the standard POSIX equivalents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;Implementing TLS from scratch gave me several important insights:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The abstraction is powerful but complex.&lt;/strong&gt; OpenSSL handles an enormous amount of complexity behind relatively simple function calls. Understanding what happens during &lt;code&gt;SSL_accept()&lt;/code&gt; helps appreciate the engineering that goes into secure communications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Certificate management matters.&lt;/strong&gt; In production, you'll need properly signed certificates from a Certificate Authority. For development, self-signed certificates work fine, but browsers will show security warnings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance considerations are real.&lt;/strong&gt; The TLS handshake adds latency to each new connection. This is why HTTP/2 and HTTP/3 emphasize connection reuse and why session resumption exists in TLS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error handling is critical.&lt;/strong&gt; OpenSSL provides detailed error information through &lt;code&gt;ERR_print_errors_fp()&lt;/code&gt;, which was invaluable during debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Now that the server supports TLS, I'm planning to take security further with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Scanner:&lt;/strong&gt; Build a tool to test my server against common vulnerabilities like weak cipher suites, certificate validation issues, and protocol downgrade attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP Fuzzer:&lt;/strong&gt; Create a fuzzer to send malformed requests and edge cases to ensure the server handles unexpected input gracefully without crashes or security issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability Analysis:&lt;/strong&gt; Implement security headers (HSTS, CSP, X-Frame-Options) and test against tools like Nikto and OWASP ZAP to identify any remaining vulnerabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it Yourself
&lt;/h2&gt;

&lt;p&gt;If you want to experiment with TLS implementation, checkout out my project on &lt;a href="https://github.com/EthanMartin123/http-tls-security-toolkit" rel="noopener noreferrer"&gt;Github&lt;/a&gt;! &lt;/p&gt;

&lt;p&gt;Building a TLS-enabled server from scratch has been one of the most educational projects I've undertaken. It transformed my theoretical knowledge of cryptography and network security into practical, hands-on experience. I highly recommend trying it yourself if you want to deepen your understanding of how secure communications work at a fundamental level.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have questions or suggestions? Feel free to reach out or leave a comment below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>security</category>
      <category>c</category>
    </item>
    <item>
      <title>Building an HTTP Server from Scratch in C: A Journey into Network Programming</title>
      <dc:creator>Ethan</dc:creator>
      <pubDate>Fri, 10 Oct 2025 18:43:17 +0000</pubDate>
      <link>https://dev.to/ethan_ac5ca38abc559d950c9/building-an-http-server-from-scratch-in-c-a-journey-into-network-programming-19oa</link>
      <guid>https://dev.to/ethan_ac5ca38abc559d950c9/building-an-http-server-from-scratch-in-c-a-journey-into-network-programming-19oa</guid>
      <description>&lt;p&gt;When you type a URL into your browser and hit enter, a complex dance of network protocols springs into action. But how many developers actually understand what's happening under the hood? I decided to find out by building a bare-metal HTTP/1.1 server in C—no frameworks, no libraries, just sockets and the HTTP specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build This?
&lt;/h2&gt;

&lt;p&gt;I had three main motivations for this project:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning by doing.&lt;/strong&gt; Reading about TCP sockets and HTTP is one thing; implementing them yourself is entirely different. You discover edge cases the documentation never mentions and develop an intuition for how these fundamental protocols actually work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preparing for security work.&lt;/strong&gt; My ultimate goal is to add TLS encryption and build security testing tools (scanner, fuzzer, analyzer) on top of this server. You can't secure what you don't understand, and understanding starts at the lowest level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The satisfaction of first principles.&lt;/strong&gt; There's something deeply satisfying about writing &lt;code&gt;socket()&lt;/code&gt;, &lt;code&gt;bind()&lt;/code&gt;, and &lt;code&gt;listen()&lt;/code&gt; yourself and watching your browser successfully connect to your creation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;The server currently supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP/1.1 protocol with proper socket programming&lt;/li&gt;
&lt;li&gt;GET requests for static file serving&lt;/li&gt;
&lt;li&gt;POST requests with form data parsing&lt;/li&gt;
&lt;li&gt;Multiple route support (/, /about, /submit)&lt;/li&gt;
&lt;li&gt;Proper HTTP status codes (200, 404, 400, 405, 500)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server listens on port 8080 and handles one connection at a time (yes, I know—more on that later).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setting Up the Socket
&lt;/h3&gt;

&lt;p&gt;The foundation of any network server is the socket. Here's the basic flow I implemented:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create address info structure&lt;/strong&gt; using &lt;code&gt;getaddrinfo()&lt;/code&gt; to handle both IPv4 and IPv6&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create the socket&lt;/strong&gt; with &lt;code&gt;socket()&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set socket options&lt;/strong&gt; with &lt;code&gt;SO_REUSEADDR&lt;/code&gt; to avoid "Address already in use" errors during development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bind to a port&lt;/strong&gt; so the OS knows which port belongs to our server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listen for connections&lt;/strong&gt; with a backlog of 1 (handling one connection at a time)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The beauty of using &lt;code&gt;getaddrinfo()&lt;/code&gt; is that it makes the code protocol-agnostic. The same code works for IPv4 and IPv6 without modification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parsing HTTP Requests
&lt;/h3&gt;

&lt;p&gt;Once a connection arrives via &lt;code&gt;accept()&lt;/code&gt;, I receive the raw HTTP request into a buffer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;bytes_received&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bytes_received&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request comes in as plain text that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /about HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I parse the request line using &lt;code&gt;sscanf()&lt;/code&gt; to extract the method, path, and HTTP version. Simple, but effective for this learning project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serving Static Files
&lt;/h3&gt;

&lt;p&gt;For GET requests, the server maps URLs to files and serves them. The routing logic is straightforward—special paths like &lt;code&gt;/&lt;/code&gt; map to &lt;code&gt;index.html&lt;/code&gt;, while other paths are treated as literal filenames.&lt;/p&gt;

&lt;p&gt;The file serving function handles several scenarios:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Success case (200 OK):&lt;/strong&gt; Read the file, calculate its size, send proper headers with Content-Length, then send the file content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File not found (404):&lt;/strong&gt; Return an HTML error page explaining the file doesn't exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory allocation failure (500):&lt;/strong&gt; Return an internal server error if we can't allocate memory for the file content.&lt;/p&gt;

&lt;p&gt;One interesting challenge here was getting the Content-Length header right. Browsers need to know how many bytes to expect, so I use &lt;code&gt;ftell()&lt;/code&gt; after seeking to the end of the file to get the exact size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling POST Requests
&lt;/h3&gt;

&lt;p&gt;POST request handling is significantly more complex than GET. Here's why:&lt;/p&gt;

&lt;p&gt;The HTTP request body might not arrive all at once. The headers come first, terminated by &lt;code&gt;\r\n\r\n&lt;/code&gt;, and then the body follows. The body might be small enough to arrive in the same TCP packet, or it might require multiple &lt;code&gt;recv()&lt;/code&gt; calls.&lt;/p&gt;

&lt;p&gt;My approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Extract Content-Length&lt;/strong&gt; from the headers to know how many body bytes to expect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find the body start&lt;/strong&gt; by locating the &lt;code&gt;\r\n\r\n&lt;/code&gt; delimiter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calculate partial body bytes&lt;/strong&gt; already received in the initial buffer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loop and receive&lt;/strong&gt; additional data until we have the full content length&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parse the form data&lt;/strong&gt; (key=value pairs separated by &amp;amp;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write to output.txt&lt;/strong&gt; for persistence&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the loop that ensures we get the complete body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body_bytes_received&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;content_length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="n"&gt;new_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;full_body&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;body_bytes_received&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;content_length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;body_bytes_received&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_bytes&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;body_bytes_received&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;new_bytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was crucial to learn—network programming is fundamentally asynchronous, and you can't assume data arrives all at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Memory Management in C is Unforgiving
&lt;/h3&gt;

&lt;p&gt;Coming from higher-level languages, C's manual memory management was a wake-up call. Every &lt;code&gt;malloc()&lt;/code&gt; needs a corresponding &lt;code&gt;free()&lt;/code&gt;, and forgetting one creates a memory leak. I use Valgrind during development to catch these issues.&lt;/p&gt;

&lt;p&gt;For the file content and POST body, I dynamically allocate based on the size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// +1 for null terminator&lt;/span&gt;
&lt;span class="c1"&gt;// ... use it ...&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// must not forget!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Buffer Overflows Are Real
&lt;/h3&gt;

&lt;p&gt;With a fixed &lt;code&gt;BUFFER_SIZE&lt;/code&gt; of 8192 bytes, I had to be careful about buffer overflows. Using &lt;code&gt;sizeof(buffer) - 1&lt;/code&gt; when receiving data and properly null-terminating strings became second nature. One typo using &lt;code&gt;strcpy()&lt;/code&gt; instead of &lt;code&gt;strncpy()&lt;/code&gt; could lead to security vulnerabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP Parsing Edge Cases
&lt;/h3&gt;

&lt;p&gt;The HTTP specification has many edge cases I didn't initially consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What if there's no Content-Length header in a POST request?&lt;/li&gt;
&lt;li&gt;What if the request is malformed with no &lt;code&gt;\r\n\r\n&lt;/code&gt; delimiter?&lt;/li&gt;
&lt;li&gt;What if the Content-Length value isn't a valid integer?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these required adding defensive checks and returning proper 400 Bad Request responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Debug Printf Dilemma
&lt;/h3&gt;

&lt;p&gt;You'll notice the code has many &lt;code&gt;printf()&lt;/code&gt; statements with "DEBUG:" prefixes. During development, these were invaluable for understanding the flow of data. In a production server, these would be replaced with a proper logging framework, but for learning purposes, seeing the raw data flow in the terminal was incredibly educational.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrency (or Lack Thereof)
&lt;/h3&gt;

&lt;p&gt;The biggest limitation of my current implementation is that it handles only one connection at a time with &lt;code&gt;BACKLOG 1&lt;/code&gt;. While one client is being served, others must wait. The traditional solutions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fork a new process&lt;/strong&gt; for each connection (the Apache model)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use threads&lt;/strong&gt; with pthread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement non-blocking I/O&lt;/strong&gt; with select/poll/epoll (the nginx model)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I plan to explore these approaches as the project evolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next: Security Focus
&lt;/h2&gt;

&lt;p&gt;The natural next step is adding TLS/SSL encryption, but I'm taking this further by building a security testing suite:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLS 1.2/1.3 Implementation:&lt;/strong&gt; Understanding encryption protocols from the ground up using OpenSSL or mbedTLS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Scanner:&lt;/strong&gt; A tool to scan web servers for common vulnerabilities (missing headers, outdated protocols, weak ciphers).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP Fuzzer:&lt;/strong&gt; Automated testing that sends malformed requests to find parsing bugs and potential crashes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability Analysis:&lt;/strong&gt; Documentation of common web server vulnerabilities and how to prevent them.&lt;/p&gt;

&lt;p&gt;The goal is to understand not just how to build a server, but how attackers might exploit one and how to defend against those attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;Building this HTTP server taught me more about networking in a week than years of using high-level frameworks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstractions hide complexity.&lt;/strong&gt; Express.js and Flask make web development easy, but they obscure the fundamental protocols. Understanding the foundation makes you a better developer at every level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C demands precision.&lt;/strong&gt; Every byte matters. Every pointer must be valid. Every buffer must be sized correctly. This discipline translates to better code in any language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network programming is asynchronous by nature.&lt;/strong&gt; You can't assume data arrives all at once or in the order you expect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security starts at the design level.&lt;/strong&gt; Every parsing decision, every buffer allocation, every user input is a potential vulnerability if not handled carefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;If you're interested in learning network programming, I highly recommend building your own server. Start simple with a hello-world HTTP response, then gradually add features. The &lt;a href="https://beej.us/guide/bgnet/" rel="noopener noreferrer"&gt;Beej's Guide to Network Programming&lt;/a&gt; is an excellent resource for learning socket programming in C.&lt;/p&gt;

&lt;p&gt;The complete source code for this project is available on my &lt;a href="https://github.com/EthanMartin123/http-tls-security-toolkit" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and I'll be documenting the security additions in future posts.&lt;/p&gt;

&lt;p&gt;What low-level project are you working on? I'd love to hear about your experience in the comments below.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of my journey into network security. Follow along as I add TLS encryption and build security testing tools on top of this foundation.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>security</category>
      <category>c</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
