2 पॉइंट द्वारा GN⁺ 2024-09-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • BlogTech छोटे से मध्यम आकार की वेबसाइटों को मैनेज करने के लिए C-आधारित टूलकिट है, जो HTTPS, virtual hosts, ACME-आधारित automatic certificate management, और remote server management client प्रदान करता है
  • यह फिलहाल test stage में है, और version 0.4.x को https://coz.is/ चलाने में कुछ हफ्तों तक इस्तेमाल किया गया, लेकिन इसे stable release के रूप में पेश नहीं किया गया है
  • सर्वर Linux और Windows पर चलता है, लेकिन HTTPS केवल Linux पर supported है; Windows पर client और server दोनों केवल HTTP इस्तेमाल कर सकते हैं
  • remote file management --put, --get, --delete से किया जाता है, और resources बदलने वाली requests को shared secret key-आधारित HMAC/SHA256 signatures से authenticate किया जाता है
  • production environment में port 80 पर HTTP server और domain DNS records की जरूरत होती है, और ACME चालू करने पर certificate और private key files अपने-आप बनती हैं तथा errors acme.log में दर्ज होते हैं

BlogTech का उद्देश्य और वर्तमान स्थिति

  • BlogTech छोटे से मध्यम आकार की वेबसाइटों के management के लिए एक टूलकिट है
  • supported features इस प्रकार हैं
    • HTTPS

    • Virtual hosts

      • ACME के जरिए automatic certificate management
      • server के remote management के लिए client
      • यह अभी test stage में है
      • version 0.4.x के साथ https://coz.is/ को कुछ हफ्तों तक सफलतापूर्वक serve करने का उदाहरण है
      • पुराना single-file version single_file branch में मौजूद है

Build और basic run

  • BlogTech Linux और Windows पर चलता है
    • Linux build के लिए OpenSSL development libraries और gcc चाहिए
    • Windows build के लिए clang चाहिए
  • build platform-specific scripts से किया जाता है
    • Linux: ./build.sh
    • Windows: .\build.bat
  • build outputs इस प्रकार हैं
    • Linux: blogtech
    • Windows: blogtech.exe
  • Linux पर ./install.sh से install किया जा सकता है
  • basic server run का उदाहरण docroot directory बनाकर --serve, --document-root=docroot, --skip-auth-check specify करता है
  • default HTTP server 127.0.0.1:8080 पर listen करता है और docroot की content serve करता है
  • खाली docroot होने पर http://127.0.0.1:8080/ खोलने पर 404 लौटता है

Remote file management और authentication

  • BlogTech client mode में files को server पर upload कर सकता है
    • --put से file upload
    • --get से remote file download
    • --delete से remote file delete
  • client और server एक ही machine पर चलें या remote machine के server पर हों, दोनों ही स्थितियों में यही तरीका काम करता है
  • resources बदलने वाली requests को HMAC/SHA256 signatures से digitally sign किया जाता है
  • client और server को एक ही secret key share करनी होती है, जिसे परंपरागत रूप से admin.pwd file में रखा जाता है
  • password file को --auth-password-file option से specify किया जाता है
  • अगर password file नहीं है, तो authentication आवश्यक सभी requests reject कर दी जाती हैं
  • खाली password भी reject किया जाता है
  • development के दौरान --skip-auth-check से सभी requests को authenticated माना जा सकता है
    • इस option का उपयोग करने पर --auth-password-file दिया गया हो तब भी उसे ignore किया जाता है
    • इसे सावधानी से इस्तेमाल करना चाहिए
  • Authentication headers और replay conditions

    • authenticated HTTP requests में X-BlogTech- headers शामिल होते हैं
    • X-BlogTech-Nonce: client द्वारा random चुना गया token
    • X-BlogTech-Timestamp: वह UNIX timestamp जब request पहली बार sign की गई
    • X-BlogTech-Expire: sign होने के समय से request कितने seconds तक valid रहेगी
    • X-BlogTech-Signature: request information के HMAC का Base64-encoded मान
    • signature पाने के लिए पहले normalized request string बनाई जाती है, फिर authentication password को key की तरह इस्तेमाल करके HMAC/SHA256 निकाला जाता है, और परिणाम को padding सहित Base64 में encode किया जाता है
    • server पहले से देखे गए nonce को memory में रखता है
    • server reload होने पर पुराने nonce भूल जाता है, इसलिए unexpired requests दोबारा replay की जा सकती हैं

