2 पॉइंट द्वारा GN⁺ 2024-09-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें

My Blog Technology

यह web server मेरे ब्लॉग को होस्ट करने के लिए डिज़ाइन किया गया एक न्यूनतम web server है। इसे शुरू से ही इस तरह मज़बूती से बनाया गया है कि यह सार्वजनिक इंटरनेट पर टिक सके। reverse proxy की आवश्यकता नहीं है। आप इसे काम करते हुए http://playin.coz.is/index.html पर देख सकते हैं। मैंने मज़े के लिए Reddit पर लोगों से इसे hack करने की कोशिश करने को कहा और दिलचस्प व दुर्भावनापूर्ण request logs को gigabytes में इकट्ठा किया। उनमें से कुछ को attempts.txt में रखा है, और बाद में मज़े के लिए और भी देखूँगा।

लेकिन.. क्यों?

मुझे अपने खुद के tools बनाना पसंद है, और मैं यह सुन-सुनकर थक गया था कि हर चीज़ को "battle-tested" होना चाहिए। अगर crash हो जाए तो क्या? bugs को ठीक किया जा सकता है।

विनिर्देश

  • केवल Linux
  • HTTP/1.1, pipelining, keep-alive connections implemented
  • HTTPS समर्थन (BearSSL का उपयोग करके TLS 1.2 तक)
  • न्यूनतम dependencies (HTTPS के लिए libc और BearSSL)
  • configurable timeouts
  • access logs, crash logs, log rotation, disk usage limits
  • Transfer-Encoding: Chunked नहीं (411 Length Required के साथ response देता है ताकि client Content-Length के साथ फिर से भेजे)
  • single core (बेहतर VPS मिलने पर बदलेगा)
  • static file caching नहीं (अभी)

बेंचमार्क

इस project का फोकस robustness है, लेकिन यह किसी भी तरह से धीमा नहीं है। nginx के साथ एक सरल तुलना (static endpoint, दोनों single-threaded, 1K connection limit):

nginx configuration:

worker_processes 1;
events {
  worker_connections 1024;
}
http {
  server {
    listen 8080;
    location /hello {
      add_header Content-Type text/plain;
      return 200 "Hello, world!";
    }
  }
}

build और run

डिफ़ॉल्ट रूप से server build केवल HTTP के लिए है:

$ make

यह command serve (release build), serve_cov (coverage build), serve_debug (debug build) executable files बनाता है। release build port 80 पर listen करता है, और debug build port 8080 पर।

HTTPS सक्षम करने के लिए BearSSL को clone और build करना होगा:

$ mkdir 3p
$ cd 3p
$ git clone https://www.bearssl.org/git/BearSSL
$ cd BearSSL
$ make -j
$ cd ../../
$ make -B HTTPS=1

वही executable files बनती हैं, लेकिन अब port 443 (release) या 8081 (debug) पर secure connections संभव हैं। cert.pem और key.pem files को executable के उसी directory में रखना होगा। नाम और location बदलने के लिए यह संशोधित करें:

#define HTTPS_KEY_FILE "key.pem"
#define HTTPS_CERT_FILE "cert.pem"

स्थानीय रूप से HTTPS के साथ test करने के लिए self-signed certificate (और private key) बनाएँ:

openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048
openssl req -new -x509 -key key.pem -out cert.pem -days 365

उपयोग

server docroot/ folder से static content serve करता है। इसे बदलने के लिए respond function को संशोधित करें:

typedef struct {
  Method method;
  string path;
  int major;
  int minor;
  int nheaders;
  Header headers[MAX_HEADERS];
  string content;
} Request;

void respond(Request request, ResponseBuilder *b) {
  if (request.major != 1 || request.minor > 1) {
    status_line(b, 505); // HTTP Version Not Supported
    return;
  }

  if (request.method != M_GET) {
    status_line(b, 405); // Method Not Allowed
    return;
  }

  if (string_match_case_insensitive(request.path, LIT("/hello"))) {
    status_line(b, 200);
    append_content_s(b, LIT("Hello, world!"));
    return;
  }

  if (serve_file_or_dir(b, LIT("/"), LIT("docroot/"), request.path, NULLSTR, false))
    return;

  status_line(b, 404);
  append_content_s(b, LIT("Nothing here :|"));
}

यहाँ आप request.path field पर switch करके endpoints जोड़ सकते हैं। path सिर्फ request buffer का एक slice है। URI parse नहीं किया जाता।

testing

