SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-13

HTTP کیا ہے؟ سرور ایڈمن کے لیے مکمل رہنما

HTTP کے methods، status codes، اہم headers اور nginx logs سمجھیں، پھر جانیں کہ HTTP/3 اور TLS کہاں آتے ہیں اور server پر ان کا کیا اثر پڑتا ہے۔

HTTP کیا ہے؟

HTTP (hypertext transfer protocol) ان قواعد کا مجموعہ ہے جنہیں client اور web server کسی چیز کی درخواست کرنے اور اسے واپس بھیجنے کے لیے استعمال کرتے ہیں۔ client ایک request بھیجتا ہے: GET جیسا method، /pricing جیسا path، protocol version، headers کی فہرست، اور بعض اوقات body۔ server status code 200 جیسا جواب بھیجتا ہے، جس کے بعد اس کے اپنے headers اور عموماً body ہوتی ہے۔ آپ کے server پر ہر page view اور ہر API (application programming interface) call اسی ایک تبادلے کی بار بار ہونے والی شکل ہے۔

HTTP اپنی کوئی state محفوظ نہیں رکھتا۔ server کو یہ یاد نہیں رہتا کہ آپ نے ایک سیکنڈ پہلے کیا درخواست کی تھی۔ اس لیے memory جیسا کوئی بھی رویہ، مثلاً login session، ہر request کے header میں شامل کیا جاتا ہے۔ یہی خصوصیت آگے بیان ہونے والی بہت سی باتوں کی وضاحت کرتی ہے: caching مکمل طور پر headers کے ذریعے control ہوتی ہے، اور load balancer آپ کی اگلی request کسی دوسرے backend کو بھیج سکتا ہے، بغیر اس کے کہ کوئی چیز خراب ہو۔

ذیل کی تمام وضاحتیں server کی جانب سے اسی model کی عملی شکل دکھاتی ہیں، آپ کے access log اور nginx config میں۔

خام درخواست اور جواب، تشریحات کے ساتھ

یہ مکمل HTTP/1.1 درخواست ہے۔ خالی سطر headers کو ختم کرتی ہے، اور اس سطر کے بعد آنے والی ہر چیز body ہوتی ہے۔ GET میں عموماً body نہیں ہوتی۔