Virtual hosts और directory mapping

  • BlogTech एक ही server पर कई websites host कर सकता है
  • domains को --domain option कई बार देकर configure किया जाता है
  • BlogTech document root के अंदर domain-specific directories बनाता है
    • default
    • websiteA.com
    • websiteB.com
  • किसी खास host पर आई request उसी host से जुड़ी directory को refer करती है
  • जो requests किसी specific folder से mapped नहीं हैं, वे default directory को refer करती हैं
  • उदाहरण में websiteA.com, websiteB.com, other.com पर upload की गई files क्रमशः domain directories या default directory में store होती हैं

HTTPS और certificate configuration

  • HTTPS केवल Linux पर supported है
  • क्योंकि underlying HTTP library cHTTP OpenSSL के जरिए HTTPS implement करती है
  • Windows पर client और server दोनों केवल HTTP उपयोग कर सकते हैं
  • HTTPS चालू करने के लिए ये options चाहिए
    • --https-enabled
    • --cert-file
    • --cert-key-file
  • default HTTPS listen address 127.0.0.1:8443 है
  • listen address और port इन options से बदले जा सकते हैं
    • --https-addr=<addr>
    • --https-port=<port>
  • development के दौरान OpenSSL command से self-signed certificate बनाया जा सकता है
  • browser self-signed certificate वाले HTTPS server को browse करने की अनुमति नहीं देते
  • cURL से self-signed certificate server तक पहुँचने के लिए --insecure flag का उपयोग करना होगा
  • अगर कई certificates चाहिए, तो --extra-cert अतिरिक्त रूप से दिया जा सकता है
    • default certificate --cert-file, --cert-key-file से दिया जाता है
    • अतिरिक्त certificates तब उपयोग होते हैं जब client किसी specific domain की request करता है
  • लंबे command-line options को config file में ले जाया जा सकता है

ACME-आधारित automatic certificate issuance

  • ACME protocol web server को certificate authority से certificate issuance अपने-आप request करने देता है
  • BlogTech certificate के बिना HTTPS mode में शुरू होकर बाद में certificate generate होने वाला flow support करता है
  • production environment में ये शर्तें जरूरी हैं
    • HTTP server को port 80 पर चलाना
    • DNS record बनाना जो server चलने वाली machine और domain को जोड़े
  • ACME को HTTPS options के साथ --acme-enabled देकर चालू किया जाता है
  • सामान्य HTTPS mode के विपरीत, ACME mode में माना जाता है कि certificate पहले से मौजूद नहीं होगा
  • certificate generation के लिए ये values चाहिए
    • --acme-domain
    • --acme-email
    • --acme-country
    • --acme-organization
    • --acme-agree-tos
  • सफल होने पर ये files बनती हैं
    • acme_key.pem: ACME account से जुड़ी secret key
    • cert.pem: issued certificate, या --cert-file से specify की गई file
    • key.pem: certificate से जुड़ी private key, या --cert-key-file से specify की गई file
  • error होने पर messages acme.log में लिखे जाते हैं
  • --acme-domain कई बार देने पर कई domains को ACME से process किया जा सकता है
  • resulting certificate में specified सभी domains शामिल होंगे

ACME client testing

  • Linux पर ACME client test करने के लिए Docker install करना होगा और Pebble ACME server को clone करना होगा
  • docker-compose.yml में test domains को host-gateway से जोड़ने के लिए extra_hosts entry जोड़नी होगी
  • /etc/hosts में test domains को 127.0.0.1 पर map करना होगा
  • Pebble को docker compose up से शुरू किया जाता है
  • BlogTech test instance को ./blogtech -s --config=misc/pebble_blogtech.conf से चलाता है
  • ACME server के साथ interaction stdout पर output होता है
  • सफल होने पर acme_key.pem, cert.pem, key.pem बनते हैं
  • certificate renewal test के लिए pebble/test/config/pebble-config.json में validityPeriod value बदली जा सकती है
  • --acme-force-renewal-period=<maximum duration in ms> option इस्तेमाल करने पर certificate expire न हुआ हो तब भी renewal के लिए निर्देश दिया जा सकता है