मैं नियमित रूप से server को valgrind और sanitizers (address, undefined) के साथ चलाता हूँ और wrk से target करता हूँ। साथ ही HTTP/1.1 spec compliance जाँचने के लिए tests/test.py में automated tests जोड़ रहा हूँ। मैं अपनी वेबसाइट को इसी पर होस्ट करके और इधर-उधर पोस्ट करके stress बनाए रखता हूँ। इंटरनेट पर कमजोर websites scan करने वाले सभी bots बेहतरीन fuzzers बन जाते हैं।

ज्ञात समस्याएँ

  • server HTTP/1.0 clients को HTTP/1.1 में response देता है

योगदान

मैं ज़्यादातर DEV branch पर काम करता हूँ और कभी-कभी MAIN में merge करता हूँ। pull request खोलते समय DEV को target करना आसान रहेगा।

GN⁺ का सारांश

  • यह project न्यूनतम dependencies और robustness पर केंद्रित एक web server है।
  • यह HTTP/1.1 और HTTPS का समर्थन करता है, और विभिन्न logging features व configurable timeouts देता है।
  • benchmark परिणाम nginx की तुलना में तेज़ response time दिखाते हैं।
  • इसे इस तरह डिज़ाइन किया गया है कि developers अपने tools बना सकें और bugs को ठीक करने की प्रक्रिया का आनंद ले सकें।
  • समान features वाले projects में Nginx और Apache HTTP Server शामिल हैं।

1 टिप्पणियां

 
GN⁺ 2024-09-26
Hacker News की राय
  • reverse proxy की ज़रूरत नहीं: Jetty का उपयोग करके reverse proxy के बिना भी ऐप को इंटरनेट पर deploy किया गया और कोई समस्या नहीं हुई

    • security या performance के बारे में कोई ठोस कारण दिए बिना reverse proxy इस्तेमाल करने की सलाह देने वाले बहुत लोग हैं
    • क्या reverse proxy सच में ज़रूरी है, इस पर सवाल उठता है
  • खुद बनाया गया C web server: एक C web server बनाया गया था जिसने commercial website चलाई थी

    • 128MB RAM और 1 CPU के साथ बहुत सारा traffic संभाला गया
    • यह भी कहा गया कि 20 साल पहले का इंटरनेट माहौल इतना hostile नहीं था
    • bots अच्छे fuzzer की तरह काम करते हैं, लेकिन असली fuzzing भी ज़रूरी है
  • service बनाने की संतुष्टि: system API का उपयोग करके बुनियादी services बनाना बहुत संतोषजनक है

    • poll() function का इतना अच्छा performance देखकर हैरानी होती है
    • per-connection functions, संबंधित structs और arrays, nginx, redis, memcached जैसे लगते हैं
    • बहुत बढ़िया काम है
  • छोटे प्रोजेक्ट का परिचय: फुर्सत के समय में शुरू किया गया एक मज़ेदार प्रोजेक्ट पेश किया गया

  • Kore framework की सिफारिश: अगर C app लिखते समय public-facing हिस्सा लिखना असुविधाजनक लगे, तो Kore framework की सिफारिश की जाती है

    • ACME certificate management, Pgsql, curl, WebSocket जैसी सुविधाएँ built-in हैं
    • Lua/Python और C को मिलाकर modules build और run किए जा सकते हैं
  • दिलचस्प लिंक साझा: sqlite.org का althttpd instance हर दिन 5 लाख से ज़्यादा HTTP requests संभालता है

    • $40/माह वाले Linode पर 200GB content serve किया जाता है
    • 19% HTTP requests, CGI के ज़रिए Fossil source code repository तक पहुँचती हैं
  • अपने tools बनाने का आनंद: इस बात से थकान है कि हर चीज़ को "battle-tested" होना चाहिए

    • bugs को ठीक किया जा सकता है
  • Chaos Communication Congress का व्याख्यान: security features के साथ C में लिखे गए blog/web server पर एक talk की याद दिलाता है

    • इसमें immutable storage, privilege reduction, और TLS certificates तक पहुँच न होना जैसी सुविधाएँ शामिल थीं
  • स्थिर website: ऐसा website जो front page पर दिखने पर भी crash नहीं होता

  • बुनियाद की ओर वापसी: सिर्फ़ ज़रूरी चीज़ों का उपयोग करके basics पर लौटने वाला तरीका पसंद आया

    • software की गैर-ज़रूरी सुविधाएँ performance को कितना प्रभावित करती हैं, इस पर सवाल है
    • developer को बधाई दी गई है