GET /pricing HTTP/1.1
Host: example.com
User-Agent: curl/8.5.0
Accept: */*
Accept-Encoding: gzip
  • GET method ہے، جو بتاتا ہے کہ آپ کیا کارروائی چاہتے ہیں۔ GET پڑھتا ہے، POST data بھیجتا ہے، PUT موجودہ data کو replace کرتا ہے، DELETE اسے remove کرتا ہے، جبکہ HEAD کسی GET کے headers اس کی body کے بغیر طلب کرتا ہے۔
  • /pricing path ہے۔ hostname request line کا حصہ نہیں ہوتا، اسی لیے اگلا header موجود ہے۔
  • HTTP/1.1 protocol version ہے جسے client استعمال کر رہا ہے۔
  • Host: example.com اس site کا نام بتاتا ہے جسے client مطلوبہ سمجھتا ہے۔ HTTP/1.1 میں یہ ضروری ہے، اس لیے nginx اس کے بغیر آنے والی درخواست کا جواب 400 Bad Request سے دیتا ہے۔
  • باقی headers ترجیحات بیان کرتے ہیں۔ Accept-Encoding: gzip بتاتا ہے کہ client data کو decompress کر سکتا ہے، اس لیے server body کو compress کر سکتا ہے۔

Response کی ساخت بھی یہی ہوتی ہے، مگر اوپر status line ہوتی ہے۔

HTTP/1.1 200 OK
Date: Thu, 06 Aug 2026 09:12:44 GMT
Server: nginx
Content-Type: text/html; charset=utf-8
Content-Length: 5310
Cache-Control: public, max-age=300

<!doctype html>...
  • 200 OK status code اور اس کے reason phrase پر مشتمل ہوتا ہے۔ اہم code ہوتا ہے۔ phrase صرف اضافی وضاحت ہے اور clients اسے نظرانداز کرتے ہیں۔
  • Content-Type client کو بتاتا ہے کہ اس کے بعد آنے والے bytes کے ساتھ کیا سلوک کرنا ہے۔
  • Content-Length body کا سائز bytes میں بتاتا ہے، تاکہ client جان سکے کہ body کہاں ختم ہوتی ہے۔ جب سائز پہلے سے معلوم نہ ہو تو server اس کے بجائے Transfer-Encoding: chunked بھیجتا ہے اور اختتام کو zero length chunk سے ظاہر کرتا ہے۔
  • Cache-Control browser اور درمیان میں موجود کسی بھی cache کو بتاتا ہے کہ وہ اس response کو کتنی دیر محفوظ رکھ سکتے ہیں۔
  • Headers کے بعد آنے والی خالی سطر انہیں body سے الگ کرتی ہے، اور یہ اصول دونوں سمتوں میں لاگو ہوتا ہے۔

Header names میں uppercase اور lowercase کا فرق نہیں ہوتا، اور ہر سطر bare newline کے بجائے carriage return کے بعد line feed پر ختم ہوتی ہے۔ آپ انہیں ہاتھ سے نہیں لکھیں گے، لیکن packet capture میں ان سے واسطہ پڑے گا۔

کسی ایسی site کے خلاف یہ command چلائیں جو آپ کی ملکیت ہو، تاکہ حقیقی request اور response کا جوڑا دیکھا جا سکے:

curl -sS -o /dev/null -D - https://example.com/

-D - response headers آپ کے terminal پر لکھتا ہے، جبکہ -o /dev/null body کو ضائع کر دیتا ہے۔ اسے curl -I پر ترجیح دیں، کیونکہ -I ایک HEAD request بھیجتا ہے۔ ایسا application server جو HEAD کو GET سے مختلف طریقے سے handle کرتا ہو، اور بہت سے servers ایسا کرتے ہیں، آپ کو وہ headers دکھائے گا جو کوئی browser کبھی وصول نہیں کرتا۔ curl -v دونوں سمتیں print کرتا ہے؛ request lines کو > اور response lines کو < سے نشان زد کیا جاتا ہے۔

آپ کے nginx access log میں request line کی شکل

nginx ایک combined log format کے ساتھ آتا ہے، اور اس کی تعریف یہ ہے:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

اس سے تیار ہونے والی ایک لائن:

203.0.113.45 - - [06/Aug/2026:09:12:44 +0000] "GET /pricing HTTP/1.1" 200 5310 "https://example.com/" "Mozilla/5.0 (X11; Linux x86_64) Chrome/127.0.0.0 Safari/537.36"
  • 203.0.113.45، $remote_addr ہے، یعنی وہ address جس نے TCP (transmission control protocol) connection کھولا۔ Proxy کے پیچھے یہ visitor کا نہیں بلکہ proxy کا address ہوتا ہے۔
  • پہلا - ایک مستقل placeholder ہے۔ دوسرا $remote_user ہے، جو صرف HTTP basic authentication استعمال ہونے پر پُر ہوتا ہے۔
  • "GET /pricing HTTP/1.1"، $request ہے، یعنی request line جو بالکل اسی طرح نقل کی گئی ہے جیسے موصول ہوئی تھی۔
  • 200 وہ status ہے جو آپ کے server نے واپس کیا، نہ کہ وہ status جو visitor نے دیکھا۔
  • 5310، $body_bytes_sent ہے، یعنی صرف body۔ Response headers شمار نہیں کیے جاتے، اس لیے یہ عدد ہمیشہ بھیجے گئے حقیقی bytes سے کم ہوتا ہے۔
  • آخر کے دو quoted fields Referer اور User-Agent ہیں۔ دونوں client سے آتے ہیں، اس لیے دونوں میں کوئی بھی مواد ہو سکتا ہے۔

چونکہ $request کو لفظ بہ لفظ نقل کیا جاتا ہے، اس لیے غیر متعلقہ مواد بھی اسی طرح ظاہر ہوتا ہے۔ جو client آپ کے plaintext port 80 سے TLS (transport layer security) کے ذریعے بات کرنے کی کوشش کرے، وہ 400 line چھوڑتا ہے جس کے request field کا آغاز "\x16\x03\x01\x02\x00\x01" جیسی escaped bytes سے ہوتا ہے۔ \x16، TLS handshake record type ہے، اس لیے یہ bytes ClientHello کا آغاز ہیں، request line کا نہیں۔ آپ کا server درست طریقے سے کام کر رہا ہے۔ کوئی چیز HTTPS کو HTTP port پر بھیج رہی ہے۔

اپنے log format میں $server_protocol بھی شامل کریں۔ یہ HTTP/1.1، HTTP/2.0 یا HTTP/3.0 دکھاتا ہے، اور یہ ثابت کرنے کا تیز ترین طریقہ ہے کہ protocol change واقعی نافذ ہوئی ہے۔

جب آپ کی اپنی site یہ status codes واپس کرے تو ان کا عام مطلب

پہلا ہندسہ class بتاتا ہے، اور سب سے پہلے اسی class کو سمجھنا چاہیے۔

2xx کا مطلب ہے کہ کام کامیاب رہا۔ 200 OK عام read کے لیے ہے۔ کسی چیز کو بنانے والے POST کے بعد 201 Created آتا ہے۔ 204 No Content اس کامیابی کے لیے ہے جس میں واپس بھیجنے کے لیے کچھ نہ ہو، اور DELETE کا عام جواب یہی ہوتا ہے۔

3xx کا مطلب ہے کہ کہیں اور دیکھیں۔ 301 مستقل ہوتا ہے اور browsers اسے مضبوطی سے cache کرتے ہیں، بعض اوقات user کے profile کو clear کرنے تک۔ اس لیے غلط hostname کی طرف اشارہ کرنے والا 301 واپس تبدیل کرنا مشکل ہو سکتا ہے۔ Redirect کی testing کے دوران 302 استعمال کریں۔ 304 Not Modified کامیابی ہے، error نہیں۔ Client نے ETag (entity tag) رکھنے والا If-None-Match بھیجا جسے آپ اب بھی شناختتے ہیں، اس لیے آپ نے headers کے ساتھ کوئی body نہیں بھیجی۔ Logs میں 304s کی بڑی تعداد کا مطلب ہے کہ caching کام کر رہی ہے۔

4xx کا مطلب ہے کہ request غلط تھی۔ 400 Bad Request malformed input کے لیے ہے۔ 401 Unauthorized کا اصل مطلب unauthenticated ہے، اور اس میں scheme کا نام دینے والا WWW-Authenticate header ہونا ضروری ہے۔ 403 Forbidden کا مطلب ہے کہ request سمجھی گئی، لیکن پھر بھی مسترد کر دی گئی۔ 404 Not Found اس path کے لیے ہے جو موجود نہیں۔ 405 Method Not Allowed درست path لیکن غلط method کے لیے ہے، اور static file location کو بھیجے گئے POST کا یہی جواب آتا ہے۔ 413 ایسی body کے لیے ہے جو nginx کی client_max_body_size سے بڑی ہو۔ اس کی default قدر 1 megabyte ہے، اور error log client intended to send too large body کے ذریعے اس کی تصدیق کرتا ہے۔

Static file پر 403 تقریباً ہمیشہ HTTP rule کے بجائے filesystem کا مسئلہ ہوتا ہے۔ Configuration تبدیل کرنے سے پہلے /var/log/nginx/error.log پڑھیں۔ open() "/srv/site/index.html" failed (13: Permission denied) کا مطلب ہے کہ nginx worker user file نہیں پڑھ سکتا۔ عموماً اس کی وجہ یہ ہوتی ہے کہ parent directory پر others کے لیے execute permission موجود نہیں ہوتی۔ directory index of "/srv/site/" is forbidden کا مطلب ہے کہ path ایسی directory تک پہنچا جس میں index file نہیں، جبکہ autoindex بند ہے۔

5xx کا مطلب ہے کہ خرابی آپ کی طرف ہوئی۔ 500 آپ کی application میں unhandled error ہے۔ 502 Bad Gateway کا مطلب ہے کہ nginx upstream سے قابلِ استعمال response حاصل نہیں کر سکا۔ Error log وجہ بھی بتاتا ہے: connect() failed (111: Connection refused) while connecting to upstream کا مطلب ہے کہ proxy_pass میں موجود address پر کوئی service listening نہیں کر رہی۔ 504 Gateway Timeout کا مطلب ہے کہ upstream نے connection قبول کی، لیکن proxy_read_timeout کے اندر کوئی جواب نہیں دیا۔ اس کی default قدر 60 seconds ہے، اور log اسے upstream timed out (110: Connection timed out) while reading response header from upstream کے طور پر record کرتا ہے۔ 503 Service Unavailable دانستہ refusal کے لیے ہے۔ یاد رکھیں کہ nginx کا اپنا rate limiter 503 واپس کرتا ہے، کیونکہ limit_req_status کی default قدر 503 ہے۔ اگر آپ اپنے log میں 429 Too Many Requests تلاش کر رہے ہیں لیکن 503 مل رہا ہے، تو وجہ یہی ہے۔ درست code حاصل کرنے کے لیے limit_req_status 429; set کریں۔

سرور چلانے کے وقت اہم headers

Host ویب سائٹ منتخب کرتا ہے۔ ایک IP address سینکڑوں hostnames فراہم کر سکتا ہے، اور nginx Host کو server_name سے ملاتا ہے تاکہ فیصلہ کرے کہ کون سا server block جواب دے گا۔ اگر کوئی مطابقت نہ ملے تو nginx default server استعمال کرتا ہے۔ یہ عموماً اس address اور port پر listening کرنے والا پہلا block ہوتا ہے، الا یہ کہ کسی دوسرے block کو default_server کے طور پر نشان زد کیا گیا ہو۔ نئے virtual host سے غلط ویب سائٹ ملنے کی وجہ تقریباً ہمیشہ یہی ہوتی ہے: نام match نہیں ہوا، اس لیے request default server تک پہنچ گئی۔ DNS کو تبدیل کیے بغیر اس کی جانچ کریں:

curl -sS -o /dev/null -D - -H 'Host: app.example.com' http://127.0.0.1/

User-Agent client کی جانب سے لکھی گئی ایک self description ہے، اور یہ free text ہوتی ہے۔ Logs پڑھتے وقت اسے صرف ایک اشارے کے طور پر استعمال کریں۔ اسے control کے طور پر کبھی استعمال نہ کریں، کیونکہ جو client اس کے بارے میں جھوٹ بولنا چاہے وہ آسانی سے ایسا کر سکتا ہے۔ اس لیے User-Agent کے ذریعے scraper کو block کرنے سے صرف وہ scraper رکیں گے جو اپنا تعارف درست بتاتے ہیں۔

Content-Type طے کرتا ہے کہ bytes کی تشریح کیسے کی جائے: API request کے لیے application/json، اور page کے لیے text/html; charset=utf-8۔ nginx file extensions کو types سے /etc/nginx/mime.types کے ذریعے map کرتا ہے، جبکہ فراہم کردہ nginx.conf default_type application/octet-stream; مقرر کرتا ہے۔ اس لیے جس extension کو nginx نہیں جانتا، اس والی file rendered ہونے کے بجائے download کے طور پر پیش کی جاتی ہے۔ اس کی ظاہری علامت یہ ہے کہ page styling کے بغیر load ہوتا ہے اور browser console میں Refused to apply style from ... because its MIME type ('text/plain') is not a supported stylesheet MIME type ظاہر ہوتا ہے۔ یہاں MIME سے مراد multipurpose internet mail extensions ہے، جس naming scheme سے یہ type strings اخذ کی گئی ہیں۔

Cache-Control کے ذریعے آپ اپنے server اور قاری کے درمیان موجود ہر cache کو control کرتے ہیں۔ public, max-age=31536000, immutable ان assets کے لیے موزوں ہے جن کے filename میں content hash شامل ہو، کیونکہ content بدلنے پر نام بھی بدل جاتا ہے۔ no-store ہر user-specific چیز پر ہونا چاہیے، کیونکہ logged in page کو محفوظ رکھنے والا shared cache وہی page اگلے ایسے شخص کو دے دے گا جو اسی URL کی درخواست کرے۔ private درمیانی setting ہے: browser اسے محفوظ رکھ سکتا ہے، لیکن shared cache نہیں۔

X-Forwarded-For اس لیے موجود ہے کہ proxy visitor کا address چھپا دیتا ہے۔ جب request reverse proxy سے گزر جاتی ہے تو $remote_addr proxy کا address ہوتا ہے۔ اس صورت میں آپ کے logs، geolocation اور rate limiting سب کو ایک ہی client نظر آتا ہے۔ Proxy کو original address آگے بھیجنا ہوتا ہے:

proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

اس کے بعد receiving server کو یہ بتایا جانا چاہیے کہ وہ اس address پر اعتماد کرے، اور یہ بھی واضح کیا جانا چاہیے کہ کس پر اعتماد کرنا ہے:

set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;

صرف وہ ranges فہرست میں شامل کریں جنہیں آپ control کرتے ہیں۔ X-Forwarded-For سادہ text ہے جسے کوئی بھی client بھیج سکتا ہے۔ اس لیے set_real_ip_from 0.0.0.0/0; کے ذریعے visitor وہ address منتخب کر سکتا ہے جسے آپ log کرتے ہیں اور جسے آپ کا rate limiter شمار کرتا ہے۔

X-Forwarded-Proto ایک مخصوص اور بہت عام failure کو روکتا ہے۔ آپ کا proxy TLS terminate کرتا ہے اور request کو plain HTTP کے ذریعے application تک بھیجتا ہے۔ Application کو plain request نظر آتی ہے، اس لیے وہ فیصلہ کرتی ہے کہ visitor کو HTTPS پر ہونا چاہیے، اور 301 https://example.com/ کا جواب دیتی ہے۔ Browser اس redirect پر عمل کرتا ہے، proxy دوبارہ TLS terminate کر کے plain HTTP آگے بھیجتا ہے، اور یہ loop اس وقت تک جاری رہتا ہے جب تک browser ERR_TOO_MANY_REDIRECTS کے ساتھ کوشش ترک نہیں کر دیتا۔ X-Forwarded-Proto: https بھیجنے سے application کو معلوم ہوتا ہے کہ visitor پہلے ہی HTTPS پر ہے، اس لیے وہ redirect کرنا بند کر دیتی ہے۔

HTTP/1.1 بمقابلہ HTTP/2 بمقابلہ HTTP/3: آپ کے لیے کیا تبدیل ہوتا ہے

HTTP/1.1 متن پر مبنی ہے اور ہر connection پر ایک وقت میں ایک request سنبھالتا ہے۔ Connection: keep-alive اگلی request کو اسی TCP connection پر دوبارہ استعمال کرنے دیتا ہے۔ اس سے setup کی لاگت بچتی ہے، لیکن responses اب بھی اسی ترتیب سے واپس آتے ہیں جس ترتیب سے requests بھیجی گئی تھیں۔ ایک سست response اس کے پیچھے queue میں موجود ہر چیز کو روک دیتا ہے۔ اسے head-of-line blocking کہتے ہیں۔ Browsers ایک ہی hostname کے لیے بیک وقت کئی connections کھول کر اس سے نمٹتے ہیں۔

HTTP/2 میں وہی methods اور وہی status codes برقرار رہتے ہیں، لیکن framing binary ہو جاتی ہے۔ بہت سی requests ایک ہی connection پر independent streams کے طور پر share ہوتی ہیں، اور بار بار آنے والا header text compress کیا جاتا ہے۔ یہ اہم ہے کیونکہ جدید request میں header text کافی زیادہ ہوتا ہے۔ Connection اب بھی TCP ہوتا ہے، اس لیے ایک lost packet اس connection کی ہر stream کو اس وقت تک روک دیتا ہے جب تک retransmission نہ پہنچ جائے۔ Head-of-line blocking ختم نہیں ہوئی۔ یہ HTTP سے transport layer میں منتقل ہو گئی۔ Server push، HTTP/2 کا حصہ تھا، مگر عملی طور پر ختم ہو چکا ہے کیونکہ Chrome نے 2022 میں اس کی support ہٹا دی۔

HTTP/3 میں بھی وہی semantics برقرار رہتی ہیں، لیکن TCP کی جگہ QUIC استعمال ہوتا ہے۔ یہ UDP (user datagram protocol) پر بنایا گیا transport ہے۔ QUIC streams نچلی layers تک ایک دوسرے سے independent رہتی ہیں، اس لیے lost packet صرف اسی stream کو روکتا ہے جس سے وہ متعلق ہو۔ TLS 1.3، QUIC handshake میں شامل ہوتا ہے، اس کے اوپر الگ layer کے طور پر نہیں چلتا۔ اس لیے نئے connection کو کم round trips درکار ہوتے ہیں۔ اس کے دو عملی نتائج ہیں: راستے میں موجود ہر firewall پر UDP port 443 کھلا ہونا چاہیے، اور جو network UDP کو محدود یا block کرتا ہو وہ clients کو HTTP/2 پر واپس بھیج دے گا۔

آپ کے لیے عملی طور پر کیا تبدیل ہوتا ہے۔ Browsers کبھی بھی HTTP/3 سے آغاز نہیں کرتے۔ وہ HTTP/2 یا HTTP/1.1 کے ذریعے connect ہوتے ہیں، response میں Alt-Svc: h3=":443"; ma=86400 header دیکھتے ہیں، اور اسی host کے لیے بعد کے connections میں HTTP/3 استعمال کرتے ہیں۔ اس لیے یہ header محض اختیاری سجاوٹ نہیں ہے۔ یہی discovery mechanism ہے۔ nginx میں version 1.25.1 سے HTTP/2 اپنی الگ directive بن گیا ہے (server block کے اندر http2 on;، جو پرانے listen ... http2 parameter کی جگہ استعمال ہوتا ہے)، اور mainline 1.25.0 میں QUIC شامل ہوا، جہاں HTTP/3 site کو عام listen 443 ssl; کے ساتھ listen 443 quic reuseport; بھی درکار ہوتا ہے۔

اس معاملے میں proxies کی maturity مختلف ہے، اس لیے اپنی چلنے والی version کے مطابق اس کی تصدیق کرنا ضروری ہے۔ August 2026 تک Caddy بغیر configuration کے default طور پر HTTP/3 serve کرتا ہے۔ nginx کو اوپر بیان کردہ explicit quic listener اور Alt-Svc header درکار ہوتے ہیں۔ Traefik میں اسے ہر entry point کے لیے explicit http3 option کے ذریعے enable کیا جاتا ہے۔ اگر آپ TLS کو متعدد Docker ایپس کے سامنے Traefik میں terminate کرتے ہیں تو visitors کو ملنے والی protocol version وہیں طے ہوتی ہے، اور proxy سے آپ کے container تک hop عموماً plain HTTP/1.1 ہوتا ہے، چاہے browser نے جو بھی protocol negotiate کیا ہو۔

اندازے کے بجائے تصدیق کریں۔ curl --http3 -sS -o /dev/null -D - https://example.com/ صرف اسی وقت کام کرتا ہے جب curl -V اپنی features میں HTTP3 درج کرے، اور زیادہ تر distribution builds میں یہ شامل نہیں ہوتا۔ قابل اعتماد طریقہ آپ کا اپنا log ہے: format میں $server_protocol شامل کریں اور دیکھیں کہ حقیقی browsers کون سا protocol negotiate کرتے ہیں۔ اس سے پہلے تصدیق کریں کہ UDP 443 واقعی کھلا ہے، کیونکہ ایسا firewall جو صرف TCP 443 کی اجازت دیتا ہو HTTP/3 کو خاموشی سے ناکام ہونے دے گا، جبکہ site HTTP/2 کے ذریعے کام کرتی رہے گی۔ آپ کے Linux server پر کون سے ports کھلے اور listening ہیں یہ جاننا سب سے پہلے جانچنے والی چیز ہے۔

HTTPS: HTTP پروٹوکول ہے، TLS اس کی حفاظتی تہہ ہے

HTTPS کوئی الگ پروٹوکول نہیں ہے۔ یہ وہی requests اور وہی status codes ہیں جو TLS session کے اندر منتقل ہوتی ہیں۔ Port 80 انہیں plain text میں منتقل کرتا ہے، جبکہ port 443 انہیں encrypted شکل میں منتقل کرتا ہے۔ پہلے TLS handshake مکمل ہوتا ہے، پھر HTTP request encrypted channel کے اندر سفر کرتی ہے۔ اسی ترتیب کی وجہ سے certificate کے مسئلے کے ساتھ کبھی status code منسلک نہیں ہوتا: failure ایک بھی HTTP byte بھیجے جانے سے پہلے واقع ہوتی ہے، اس لیے نمبر دینے کے لیے کوئی response موجود نہیں ہوتا۔

ایک server پر متعدد sites host کرتے وقت ترتیب کی ایک تفصیل اہم ہے۔ Certificate کا انتخاب SNI (server name indication) کے ذریعے ہوتا ہے۔ یہ TLS handshake کا ایک field ہے جو HTTP header موجود ہونے سے پہلے hostname کو plain text میں منتقل کرتا ہے۔ اس لیے server پہلے SNI سے certificate منتخب کرتا ہے، پھر Host header سے virtual host منتخب کرتا ہے۔ یہ دو الگ lookups ہیں، جو عموماً ایک دوسرے سے مطابقت رکھتے ہیں۔ جب ایسا نہ ہو تو browser NET::ERR_CERT_COMMON_NAME_INVALID جیسی name mismatch دکھاتا ہے اور کوئی request نہیں بھیجتا، کیونکہ آپ کے default server کا certificate ایسے name کے لیے پیش کیا گیا تھا جسے وہ cover نہیں کرتا۔

Public site کے لیے اصل certificate حاصل کریں اور اسے خود renew ہونے دیں۔ nginx پر Let's Encrypt کے ساتھ Certbot certificate paths کو آپ کے server block میں لکھتا ہے اور renewal timer بھی خود install کرتا ہے۔ ایسے hostname کے لیے جس کی کوئی public authority تصدیق نہیں کر سکتی، مثلاً internal name یا آپ کے اپنے network پر موجود bare IP address، Ubuntu پر self-signed certificate مناسب اور واضح انتخاب ہے، بشرطیکہ آپ ہر client کو اسے trust کرنے کی ہدایت دینے کے لیے تیار ہوں۔

TLS کام کرنے لگے تو port 80 پر آنے والی تمام درخواستیں port 443 پر بھیجیں:

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

Strict-Transport-Security صرف اس وقت شامل کریں جب آپ کو مکمل یقین ہو۔ add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; header browsers کو اس hostname کے لیے دو سال تک plain HTTP سے انکار کرنے کی ہدایت دیتا ہے۔ Browsers اس ہدایت پر اپنی cache سے عمل کرتے ہیں، اس لیے بعد میں header ہٹانے سے یہ پابندی ختم نہیں ہوتی۔ پہلے max-age کی مدت چند گھنٹے رکھیں، تصدیق کریں کہ ہر subdomain واقعی HTTPS پر ہے، پھر مدت بڑھائیں۔

FAQ

HTTP اور HTTPS میں کیا فرق ہے؟

HTTPS، TLS (transport layer security) سیشن کے اندر بھیجا جانے والا HTTP ہے۔ Methods اور status codes یکساں ہوتے ہیں۔ فرق یہ ہے کہ client اور TLS terminate کرنے والے endpoint کے درمیان bytes encrypted ہوتے ہیں، اور default port 80 سے 443 ہو جاتا ہے۔ چونکہ پہلا HTTP byte بھیجے جانے سے پہلے TLS handshake مکمل ہو جاتا ہے، اس لیے certificate failure کبھی status code پیدا نہیں کرتی۔ اسی وجہ سے browser کا certificate warning 403 جیسے نمبر کے بجائے NET::ERR_CERT_COMMON_NAME_INVALID جیسا error name دکھاتا ہے۔

میری site 502 Bad Gateway کیوں واپس کرتی ہے؟

nginx کی طرف سے 502 کا مطلب ہے کہ nginx کو اس upstream سے قابلِ استعمال response نہیں ملا جس پر وہ proxy کر رہا ہے۔ اس لیے visitor کی request درست تھی، لیکن nginx کے پیچھے موجود کوئی جزو درست نہیں تھا۔ /var/log/nginx/error.log پڑھیں۔ connect() failed (111: Connection refused) while connecting to upstream کا مطلب ہے کہ proxy_pass میں دیے گئے address اور port پر کوئی process listening نہیں کر رہا۔ اس لیے تصدیق کریں کہ application چل رہی ہے اور متوقع address پر bind ہے۔ no live upstreams while connecting to upstream کا مطلب ہے کہ upstream block میں موجود ہر server کو بار بار failure کے بعد down mark کر دیا گیا ہے۔ اس کا موازنہ 504 Gateway Timeout سے کریں، جس کا مطلب ہے کہ upstream نے connection قبول کیا، لیکن proxy_read_timeout کے اندر جواب دینے میں ناکام رہا۔

میرے access log میں ہر visitor کے لیے ایک ہی IP address کیوں دکھائی دیتا ہے؟

کیونکہ $remote_addr اس address کو record کرتا ہے جس نے TCP connection کھولا تھا۔ reverse proxy یا content delivery network کے پیچھے یہ address proxy کا ہوتا ہے۔ Visitor کا address اس کے بجائے X-Forwarded-For header میں آتا ہے۔ Proxy پر proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; set کریں، پھر وصول کرنے والے nginx پر set_real_ip_from کو proxy کے address range پر set کریں اور real_ip_header X-Forwarded-For; شامل کریں۔ صرف وہ ranges درج کریں جنہیں آپ control کرتے ہیں، کیونکہ یہ header ایسا text ہے جو کوئی بھی client بھیج سکتا ہے۔ پورے internet سے اس پر اعتماد کرنے کی صورت میں visitor وہ address منتخب کر سکتا ہے جسے آپ log کریں اور جس پر rate limit لگائیں۔

کیا مجھے HTTP/2 یا HTTP/3 فعال کرنا چاہیے؟

HTTP/2 فعال کرنا مفید ہے، کیونکہ TLS رکھنے والی site پر یہ صرف ایک directive سے فعال ہوتا ہے اور فی connection request limit ختم کر دیتا ہے۔ یہی limit بہت سی چھوٹی files والی page کو سست بناتی ہے۔ HTTP/3 کا فائدہ کم اور کم یقینی ہے۔ اس کے لیے UDP port 443 کھلا ہونا اور QUIC support والی proxy build درکار ہوتی ہے۔ یاد رکھیں کہ browsers HTTP/3 پر صرف اس وقت switch کرتے ہیں جب انہیں پہلے کے response میں Alt-Svc header ملے۔ اس header کے بغیر آپ کی listen line کچھ بھی کہے، کوئی تبدیلی نہیں ہوگی۔ اپنے log format میں $server_protocol شامل کریں اور وقت صرف کرنے سے پہلے معلوم کریں کہ visitors حقیقت میں کون سا protocol negotiate کرتے ہیں۔

File موجود ہونے کے باوجود 403 Forbidden کا کیا مطلب ہے؟

Static site پر 403 عموماً HTTP rule کے بجائے filesystem permission کا مسئلہ ہوتا ہے۔ /var/log/nginx/error.log میں open() ... failed (13: Permission denied) کا مطلب ہے کہ nginx worker user file پڑھ نہیں سکتا۔ اس کی عام وجہ یہ ہوتی ہے کہ parent directory میں others کے لیے execute permission نہیں ہوتی، نہ کہ file mode غلط ہو۔ directory index of ... is forbidden کا مطلب ہے کہ request ایسی directory تک پہنچی جس میں index file نہیں تھی، جبکہ autoindex غیر فعال ہے۔ Matching location block میں موجود واضح deny rule بھی 403 واپس کرتا ہے۔ اس لیے جب error log کچھ نہ بتائے تو وہ block پڑھیں۔

#http#https#web-server#headers#http3