Config file और automatic loading

  • BlogTech किसी भी संख्या के command-line arguments को config file में ले जा सकता है
  • उदाहरण के लिए HTTPS और ACME से जुड़े options को blogtech_server.conf में लिखकर --config=blogtech_server.conf से चलाया जा सकता है
  • अगर config file का नाम ठीक blogtech.conf है, तो BlogTech उसे अपने-आप load करता है
  • इस स्थिति में ./blogtech --serve जैसे command से चलाया जा सकता है
  • implicit config file loading को ignore करने के लिए --no-config उपयोग करें

Crash logs और systemd daemon

  • server mode में BlogTech crash होने पर crash.bin file बनती है
  • अगली बार server start होने पर crash.bin को human-readable stack trace crash.log में convert किया जाता है
  • addresses को symbol names या line numbers में convert करने की प्रक्रिया कुछ हद तक unreliable हो सकती है
  • BlogTech को systemd daemon के रूप में install किया जा सकता है
  • उदाहरण blogtech.service /root/blogtech/blogtech -s चलाता है, failure पर restart करता है, और working directory को /root/blogtech/ पर set करता है
  • server options /root/blogtech/blogtech.conf से automatically load होते हैं
  • service file को /etc/systemd/system/ में copy करने के बाद इन commands से enable और start किया जाता है
    • systemctl daemon-reload
    • systemctl enable blogtech
    • systemctl start blogtech
  • service management systemctl start, systemctl stop, systemctl restart, journalctl -u blogtech से किया जाता है

