How I Built a Login System with Just NGINX, socat, and Bash

Blog Image

Why I Did It

I’ve always configured systems, maintained infrastructure, and debugged networks. But writing web applications? Not really my thing.

Yet one day I asked myself: how does a login system really work, under the hood?

So I decided to build one—not using a language or framework, but with just the tools I know best:

  • nginx for hosting and routing
  • socat for TCP forwarding
  • bash scripts for logic
  • A flat file for credentials

No libraries. No runtime. No “web stack.” Just Linux.


The Tools I Used

  • NGINX – to serve static pages and proxy requests
  • socat – to connect TCP ports to scripts
  • Bash – to handle POST requests and session logic
  • login.db – a simple flat file to store userid:hashedpassword (SHA-512)

The Login Flow

Here’s how it works, step by step:

1. The Login Form

A static login.html is served by NGINX. Here’s a minimal version:

<form action="/login" method="POST">
  <input type="text" name="username" />
  <input type="password" name="password" />
  <button type="submit">Login</button>
</form>

2. NGINX Proxies the Request

In my nginx.conf, I configured the /login path like this:

location /login {
    proxy_pass http://127.0.0.1:9000;
}

3. socat Forwards to Bash

socat listens on port 9000 and forwards input to a script:

socat TCP-LISTEN:9000,fork EXEC:/usr/local/bin/login.sh

The login.sh script does the following:

  • Reads POST data from stdin
  • Parses username and password
  • Verifies them against /etc/login.db
  • On success:
    • Generates a random session token
    • Saves it in /etc/sessions/<token>
    • Sends a Set-Cookie header and a 302 Redirect to /protected

4. Session Validation

Requests to /protected are routed like this:

location /protected {
    proxy_pass http://127.0.0.1:9001;
}

With socat again:

socat TCP-LISTEN:9001,fork EXEC:/usr/local/bin/check_session.sh

The check_session.sh script:

  • Reads the session cookie
  • Checks against existing session tokens
  • If valid: responds with a 302 to /protected/dashboard.html
  • Else: returns 403 Forbidden

5. Static Dashboard

If the session is valid, NGINX serves the static dashboard.html page.


What I Learned

  • How HTTP requests and cookies work behind the scenes
  • Parsing form data with Bash (even if a bit hacky)
  • Managing sessions with just files and timestamps
  • Password hashing with openssl passwd -6 (SHA-512 + salt)

Why This Matters

I didn’t use Python, PHP, Go, or Node.js. I didn’t rely on a login plugin, web framework, or ORM.

I just used the tools I’m comfortable with as a Linux admin. It’s far from perfect—but it’s mine, and it works. And most importantly, I learned a lot in the process.


ant the Scripts?

If you’re interested in trying this out yourself, I can share the core files:

  • login.sh
  • check_session.sh
  • nginx.conf snips
  • socat launch systemd units

Drop me a message or comment on abhishek.cloud.


Built on a weekend with coffee, curiosity, and a terminal.