HN पर साझा: C वेब सर्वर का उपयोग करके वेबसाइट होस्टिंग
(github.com/cozis)- 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_filebranch में मौजूद है
-
Build और basic run
- BlogTech Linux और Windows पर चलता है
- Linux build के लिए OpenSSL development libraries और
gccचाहिए - Windows build के लिए
clangचाहिए
- Linux build के लिए OpenSSL development libraries और
- build platform-specific scripts से किया जाता है
- Linux:
./build.sh - Windows:
.\build.bat
- Linux:
- build outputs इस प्रकार हैं
- Linux:
blogtech - Windows:
blogtech.exe
- Linux:
- Linux पर
./install.shसे install किया जा सकता है - basic server run का उदाहरण
docrootdirectory बनाकर--serve,--document-root=docroot,--skip-auth-checkspecify करता है - 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.pwdfile में रखा जाता है - password file को
--auth-password-fileoption से specify किया जाता है - अगर password file नहीं है, तो authentication आवश्यक सभी requests reject कर दी जाती हैं
- खाली password भी reject किया जाता है
- development के दौरान
--skip-auth-checkसे सभी requests को authenticated माना जा सकता है- इस option का उपयोग करने पर
--auth-password-fileदिया गया हो तब भी उसे ignore किया जाता है - इसे सावधानी से इस्तेमाल करना चाहिए
- इस option का उपयोग करने पर
-
Authentication headers और replay conditions
- authenticated HTTP requests में
X-BlogTech-headers शामिल होते हैं X-BlogTech-Nonce: client द्वारा random चुना गया tokenX-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 की जा सकती हैं
- authenticated HTTP requests में
Virtual hosts और directory mapping
- BlogTech एक ही server पर कई websites host कर सकता है
- domains को
--domainoption कई बार देकर configure किया जाता है - BlogTech document root के अंदर domain-specific directories बनाता है
defaultwebsiteA.comwebsiteB.com
- किसी खास host पर आई request उसी host से जुड़ी directory को refer करती है
- जो requests किसी specific folder से mapped नहीं हैं, वे default directory को refer करती हैं
- उदाहरण में
websiteA.com,websiteB.com,other.comपर upload की गई files क्रमशः domain directories याdefaultdirectory में 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 तक पहुँचने के लिए
--insecureflag का उपयोग करना होगा - अगर कई certificates चाहिए, तो
--extra-certअतिरिक्त रूप से दिया जा सकता है- default certificate
--cert-file,--cert-key-fileसे दिया जाता है - अतिरिक्त certificates तब उपयोग होते हैं जब client किसी specific domain की request करता है
- default certificate
- लंबे 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 keycert.pem: issued certificate, या--cert-fileसे specify की गई filekey.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_hostsentry जोड़नी होगी/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मेंvalidityPeriodvalue बदली जा सकती है --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.binfile बनती है - अगली बार server start होने पर
crash.binको human-readable stack tracecrash.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-reloadsystemctl enable blogtechsystemctl start blogtech
- service management
systemctl start,systemctl stop,systemctl restart,journalctl -u blogtechसे किया जाता है
1 टिप्पणियां
Hacker News की राय
“रिवर्स प्रॉक्सी की जरूरत नहीं” वाला हिस्सा मुझे हमेशा अजीब लगा है
अगर रिवर्स प्रॉक्सी से खास मदद मिलने की कोई वजह न हो, तो मैं embedded Jetty ऐप्स को बिना किसी front-end के सीधे इंटरनेट पर expose कर देता था, और कोई समस्या नहीं आई
इंफ्रा या सिक्योरिटी वाले पूछते हैं कि आगे nginx क्यों नहीं लगाया, लेकिन वजह पूछने पर सुरक्षा या performance को लेकर बस गोलमोल बातें करते हैं, ठोस बात कम होती है। सबसे ठोस जवाब slow loris था, लेकिन वह भी काफी समय से बड़ी समस्या नहीं रहा
सोचता हूं कि क्या रिवर्स प्रॉक्सी सामूहिक रूप से cargo cult बन गया है, या मैं कोई सामान्य रूप से लागू होने वाली अच्छी वजह मिस कर रहा हूं
कुल मिलाकर origin server को सुरक्षित रखा जा सकता है और वह केवल संबंधित traffic ही प्राप्त करता है। ग्राहकों को custom domain देने की स्थिति में भी customer DNS origin server की बजाय रिवर्स प्रॉक्सी की ओर point करता है, इसलिए जरूरत पड़ने पर origin server बदल भी दें तो customer DNS बदलाव की चिंता नहीं करनी पड़ती
वे अलग-अलग ports पर चलते हैं, लेकिन मैं चाहता हूं कि वे सब अलग-अलग URL से public access के लिए उपलब्ध हों और इंटरनेट पर केवल port 443 expose हो
हर domain के TLS certificate का automatic renewal भी चाहिए। पहली जरूरत के लिए रिवर्स प्रॉक्सी चाहिए, और Caddy दोनों काम कर देता है
अगर आप सिर्फ एक server चला रहे हैं और वही server TLS termination भी करता है, तो रिवर्स प्रॉक्सी जरूरी नहीं है
बाद में TLS termination, URL rewriting और अन्य काम बिना ज्यादा मेहनत के जोड़े जा सकते हैं, इसलिए यह आदत जैसी बन गई है और अब तक इस आदत ने फायदा ही दिया है
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 का उपयोग कम हो
न्यूनतम 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
मेरी website https://blessed.rs सबसे छोटी उपलब्ध VM पर चलती है, जिसमें 256MB RAM है, लेकिन आमतौर पर यह लगभग 60MB ही इस्तेमाल करती है
सच में हैरान करने वाली बात यह थी कि अगर memory map सिर्फ 4KB pages के 5 pages का हो, तो Linux का fork बेहद तेज हो जाता है
यह मजे के लिए खाली समय में शुरू किया गया छोटा project है, लगा यहां लोगों को पसंद आएगा :)
शानदार। मुझे हमेशा से लगता रहा है, और अब भी लगता है, कि इस तरह सबसे निचले स्तर की system API का इस्तेमाल करके न्यूनतम सेवा खड़ी करना वाकई संतोषजनक होता है
यह लगभग जादू जैसा है, और जब उसे असली traffic संभालते देखते हैं तो और भी ज्यादा। यह थोड़ा हैरान करने वाला था कि साधारण
poll()इतने अच्छे numbers दे सकता है, लेकिन शायद इसलिए कि मुझे उस level पर events या benchmarks से काम किए काफी समय हो गया हैहर connection के लिए function और उससे जुड़ी structs, arrays से connections manage करने का तरीका, और
pollfile descriptor array भी अच्छे लगे। यह nginx, Redis, memcached जैसे high throughput के लिए जाने जाने वाले कई open source packages में अपनाए गए तरीके की याद दिलाता हैमुझे लगने लगा कि हर किसी को जितनी हो सकें उतनी भाषाएं—चाहे programming languages हों या natural languages—जाननी और आजमानी चाहिए। किसी भाषा में सोचना एक अनोखा अनुभव है। अलग-अलग contexts हर चीज को अलग महसूस कराते हैं, और आखिर में भले आप मिलती-जुलती चीज कर रहे हों, नजरिया बदल जाता है
उदाहरण के लिए Linux या Git का सार सच में समझना हो तो आपको वह भाषा बोलनी होगी और वे nuances समझने होंगे जो translation में आमतौर पर खो जाते हैं। यह कुछ वैसा ही है जैसे Russian में “forest” शब्द का असली subjective अर्थ समझने के लिए Russian बोलना और समझना पड़ता है
context नजरिया बदल देता है, और कभी-कभी सब कुछ बदल देता है
मुझे भी हैरानी हुई कि साधारण
poll()इतना संभाल सकता है। मुझे लगा था कि कभी न कभीepollपर जाना पड़ेगा, लेकिनpoll()बहुत अच्छी तरह काम कर रहा हैसूरज के नीचे कुछ भी नया नहीं है
यह भी दिलचस्प हो सकता है: 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 होती हैं
अगर आप 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 पर आने के बाद भी मरती नहीं
इसका मतलब यह नहीं कि यह project शानदार नहीं है, लेकिन अगर production environment में यह आपके लिए सच में महत्वपूर्ण है और आप ज्यादातर static content serve कर रहे हैं, तो बस CDN इस्तेमाल करें। वह आपके खुद लिखे लगभग किसी भी चीज से हमेशा बेहतर performance देगा। बस इसमें मजा नहीं है
project साफ-सुथरा और बढ़िया है, लेकिन मुझे लगता है कि ज्यादातर लोग GitHub पर जाएंगे, उस link पर नहीं जो webpage दिखाता है। क्या मैं कुछ miss कर रहा हूं?
“मुझे अपने tools खुद बनाना पसंद है, और यह सुन-सुनकर थोड़ा थक गया हूं कि सब कुछ battle-tested होना चाहिए। तो अगर यह मर जाए तो क्या हुआ? bug ठीक कर देंगे :^)” वाला हिस्सा अच्छा लगा
C code की सिर्फ 3.4k lines में पूरा HTTP और HTTPS server? सच कहूं तो spec को पूरी तरह comply करने के लिए मुझे लगा था कि इससे कहीं ज्यादा चाहिए होगा
सिर्फ GET requests लें और response में
Content-Lengthset कर दें, तो 99% user agents के लिए काफी है।Transfer-Encodingऔर byte range headers handle करने से भी code बहुत नहीं बढ़ताHTTPS तो TLS socket के ऊपर HTTP ही है, और अगर आप encryption खुद implement नहीं कर रहे हैं तो abstraction का level बस इतना ही होना चाहिए। मजेदार है और असल में इतना बुरा नहीं है
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
बेशक मैं उसे public internet पर नहीं डालूंगा और उसने HTTP/1.1 का बहुत छोटा हिस्सा ही implement किया था, लेकिन वह काम करता है और
mallocसिर्फ initialization के समय चाहिएC में लिखे blog/web server पर Chaos Communication Congress की presentation याद आती है
इसमें immutable storage, privilege dropping, blog को TLS certificate तक पहुंचने से रोकना जैसी कई security features शामिल थीं: https://www.youtube.com/watch?v=TaE28fJVPTk