1 टिप्पणियां

 
GN⁺ 2024-09-26
Hacker News की राय
  • रिवर्स प्रॉक्सी की जरूरत नहीं” वाला हिस्सा मुझे हमेशा अजीब लगा है
    अगर रिवर्स प्रॉक्सी से खास मदद मिलने की कोई वजह न हो, तो मैं embedded Jetty ऐप्स को बिना किसी front-end के सीधे इंटरनेट पर expose कर देता था, और कोई समस्या नहीं आई
    इंफ्रा या सिक्योरिटी वाले पूछते हैं कि आगे nginx क्यों नहीं लगाया, लेकिन वजह पूछने पर सुरक्षा या performance को लेकर बस गोलमोल बातें करते हैं, ठोस बात कम होती है। सबसे ठोस जवाब slow loris था, लेकिन वह भी काफी समय से बड़ी समस्या नहीं रहा
    सोचता हूं कि क्या रिवर्स प्रॉक्सी सामूहिक रूप से cargo cult बन गया है, या मैं कोई सामान्य रूप से लागू होने वाली अच्छी वजह मिस कर रहा हूं

    • मेरे लिए रिवर्स प्रॉक्सी origin server को सिर्फ application delivery करने देता है। TLS termination, load balancing, URL rewriting, और जरूरत पड़ने पर WAF जैसी security सुविधाएं—सब रिवर्स प्रॉक्सी पर संभाली जा सकती हैं, जिससे separation of roles हो जाता है
      कुल मिलाकर origin server को सुरक्षित रखा जा सकता है और वह केवल संबंधित traffic ही प्राप्त करता है। ग्राहकों को custom domain देने की स्थिति में भी customer DNS origin server की बजाय रिवर्स प्रॉक्सी की ओर point करता है, इसलिए जरूरत पड़ने पर origin server बदल भी दें तो customer DNS बदलाव की चिंता नहीं करनी पड़ती
    • मैं homelab में कई server programs चला रहा हूं
      वे अलग-अलग ports पर चलते हैं, लेकिन मैं चाहता हूं कि वे सब अलग-अलग URL से public access के लिए उपलब्ध हों और इंटरनेट पर केवल port 443 expose हो
      हर domain के TLS certificate का automatic renewal भी चाहिए। पहली जरूरत के लिए रिवर्स प्रॉक्सी चाहिए, और Caddy दोनों काम कर देता है
      अगर आप सिर्फ एक server चला रहे हैं और वही server TLS termination भी करता है, तो रिवर्स प्रॉक्सी जरूरी नहीं है
    • ज्यादातर deployments में रिवर्स प्रॉक्सी का performance impact नगण्य होता है, और configuration भी पहले से तैयार रखी होती है
      बाद में TLS termination, URL rewriting और अन्य काम बिना ज्यादा मेहनत के जोड़े जा सकते हैं, इसलिए यह आदत जैसी बन गई है और अब तक इस आदत ने फायदा ही दिया है
    • वेब application के आगे लगाए जाने वाले अलग-अलग तरह के servers पर लागू होने वाला जवाब देना हो, तो security और performance दोनों में extra equipment मदद कर सकता है, इसके कई तरीके हैं
      security के लिहाज से, पूरे system में जितना हो सके उतना कम code और robust operating system रखना चाहूंगा। proxy-type apps web/application server की तुलना में कहीं ज्यादा सरल हो सकते हैं, और incoming traffic को filter कर सकते हैं, input validate कर सकते हैं, या उसे ऐसी form में बदल सकते हैं जिसे ज्यादा सुरक्षित और तेजी से parse किया जा सके। इन्हें OpenBSD, GenodeOS, INTEGRITY-178B जैसे attack करना मुश्किल operating systems पर भी चलाया जा सकता है
      availability के लिहाज से भी load balancing, monitoring और recovery को ऐसे systems में रखना अक्सर ज्यादा सुरक्षित होता है, क्योंकि application server ज्यादा बार crash हो सकता है
      performance के लिहाज से, सबसे पहले फायदा यह है कि सरल और focused app को बहुत optimize किया जा सकता है। इसके बाद CPU या PCI hardware accelerators से compression या encryption को तेज किया जा सकता है, जिसे आमतौर पर offloading कहा जाता है। सबसे cost-effective setup वह होता है जिसमें कई general-purpose servers को कुछ महंगे offloading servers का फायदा मिलता है। कुछ setups load balancing के जरिए incoming traffic को उस server पर भेजते हैं जो उसे सबसे बेहतर handle कर सके, ताकि महंगे resources का उपयोग कम हो
    • मुझे नहीं लगता कि सभी servers पर लागू होने वाला कोई सामान्य नियम है
      न्यूनतम setup में इसकी जरूरत नहीं, लेकिन single-host operating environment में भी यह rolling releases, compression, TLS, तेज static file serving और संभावित A/B testing संभव बनाता है
      request और server के बीच indirection layer काफी उपयोगी हो सकती है
  • शानदार। मैंने भी पहले खुद C web server लिखा था, और source नीचे है। कुछ समय तक इससे commercial website भी चलाई थी
    यह देखकर हैरानी होती है कि HTTP/1.1 web server को कितना छोटा और lightweight बनाया जा सकता है। वह commercial site 128MB RAM और 1 CPU वाली machine पर चलती थी, और closed-source interactive web-based chat system के रूप में UK के काफी सारे schools को नियमित रूप से service देती थी। हालांकि यह 20 साल पहले की बात है, जब इंटरनेट आज जितना hostile नहीं था
    पोस्ट में कहा गया कि bots बेहतरीन fuzzer की भूमिका निभाते हैं, फिर भी मुझे लगता है कि असली fuzzing भी थोड़ी कर लेनी चाहिए
    http://git.annexia.org/?p=rws.git;a=tree
    जरूरत की चीजें:
    http://git.annexia.org/?p=c2lib.git;a=tree
    http://git.annexia.org/?p=pthrlib.git;a=tree

    • इस size का web server चलाते हुए hostile internet को लेकर बहुत ज्यादा चिंता न करनी पड़े, इसके लिए Rust अच्छा विकल्प है
      मेरी website https://blessed.rs सबसे छोटी उपलब्ध VM पर चलती है, जिसमें 256MB RAM है, लेकिन आमतौर पर यह लगभग 60MB ही इस्तेमाल करती है
    • यह मेरे बनाए छोटे और lightweight HTTP/1.0 web server से कहीं ज्यादा practical लगता है, लेकिन rws शायद उतना छोटा और lightweight नहीं होगा: http://canonical.org/~kragen/sw/dev3/server.s http://canonical.org/~kragen/sw/dev3/httpdito-readme
      सच में हैरान करने वाली बात यह थी कि अगर memory map सिर्फ 4KB pages के 5 pages का हो, तो Linux का fork बेहद तेज हो जाता है
  • यह मजे के लिए खाली समय में शुरू किया गया छोटा project है, लगा यहां लोगों को पसंद आएगा :)

    • पुराने HTTP server bugs और CVE को देखते हुए यह समझना दिलचस्प अभ्यास बनता है कि वे मेरे code को प्रभावित कर सकते हैं या नहीं, और उन्हें कैसे fix किया जा सकता है। ऐसी चीज खुद बनाना मजेदार है
    • संयोग से मैं C11 concurrency API के साथ प्रयोग करना चाहता था, और C++ background से आने के कारण जिज्ञासा थी कि वे constructs C में कैसे काम करते हैं, इसलिए server जैसी कोई चीज लिखकर देखना चाहता था
  • शानदार। मुझे हमेशा से लगता रहा है, और अब भी लगता है, कि इस तरह सबसे निचले स्तर की system API का इस्तेमाल करके न्यूनतम सेवा खड़ी करना वाकई संतोषजनक होता है
    यह लगभग जादू जैसा है, और जब उसे असली traffic संभालते देखते हैं तो और भी ज्यादा। यह थोड़ा हैरान करने वाला था कि साधारण poll() इतने अच्छे numbers दे सकता है, लेकिन शायद इसलिए कि मुझे उस level पर events या benchmarks से काम किए काफी समय हो गया है
    हर connection के लिए function और उससे जुड़ी structs, arrays से connections manage करने का तरीका, और poll file descriptor array भी अच्छे लगे। यह nginx, Redis, memcached जैसे high throughput के लिए जाने जाने वाले कई open source packages में अपनाए गए तरीके की याद दिलाता है

    • University में C/C++ करते हुए दिमाग फटने जैसा महसूस हुआ था। यह बहुत खास और विनम्र बना देने वाला experience था, जिसमें engineering, history, culture, linguistics जैसी मेरी पसंद की चीजों के छोटे-छोटे हिस्से शामिल थे
      मुझे लगने लगा कि हर किसी को जितनी हो सकें उतनी भाषाएं—चाहे programming languages हों या natural languages—जाननी और आजमानी चाहिए। किसी भाषा में सोचना एक अनोखा अनुभव है। अलग-अलग contexts हर चीज को अलग महसूस कराते हैं, और आखिर में भले आप मिलती-जुलती चीज कर रहे हों, नजरिया बदल जाता है
      उदाहरण के लिए Linux या Git का सार सच में समझना हो तो आपको वह भाषा बोलनी होगी और वे nuances समझने होंगे जो translation में आमतौर पर खो जाते हैं। यह कुछ वैसा ही है जैसे Russian में “forest” शब्द का असली subjective अर्थ समझने के लिए Russian बोलना और समझना पड़ता है
      context नजरिया बदल देता है, और कभी-कभी सब कुछ बदल देता है
    • पूरी तरह सहमत। और असल में इस्तेमाल करने पर यह और भी संतोषजनक है। अब तो email protocol भी मुझे उत्सुक करने लगा है
      मुझे भी हैरानी हुई कि साधारण poll() इतना संभाल सकता है। मुझे लगा था कि कभी न कभी epoll पर जाना पड़ेगा, लेकिन poll() बहुत अच्छी तरह काम कर रहा है
    • लोग शायद भूल जाते हैं कि सारी बेहतरीन और cool abstractions भी मूल में आखिर वही काम करती हैं। socket खोलना, पढ़ना और लिखना
      सूरज के नीचे कुछ भी नया नहीं है
  • यह भी दिलचस्प हो सकता है: https://news.ycombinator.com/item?id=27431910
    2024 तक sqlite.org का althttpd instance रोज 5 लाख से ज्यादा HTTP requests, लगभग 5–6 प्रति second संभालता है, और रोज करीब 200GB content, लगभग 18Mbit/s, 40 डॉलर प्रति माह वाले Linode से serve करता है। इस machine का load average आमतौर पर 0.5 के आसपास रहता है। HTTP requests में से करीब 19% कई Fossil source code repositories की ओर जाने वाली CGI होती हैं

    • इस लेख से मुझे बहुत inspiration मिली। इसने एहसास कराया कि ऐसी चीज वास्तव में संभव है
  • अगर आप C app लिखना चाहते हैं लेकिन public internet से सीधे touch करने वाला हिस्सा खुद लिखने में असहज हैं, तो Kore एक अच्छा framework है
    इसमें ACME certificate management, Pgsql, curl, websockets जैसी सुविधाजनक built-in features हैं
    मूल रूप से आप modules build करके run और combine कर सकते हैं, और Lua/Python के साथ C mix करना भी संभव है
    https://kore.io/

  • आखिरकार एक ऐसी website आई जो front page पर आने के बाद भी मरती नहीं

    • आगे CDN हो तो कोई भी site ऐसा कर सकती है
      इसका मतलब यह नहीं कि यह project शानदार नहीं है, लेकिन अगर production environment में यह आपके लिए सच में महत्वपूर्ण है और आप ज्यादातर static content serve कर रहे हैं, तो बस CDN इस्तेमाल करें। वह आपके खुद लिखे लगभग किसी भी चीज से हमेशा बेहतर performance देगा। बस इसमें मजा नहीं है
    • क्या link GitHub पर नहीं जाता? यह comment थोड़ा उलझाने वाला है
      project साफ-सुथरा और बढ़िया है, लेकिन मुझे लगता है कि ज्यादातर लोग GitHub पर जाएंगे, उस link पर नहीं जो webpage दिखाता है। क्या मैं कुछ miss कर रहा हूं?
  • “मुझे अपने tools खुद बनाना पसंद है, और यह सुन-सुनकर थोड़ा थक गया हूं कि सब कुछ battle-tested होना चाहिए। तो अगर यह मर जाए तो क्या हुआ? bug ठीक कर देंगे :^)” वाला हिस्सा अच्छा लगा

  • C code की सिर्फ 3.4k lines में पूरा HTTP और HTTPS server? सच कहूं तो spec को पूरी तरह comply करने के लिए मुझे लगा था कि इससे कहीं ज्यादा चाहिए होगा

    • HTTP/1.1 बहुत simple है, अगर आप spec का ज्यादातर हिस्सा ignore कर दें
      सिर्फ GET requests लें और response में Content-Length set कर दें, तो 99% user agents के लिए काफी है। Transfer-Encoding और byte range headers handle करने से भी code बहुत नहीं बढ़ता
      HTTPS तो TLS socket के ऊपर HTTP ही है, और अगर आप encryption खुद implement नहीं कर रहे हैं तो abstraction का level बस इतना ही होना चाहिए। मजेदार है और असल में इतना बुरा नहीं है
    • यह size ठीक लगता है। OpenBSD का httpd(8) [1] भी documentation सहित अभी 15,000 lines से थोड़ा कम है
      कुछ features हटाकर और कुछ assumptions रखकर, इस project की तरह 5,000 lines की range में आ जाना हैरान करने वाला नहीं होगा
      $ wc -l * का result कुल 14815 lines है
      [1]: https://man.openbsd.org/httpd.8
    • अपने एक experiment में data collection live view देने के लिए मैंने एक simple embedded C web server लिखा था, जो 250 lines से कम था
      बेशक मैं उसे public internet पर नहीं डालूंगा और उसने HTTP/1.1 का बहुत छोटा हिस्सा ही implement किया था, लेकिन वह काम करता है और malloc सिर्फ initialization के समय चाहिए
    • इस size के कुछ और HTTP/1.1 servers भी हैं: https://www.acme.com/software/thttpd/benchmarks.html
  • C में लिखे blog/web server पर Chaos Communication Congress की presentation याद आती है
    इसमें immutable storage, privilege dropping, blog को TLS certificate तक पहुंचने से रोकना जैसी कई security features शामिल थीं: https://www.youtube.com/watch?v=TaE28fJVPTk