[{"data":1,"prerenderedAt":4532},["ShallowReactive",2],{"home-posts":3,"home-projects":4040},[4,1707,2965],{"id":5,"title":6,"body":7,"date":1691,"description":1692,"draft":1693,"extension":1694,"image":42,"meta":1695,"navigation":977,"path":1696,"seo":1697,"stem":1698,"tags":1699,"__hash__":1706},"blogs\u002Fblogs\u002Fdns_explained_the_backbone_of_the_world_wide_web\u002Findex.md","DNS Explained: The Backbone of the World Wide Web",{"type":8,"value":9,"toc":1634},"minimark",[10,14,17,20,33,36,43,48,51,54,57,62,67,70,103,106,120,123,126,137,140,145,153,161,164,168,171,181,184,187,190,193,241,244,247,251,254,257,268,271,286,289,293,296,299,335,338,353,357,360,364,367,370,374,377,397,400,404,407,418,421,425,428,432,435,439,442,446,449,452,456,459,462,466,469,472,476,479,485,488,492,495,499,502,510,514,517,523,527,530,536,540,543,549,552,556,559,565,569,572,578,582,585,591,595,598,604,607,611,614,620,624,627,638,641,645,648,662,665,669,672,698,701,705,708,711,715,718,722,725,745,748,752,755,769,772,776,781,784,788,791,795,798,802,805,809,826,830,833,837,844,1158,1161,1177,1181,1188,1192,1195,1219,1222,1286,1290,1293,1320,1323,1327,1330,1358,1362,1382,1385,1389,1392,1396,1400,1417,1421,1435,1439,1442,1469,1473,1476,1487,1490,1494,1498,1515,1519,1533,1537,1554,1557,1561,1614,1618,1621,1624,1627,1630],[11,12,13],"p",{},"Domain Name System ( DNS ) is one of the most critical infrastructure pieces of the internet. Every website visit, API call, or email delivery begins with a DNS query.",[11,15,16],{},"While most organizations rely on managed DNS providers, self-hosting a DNS nameserver can be a powerful learning experience and, in some cases, a practical solution for greater control, privacy, or experimentation.",[11,18,19],{},"In this blog, we will:",[21,22,23,27,30],"ul",{},[24,25,26],"li",{},"Understand how DNS works at a global scale",[24,28,29],{},"Explore real-world DNS architecture and infrastructure",[24,31,32],{},"Walk through self-hosting an authoritative DNS server using PowerDNS",[11,34,35],{},"This article is aimed at system administrators, DevOps engineers, and curious learners who want to go deeper than “just use a managed DNS provider.”",[11,37,38],{},[39,40],"img",{"alt":41,"src":42},"dns","\u002Fimages\u002Fblogs\u002Fdns_explained_the_backbone_of_the_world_wide_web\u002Fdns.png",[44,45,47],"h2",{"id":46},"what-problem-dns-solves","What Problem DNS Solves ?",[11,49,50],{},"At its core, DNS exists to solve a human problem, not a technical one.",[11,52,53],{},"Computers are extremely good at working with numbers. Humans are not.",[11,55,56],{},"The internet, however, must work for both.",[39,58],{"src":59,"style":60,"alt":61},"\u002Fimages\u002Fblogs\u002Fdns_explained_the_backbone_of_the_world_wide_web\u002Fip_communication.png","display:block; margin-left:auto; margin-right:auto","IP communication diagram",[63,64,66],"h3",{"id":65},"why-humans-cannot-use-ip-addresses","Why Humans Cannot Use IP Addresses ?",[11,68,69],{},"Every device connected to the internet is identified by an IP address, such as:",[71,72,77],"pre",{"className":73,"code":74,"language":75,"meta":76,"style":76},"language-bash shiki shiki-themes github-light","IPv4: 37.27.249.121\nIPv6: 2001:db8:85a3::8a2e:370:7334\n","bash","",[78,79,80,93],"code",{"__ignoreMap":76},[81,82,85,89],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"s7eDp","IPv4:",[81,90,92],{"class":91},"sYu0t"," 37.27.249.121\n",[81,94,96,99],{"class":83,"line":95},2,[81,97,98],{"class":87},"IPv6:",[81,100,102],{"class":101},"sYBdl"," 2001:db8:85a3::8a2e:370:7334\n",[11,104,105],{},"While these numbers are efficient for machines, they are fundamentally unsuitable for humans:",[21,107,108,111,114,117],{},[24,109,110],{},"They are hard to remember",[24,112,113],{},"They have no semantic meaning",[24,115,116],{},"They change frequently (cloud, load balancers, failovers)",[24,118,119],{},"IPv6 addresses are even longer and more complex",[11,121,122],{},"Humans think in names, not numbers.",[11,124,125],{},"We remember:",[21,127,128,131,134],{},[24,129,130],{},"google.com",[24,132,133],{},"github.com",[24,135,136],{},"example.com",[11,138,139],{},"Not:",[21,141,142],{},[24,143,144],{},"142.250.195.78",[11,146,147,148,152],{},"The core problem DNS solves is ",[149,150,151],"strong",{},"decoupling identity from location",":",[21,154,155,158],{},[24,156,157],{},"A name represents a service or organization",[24,159,160],{},"An IP address represents where that service currently lives",[11,162,163],{},"This separation allows infrastructure to evolve without breaking human access.",[63,165,167],{"id":166},"why-centralized-name-mapping-doesnt-scale","Why Centralized Name Mapping Doesn’t Scale ?",[11,169,170],{},"In the very early days of the internet, name resolution was centralized.",[11,172,173,174,177,178],{},"There was a single file: ",[78,175,176],{},"HOSTS.txt"," or ",[78,179,180],{},"\u002Fetc\u002Fhosts",[11,182,183],{},"Every hostname and IP mapping lived in this file, maintained by a central authority.",[11,185,186],{},"Each computer periodically downloaded the latest version.",[11,188,189],{},"This approach worked — until it didn’t.",[11,191,192],{},"The Problems with Centralization :",[21,194,195,203,211,222,233],{},[24,196,197,198],{},"Single Point of Failure\n",[21,199,200],{},[24,201,202],{},"If the central server went down, name resolution stopped",[24,204,205,206],{},"Administrative Bottleneck\n",[21,207,208],{},[24,209,210],{},"Every new host required manual approval and distribution",[24,212,213,214],{},"Update Latency\n",[21,215,216,219],{},[24,217,218],{},"Changes propagated slowly",[24,220,221],{},"Stale data caused outages",[24,223,224,225],{},"No Delegation\n",[21,226,227,230],{},[24,228,229],{},"One organization controlled all names",[24,231,232],{},"No ownership model",[24,234,235,236],{},"Security Risk\n",[21,237,238],{},[24,239,240],{},"Anyone who compromised the central file could hijack the entire internet",[11,242,243],{},"As the number of connected machines grew from hundreds to millions and now billions this model became impossible.",[11,245,246],{},"The internet needed a distributed naming system.",[63,248,250],{"id":249},"why-dns-must-be-distributed","Why DNS Must Be Distributed ?",[11,252,253],{},"DNS is distributed by design because no single system can know everything.",[11,255,256],{},"Instead:",[21,258,259,262,265],{},[24,260,261],{},"Responsibility is split",[24,263,264],{},"Authority is delegated",[24,266,267],{},"Queries are answered locally whenever possible",[11,269,270],{},"Each domain owner controls their own namespace:",[21,272,273,278,283],{},[24,274,275,276],{},"Google controls ",[78,277,130],{},[24,279,280,281],{},"GitHub controls ",[78,282,133],{},[24,284,285],{},"You control your domain",[11,287,288],{},"There is no “master DNS database” for the internet and that is intentional.",[63,290,292],{"id":291},"why-dns-is-hierarchical","Why DNS Is Hierarchical ?",[11,294,295],{},"Distribution alone is not enough. Without structure, discovery would still be inefficient.",[11,297,298],{},"DNS solves this with hierarchy.",[71,300,302],{"className":73,"code":301,"language":75,"meta":76,"style":76},".\n└── com\n    └── example\n        └── www\n",[78,303,304,309,317,326],{"__ignoreMap":76},[81,305,306],{"class":83,"line":84},[81,307,308],{"class":91},".\n",[81,310,311,314],{"class":83,"line":95},[81,312,313],{"class":87},"└──",[81,315,316],{"class":101}," com\n",[81,318,320,323],{"class":83,"line":319},3,[81,321,322],{"class":87},"    └──",[81,324,325],{"class":101}," example\n",[81,327,329,332],{"class":83,"line":328},4,[81,330,331],{"class":87},"        └──",[81,333,334],{"class":101}," www\n",[11,336,337],{},"A strong deep-technical blog must move through four layers:",[339,340,341,344,347,350],"ol",{},[24,342,343],{},"Conceptual model – what DNS is and why it exists",[24,345,346],{},"Real internet behavior – how DNS works globally",[24,348,349],{},"Hands-on mechanics – commands, configs, files",[24,351,352],{},"Operational reality – security, failure modes, best practices",[44,354,356],{"id":355},"dns-hierarchy-in-detail","DNS Hierarchy in Detail",[11,358,359],{},"DNS is organized as an inverted tree structure, starting from the root and branching down to individual domains. This hierarchy ensures efficient delegation and scalability.",[63,361,363],{"id":362},"root-servers","Root Servers",[11,365,366],{},"At the top of the DNS hierarchy are the root servers. There are 13 logical root server clusters (labeled A through M), operated by different organizations worldwide. These servers maintain the master list of all top-level domains (TLDs).",[11,368,369],{},"Root servers don't contain actual domain records but point resolvers to the authoritative servers for each TLD. They respond with NS records directing queries to the appropriate TLD servers.",[63,371,373],{"id":372},"top-level-domains-tlds","Top-Level Domains (TLDs)",[11,375,376],{},"TLDs are the highest level of domain names, appearing after the last dot. They are divided into categories:",[21,378,379,385,391],{},[24,380,381,384],{},[149,382,383],{},"gTLDs (Generic TLDs):"," .com, .org, .net, .info, .biz",[24,386,387,390],{},[149,388,389],{},"ccTLDs (Country Code TLDs):"," .us, .uk, .de, .in, .jp",[24,392,393,396],{},[149,394,395],{},"New gTLDs:"," .app, .dev, .tech, .blog",[11,398,399],{},"Each TLD has its own set of authoritative name servers managed by registries (like Verisign for .com or individual country registries).",[63,401,403],{"id":402},"authoritative-name-servers","Authoritative Name Servers",[11,405,406],{},"For each domain, there are authoritative name servers that hold the actual DNS records. These are typically provided by:",[21,408,409,412,415],{},[24,410,411],{},"Domain registrars (when you register a domain)",[24,413,414],{},"DNS hosting providers (like Cloudflare, Route 53, DigitalOcean)",[24,416,417],{},"Self-hosted servers (for organizations with their own infrastructure)",[11,419,420],{},"Authoritative servers are the source of truth for a domain's records and are responsible for responding to queries about that domain.",[44,422,424],{"id":423},"dns-resolution-process-step-by-step","DNS Resolution Process: Step-by-Step",[11,426,427],{},"When you type \"example.com\" into your browser, a complex resolution process occurs behind the scenes. Let's trace through a typical DNS lookup:",[63,429,431],{"id":430},"step-1-local-cache-check","Step 1: Local Cache Check",[11,433,434],{},"Your operating system and browser maintain a DNS cache. The resolver first checks these local caches for the requested domain. If found and not expired, it returns the cached IP address immediately.",[63,436,438],{"id":437},"step-2-recursive-resolver-query","Step 2: Recursive Resolver Query",[11,440,441],{},"If not cached locally, your device queries a recursive DNS resolver (usually provided by your ISP, or public ones like 8.8.8.8 or 1.1.1.1). This resolver acts on your behalf to find the answer.",[63,443,445],{"id":444},"step-3-root-server-query","Step 3: Root Server Query",[11,447,448],{},"The recursive resolver starts at the root. It queries one of the 13 root servers asking \"Who handles .com domains?\"",[11,450,451],{},"The root server responds with NS records pointing to the TLD servers for .com.",[63,453,455],{"id":454},"step-4-tld-server-query","Step 4: TLD Server Query",[11,457,458],{},"The resolver queries the .com TLD servers: \"Who handles example.com?\"",[11,460,461],{},"The TLD server responds with NS records pointing to example.com's authoritative servers.",[63,463,465],{"id":464},"step-5-authoritative-server-query","Step 5: Authoritative Server Query",[11,467,468],{},"Finally, the resolver queries example.com's authoritative servers: \"What is the IP address for example.com?\"",[11,470,471],{},"The authoritative server returns the A or AAAA record with the IP address.",[63,473,475],{"id":474},"step-6-response-and-caching","Step 6: Response and Caching",[11,477,478],{},"The recursive resolver returns the IP to your device, which caches it. Future requests for the same domain will be served from cache until expiration.",[11,480,481],{},[39,482],{"alt":483,"src":484},"DNS Resolution","\u002Fimages\u002Fblogs\u002Fdns_explained_the_backbone_of_the_world_wide_web\u002Fweb_request.png",[11,486,487],{},"This process typically takes 20-100ms and involves multiple network round trips across the globe.",[44,489,491],{"id":490},"dns-record-types","DNS Record Types",[11,493,494],{},"DNS stores different types of records, each serving a specific purpose. Here are the most common ones:",[63,496,498],{"id":497},"a-record-address-record","A Record (Address Record)",[11,500,501],{},"Maps a domain name to an IPv4 address.",[71,503,508],{"className":504,"code":506,"language":507},[505],"language-text","example.com.    IN  A   93.184.216.34\n","text",[78,509,506],{"__ignoreMap":76},[63,511,513],{"id":512},"aaaa-record-ipv6-address-record","AAAA Record (IPv6 Address Record)",[11,515,516],{},"Maps a domain name to an IPv6 address.",[71,518,521],{"className":519,"code":520,"language":507},[505],"example.com.    IN  AAAA   2606:2800:220:1:248:1893:25c8:1946\n",[78,522,520],{"__ignoreMap":76},[63,524,526],{"id":525},"cname-record-canonical-name","CNAME Record (Canonical Name)",[11,528,529],{},"Creates an alias from one domain to another.",[71,531,534],{"className":532,"code":533,"language":507},[505],"www.example.com.    IN  CNAME   example.com.\n",[78,535,533],{"__ignoreMap":76},[63,537,539],{"id":538},"mx-record-mail-exchange","MX Record (Mail Exchange)",[11,541,542],{},"Specifies mail servers for the domain.",[71,544,547],{"className":545,"code":546,"language":507},[505],"example.com.    IN  MX  10 mail.example.com.\n",[78,548,546],{"__ignoreMap":76},[11,550,551],{},"The number (10) indicates priority; lower numbers have higher priority.",[63,553,555],{"id":554},"txt-record-text-record","TXT Record (Text Record)",[11,557,558],{},"Stores arbitrary text data, commonly used for SPF, DKIM, and verification.",[71,560,563],{"className":561,"code":562,"language":507},[505],"example.com.    IN  TXT   \"v=spf1 include:_spf.google.com ~all\"\n",[78,564,562],{"__ignoreMap":76},[63,566,568],{"id":567},"ns-record-name-server","NS Record (Name Server)",[11,570,571],{},"Delegates a subdomain to specific name servers.",[71,573,576],{"className":574,"code":575,"language":507},[505],"example.com.    IN  NS   ns1.example.com.\n",[78,577,575],{"__ignoreMap":76},[63,579,581],{"id":580},"soa-record-start-of-authority","SOA Record (Start of Authority)",[11,583,584],{},"Contains administrative information about the zone.",[71,586,589],{"className":587,"code":588,"language":507},[505],"example.com.    IN  SOA   ns1.example.com. admin.example.com. (\n    2023010101 ; Serial\n    3600       ; Refresh\n    1800       ; Retry\n    604800     ; Expire\n    86400      ; Minimum TTL\n)\n",[78,590,588],{"__ignoreMap":76},[63,592,594],{"id":593},"ptr-record-pointer-record","PTR Record (Pointer Record)",[11,596,597],{},"Maps an IP address back to a domain name (reverse DNS).",[71,599,602],{"className":600,"code":601,"language":507},[505],"34.216.184.93.in-addr.arpa.    IN  PTR   example.com.\n",[78,603,601],{"__ignoreMap":76},[11,605,606],{},"These records work together to provide complete domain information and enable various internet services.",[44,608,610],{"id":609},"dns-infrastructure-the-global-network","DNS Infrastructure: The Global Network",[11,612,613],{},"DNS operates through a distributed network of servers working in harmony:",[11,615,616],{},[39,617],{"alt":618,"src":619},"DNS Infrastructure Diagram","\u002Fimages\u002Fblogs\u002Fdns_explained_the_backbone_of_the_world_wide_web\u002Fcomplete-dns-lookup-and-webpage-query.png",[63,621,623],{"id":622},"recursive-resolvers","Recursive Resolvers",[11,625,626],{},"These are the \"middlemen\" of DNS. They accept queries from clients and perform the full resolution process on their behalf. Popular public recursive resolvers include:",[21,628,629,632,635],{},[24,630,631],{},"Google Public DNS (8.8.8.8, 8.8.4.4)",[24,633,634],{},"Cloudflare (1.1.1.1, 1.0.0.1)",[24,636,637],{},"Quad9 (9.9.9.9)",[11,639,640],{},"Recursive resolvers implement aggressive caching to improve performance and reduce load on authoritative servers.",[63,642,644],{"id":643},"authoritative-servers","Authoritative Servers",[11,646,647],{},"These hold the actual zone files and are the definitive source for domain information. They come in two types:",[21,649,650,656],{},[24,651,652,655],{},[149,653,654],{},"Primary (Master):"," Contains the original zone file",[24,657,658,661],{},[149,659,660],{},"Secondary (Slave):"," Replicates data from the primary for redundancy",[11,663,664],{},"Authoritative servers are organized hierarchically and delegate subdomains to other servers.",[63,666,668],{"id":667},"caching-the-performance-booster","Caching: The Performance Booster",[11,670,671],{},"DNS heavily relies on caching at multiple levels:",[21,673,674,680,686,692],{},[24,675,676,679],{},[149,677,678],{},"Browser Cache:"," Short-term storage in the browser",[24,681,682,685],{},[149,683,684],{},"OS Cache:"," System-level DNS cache",[24,687,688,691],{},[149,689,690],{},"Resolver Cache:"," Recursive resolvers cache responses",[24,693,694,697],{},[149,695,696],{},"Authoritative Cache:"," Some authoritative servers implement caching",[11,699,700],{},"TTL (Time To Live) values control how long records are cached. Shorter TTLs provide more current data but increase query volume.",[63,702,704],{"id":703},"anycast-global-distribution","Anycast: Global Distribution",[11,706,707],{},"Many DNS servers use anycast routing, where the same IP address is announced from multiple physical locations worldwide. This ensures queries are routed to the nearest server, reducing latency.",[11,709,710],{},"For example, the root servers are anycasted across hundreds of locations globally, ensuring fast responses from anywhere on earth.",[44,712,714],{"id":713},"dns-security-protecting-the-foundation","DNS Security: Protecting the Foundation",[11,716,717],{},"DNS was designed without security in mind, making it vulnerable to various attacks. Modern solutions address these issues:",[63,719,721],{"id":720},"dnssec-dns-security-extensions","DNSSEC (DNS Security Extensions)",[11,723,724],{},"DNSSEC adds cryptographic signatures to DNS records, ensuring:",[21,726,727,733,739],{},[24,728,729,732],{},[149,730,731],{},"Data Integrity:"," Records haven't been tampered with",[24,734,735,738],{},[149,736,737],{},"Authentication:"," Responses come from legitimate servers",[24,740,741,744],{},[149,742,743],{},"Non-existence Proofs:"," Proves when domains don't exist",[11,746,747],{},"DNSSEC uses a chain of trust from the root down to individual domains. Keys are managed hierarchically, with the root KSK (Key Signing Key) being the ultimate trust anchor.",[63,749,751],{"id":750},"encrypted-dns-protocols","Encrypted DNS Protocols",[11,753,754],{},"Traditional DNS sends queries in plaintext, allowing interception and manipulation.",[21,756,757,763],{},[24,758,759,762],{},[149,760,761],{},"DoT (DNS over TLS):"," Encrypts DNS queries over port 853",[24,764,765,768],{},[149,766,767],{},"DoH (DNS over HTTPS):"," Sends DNS queries over HTTPS (port 443), blending with normal web traffic",[11,770,771],{},"These prevent eavesdropping and make blocking DNS traffic more difficult.",[63,773,775],{"id":774},"common-dns-attacks","Common DNS Attacks",[777,778,780],"h4",{"id":779},"dns-spoofingcache-poisoning","DNS Spoofing\u002FCache Poisoning",[11,782,783],{},"Attackers send fake responses to recursive resolvers, polluting their cache with malicious IP addresses.",[777,785,787],{"id":786},"ddos-amplification","DDoS Amplification",[11,789,790],{},"DNS servers can be used to amplify DDoS attacks since UDP responses can be much larger than queries.",[777,792,794],{"id":793},"dns-tunneling","DNS Tunneling",[11,796,797],{},"Malware uses DNS queries to exfiltrate data by encoding information in domain names.",[777,799,801],{"id":800},"nxdomain-attacks","NXDOMAIN Attacks",[11,803,804],{},"Overloading resolvers with queries for non-existent domains to exhaust resources.",[63,806,808],{"id":807},"mitigation-strategies","Mitigation Strategies",[21,810,811,814,817,820,823],{},[24,812,813],{},"Implement DNSSEC for your domains",[24,815,816],{},"Use encrypted DNS (DoT\u002FDoH) clients",[24,818,819],{},"Deploy DNS firewalls (like Response Policy Zones)",[24,821,822],{},"Monitor for anomalous query patterns",[24,824,825],{},"Use rate limiting on authoritative servers",[44,827,829],{"id":828},"self-hosting-an-authoritative-dns-server-with-powerdns","Self-Hosting an Authoritative DNS Server with PowerDNS",[11,831,832],{},"While managed DNS providers are convenient, self-hosting gives you complete control. PowerDNS is an excellent open-source authoritative DNS server. Let's set it up:",[63,834,836],{"id":835},"installation-with-docker","Installation with Docker",[11,838,839,840,843],{},"Use Docker Compose for easy setup with MySQL backend. Create a ",[78,841,842],{},"docker-compose.yml"," file:",[71,845,849],{"className":846,"code":847,"language":848,"meta":76,"style":76},"language-yaml shiki shiki-themes github-light","version: '3.8'\nservices:\n  mysql:\n    image: mysql:8.0\n    environment:\n      MYSQL_ROOT_PASSWORD: your_mysql_root_password\n      MYSQL_DATABASE: pdns\n      MYSQL_USER: pdns\n      MYSQL_PASSWORD: your_pdns_password\n    volumes:\n      - mysql_data:\u002Fvar\u002Flib\u002Fmysql\n    networks:\n      - pdns\n\n  powerdns:\n    image: pschiffe\u002Fpdns-mysql:latest\n    environment:\n      MYSQL_HOST: mysql\n      MYSQL_PORT: 3306\n      MYSQL_USER: pdns\n      MYSQL_PASS: your_pdns_password\n      MYSQL_DB: pdns\n    ports:\n      - \"53:53\u002Ftcp\"\n      - \"53:53\u002Fudp\"\n      - \"8081:8081\"\n    depends_on:\n      - mysql\n    networks:\n      - pdns\n\nvolumes:\n  mysql_data:\n\nnetworks:\n  pdns:\n","yaml",[78,850,851,864,872,879,889,897,908,919,929,940,948,957,965,972,979,987,997,1004,1015,1026,1035,1045,1055,1063,1071,1079,1087,1095,1102,1109,1116,1121,1129,1137,1142,1150],{"__ignoreMap":76},[81,852,853,857,861],{"class":83,"line":84},[81,854,856],{"class":855},"shJU0","version",[81,858,860],{"class":859},"sgsFI",": ",[81,862,863],{"class":101},"'3.8'\n",[81,865,866,869],{"class":83,"line":95},[81,867,868],{"class":855},"services",[81,870,871],{"class":859},":\n",[81,873,874,877],{"class":83,"line":319},[81,875,876],{"class":855},"  mysql",[81,878,871],{"class":859},[81,880,881,884,886],{"class":83,"line":328},[81,882,883],{"class":855},"    image",[81,885,860],{"class":859},[81,887,888],{"class":101},"mysql:8.0\n",[81,890,892,895],{"class":83,"line":891},5,[81,893,894],{"class":855},"    environment",[81,896,871],{"class":859},[81,898,900,903,905],{"class":83,"line":899},6,[81,901,902],{"class":855},"      MYSQL_ROOT_PASSWORD",[81,904,860],{"class":859},[81,906,907],{"class":101},"your_mysql_root_password\n",[81,909,911,914,916],{"class":83,"line":910},7,[81,912,913],{"class":855},"      MYSQL_DATABASE",[81,915,860],{"class":859},[81,917,918],{"class":101},"pdns\n",[81,920,922,925,927],{"class":83,"line":921},8,[81,923,924],{"class":855},"      MYSQL_USER",[81,926,860],{"class":859},[81,928,918],{"class":101},[81,930,932,935,937],{"class":83,"line":931},9,[81,933,934],{"class":855},"      MYSQL_PASSWORD",[81,936,860],{"class":859},[81,938,939],{"class":101},"your_pdns_password\n",[81,941,943,946],{"class":83,"line":942},10,[81,944,945],{"class":855},"    volumes",[81,947,871],{"class":859},[81,949,951,954],{"class":83,"line":950},11,[81,952,953],{"class":859},"      - ",[81,955,956],{"class":101},"mysql_data:\u002Fvar\u002Flib\u002Fmysql\n",[81,958,960,963],{"class":83,"line":959},12,[81,961,962],{"class":855},"    networks",[81,964,871],{"class":859},[81,966,968,970],{"class":83,"line":967},13,[81,969,953],{"class":859},[81,971,918],{"class":101},[81,973,975],{"class":83,"line":974},14,[81,976,978],{"emptyLinePlaceholder":977},true,"\n",[81,980,982,985],{"class":83,"line":981},15,[81,983,984],{"class":855},"  powerdns",[81,986,871],{"class":859},[81,988,990,992,994],{"class":83,"line":989},16,[81,991,883],{"class":855},[81,993,860],{"class":859},[81,995,996],{"class":101},"pschiffe\u002Fpdns-mysql:latest\n",[81,998,1000,1002],{"class":83,"line":999},17,[81,1001,894],{"class":855},[81,1003,871],{"class":859},[81,1005,1007,1010,1012],{"class":83,"line":1006},18,[81,1008,1009],{"class":855},"      MYSQL_HOST",[81,1011,860],{"class":859},[81,1013,1014],{"class":101},"mysql\n",[81,1016,1018,1021,1023],{"class":83,"line":1017},19,[81,1019,1020],{"class":855},"      MYSQL_PORT",[81,1022,860],{"class":859},[81,1024,1025],{"class":91},"3306\n",[81,1027,1029,1031,1033],{"class":83,"line":1028},20,[81,1030,924],{"class":855},[81,1032,860],{"class":859},[81,1034,918],{"class":101},[81,1036,1038,1041,1043],{"class":83,"line":1037},21,[81,1039,1040],{"class":855},"      MYSQL_PASS",[81,1042,860],{"class":859},[81,1044,939],{"class":101},[81,1046,1048,1051,1053],{"class":83,"line":1047},22,[81,1049,1050],{"class":855},"      MYSQL_DB",[81,1052,860],{"class":859},[81,1054,918],{"class":101},[81,1056,1058,1061],{"class":83,"line":1057},23,[81,1059,1060],{"class":855},"    ports",[81,1062,871],{"class":859},[81,1064,1066,1068],{"class":83,"line":1065},24,[81,1067,953],{"class":859},[81,1069,1070],{"class":101},"\"53:53\u002Ftcp\"\n",[81,1072,1074,1076],{"class":83,"line":1073},25,[81,1075,953],{"class":859},[81,1077,1078],{"class":101},"\"53:53\u002Fudp\"\n",[81,1080,1082,1084],{"class":83,"line":1081},26,[81,1083,953],{"class":859},[81,1085,1086],{"class":101},"\"8081:8081\"\n",[81,1088,1090,1093],{"class":83,"line":1089},27,[81,1091,1092],{"class":855},"    depends_on",[81,1094,871],{"class":859},[81,1096,1098,1100],{"class":83,"line":1097},28,[81,1099,953],{"class":859},[81,1101,1014],{"class":101},[81,1103,1105,1107],{"class":83,"line":1104},29,[81,1106,962],{"class":855},[81,1108,871],{"class":859},[81,1110,1112,1114],{"class":83,"line":1111},30,[81,1113,953],{"class":859},[81,1115,918],{"class":101},[81,1117,1119],{"class":83,"line":1118},31,[81,1120,978],{"emptyLinePlaceholder":977},[81,1122,1124,1127],{"class":83,"line":1123},32,[81,1125,1126],{"class":855},"volumes",[81,1128,871],{"class":859},[81,1130,1132,1135],{"class":83,"line":1131},33,[81,1133,1134],{"class":855},"  mysql_data",[81,1136,871],{"class":859},[81,1138,1140],{"class":83,"line":1139},34,[81,1141,978],{"emptyLinePlaceholder":977},[81,1143,1145,1148],{"class":83,"line":1144},35,[81,1146,1147],{"class":855},"networks",[81,1149,871],{"class":859},[81,1151,1153,1156],{"class":83,"line":1152},36,[81,1154,1155],{"class":855},"  pdns",[81,1157,871],{"class":859},[11,1159,1160],{},"Run the services:",[71,1162,1164],{"className":73,"code":1163,"language":75,"meta":76,"style":76},"docker-compose up -d\n",[78,1165,1166],{"__ignoreMap":76},[81,1167,1168,1171,1174],{"class":83,"line":84},[81,1169,1170],{"class":87},"docker-compose",[81,1172,1173],{"class":101}," up",[81,1175,1176],{"class":91}," -d\n",[63,1178,1180],{"id":1179},"configuration","Configuration",[11,1182,1183,1184,1187],{},"PowerDNS auto-configures with the MySQL backend. Access the web interface at ",[78,1185,1186],{},"http:\u002F\u002Flocalhost:8081",".",[63,1189,1191],{"id":1190},"database-setup","Database Setup",[11,1193,1194],{},"The MySQL database initializes automatically. Create zones via the API or command line:",[71,1196,1198],{"className":73,"code":1197,"language":75,"meta":76,"style":76},"docker-compose exec powerdns pdnsutil create-zone example.com\n",[78,1199,1200],{"__ignoreMap":76},[81,1201,1202,1204,1207,1210,1213,1216],{"class":83,"line":84},[81,1203,1170],{"class":87},[81,1205,1206],{"class":101}," exec",[81,1208,1209],{"class":101}," powerdns",[81,1211,1212],{"class":101}," pdnsutil",[81,1214,1215],{"class":101}," create-zone",[81,1217,1218],{"class":101}," example.com\n",[11,1220,1221],{},"Add some records:",[71,1223,1225],{"className":73,"code":1224,"language":75,"meta":76,"style":76},"sudo pdnsutil add-record example.com @ A 192.168.1.10\nsudo pdnsutil add-record example.com www CNAME example.com\nsudo pdnsutil add-record example.com mail MX \"10 mail.example.com\"\n",[78,1226,1227,1249,1267],{"__ignoreMap":76},[81,1228,1229,1232,1234,1237,1240,1243,1246],{"class":83,"line":84},[81,1230,1231],{"class":87},"sudo",[81,1233,1212],{"class":101},[81,1235,1236],{"class":101}," add-record",[81,1238,1239],{"class":101}," example.com",[81,1241,1242],{"class":101}," @",[81,1244,1245],{"class":101}," A",[81,1247,1248],{"class":91}," 192.168.1.10\n",[81,1250,1251,1253,1255,1257,1259,1262,1265],{"class":83,"line":95},[81,1252,1231],{"class":87},[81,1254,1212],{"class":101},[81,1256,1236],{"class":101},[81,1258,1239],{"class":101},[81,1260,1261],{"class":101}," www",[81,1263,1264],{"class":101}," CNAME",[81,1266,1218],{"class":101},[81,1268,1269,1271,1273,1275,1277,1280,1283],{"class":83,"line":319},[81,1270,1231],{"class":87},[81,1272,1212],{"class":101},[81,1274,1236],{"class":101},[81,1276,1239],{"class":101},[81,1278,1279],{"class":101}," mail",[81,1281,1282],{"class":101}," MX",[81,1284,1285],{"class":101}," \"10 mail.example.com\"\n",[63,1287,1289],{"id":1288},"dnssec-setup","DNSSEC Setup",[11,1291,1292],{},"Enable DNSSEC for the zone:",[71,1294,1296],{"className":73,"code":1295,"language":75,"meta":76,"style":76},"sudo pdnsutil secure-zone example.com\nsudo pdnsutil set-nsec3 example.com\n",[78,1297,1298,1309],{"__ignoreMap":76},[81,1299,1300,1302,1304,1307],{"class":83,"line":84},[81,1301,1231],{"class":87},[81,1303,1212],{"class":101},[81,1305,1306],{"class":101}," secure-zone",[81,1308,1218],{"class":101},[81,1310,1311,1313,1315,1318],{"class":83,"line":95},[81,1312,1231],{"class":87},[81,1314,1212],{"class":101},[81,1316,1317],{"class":101}," set-nsec3",[81,1319,1218],{"class":101},[11,1321,1322],{},"This generates keys and signs the zone automatically.",[63,1324,1326],{"id":1325},"testing","Testing",[11,1328,1329],{},"Test your setup:",[71,1331,1333],{"className":73,"code":1332,"language":75,"meta":76,"style":76},"dig @localhost example.com A\nnslookup example.com localhost\n",[78,1334,1335,1348],{"__ignoreMap":76},[81,1336,1337,1340,1343,1345],{"class":83,"line":84},[81,1338,1339],{"class":87},"dig",[81,1341,1342],{"class":101}," @localhost",[81,1344,1239],{"class":101},[81,1346,1347],{"class":101}," A\n",[81,1349,1350,1353,1355],{"class":83,"line":95},[81,1351,1352],{"class":87},"nslookup",[81,1354,1239],{"class":101},[81,1356,1357],{"class":101}," localhost\n",[63,1359,1361],{"id":1360},"production-considerations","Production Considerations",[21,1363,1364,1367,1370,1373,1376,1379],{},[24,1365,1366],{},"Use MySQL clustering or replication for high availability",[24,1368,1369],{},"Implement monitoring and alerting for both PowerDNS and MySQL",[24,1371,1372],{},"Set up secondary PowerDNS servers for redundancy",[24,1374,1375],{},"Configure proper firewall rules (UDP\u002FTCP port 53)",[24,1377,1378],{},"Implement rate limiting and DDoS protection",[24,1380,1381],{},"Regularly update Docker images and patch PowerDNS",[11,1383,1384],{},"Self-hosting DNS requires careful maintenance but provides maximum control and privacy.",[44,1386,1388],{"id":1387},"dns-troubleshooting-and-best-practices","DNS Troubleshooting and Best Practices",[11,1390,1391],{},"DNS issues can be frustrating but are usually solvable with systematic debugging.",[63,1393,1395],{"id":1394},"common-issues-and-solutions","Common Issues and Solutions",[777,1397,1399],{"id":1398},"slow-resolution","Slow Resolution",[21,1401,1402,1405,1411,1414],{},[24,1403,1404],{},"Check resolver performance",[24,1406,1407,1408],{},"Clear local DNS cache: ",[78,1409,1410],{},"sudo systemd-resolve --flush-caches",[24,1412,1413],{},"Switch to faster public resolvers",[24,1415,1416],{},"Check for network congestion",[777,1418,1420],{"id":1419},"nxdomain-errors","NXDOMAIN Errors",[21,1422,1423,1426,1429,1432],{},[24,1424,1425],{},"Verify domain registration status",[24,1427,1428],{},"Check for typos in domain names",[24,1430,1431],{},"Confirm authoritative servers are responding",[24,1433,1434],{},"Test with different resolvers",[777,1436,1438],{"id":1437},"propagation-delays","Propagation Delays",[11,1440,1441],{},"DNS changes can take 24-48 hours to propagate globally due to caching. Use tools like:",[71,1443,1445],{"className":73,"code":1444,"language":75,"meta":76,"style":76},"dig @8.8.8.8 example.com A\ndig @1.1.1.1 example.com A\n",[78,1446,1447,1458],{"__ignoreMap":76},[81,1448,1449,1451,1454,1456],{"class":83,"line":84},[81,1450,1339],{"class":87},[81,1452,1453],{"class":101}," @8.8.8.8",[81,1455,1239],{"class":101},[81,1457,1347],{"class":101},[81,1459,1460,1462,1465,1467],{"class":83,"line":95},[81,1461,1339],{"class":87},[81,1463,1464],{"class":101}," @1.1.1.1",[81,1466,1239],{"class":101},[81,1468,1347],{"class":101},[777,1470,1472],{"id":1471},"dns-leaks","DNS Leaks",[11,1474,1475],{},"When using VPNs, DNS queries might bypass the tunnel. Test with:",[71,1477,1479],{"className":73,"code":1478,"language":75,"meta":76,"style":76},"nslookup example.com\n",[78,1480,1481],{"__ignoreMap":76},[81,1482,1483,1485],{"class":83,"line":84},[81,1484,1352],{"class":87},[81,1486,1218],{"class":101},[11,1488,1489],{},"Should show VPN resolver IPs, not local ISP.",[63,1491,1493],{"id":1492},"best-practices","Best Practices",[777,1495,1497],{"id":1496},"for-domain-owners","For Domain Owners",[21,1499,1500,1503,1506,1509,1512],{},[24,1501,1502],{},"Use multiple authoritative servers for redundancy",[24,1504,1505],{},"Implement DNSSEC",[24,1507,1508],{},"Set appropriate TTL values (lower for dynamic content)",[24,1510,1511],{},"Monitor DNS performance and availability",[24,1513,1514],{},"Use CDN-integrated DNS for global performance",[777,1516,1518],{"id":1517},"for-developers","For Developers",[21,1520,1521,1524,1527,1530],{},[24,1522,1523],{},"Understand DNS in your application architecture",[24,1525,1526],{},"Implement proper error handling for DNS failures",[24,1528,1529],{},"Use connection pooling to reduce DNS lookups",[24,1531,1532],{},"Consider DNS prefetching in web applications",[777,1534,1536],{"id":1535},"for-system-administrators","For System Administrators",[21,1538,1539,1542,1545,1548,1551],{},[24,1540,1541],{},"Monitor DNS server logs for anomalies",[24,1543,1544],{},"Implement rate limiting to prevent abuse",[24,1546,1547],{},"Keep DNS software updated",[24,1549,1550],{},"Have backup DNS providers ready",[24,1552,1553],{},"Document your DNS configuration thoroughly",[11,1555,1556],{},"DNS reliability is crucial for internet availability. Regular monitoring and proactive maintenance prevent most issues.",[44,1558,1560],{"id":1559},"learning-resources","Learning Resources",[21,1562,1563,1572,1579,1586,1593,1600,1607],{},[24,1564,1565],{},[1566,1567,1571],"a",{"href":1568,"rel":1569},"https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc1035",[1570],"nofollow","RFC 1035 - Domain Names - Implementation and Specification",[24,1573,1574],{},[1566,1575,1578],{"href":1576,"rel":1577},"https:\u002F\u002Fwww.icann.org\u002Fdnssec",[1570],"DNSSEC Practice Statement",[24,1580,1581],{},[1566,1582,1585],{"href":1583,"rel":1584},"https:\u002F\u002Fdoc.powerdns.com\u002F",[1570],"PowerDNS Documentation",[24,1587,1588],{},[1566,1589,1592],{"href":1590,"rel":1591},"https:\u002F\u002Fwww.cloudflare.com\u002Flearning\u002Fdns\u002F",[1570],"Cloudflare Learning Center - DNS",[24,1594,1595],{},[1566,1596,1599],{"href":1597,"rel":1598},"https:\u002F\u002Fdnsmadeeasy.com\u002Fsupport\u002Fdns-glossary\u002F",[1570],"DNS Made Easy - DNS Glossary",[24,1601,1602],{},[1566,1603,1606],{"href":1604,"rel":1605},"https:\u002F\u002Fwww.nlnetlabs.nl\u002Fprojects\u002Fldns\u002F",[1570],"Practical DNSSEC",[24,1608,1609],{},[1566,1610,1613],{"href":1611,"rel":1612},"https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc8484",[1570],"DNS over HTTPS (DoH) RFC 8484",[44,1615,1617],{"id":1616},"conclusion","Conclusion",[11,1619,1620],{},"DNS is the unsung hero of the internet, silently translating human-readable names into machine-routable addresses billions of times per day. Its distributed, hierarchical design has proven remarkably resilient, scaling from a handful of hosts to billions of connected devices.",[11,1622,1623],{},"Understanding DNS goes beyond technical curiosity—it's essential for anyone working with internet technologies. Whether you're a developer troubleshooting connectivity issues, a system administrator designing resilient infrastructure, or simply a user wanting to understand how the web works, DNS knowledge is fundamental.",[11,1625,1626],{},"As the internet evolves with new protocols like DNS over HTTPS and DNSSEC adoption grows, DNS continues to adapt while maintaining its core principles of decentralization and reliability. The next time you type a URL into your browser, remember the complex, global infrastructure that makes it all possible.",[11,1628,1629],{},"DNS truly is the backbone of the World Wide Web.",[1631,1632,1633],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}",{"title":76,"searchDepth":95,"depth":95,"links":1635},[1636,1642,1647,1655,1665,1671,1677,1685,1689,1690],{"id":46,"depth":95,"text":47,"children":1637},[1638,1639,1640,1641],{"id":65,"depth":319,"text":66},{"id":166,"depth":319,"text":167},{"id":249,"depth":319,"text":250},{"id":291,"depth":319,"text":292},{"id":355,"depth":95,"text":356,"children":1643},[1644,1645,1646],{"id":362,"depth":319,"text":363},{"id":372,"depth":319,"text":373},{"id":402,"depth":319,"text":403},{"id":423,"depth":95,"text":424,"children":1648},[1649,1650,1651,1652,1653,1654],{"id":430,"depth":319,"text":431},{"id":437,"depth":319,"text":438},{"id":444,"depth":319,"text":445},{"id":454,"depth":319,"text":455},{"id":464,"depth":319,"text":465},{"id":474,"depth":319,"text":475},{"id":490,"depth":95,"text":491,"children":1656},[1657,1658,1659,1660,1661,1662,1663,1664],{"id":497,"depth":319,"text":498},{"id":512,"depth":319,"text":513},{"id":525,"depth":319,"text":526},{"id":538,"depth":319,"text":539},{"id":554,"depth":319,"text":555},{"id":567,"depth":319,"text":568},{"id":580,"depth":319,"text":581},{"id":593,"depth":319,"text":594},{"id":609,"depth":95,"text":610,"children":1666},[1667,1668,1669,1670],{"id":622,"depth":319,"text":623},{"id":643,"depth":319,"text":644},{"id":667,"depth":319,"text":668},{"id":703,"depth":319,"text":704},{"id":713,"depth":95,"text":714,"children":1672},[1673,1674,1675,1676],{"id":720,"depth":319,"text":721},{"id":750,"depth":319,"text":751},{"id":774,"depth":319,"text":775},{"id":807,"depth":319,"text":808},{"id":828,"depth":95,"text":829,"children":1678},[1679,1680,1681,1682,1683,1684],{"id":835,"depth":319,"text":836},{"id":1179,"depth":319,"text":1180},{"id":1190,"depth":319,"text":1191},{"id":1288,"depth":319,"text":1289},{"id":1325,"depth":319,"text":1326},{"id":1360,"depth":319,"text":1361},{"id":1387,"depth":95,"text":1388,"children":1686},[1687,1688],{"id":1394,"depth":319,"text":1395},{"id":1492,"depth":319,"text":1493},{"id":1559,"depth":95,"text":1560},{"id":1616,"depth":95,"text":1617},"2026-01-13","How DNS works at a global scale, real-world DNS architecture, and a walkthrough of self-hosting an authoritative DNS server with PowerDNS.",false,"md",{},"\u002Fblogs\u002Fdns_explained_the_backbone_of_the_world_wide_web",{"title":6,"description":1692},"blogs\u002Fdns_explained_the_backbone_of_the_world_wide_web\u002Findex",[1700,1701,1702,1703,1704,1705],"DNS","Networking","Infrastructure","PowerDNS","Self-hosting","Internet Protocols","pgiSwRqY8V4zd_XGWgti2-CEotu0Dv8TIDVw5nQR1c8",{"id":1708,"title":1709,"body":1710,"date":2954,"description":2955,"draft":1693,"extension":1694,"image":1727,"meta":2956,"navigation":977,"path":2957,"seo":2958,"stem":2959,"tags":2960,"__hash__":2964},"blogs\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Findex.md","What is a web server and role of nginx in it ?",{"type":8,"value":1711,"toc":2936},[1712,1716,1719,1722,1728,1732,1735,1749,1752,1755,1759,1762,1770,1773,1781,1784,1787,1807,1810,1814,1817,1820,1823,1829,1835,1838,1841,1844,1850,1853,1856,1860,1863,1866,1873,1879,1882,1885,1893,1896,1900,1903,1906,1912,1915,1918,1921,1924,1927,1930,1933,1936,1940,1943,1951,1956,1959,1963,1966,1969,1972,1975,1978,1981,1987,1990,1993,1997,2000,2003,2006,2009,2012,2017,2020,2024,2032,2035,2066,2069,2078,2080,2083,2093,2103,2134,2137,2153,2156,2160,2163,2177,2184,2190,2281,2288,2292,2295,2304,2307,2346,2352,2504,2508,2599,2602,2609,2655,2665,2676,2680,2683,2686,2710,2716,2809,2811,2815,2852,2855,2867,2869,2872,2879,2882,2900,2903,2906,2910,2933],[44,1713,1715],{"id":1714},"introduction","Introduction",[11,1717,1718],{},"The World Wide Web (WWW) was invented in 1989 by Tim Berners-Lee, but it wasn’t until 1991 that it became publicly available. Since then, the internet has evolved dramatically, with billions of users accessing websites daily. At the core of this communication lies the web server a foundational component that delivers content from a server to a user's browser.",[11,1720,1721],{},"Among the most popular web servers today is Nginx (pronounced engine-x), known for its high performance, scalability, and efficiency.",[11,1723,1724],{},[39,1725],{"alt":1726,"src":1727},"Nginx","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fnginx.png",[44,1729,1731],{"id":1730},"the-problem-it-solves","The problem it solves",[11,1733,1734],{},"Imagine writing a custom web server from scratch every time you build an application. You’d need to handle:",[339,1736,1737,1740,1743,1746],{},[24,1738,1739],{},"Networking (managing TCP connections, sockets, etc.)",[24,1741,1742],{},"HTTP protocol compliance (handling GET, POST, headers, caching)",[24,1744,1745],{},"Concurrency (serving thousands of clients at once)",[24,1747,1748],{},"Security (TLS\u002FSSL, request limits, filtering)",[11,1750,1751],{},"That’s a lot of work for something every developer needs.",[11,1753,1754],{},"Nginx solves this by providing reusable web server that works across programming languages and frameworks. Instead of reinventing the wheel, developers can let Nginx handle the web traffic while their application focuses on business logic.",[44,1756,1758],{"id":1757},"architecture","Architecture",[11,1760,1761],{},"At its core, Nginx follows a client-server model:",[21,1763,1764,1767],{},[24,1765,1766],{},"A client (Browser, API consumer, Mobile app) sends an HTTP request.",[24,1768,1769],{},"The server (Nginx) processes that request and sends a response.",[11,1771,1772],{},"Default Ports by convention on which all web servers listen:",[21,1774,1775,1778],{},[24,1776,1777],{},"Port 80 → HTTP",[24,1779,1780],{},"Port 443 → HTTPS (with SSL\u002FTLS)",[11,1782,1783],{},"NGINX acts as an intermediary between the client and the web services. It handles the client requests and routes it to the backend web service. It is also known as a reverse proxy and can load balance the request among multiple backend servers.",[11,1785,1786],{},"While NGINX solves most of the problems with traditional web service architecture, it still needs to solve:",[339,1788,1789,1795,1801],{},[24,1790,1791,1794],{},[149,1792,1793],{},"Concurrent connections"," - Large number of concurrent connections from clients.",[24,1796,1797,1800],{},[149,1798,1799],{},"Performance"," - No performance degradation with user growth.",[24,1802,1803,1806],{},[149,1804,1805],{},"Efficient resource utilization"," - Low memory usage and optimal CPU utilization.",[11,1808,1809],{},"Before diving into the solution, let’s revisit connection management basics and understand the scalability bottlenecks.",[63,1811,1813],{"id":1812},"how-are-the-connections-handled","How are the connections handled ?",[11,1815,1816],{},"When a web server starts, it calls the operating System and passes the port on which it listens. For e.g., Web servers would pass port 80 (http) or 443 (https) to listen.",[11,1818,1819],{},"When the client connects, the OS’s kernel stack performs a TCP handshake and establishes a connection. The OS assigns a file descriptor or a socket for each connection.",[11,1821,1822],{},"The below diagram shows the connection establishment between the client and the server:",[11,1824,1825],{},[39,1826],{"alt":1827,"src":1828},"client-connection","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fclient-connection.png",[11,1830,1831,1834],{},[149,1832,1833],{},"Note:"," NIC stands for Network interface card",[11,1836,1837],{},"By default, sending and receiving data over a network (Network I\u002FO) is blocking. A thread or a process goes into waiting state while writing or reading data to\u002Ffrom the network.",[11,1839,1840],{},"Also, the network I\u002FO is dependent on the client’s bandwidth. Data transfer may take a long time for slow clients.",[11,1842,1843],{},"The following diagram shows how a process waits until the complete data transfer:",[11,1845,1846],{},[39,1847],{"alt":1848,"src":1849},"data-transfer","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fdata-transfer.png",[11,1851,1852],{},"As a result, the server can’t accept new connections if it’s already processing request from a client. This hinders the system’s scalability and performance both.",[11,1854,1855],{},"There are several ways to tackle this problem and handle more connections. Let’s understand the different approaches and their limitations.",[63,1857,1859],{"id":1858},"process-per-request-approach","Process-Per-Request Approach",[11,1861,1862],{},"To overcome the network I\u002FO bottleneck, the process can fork a new child process. The child process would then handle a new client connection.",[11,1864,1865],{},"Every connection would correspond to a new child process. Once the request\u002Fresponse cycle is completed, the child process would be killed.",[11,1867,1868,1869],{},"The below diagram illustrates this process:\n",[39,1870],{"alt":1871,"src":1872},"process-per-request","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fprocess-per-request.png",[1874,1875,1876],"blockquote",{},[11,1877,1878],{},"Do you think this approach would scale to millions of users\u002Fconnections ? Take a moment to think and then continue reading",[11,1880,1881],{},"Let’s assume the server RAM size is 32 GB and each process takes 100 MB. So, then it can handle only 320 (32 GB\u002F 100 MB) connections in the best case.",[11,1883,1884],{},"Here are some downsides of this approach:",[21,1886,1887,1890],{},[24,1888,1889],{},"Scalability Issues - Number of connections depend on the hardware (RAM size). More connections would lead to out of memory issues.",[24,1891,1892],{},"Performance Issues - Forking a child process is slow and would impact the performance.",[11,1894,1895],{},"Can we do better ?  What if instead of forking a process, we launch a thread ? Let’s explore this approach in the next section.",[63,1897,1899],{"id":1898},"thread-per-request-approach","Thread-Per-Request Approach",[11,1901,1902],{},"In this approach, a thread is launched every time a client connection is established. Each request is handled independently by a different thread.",[11,1904,1905],{},"The below diagram shows how this model works:",[11,1907,1908],{},[39,1909],{"alt":1910,"src":1911},"thread-per-request","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fthread-per-request.png",[11,1913,1914],{},"Threads are lightweight and almost 1\u002F10th size of a process. As a result, this is a significant improvement from the Process-Per-Request approach.",[11,1916,1917],{},"While this approach can handle more number of connections, it would still run into issues highlighted in the previous section.",[11,1919,1920],{},"A process can’t launch an infinite number of threads. The benefits of multi-threading diminish with large number of threads due to frequent CPU context switching.",[11,1922,1923],{},"We can still improve by using a thread pool and launching a fixed number of threads. For eg:- 500 threads in the process.",[11,1925,1926],{},"This improvement would result in efficient memory usage. However, if all the threads are busy, the new connections would wait in the request queue resulting in slowness.",[11,1928,1929],{},"Hence, this approach also doesn’t solve for scalability and performance. We can’t scale since the primary bottleneck is the time-consuming network I\u002FO.",[11,1931,1932],{},"Is there a way to unblock the process or thread during the network I\u002FO ? Yes, and NGINX employs an intelligent tactic using its event-driven non-blocking I\u002FO.",[11,1934,1935],{},"Let’s understand NGINX’s architecture in detail in the next section.",[63,1937,1939],{"id":1938},"nginx-architecture","NGINX Architecture",[11,1941,1942],{},"NGINX uses a modular architecture and consists of several components such as:",[339,1944,1945,1948],{},[24,1946,1947],{},"Master process - It acts as the central controller and is responsible for starting, stopping, and launching the worker processes.",[24,1949,1950],{},"Worker processes - These run the core NGINX logic and are responsible for connection handling, request forwarding, load balancing, etc.",[11,1952,1953],{},[39,1954],{"alt":1938,"src":1955},"\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fnginx-architecture.png",[11,1957,1958],{},"Let’s now dive into the details of how NGINX can scale to million concurrent connections.",[777,1960,1962],{"id":1961},"event-driven-non-blocking-io","Event-driven Non-blocking I\u002FO",[11,1964,1965],{},"In case of non-blocking I\u002FO, the web server or the application doesn’t wait for the client’s data. Instead, the OS informs the application once the data is available.",[11,1967,1968],{},"This makes the process event-driven. Whenever the client’s data is available, the application would get interrupted and it would process the data. Otherwise, it would continue to do something else.",[11,1970,1971],{},"Further, the application doesn’t go into a waiting state. It can execute other tasks and efficiently utilize the CPU.",[11,1973,1974],{},"Internally, the application uses a system call called epoll or kqueue and then registers the sockets. The operating system uses a kernel data structure (Epoll instance) to keep track of the sockets that an application is interested in.",[11,1976,1977],{},"Once data is available in a subset of sockets, those sockets are moved into a ready list. The OS then informs the application about those sockets. Finally, the application then processes the data.",[11,1979,1980],{},"The below diagram illustrates this flow:",[11,1982,1983],{},[39,1984],{"alt":1985,"src":1986},"event-driven-io","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fevent-driven-io.png",[11,1988,1989],{},"As seen from the above diagram, once data becomes available on fd3, and fd4, the process is notified by the OS.",[11,1991,1992],{},"Let’s now understand this in the context of a NGINX worker.",[777,1994,1996],{"id":1995},"nginx-worker","Nginx worker",[11,1998,1999],{},"Each NGINX worker is single-threaded and it runs an event loop. The event loop works like a while loop and checks for any activity on the socket or new connections.",[11,2001,2002],{},"With non-blocking sockets, the worker doesn’t need to wait till the data is completely sent to the client. It can quickly move onto the next connection and process the request.",[11,2004,2005],{},"Since network I\u002FO is non-blocking, the process doesn’t wait for the data transfer. And the worker uses CPU only for request parsing, filtering and other compute operations.",[11,2007,2008],{},"Compute operations are less time-taking (in order of micro-seconds). As a result, a single worker can process 100K requests every second concurrently.",[11,2010,2011],{},"Assuming that a single worker can handle 100K connections, if it’s a 10-core CPU, the server can handle 1 million concurrent connections. (Example for illustration only, in real world, things might be different).",[1874,2013,2014],{},[11,2015,2016],{},"Note: A server must have sufficient memory to serve 1 million connections since each connection needs 100KB-1MB memory. But the OS kernel can be tuned to reduce the connection’s memory.(there are trade-offs to this approach)",[11,2018,2019],{},"The event-driven non-blocking I\u002FO efficiently utilizes the CPU and doesn’t consume memory like Process-Per-Request or Thread-Per-Request approach.",[44,2021,2023],{"id":2022},"installation","Installation",[11,2025,2026,2027],{},"Prerequisite: ",[1566,2028,2031],{"href":2029,"rel":2030},"https:\u002F\u002F9ovind.in\u002Fblogs\u002Fvirtualization_containers_and_role_of_docker_in_it\u002F#docker-installation-on-linux",[1570],"Docker",[11,2033,2034],{},"One of the simplest ways to install and run Nginx today is via Docker:",[71,2036,2038],{"className":73,"code":2037,"language":75,"meta":76,"style":76},"docker run --rm --name web_server -p 80:80 nginx\n",[78,2039,2040],{"__ignoreMap":76},[81,2041,2042,2045,2048,2051,2054,2057,2060,2063],{"class":83,"line":84},[81,2043,2044],{"class":87},"docker",[81,2046,2047],{"class":101}," run",[81,2049,2050],{"class":91}," --rm",[81,2052,2053],{"class":91}," --name",[81,2055,2056],{"class":101}," web_server",[81,2058,2059],{"class":91}," -p",[81,2061,2062],{"class":101}," 80:80",[81,2064,2065],{"class":101}," nginx\n",[11,2067,2068],{},"This pulls the latest Nginx image and starts a container listening on port 80.",[11,2070,2071,2072,2077],{},"Visit ",[1566,2073,2076],{"href":2074,"rel":2075},"http:\u002F\u002Flocalhost",[1570],"localhost"," in your Browser and you will see a nginx welcome page.",[44,2079,1180],{"id":1179},[11,2081,2082],{},"Nginx has one master process and several worker processes. The main purpose of the master process is to read and evaluate configuration, and maintain worker processes. Worker processes do actual processing of requests.",[11,2084,2085,2086,2089,2090,1187],{},"The way nginx and its modules work is determined in the configuration file. By default, the configuration file is named ",[78,2087,2088],{},"nginx.conf"," and placed in the directory ",[78,2091,2092],{},"\u002Fetc\u002Fnginx",[11,2094,2095,2096,2098,2099,2102],{},"To view the default configuration file ",[78,2097,2088],{},", you first need to exec into ",[78,2100,2101],{},"web_server"," container.",[71,2104,2106],{"className":73,"code":2105,"language":75,"meta":76,"style":76},"docker exec -it web_server bash\n\ncat \u002Fetc\u002Fnginx\u002Fnginx.conf\n",[78,2107,2108,2122,2126],{"__ignoreMap":76},[81,2109,2110,2112,2114,2117,2119],{"class":83,"line":84},[81,2111,2044],{"class":87},[81,2113,1206],{"class":101},[81,2115,2116],{"class":91}," -it",[81,2118,2056],{"class":101},[81,2120,2121],{"class":101}," bash\n",[81,2123,2124],{"class":83,"line":95},[81,2125,978],{"emptyLinePlaceholder":977},[81,2127,2128,2131],{"class":83,"line":319},[81,2129,2130],{"class":87},"cat",[81,2132,2133],{"class":101}," \u002Fetc\u002Fnginx\u002Fnginx.conf\n",[11,2135,2136],{},"Changes made in the configuration file will not be applied until the command to reload configuration is sent to nginx or it is restarted. To reload configuration, execute:",[71,2138,2140],{"className":73,"code":2139,"language":75,"meta":76,"style":76},"nginx -s reload\n",[78,2141,2142],{"__ignoreMap":76},[81,2143,2144,2147,2150],{"class":83,"line":84},[81,2145,2146],{"class":87},"nginx",[81,2148,2149],{"class":91}," -s",[81,2151,2152],{"class":101}," reload\n",[11,2154,2155],{},"Once the master process receives the signal to reload configuration, it checks the syntax validity of the new configuration file and tries to apply the configuration provided in it. If this is a success, the master process starts new worker processes and sends messages to old worker processes, requesting them to shut down. Otherwise, the master process rolls back the changes and continues to work with the old configuration. Old worker processes, receiving a command to shut down, stop accepting new connections and continue to service current requests until all such requests are serviced. After that, the old worker processes exit.",[63,2157,2159],{"id":2158},"configuration-file-structure","Configuration file structure",[11,2161,2162],{},"nginx consists of modules which are controlled by directives specified in the configuration file.\nDirectives are divided into:",[339,2164,2165,2171],{},[24,2166,2167,2170],{},[149,2168,2169],{},"Simple directives"," consists of the name and parameters separated by spaces and ends with a semicolon (;)",[24,2172,2173,2176],{},[149,2174,2175],{},"Block directives"," has the same structure as a simple directive, but instead of the semicolon it ends with a set of additional instructions surrounded by braces ({ and }).",[11,2178,2179,2180,2183],{},"If a block directive can have other directives inside braces, it is called a ",[149,2181,2182],{},"context",". Eg: events, http, server and location.",[11,2185,2186,2187,1187],{},"Directives placed in the configuration file outside of any contexts are considered to be in the ",[149,2188,2189],{},"main context",[71,2191,2195],{"className":2192,"code":2193,"language":2194,"meta":76,"style":76},"language-conf shiki shiki-themes github-light","# nginx.conf is the main context\n\n# simple directives\nuser nginx;\nworker_processes auto;\n\n# block directives\nevents {\n\n}\n\nhttp {\n    server {\n        location {\n\n        }\n    }\n}\n","conf",[78,2196,2197,2202,2206,2211,2216,2221,2225,2230,2235,2239,2244,2248,2253,2258,2263,2267,2272,2277],{"__ignoreMap":76},[81,2198,2199],{"class":83,"line":84},[81,2200,2201],{},"# nginx.conf is the main context\n",[81,2203,2204],{"class":83,"line":95},[81,2205,978],{"emptyLinePlaceholder":977},[81,2207,2208],{"class":83,"line":319},[81,2209,2210],{},"# simple directives\n",[81,2212,2213],{"class":83,"line":328},[81,2214,2215],{},"user nginx;\n",[81,2217,2218],{"class":83,"line":891},[81,2219,2220],{},"worker_processes auto;\n",[81,2222,2223],{"class":83,"line":899},[81,2224,978],{"emptyLinePlaceholder":977},[81,2226,2227],{"class":83,"line":910},[81,2228,2229],{},"# block directives\n",[81,2231,2232],{"class":83,"line":921},[81,2233,2234],{},"events {\n",[81,2236,2237],{"class":83,"line":931},[81,2238,978],{"emptyLinePlaceholder":977},[81,2240,2241],{"class":83,"line":942},[81,2242,2243],{},"}\n",[81,2245,2246],{"class":83,"line":950},[81,2247,978],{"emptyLinePlaceholder":977},[81,2249,2250],{"class":83,"line":959},[81,2251,2252],{},"http {\n",[81,2254,2255],{"class":83,"line":967},[81,2256,2257],{},"    server {\n",[81,2259,2260],{"class":83,"line":974},[81,2261,2262],{},"        location {\n",[81,2264,2265],{"class":83,"line":981},[81,2266,978],{"emptyLinePlaceholder":977},[81,2268,2269],{"class":83,"line":989},[81,2270,2271],{},"        }\n",[81,2273,2274],{"class":83,"line":999},[81,2275,2276],{},"    }\n",[81,2278,2279],{"class":83,"line":1006},[81,2280,2243],{},[11,2282,2283,2284,2287],{},"The rest of a line after the ",[78,2285,2286],{},"#"," sign is considered a comment.",[44,2289,2291],{"id":2290},"serving-static-content","Serving static content",[11,2293,2294],{},"An important web server task is serving out files (such as images or static HTML pages).",[11,2296,2297,2298,2301,2302,1187],{},"We will implement an example where files will be served from local directory: ",[78,2299,2300],{},"\u002Fvar\u002Fwww"," (which may contain HTML files and images). This will require editing of the configuration file ",[78,2303,2088],{},[11,2305,2306],{},"Create this file structure",[71,2308,2310],{"className":73,"code":2309,"language":75,"meta":76,"style":76},"nginx_example\u002F\n├── nginx.conf\n└── web_pages\n    └── index.html\n    └── image.png\n",[78,2311,2312,2317,2325,2332,2339],{"__ignoreMap":76},[81,2313,2314],{"class":83,"line":84},[81,2315,2316],{"class":87},"nginx_example\u002F\n",[81,2318,2319,2322],{"class":83,"line":95},[81,2320,2321],{"class":87},"├──",[81,2323,2324],{"class":101}," nginx.conf\n",[81,2326,2327,2329],{"class":83,"line":319},[81,2328,313],{"class":87},[81,2330,2331],{"class":101}," web_pages\n",[81,2333,2334,2336],{"class":83,"line":328},[81,2335,322],{"class":87},[81,2337,2338],{"class":101}," index.html\n",[81,2340,2341,2343],{"class":83,"line":891},[81,2342,322],{"class":87},[81,2344,2345],{"class":101}," image.png\n",[11,2347,2348,2349],{},"Put below content in ",[78,2350,2351],{},"index.html",[71,2353,2357],{"className":2354,"code":2355,"language":2356,"meta":76,"style":76},"language-html shiki shiki-themes github-light","\u003C!DOCTYPE html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n    \u003Cmeta charset=\"UTF-8\">\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    \u003Ctitle>Document\u003C\u002Ftitle>\n\u003C\u002Fhead>\n\u003Cbody>\n    \u003Ch1>Hello world from Nginx container\u003C\u002Fh1>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html",[78,2358,2359,2373,2391,2400,2418,2442,2456,2465,2474,2488,2496],{"__ignoreMap":76},[81,2360,2361,2364,2367,2370],{"class":83,"line":84},[81,2362,2363],{"class":859},"\u003C!",[81,2365,2366],{"class":855},"DOCTYPE",[81,2368,2369],{"class":87}," html",[81,2371,2372],{"class":859},">\n",[81,2374,2375,2378,2380,2383,2386,2389],{"class":83,"line":95},[81,2376,2377],{"class":859},"\u003C",[81,2379,2356],{"class":855},[81,2381,2382],{"class":87}," lang",[81,2384,2385],{"class":859},"=",[81,2387,2388],{"class":101},"\"en\"",[81,2390,2372],{"class":859},[81,2392,2393,2395,2398],{"class":83,"line":319},[81,2394,2377],{"class":859},[81,2396,2397],{"class":855},"head",[81,2399,2372],{"class":859},[81,2401,2402,2405,2408,2411,2413,2416],{"class":83,"line":328},[81,2403,2404],{"class":859},"    \u003C",[81,2406,2407],{"class":855},"meta",[81,2409,2410],{"class":87}," charset",[81,2412,2385],{"class":859},[81,2414,2415],{"class":101},"\"UTF-8\"",[81,2417,2372],{"class":859},[81,2419,2420,2422,2424,2427,2429,2432,2435,2437,2440],{"class":83,"line":891},[81,2421,2404],{"class":859},[81,2423,2407],{"class":855},[81,2425,2426],{"class":87}," name",[81,2428,2385],{"class":859},[81,2430,2431],{"class":101},"\"viewport\"",[81,2433,2434],{"class":87}," content",[81,2436,2385],{"class":859},[81,2438,2439],{"class":101},"\"width=device-width, initial-scale=1.0\"",[81,2441,2372],{"class":859},[81,2443,2444,2446,2449,2452,2454],{"class":83,"line":899},[81,2445,2404],{"class":859},[81,2447,2448],{"class":855},"title",[81,2450,2451],{"class":859},">Document\u003C\u002F",[81,2453,2448],{"class":855},[81,2455,2372],{"class":859},[81,2457,2458,2461,2463],{"class":83,"line":910},[81,2459,2460],{"class":859},"\u003C\u002F",[81,2462,2397],{"class":855},[81,2464,2372],{"class":859},[81,2466,2467,2469,2472],{"class":83,"line":921},[81,2468,2377],{"class":859},[81,2470,2471],{"class":855},"body",[81,2473,2372],{"class":859},[81,2475,2476,2478,2481,2484,2486],{"class":83,"line":931},[81,2477,2404],{"class":859},[81,2479,2480],{"class":855},"h1",[81,2482,2483],{"class":859},">Hello world from Nginx container\u003C\u002F",[81,2485,2480],{"class":855},[81,2487,2372],{"class":859},[81,2489,2490,2492,2494],{"class":83,"line":942},[81,2491,2460],{"class":859},[81,2493,2471],{"class":855},[81,2495,2372],{"class":859},[81,2497,2498,2500,2502],{"class":83,"line":950},[81,2499,2460],{"class":859},[81,2501,2356],{"class":855},[81,2503,2372],{"class":859},[11,2505,2348,2506],{},[78,2507,2088],{},[71,2509,2511],{"className":2192,"code":2510,"language":2194,"meta":76,"style":76},"user nginx;\nworker_processes auto;\n\nevents {\n\n}\n\nhttp {\n    server {\n        listen 80;\n        server_name _;\n\n        root \u002Fvar\u002Fwww;\n        index index.html index.htm;\n\n        location \u002F {\n            try_files $uri $uri\u002F =404;\n        }\n    }\n}\n",[78,2512,2513,2517,2521,2525,2529,2533,2537,2541,2545,2549,2554,2559,2563,2568,2573,2577,2582,2587,2591,2595],{"__ignoreMap":76},[81,2514,2515],{"class":83,"line":84},[81,2516,2215],{},[81,2518,2519],{"class":83,"line":95},[81,2520,2220],{},[81,2522,2523],{"class":83,"line":319},[81,2524,978],{"emptyLinePlaceholder":977},[81,2526,2527],{"class":83,"line":328},[81,2528,2234],{},[81,2530,2531],{"class":83,"line":891},[81,2532,978],{"emptyLinePlaceholder":977},[81,2534,2535],{"class":83,"line":899},[81,2536,2243],{},[81,2538,2539],{"class":83,"line":910},[81,2540,978],{"emptyLinePlaceholder":977},[81,2542,2543],{"class":83,"line":921},[81,2544,2252],{},[81,2546,2547],{"class":83,"line":931},[81,2548,2257],{},[81,2550,2551],{"class":83,"line":942},[81,2552,2553],{},"        listen 80;\n",[81,2555,2556],{"class":83,"line":950},[81,2557,2558],{},"        server_name _;\n",[81,2560,2561],{"class":83,"line":959},[81,2562,978],{"emptyLinePlaceholder":977},[81,2564,2565],{"class":83,"line":967},[81,2566,2567],{},"        root \u002Fvar\u002Fwww;\n",[81,2569,2570],{"class":83,"line":974},[81,2571,2572],{},"        index index.html index.htm;\n",[81,2574,2575],{"class":83,"line":981},[81,2576,978],{"emptyLinePlaceholder":977},[81,2578,2579],{"class":83,"line":989},[81,2580,2581],{},"        location \u002F {\n",[81,2583,2584],{"class":83,"line":999},[81,2585,2586],{},"            try_files $uri $uri\u002F =404;\n",[81,2588,2589],{"class":83,"line":1006},[81,2590,2271],{},[81,2592,2593],{"class":83,"line":1017},[81,2594,2276],{},[81,2596,2597],{"class":83,"line":1028},[81,2598,2243],{},[11,2600,2601],{},"Now let's stop our previous nginx container and run new one with new configurations.",[11,2603,2604,2605,2608],{},"But before running below command please make sure you are in ",[78,2606,2607],{},"nginx_example"," folder.",[71,2610,2612],{"className":73,"code":2611,"language":75,"meta":76,"style":76},"cd nginx_example\n\ndocker run --rm --name web_server -p 80:80 -v .\u002Fweb_pages:\u002Fvar\u002Fwww -v .\u002Fnginx.conf:\u002Fetc\u002Fnginx\u002Fnginx.conf nginx\n",[78,2613,2614,2622,2626],{"__ignoreMap":76},[81,2615,2616,2619],{"class":83,"line":84},[81,2617,2618],{"class":91},"cd",[81,2620,2621],{"class":101}," nginx_example\n",[81,2623,2624],{"class":83,"line":95},[81,2625,978],{"emptyLinePlaceholder":977},[81,2627,2628,2630,2632,2634,2636,2638,2640,2642,2645,2648,2650,2653],{"class":83,"line":319},[81,2629,2044],{"class":87},[81,2631,2047],{"class":101},[81,2633,2050],{"class":91},[81,2635,2053],{"class":91},[81,2637,2056],{"class":101},[81,2639,2059],{"class":91},[81,2641,2062],{"class":101},[81,2643,2644],{"class":91}," -v",[81,2646,2647],{"class":101}," .\u002Fweb_pages:\u002Fvar\u002Fwww",[81,2649,2644],{"class":91},[81,2651,2652],{"class":101}," .\u002Fnginx.conf:\u002Fetc\u002Fnginx\u002Fnginx.conf",[81,2654,2065],{"class":101},[11,2656,2071,2657,2660,2661],{},[1566,2658,2074],{"href":2074,"rel":2659},[1570]," in your Browser and you will see this page\n",[39,2662],{"alt":2663,"src":2664},"nginx-hello-world","\u002Fimages\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Fnginx-hello-world.png",[11,2666,2667,2668,2671,2672],{},"You can also view image file you have put in ",[78,2669,2670],{},"web_pages"," folder by visiting ",[1566,2673,2674],{"href":2674,"rel":2675},"http:\u002F\u002Flocalhost\u002Fimage.png",[1570],[44,2677,2679],{"id":2678},"reverse-proxy","Reverse proxy",[11,2681,2682],{},"One of the frequent uses of nginx is setting it up as a proxy server, which means a server that receives requests, passes them to the proxied servers, retrieves responses from them, and sends them to the clients.",[11,2684,2685],{},"We will configure a basic proxy server, which servers requests of other websites with our custom url like:",[339,2687,2688,2700],{},[24,2689,2690,2694,2695,2699],{},[1566,2691,2692],{"href":2692,"rel":2693},"http:\u002F\u002Flocalhost\u002Fexample",[1570]," will serve ",[1566,2696,2697],{"href":2697,"rel":2698},"https:\u002F\u002Fexample.com",[1570]," page",[24,2701,2702,2694,2706,2699],{},[1566,2703,2704],{"href":2704,"rel":2705},"http:\u002F\u002Flocalhost\u002Fwiki",[1570],[1566,2707,2708],{"href":2708,"rel":2709},"https:\u002F\u002Fwww.wikipedia.org",[1570],[11,2711,2712,2713,2715],{},"Put the below content in ",[78,2714,2088],{}," file",[71,2717,2719],{"className":2192,"code":2718,"language":2194,"meta":76,"style":76},"user nginx;\nworker_processes auto;\n\nevents {\n\n}\n\nhttp {\n    server {\n        listen 80;\n        server_name _;\n\n        location \u002Fexample\u002F {\n            proxy_pass https:\u002F\u002Fexample.com\u002F;\n        }\n\n        location \u002Fwiki\u002F {\n            proxy_pass https:\u002F\u002Fwww.wikipedia.org\u002F;\n        }\n    }\n}\n",[78,2720,2721,2725,2729,2733,2737,2741,2745,2749,2753,2757,2761,2765,2769,2774,2779,2783,2787,2792,2797,2801,2805],{"__ignoreMap":76},[81,2722,2723],{"class":83,"line":84},[81,2724,2215],{},[81,2726,2727],{"class":83,"line":95},[81,2728,2220],{},[81,2730,2731],{"class":83,"line":319},[81,2732,978],{"emptyLinePlaceholder":977},[81,2734,2735],{"class":83,"line":328},[81,2736,2234],{},[81,2738,2739],{"class":83,"line":891},[81,2740,978],{"emptyLinePlaceholder":977},[81,2742,2743],{"class":83,"line":899},[81,2744,2243],{},[81,2746,2747],{"class":83,"line":910},[81,2748,978],{"emptyLinePlaceholder":977},[81,2750,2751],{"class":83,"line":921},[81,2752,2252],{},[81,2754,2755],{"class":83,"line":931},[81,2756,2257],{},[81,2758,2759],{"class":83,"line":942},[81,2760,2553],{},[81,2762,2763],{"class":83,"line":950},[81,2764,2558],{},[81,2766,2767],{"class":83,"line":959},[81,2768,978],{"emptyLinePlaceholder":977},[81,2770,2771],{"class":83,"line":967},[81,2772,2773],{},"        location \u002Fexample\u002F {\n",[81,2775,2776],{"class":83,"line":974},[81,2777,2778],{},"            proxy_pass https:\u002F\u002Fexample.com\u002F;\n",[81,2780,2781],{"class":83,"line":981},[81,2782,2271],{},[81,2784,2785],{"class":83,"line":989},[81,2786,978],{"emptyLinePlaceholder":977},[81,2788,2789],{"class":83,"line":999},[81,2790,2791],{},"        location \u002Fwiki\u002F {\n",[81,2793,2794],{"class":83,"line":1006},[81,2795,2796],{},"            proxy_pass https:\u002F\u002Fwww.wikipedia.org\u002F;\n",[81,2798,2799],{"class":83,"line":1017},[81,2800,2271],{},[81,2802,2803],{"class":83,"line":1028},[81,2804,2276],{},[81,2806,2807],{"class":83,"line":1037},[81,2808,2243],{},[11,2810,2601],{},[11,2812,2604,2813,2608],{},[78,2814,2607],{},[71,2816,2818],{"className":73,"code":2817,"language":75,"meta":76,"style":76},"cd nginx_example\n\ndocker run --rm --name web_server -p 80:80 -v .\u002Fnginx.conf:\u002Fetc\u002Fnginx\u002Fnginx.conf nginx\n",[78,2819,2820,2826,2830],{"__ignoreMap":76},[81,2821,2822,2824],{"class":83,"line":84},[81,2823,2618],{"class":91},[81,2825,2621],{"class":101},[81,2827,2828],{"class":83,"line":95},[81,2829,978],{"emptyLinePlaceholder":977},[81,2831,2832,2834,2836,2838,2840,2842,2844,2846,2848,2850],{"class":83,"line":319},[81,2833,2044],{"class":87},[81,2835,2047],{"class":101},[81,2837,2050],{"class":91},[81,2839,2053],{"class":91},[81,2841,2056],{"class":101},[81,2843,2059],{"class":91},[81,2845,2062],{"class":101},[81,2847,2644],{"class":91},[81,2849,2652],{"class":101},[81,2851,2065],{"class":101},[11,2853,2854],{},"In your browser visit:",[339,2856,2857,2862],{},[24,2858,2859],{},[1566,2860,2692],{"href":2692,"rel":2861},[1570],[24,2863,2864],{},[1566,2865,2704],{"href":2704,"rel":2866},[1570],[44,2868,1617],{"id":1616},[11,2870,2871],{},"For me, learning about Nginx was more than just understanding another tool. it gave me clarity on how the internet really works behind the scenes.",[11,2873,2874,2875,2878],{},"At first, I always thought a ",[78,2876,2877],{},"web server"," was just something that shows HTML files, but now I realize it’s the backbone that keeps websites fast, reliable, and secure.",[11,2880,2881],{},"While experimenting, I personally liked:",[21,2883,2884,2887,2894,2897],{},[24,2885,2886],{},"How easy it was to run Nginx inside Docker with just one command.",[24,2888,2889,2890,2893],{},"The simplicity of serving my own ",[78,2891,2892],{},"Hello World"," page in a container.",[24,2895,2896],{},"Seeing reverse proxy in action which felt powerful because it showed how requests can be routed seamlessly.",[24,2898,2899],{},"The event handling architecture of nginx is just pure engineering.",[11,2901,2902],{},"Overall, I find Nginx not only useful for production systems but also a great learning tool to understand networking, load balancing, and scalability.",[11,2904,2905],{},"Writing this blog was part of my journey to simplify these concepts, and I hope it helps others get started with Nginx the way I did.",[44,2907,2909],{"id":2908},"resources","Resources",[339,2911,2912,2919,2926],{},[24,2913,2914],{},[1566,2915,2918],{"href":2916,"rel":2917},"https:\u002F\u002Fnginx.org\u002Fen\u002Fdocs\u002F",[1570],"Nginx Documnetation",[24,2920,2921],{},[1566,2922,2925],{"href":2923,"rel":2924},"https:\u002F\u002Fyoutu.be\u002FiInUBOVeBCc?si=ztRXCbfg0F_bA3Wy",[1570],"NGINX Explained - What is Nginx",[24,2927,2928],{},[1566,2929,2932],{"href":2930,"rel":2931},"https:\u002F\u002Fyoutu.be\u002FvVYM2QBk-iQ?si=QVLyA99kDAkAFKM-",[1570],"NGINX Internal Architecture - Workers",[1631,2934,2935],{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}",{"title":76,"searchDepth":95,"depth":95,"links":2937},[2938,2939,2940,2946,2947,2950,2951,2952,2953],{"id":1714,"depth":95,"text":1715},{"id":1730,"depth":95,"text":1731},{"id":1757,"depth":95,"text":1758,"children":2941},[2942,2943,2944,2945],{"id":1812,"depth":319,"text":1813},{"id":1858,"depth":319,"text":1859},{"id":1898,"depth":319,"text":1899},{"id":1938,"depth":319,"text":1939},{"id":2022,"depth":95,"text":2023},{"id":1179,"depth":95,"text":1180,"children":2948},[2949],{"id":2158,"depth":319,"text":2159},{"id":2290,"depth":95,"text":2291},{"id":2678,"depth":95,"text":2679},{"id":1616,"depth":95,"text":1617},{"id":2908,"depth":95,"text":2909},"2025-10-01","What web servers actually do, how Nginx handles thousands of concurrent connections with its event-driven architecture, and how to configure it for real workloads.",{},"\u002Fblogs\u002Fwhat_is_web_server_and_nginx_role_in_it",{"title":1709,"description":2955},"blogs\u002Fwhat_is_web_server_and_nginx_role_in_it\u002Findex",[2961,2962,2044,2963,2146,2877],"programming language","computer science","containerization","SNVQNRezGJ1LUEXpZHQtts_rpxbgJO-CzCKf_-vu_7M",{"id":2966,"title":2967,"body":2968,"date":4028,"description":4029,"draft":1693,"extension":1694,"image":3000,"meta":4030,"navigation":977,"path":4031,"seo":4032,"stem":4033,"tags":4034,"__hash__":4039},"blogs\u002Fblogs\u002Fssl_and_tls\u002Findex.md","A Deep Dive into SSL\u002FTLS: The Protocols That Secure the Internet",{"type":8,"value":2969,"toc":4010},[2970,2973,2992,2995,3001,3004,3010,3014,3017,3037,3052,3058,3062,3090,3096,3100,3103,3205,3211,3214,3224,3227,3230,3233,3237,3240,3243,3246,3311,3317,3321,3324,3350,3354,3357,3428,3431,3435,3450,3453,3506,3509,3513,3516,3521,3524,3537,3543,3546,3551,3560,3566,3571,3574,3620,3625,3628,3670,3674,3680,3683,3709,3712,3716,3722,3725,3739,3750,3754,3760,3763,3770,3806,3818,3822,3828,3835,3838,3941,3945,3952,3991,3994,3996,4005,4007],[11,2971,2972],{},"SSL (Secure Sockets Layer) and its successor, TLS (Transport Layer Security), are the cryptographic protocols that secure data transmitted over the Internet. They ensure:",[21,2974,2975,2981,2987],{},[24,2976,2977,2980],{},[149,2978,2979],{},"Confidentiality:"," Your data is only accessible to the client and server.",[24,2982,2983,2986],{},[149,2984,2985],{},"Integrity:"," Your data is not altered in transit.",[24,2988,2989,2991],{},[149,2990,737],{}," You are communicating with the real server.",[11,2993,2994],{},"When you see the padlock icon in your browser, that’s TLS protecting your connection.",[11,2996,2997],{},[39,2998],{"alt":2999,"src":3000},"TLS","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fconnection_secure.jpg",[11,3002,3003],{},"SSL was the original protocol developed at Netscape in 1994, but it is now obsolete due to security flaws. TLS is its modern, secure successor. Today, when people say \"SSL,\" they almost always mean \"TLS.\" The current version, TLS 1.3, is faster and more secure than its predecessors.",[11,3005,3006],{},[39,3007],{"alt":3008,"src":3009},"TLS history","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Ftls_history.png",[44,3011,3013],{"id":3012},"the-internet-a-network-of-networks","The Internet: A Network of Networks",[11,3015,3016],{},"At its core, the Internet is not one big \"thing\" owned by a single company. it’s thousands of independent networks connected together. These networks belong to:",[21,3018,3019,3022,3025,3028,3031,3034],{},[24,3020,3021],{},"Internet Service Providers (ISPs)",[24,3023,3024],{},"Telecom companies",[24,3026,3027],{},"Cloud providers (e.g., AWS, Azure, GCP)",[24,3029,3030],{},"Enterprises",[24,3032,3033],{},"Governments",[24,3035,3036],{},"Universities",[11,3038,3039,3040,3045,3046,3051],{},"Each network is called an ",[1566,3041,3044],{"href":3042,"rel":3043},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAutonomous_system_(Internet)",[1570],"Autonomous System"," (AS), and they peer with each other using protocols like ",[1566,3047,3050],{"href":3048,"rel":3049},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBorder_Gateway_Protocol",[1570],"Border Gateway Protocol"," (BGP) to share routes.",[11,3053,3054],{},[39,3055],{"alt":3056,"src":3057},"The internet","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fbgp.jpeg",[63,3059,3061],{"id":3060},"what-is-an-autonomous-system-as","What is an Autonomous System (AS)?",[21,3063,3064,3067,3070,3073],{},[24,3065,3066],{},"An Autonomous System is a collection of IP networks (prefixes) that are managed by a single organization and that share a common routing policy.",[24,3068,3069],{},"Each AS has a globally unique number called an Autonomous System Number (ASN).",[24,3071,3072],{},"Routers inside an AS speak internal routing protocols (like OSPF, IS-IS, or iBGP), and communicate with other AS using BGP (Border Gateway Protocol).",[24,3074,3075,3076],{},"Example:\n",[339,3077,3078,3081,3084,3087],{},[24,3079,3080],{},"Google (AS15169)",[24,3082,3083],{},"Cloudflare (AS13335)",[24,3085,3086],{},"Jio(AS55836)",[24,3088,3089],{},"Airtel(AS9498)",[11,3091,3092],{},[39,3093],{"alt":3094,"src":3095},"Autonomous system","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fas_network.png",[63,3097,3099],{"id":3098},"why-asns-matter-and-who-assigns-it","Why ASNs matter and who Assigns it ?",[11,3101,3102],{},"There is a hierarchy of organizations that manage Internet number resources (IP addresses and ASNs):",[339,3104,3105,3119,3167,3194],{},[24,3106,3107,3108],{},"IANA (Internet Assigned Numbers Authority)",[21,3109,3110,3113,3116],{},[24,3111,3112],{},"IANA is at the top level.",[24,3114,3115],{},"It manages global IP address space and ASN pools.",[24,3117,3118],{},"It is operated by ICANN (Internet Corporation for Assigned Names and Numbers).",[24,3120,3121,3122],{},"RIRs (Regional Internet Registries)",[21,3123,3124,3127,3135,3143,3151,3159],{},[24,3125,3126],{},"IANA delegates blocks of IP addresses and ASN ranges to 5 RIRs, each covering a specific region:",[24,3128,3129,3134],{},[1566,3130,3133],{"href":3131,"rel":3132},"https:\u002F\u002Farin.net",[1570],"ARIN"," (North America)",[24,3136,3137,3142],{},[1566,3138,3141],{"href":3139,"rel":3140},"https:\u002F\u002Flacnic.net",[1570],"LACNIC"," (Latin America & Caribbean)",[24,3144,3145,3150],{},[1566,3146,3149],{"href":3147,"rel":3148},"https:\u002F\u002Fripe.net",[1570],"RIPE NCC"," (Europe, Middle East, parts of Central Asia)",[24,3152,3153,3158],{},[1566,3154,3157],{"href":3155,"rel":3156},"https:\u002F\u002Fapnic.net",[1570],"APNIC"," (Asia Pacific)",[24,3160,3161,3166],{},[1566,3162,3165],{"href":3163,"rel":3164},"https:\u002F\u002Fafrinic.net",[1570],"AFRINIC"," (Africa)",[24,3168,3169,3170],{},"NIRs (National Internet Registries)",[21,3171,3172,3175],{},[24,3173,3174],{},"In some regions, there are National Internet Registries (NIRs) that further manage allocation within a country.",[24,3176,3177,3178],{},"For example these are some NIRs operating under APNIC:\n",[21,3179,3180,3188,3191],{},[24,3181,3182,3187],{},[1566,3183,3186],{"href":3184,"rel":3185},"https:\u002F\u002Fwww.irinn.in\u002F",[1570],"IRINN",", Indian Registry for Internet Names and Numbers",[24,3189,3190],{},"CNNIC, China Internet Network Information Center",[24,3192,3193],{},"JPNIC, Japan Network Information Center",[24,3195,3196,3197],{},"Local ISPs, Enterprises, Organizations",[21,3198,3199,3202],{},[24,3200,3201],{},"These entities apply to their RIR or NIR to request an ASN.\n-They must justify why they need an ASN (usually because they plan to run BGP with other networks).",[24,3203,3204],{},"Once assigned, they are globally registered.",[11,3206,3207],{},[39,3208],{"alt":3209,"src":3210},"IANA","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fiana.jpeg",[11,3212,3213],{},"Every BGP router announces IP prefixes with its ASN as it helps establish routing policies, peering agreements, and routing decisions.",[11,3215,3216,3217,3219,3220],{},"When you visit ",[78,3218,130],{},", your data may flow through:\n",[39,3221],{"alt":3222,"src":3223},"ASNs traffic","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fasn_traffic.png",[11,3225,3226],{},"Each router uses BGP to decide how to route traffic across AS boundaries.",[11,3228,3229],{},"Since your packets cross multiple ASes you don’t control. Any compromised router in any AS could inspect or modify unencrypted traffic.",[11,3231,3232],{},"TLS ensures that even though your data flows through all these ASes, only you and the server can read it.",[44,3234,3236],{"id":3235},"how-ssltls-protects-your-data","How SSL\u002FTLS protects your data ?",[11,3238,3239],{},"When you connect to a website over HTTPS, TLS works behind the scenes to secure your connection.",[11,3241,3242],{},"Since your data is flowing through someone else networks and routers to the destination server anyone in midle can read and write to the data.",[11,3244,3245],{},"TLS protects your data in three key ways:",[339,3247,3248,3271,3291],{},[24,3249,3250,3251],{},"Confidentiality",[21,3252,3253,3256,3262,3265,3268],{},[24,3254,3255],{},"Data is only accessible by client and server.",[24,3257,3258,3259,1187],{},"TLS achieves confidentiality through a cryptographic technique called ",[78,3260,3261],{},"Encryption",[24,3263,3264],{},"TLS encrypts all the data you send and receive.",[24,3266,3267],{},"Even if someone intercepts your traffic (e.g. ISP, hacker, rogue router), they only see scrambled, unreadable data.",[24,3269,3270],{},"Only your browser and the server have the keys to decrypt the data.",[24,3272,3273,3274],{},"Integrity",[21,3275,3276,3279,3285,3288],{},[24,3277,3278],{},"Data hasn't been modified between client and server.",[24,3280,3281,3282,1187],{},"TLS achieves integrity through a cryptographic technique called ",[78,3283,3284],{},"Hashing",[24,3286,3287],{},"TLS ensures that the data hasn't been tampered with during transmission but it does't prevent from modification.",[24,3289,3290],{},"If any data is altered, it will be detected instantly and the connection will fail.",[24,3292,3293,3294],{},"Authentication",[21,3295,3296,3299,3305,3308],{},[24,3297,3298],{},"Client and server are indeed who they say they are.",[24,3300,3301,3302,1187],{},"TLS achieves authentication through a system called ",[78,3303,3304],{},"PKI (Pulbic key infrastructure)",[24,3306,3307],{},"TLS verifies the identity of the server using digital certificates issued by trusted Certificate Authorities (CAs).",[24,3309,3310],{},"This prevents attackers from impersonating a real website (e.g., phishing, man-in-the-middle attacks).",[11,3312,3313],{},[39,3314],{"alt":3315,"src":3316},"TLS 3 ways","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Ftls_3_ways.png",[44,3318,3320],{"id":3319},"key-players-of-ssl-tls","Key players of SSL & TLS",[11,3322,3323],{},"Understanding TLS requires knowing the three main actors involved in the process:",[339,3325,3326,3332,3344],{},[24,3327,3328,3331],{},[149,3329,3330],{},"The Client",": This is the application that initiates the secure connection. Most commonly, this is your web browser (like Chrome, Firefox, or Safari) when you visit a website. However, it can be any application that needs to communicate securely, such as an email client or a mobile app.",[24,3333,3334,3337,3338,177,3340,3343],{},[149,3335,3336],{},"The Server",": This is the machine that the client wants to communicate with. It hosts the website or service (e.g., ",[78,3339,130],{},[78,3341,3342],{},"your-bank.com","). The server holds the digital certificate and the private key necessary to prove its identity and establish a secure connection.",[24,3345,3346,3349],{},[149,3347,3348],{},"The Certificate Authority (CA)",": A Certificate Authority is a trusted third-party organization that issues digital certificates. Its job is to verify the identity of the server's owner before issuing a certificate. This is crucial for the \"Authentication\" part of TLS. When you browser sees a certificate from a trusted CA (like Let's Encrypt, DigiCert, or GlobalSign), it knows it can trust that the server is who it claims to be. Your browser and operating system come with a pre-installed list of trusted CAs.",[44,3351,3353],{"id":3352},"server-verification-and-certificate-types","Server Verification and Certificate Types",[11,3355,3356],{},"Before a Certificate Authority (CA) issues a certificate, it must verify that the entity requesting it is who they say they are. The rigor of this verification process determines the type of certificate issued. This is crucial for establishing trust. There are three main levels of validation:",[339,3358,3359,3384,3406],{},[24,3360,3361,3364],{},[149,3362,3363],{},"Domain Validation (DV) Certificates:",[21,3365,3366,3372,3378],{},[24,3367,3368,3371],{},[149,3369,3370],{},"Verification Level:"," This is the most basic level of validation. The CA only verifies that the applicant controls the domain name. This is usually done by email verification, adding a DNS record, or uploading a specific file to the website.",[24,3373,3374,3377],{},[149,3375,3376],{},"Trust Level:"," It confirms that your connection is encrypted and that you are connected to the correct domain, but it doesn't verify who owns the domain.",[24,3379,3380,3383],{},[149,3381,3382],{},"Best for:"," Blogs, personal websites, and small projects where identity assurance is not a high priority. Let's Encrypt is a popular provider of free DV certificates.",[24,3385,3386,3389],{},[149,3387,3388],{},"Organization Validation (OV) Certificates:",[21,3390,3391,3396,3401],{},[24,3392,3393,3395],{},[149,3394,3370],{}," This involves a more substantial vetting process. The CA verifies not only domain control but also the legal existence and details of the organization (e.g., name, city, country). This requires submitting business registration documents.",[24,3397,3398,3400],{},[149,3399,3376],{}," Provides a higher level of trust by confirming the identity of the legal entity behind the website. Users can view these details in the certificate information in their browser.",[24,3402,3403,3405],{},[149,3404,3382],{}," E-commerce sites, public-facing corporate websites, and services that handle sensitive user information.",[24,3407,3408,3411],{},[149,3409,3410],{},"Extended Validation (EV) Certificates:",[21,3412,3413,3418,3423],{},[24,3414,3415,3417],{},[149,3416,3370],{}," This is the highest level of validation and involves a strict, globally standardized vetting process defined by the CA\u002FBrowser Forum. The CA performs a thorough background check on the organization, verifying its legal, physical, and operational existence.",[24,3419,3420,3422],{},[149,3421,3376],{}," Offers the highest level of trust and assurance. In the past, browsers would display the company's name in a green address bar, though this UI has been mostly phased out. Still, the verified company name is visible in the certificate details.",[24,3424,3425,3427],{},[149,3426,3382],{}," Financial institutions (banks), government agencies, and large enterprises where proving identity and building user trust is paramount.",[11,3429,3430],{},"Choosing the right certificate type depends on the website's purpose and the level of trust it needs to establish with its users.",[44,3432,3434],{"id":3433},"encryption-and-confidentiality","Encryption and Confidentiality",[11,3436,3437,3438,3441,3442,3445,3446,3449],{},"Encryption is the process of converting plaintext data into a scrambled, unreadable format called ",[149,3439,3440],{},"ciphertext",". This is the core mechanism TLS uses to ensure ",[149,3443,3444],{},"confidentiality",". Only parties with the correct ",[149,3447,3448],{},"key"," can decrypt the ciphertext back into its original, readable form.",[11,3451,3452],{},"TLS cleverly uses two types of encryption:",[339,3454,3455,3490],{},[24,3456,3457,3460],{},[149,3458,3459],{},"Asymmetric Encryption (Public-Key Cryptography):",[21,3461,3462,3472,3475,3483],{},[24,3463,3464,3465,3468,3469,1187],{},"This involves a pair of keys: a ",[149,3466,3467],{},"public key"," and a ",[149,3470,3471],{},"private key",[24,3473,3474],{},"The public key can be shared with anyone. The private key must be kept secret by the owner (in this case, the server).",[24,3476,3477,3478,3482],{},"Data encrypted with the public key can ",[3479,3480,3481],"em",{},"only"," be decrypted with the corresponding private key.",[24,3484,3485,3486,3489],{},"TLS uses asymmetric encryption during the initial ",[149,3487,3488],{},"handshake"," to securely exchange a key for symmetric encryption. This is crucial for establishing a secure channel without having to pre-share a secret.",[24,3491,3492,3495],{},[149,3493,3494],{},"Symmetric Encryption:",[21,3496,3497,3500,3503],{},[24,3498,3499],{},"This uses a single, shared secret key for both encryption and decryption.",[24,3501,3502],{},"It is much faster and more efficient for encrypting large amounts of data than asymmetric encryption.",[24,3504,3505],{},"Once the initial handshake is complete, the client and server use the securely exchanged symmetric key to encrypt all the actual application data (like your HTTP requests and the website's responses).",[11,3507,3508],{},"By combining these two methods, TLS gets the best of both worlds: the secure key exchange capability of asymmetric encryption and the high performance of symmetric encryption for the bulk of the data transfer.",[44,3510,3512],{"id":3511},"a-closer-look-at-asymmetric-encryption-how-rsa-works","A Closer Look at Asymmetric Encryption: How RSA Works",[11,3514,3515],{},"The RSA (Rivest-Shamir-Adleman) algorithm is the most well-known asymmetric encryption algorithm. Its security is based on the practical difficulty of factoring the product of two large prime numbers.",[11,3517,3518],{},[149,3519,3520],{},"The Core Concept: A Mailbox Analogy",[11,3522,3523],{},"Imagine you have a special mailbox with two keys:",[21,3525,3526,3532],{},[24,3527,3528,3529,3531],{},"A ",[149,3530,3467],{}," (the mailbox slot): You can make copies of this key and give it to anyone. Anyone with this key can open the slot and drop a message in.",[24,3533,3528,3534,3536],{},[149,3535,3471],{}," (the mailbox door key): This key is yours alone. It is the only key that can open the mailbox door to retrieve the messages.",[11,3538,3539],{},[39,3540],{"alt":3541,"src":3542},"RSA Mailbox Analogy","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Frsa_email_analogy.webp",[11,3544,3545],{},"This is the essence of RSA. The server's public key is like the mailbox slot, and its private key is the only thing that can unlock the messages sent to it.",[11,3547,3548],{},[149,3549,3550],{},"A Demo: RSA in Action",[11,3552,3553,3554,3556,3557,3559],{},"Let's see how this is used for both ",[149,3555,3250],{}," (encryption) and ",[149,3558,3293],{}," (digital signatures).",[11,3561,3562],{},[39,3563],{"alt":3564,"src":3565},"Signature vs. Encryption","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fencryption_vs_signature.png",[11,3567,3568],{},[149,3569,3570],{},"1. For Confidentiality (Encrypting the Session Key):",[11,3572,3573],{},"This is the primary role of RSA in the TLS handshake.",[21,3575,3576,3584,3590,3599,3605,3614],{},[24,3577,3578,3581,3582,1187],{},[149,3579,3580],{},"Step 1:"," The Server sends its certificate to the Client. This certificate contains the Server's ",[149,3583,3467],{},[24,3585,3586,3589],{},[149,3587,3588],{},"Step 2:"," The Client generates a small, random piece of data (the \"pre-master secret\") that will be used to create the final session key.",[24,3591,3592,3595,3596,3598],{},[149,3593,3594],{},"Step 3:"," The Client uses the Server's ",[149,3597,3467],{}," to encrypt this pre-master secret. Now, it's just scrambled, unreadable data.",[24,3600,3601,3604],{},[149,3602,3603],{},"Step 4:"," The Client sends this encrypted data to the Server.",[24,3606,3607,3610,3611,3613],{},[149,3608,3609],{},"Step 5:"," The Server uses its ",[149,3612,3471],{}," to decrypt the data and retrieve the pre-master secret. No one else could have done this, because no one else has the private key.",[24,3615,3616,3619],{},[149,3617,3618],{},"Result:"," Both the Client and Server now share a secret, which they use to independently generate the same symmetric session key. Confidentiality is achieved.",[11,3621,3622],{},[149,3623,3624],{},"2. For Authentication (How a CA Signs a Certificate):",[11,3626,3627],{},"RSA also works in reverse for digital signatures, which is how a CA guarantees a certificate is authentic.",[21,3629,3630,3635,3640,3651,3656,3665],{},[24,3631,3632,3634],{},[149,3633,3580],{}," A server owner gives their certificate information (domain name, public key, etc.) to a Certificate Authority (CA).",[24,3636,3637,3639],{},[149,3638,3588],{}," The CA creates a hash of all that information.",[24,3641,3642,3644,3645,3647,3648,1187],{},[149,3643,3594],{}," The CA uses its own ",[149,3646,3471],{}," to encrypt that hash. This encrypted hash is the ",[149,3649,3650],{},"digital signature",[24,3652,3653,3655],{},[149,3654,3603],{}," The CA attaches this signature to the certificate and sends it back to the server owner.",[24,3657,3658,3661,3662,3664],{},[149,3659,3660],{},"Step 5 (Verification):"," When your browser receives the certificate, it sees it was signed by the CA. Your browser already trusts this CA and has its ",[149,3663,3467],{},". It uses the CA's public key to decrypt the signature, revealing the original hash. It then computes its own hash of the certificate. If the two hashes match, the signature is valid.",[24,3666,3667,3669],{},[149,3668,3618],{}," Your browser has just mathematically proven that the certificate is authentic and has not been tampered with. Authentication is achieved.",[44,3671,3673],{"id":3672},"hashing-hashing-algorithms-and-collisions","Hashing, Hashing algorithms and Collisions",[11,3675,3676,3677,1187],{},"Hashing is a fundamental concept in cryptography that ensures data integrity. It's the process of taking an input (of any size) and running it through a mathematical function to produce a fixed-size output string, known as a ",[149,3678,3679],{},"hash",[11,3681,3682],{},"A good hashing algorithm is:",[21,3684,3685,3691,3697,3703],{},[24,3686,3687,3690],{},[149,3688,3689],{},"Deterministic",": The same input will always produce the same hash.",[24,3692,3693,3696],{},[149,3694,3695],{},"Efficient",": The hash is quick to compute.",[24,3698,3699,3702],{},[149,3700,3701],{},"Pre-image Resistant",": It's computationally impossible to determine the original input from its hash. This makes it a one-way function.",[24,3704,3705,3708],{},[149,3706,3707],{},"Collision Resistant",": It should be extremely difficult to find two different inputs that produce the same hash.",[11,3710,3711],{},"Common hashing algorithms include SHA-256 (Secure Hash Algorithm 256-bit), which is widely used today. Older algorithms like MD5 and SHA-1 are now considered insecure because \"collisions\" have been found. A collision means two different inputs produce the same hash, which can allow an attacker to pass off a malicious file as a legitimate one.",[44,3713,3715],{"id":3714},"data-integrity-how-tls-uses-hashing","Data integrity - How TLS uses Hashing",[11,3717,3718,3719,1187],{},"So how does TLS use hashing to ensure data hasn't been tampered with? It uses a clever mechanism called an ",[149,3720,3721],{},"HMAC (Hash-based Message Authentication Code)",[11,3723,3724],{},"Here’s how it works:",[339,3726,3727,3730,3733,3736],{},[24,3728,3729],{},"During the initial TLS handshake, the client and server securely negotiate a shared secret key.",[24,3731,3732],{},"For every message they exchange, the sender combines the message content with the secret key and then hashes the result. This creates the HMAC, which is attached to the message.",[24,3734,3735],{},"The receiver gets the message and the HMAC. It independently computes its own HMAC using the message content and the shared secret key it already has.",[24,3737,3738],{},"If the received HMAC matches the one it just computed, the data is considered authentic and unaltered. If they don't match, the connection is terminated immediately, as this indicates tampering.",[11,3740,3741,3742,3745,3746,3749],{},"This process guarantees both ",[149,3743,3744],{},"integrity"," (the data wasn't changed) and ",[149,3747,3748],{},"authentication"," (we know who sent it, because only they have the secret key).",[44,3751,3753],{"id":3752},"what-is-a-cipher-suite","What is a Cipher Suite?",[11,3755,3756],{},[39,3757],{"alt":3758,"src":3759},"Cipher Suite Bundle","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Fcipher.png",[11,3761,3762],{},"A cipher suite is a bundle of algorithms that, together, provide all the security guarantees of TLS. Think of it as a single name that defines the exact tools for the job. During the handshake, the client sends a list of cipher suites it supports (its \"menu\" of security options), and the server chooses the one it prefers, usually the strongest one they both support.",[11,3764,3765,3766,3769],{},"A typical cipher suite name, like ",[78,3767,3768],{},"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",", looks complex, but it's just a combination of four distinct types of algorithms, each mapping directly to a core TLS goal:",[339,3771,3772,3782,3790,3798],{},[24,3773,3774,3777,3778,3781],{},[149,3775,3776],{},"Key Exchange Algorithm (ECDHE):"," This algorithm's job is to let the client and server securely agree on a shared secret key for symmetric encryption, even if someone is listening in. This is the foundation for confidentiality. Using an \"ephemeral\" method like ECDHE provides ",[149,3779,3780],{},"Perfect Forward Secrecy",", meaning past conversations remain secure even if the server's long-term key is compromised later.",[24,3783,3784,3787,3788,1187],{},[149,3785,3786],{},"Authentication Algorithm (RSA):"," This determines how the server proves its identity to the client. The server uses this algorithm (e.g., RSA) to sign its certificate, proving it owns the corresponding private key. This directly provides ",[149,3789,3293],{},[24,3791,3792,3795,3796,1187],{},[149,3793,3794],{},"Bulk Encryption Algorithm (AES_128_GCM):"," This is the high-speed symmetric cipher that will encrypt all the actual data (your requests, the website's content, etc.) after the handshake is complete. This provides ",[149,3797,3250],{},[24,3799,3800,3803,3804,1187],{},[149,3801,3802],{},"Hashing Algorithm (SHA256):"," This algorithm is used to create a Message Authentication Code (MAC), which is like a tamper-proof seal on every message. This provides ",[149,3805,3273],{},[11,3807,3808,3809,3811,3812,3814,3815,3817],{},"So, the cipher suite is the complete package. By agreeing on one, the client and server are explicitly defining how they will achieve ",[149,3810,3293],{},", ",[149,3813,3250],{},", and ",[149,3816,3273],{}," for the entire session.",[44,3819,3821],{"id":3820},"the-tls-handshake","The TLS Handshake",[11,3823,3824],{},[39,3825],{"alt":3826,"src":3827},"TLS Handshake Flow","\u002Fimages\u002Fblogs\u002Fssl_and_tls\u002Ftls-handshake.png",[11,3829,3830,3831,3834],{},"Now that we understand the key players and the types of encryption, let's walk through how they all come together in the ",[149,3832,3833],{},"TLS handshake",". This is the negotiation process that happens in milliseconds before any actual data is sent. The goal is simple: for the client and server to verify each other and securely agree on a session key for symmetric encryption.",[11,3836,3837],{},"Here’s a simplified look at the steps (for TLS 1.2, as it's a bit more explicit for learning, though TLS 1.3 is faster and more common today):",[339,3839,3840,3857,3874,3894,3923],{},[24,3841,3842,3845,3846],{},[149,3843,3844],{},"Client Hello",": The client sends a \"hello\" message to the server. This message includes:",[21,3847,3848,3851,3854],{},[24,3849,3850],{},"The TLS versions it supports.",[24,3852,3853],{},"A list of cipher suites it can use (the combination of encryption, authentication, and hashing algorithms).",[24,3855,3856],{},"A random string of bytes, known as the \"Client Random.\"",[24,3858,3859,3862,3863],{},[149,3860,3861],{},"Server Hello",": The server receives the client's hello and responds with its own \"hello\" message. This includes:",[21,3864,3865,3868,3871],{},[24,3866,3867],{},"The TLS version and cipher suite it has chosen from the client's list.",[24,3869,3870],{},"Its digital certificate, which contains its public key.",[24,3872,3873],{},"Another random string of bytes, the \"Server Random.\"",[24,3875,3876,3879,3880],{},[149,3877,3878],{},"Certificate Verification",": The client examines the server's certificate. It checks:",[21,3881,3882,3885,3891],{},[24,3883,3884],{},"Is the certificate expired?",[24,3886,3887,3888,3890],{},"Is it for the correct domain (",[78,3889,130],{},", etc.)?",[24,3892,3893],{},"Is it signed by a Certificate Authority (CA) that the client trusts? (The client checks this against its built-in list of trusted CAs).\nIf any of these checks fail, the browser will show a security warning, and the connection is terminated.",[24,3895,3896,3899,3900],{},[149,3897,3898],{},"Key Exchange",": This is the clever part. The client generates another random string of bytes called the \"Pre-Master Secret.\"",[21,3901,3902,3908,3911,3917],{},[24,3903,3904,3905,3907],{},"The client encrypts this Pre-Master Secret using the server's ",[149,3906,3467],{}," (which it got from the certificate).",[24,3909,3910],{},"The client sends this encrypted Pre-Master Secret to the server.",[24,3912,3913,3914,3916],{},"Because it was encrypted with the public key, only the server, with its corresponding ",[149,3915,3471],{},", can decrypt it.",[24,3918,3919,3920,1187],{},"Now, both the client and server use the Client Random, Server Random, and the Pre-Master Secret to independently calculate the same ",[149,3921,3922],{},"session key",[24,3924,3925,3928,3929],{},[149,3926,3927],{},"Handshake Complete & Secure Communication",": The handshake is now finished.",[21,3930,3931,3934],{},[24,3932,3933],{},"Both client and server send a \"Finished\" message, which is encrypted with the newly created session key.",[24,3935,3936,3937,3940],{},"From this point on, all communication between the client and server is encrypted using this ",[149,3938,3939],{},"symmetric session key",", ensuring confidentiality and integrity for the rest of the session.",[44,3942,3944],{"id":3943},"how-to-inspect-a-websites-certificate","How to Inspect a Website's Certificate",[11,3946,3947,3948,3951],{},"Everything we've discussed is visible right in your browser. This is the best way to see how these concepts apply in the real world. Try this on any ",[78,3949,3950],{},"https:\u002F\u002F"," site:",[339,3953,3954,3960,3966],{},[24,3955,3956,3959],{},[149,3957,3958],{},"Click the Padlock:"," In your browser's address bar, click the padlock icon to the left of the website's URL.",[24,3961,3962,3965],{},[149,3963,3964],{},"View the Certificate:"," Look for an option that says \"Connection is secure,\" which will lead to a \"Certificate is valid\" button. Clicking this will open the certificate viewer.",[24,3967,3968,3971],{},[149,3969,3970],{},"What to Look For:",[21,3972,3973,3979,3985],{},[24,3974,3975,3978],{},[149,3976,3977],{},"Issued To:"," You'll see the \"Common Name\" (the domain the certificate belongs to) and often the organization's name, city, and country (for OV and EV certificates).",[24,3980,3981,3984],{},[149,3982,3983],{},"Issued By:"," This shows you which Certificate Authority (CA) verified and signed the certificate.",[24,3986,3987,3990],{},[149,3988,3989],{},"Validity Period:"," You can see the \"Not Before\" and \"Not After\" dates.",[11,3992,3993],{},"By doing this, you can directly see the results of the TLS handshake and verify the identity and security of the websites you visit.",[44,3995,1560],{"id":1559},[21,3997,3998],{},[24,3999,4000],{},[1566,4001,4004],{"href":4002,"rel":4003},"https:\u002F\u002Fyoutube.com\u002Fplaylist?list=PLIFyRwBY_4bTwRX__Zn4-letrtpSj1mzY&si=B5eft0GSTFOQ_d31",[1570],"Practical TLS Playlist",[44,4006,1617],{"id":1616},[11,4008,4009],{},"SSL\u002FTLS is a cornerstone of modern internet security. It works silently in the background, providing the essential guarantees of confidentiality, integrity, and authentication. While the process is complex, the result is a secure channel that protects our sensitive information from prying eyes and tampering.",{"title":76,"searchDepth":95,"depth":95,"links":4011},[4012,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027],{"id":3012,"depth":95,"text":3013,"children":4013},[4014,4015],{"id":3060,"depth":319,"text":3061},{"id":3098,"depth":319,"text":3099},{"id":3235,"depth":95,"text":3236},{"id":3319,"depth":95,"text":3320},{"id":3352,"depth":95,"text":3353},{"id":3433,"depth":95,"text":3434},{"id":3511,"depth":95,"text":3512},{"id":3672,"depth":95,"text":3673},{"id":3714,"depth":95,"text":3715},{"id":3752,"depth":95,"text":3753},{"id":3820,"depth":95,"text":3821},{"id":3943,"depth":95,"text":3944},{"id":1559,"depth":95,"text":1560},{"id":1616,"depth":95,"text":1617},"2025-06-29","A comprehensive guide to understanding SSL, TLS, and the cryptographic protocols that ensure confidentiality, integrity, and authentication on the web.",{},"\u002Fblogs\u002Fssl_and_tls",{"title":2967,"description":4029},"blogs\u002Fssl_and_tls\u002Findex",[2999,4035,4036,4037,4038,1705],"SSL","HTTPS","Cryptography","Cybersecurity","knGjGGxsR4ep66di6DJhalhSC9oTNyzTAwP3Ge2Pw9A",[4041,4209,4296],{"id":4042,"title":4043,"body":4044,"category":4192,"date":4193,"description":4194,"draft":1693,"extension":1694,"github":4195,"meta":4196,"navigation":977,"path":4197,"seo":4198,"status":4199,"stem":4200,"tags":4201,"url":4207,"__hash__":4208},"projects\u002Fprojects\u002Fkedarkul\u002Findex.md","Kedarkul",{"type":8,"value":4045,"toc":4187},[4046,4049,4052,4056,4082,4086,4092,4098,4104,4110,4116,4120],[11,4047,4048],{},"Kedarkul is a school management platform built for the way Indian schools actually work. It replaces the scattered mix of registers, spreadsheets, and WhatsApp forwards that most school offices depend on, with one system that covers the full school lifecycle from the day a student applies to the day they graduate.",[11,4050,4051],{},"Each school gets its own private workspace at their subdomain. Data is fully isolated and what's inside one school is never mixed with another.",[44,4053,4055],{"id":4054},"who-uses-it","Who uses it",[21,4057,4058,4064,4070,4076],{},[24,4059,4060,4063],{},[149,4061,4062],{},"School administrators"," manage admissions, fee collection, staff records, and day-to-day operations",[24,4065,4066,4069],{},[149,4067,4068],{},"Teachers"," mark attendance, enter marks, and share notices from any device",[24,4071,4072,4075],{},[149,4073,4074],{},"Parents"," get fee receipts, report cards, and school announcements without having to visit in person",[24,4077,4078,4081],{},[149,4079,4080],{},"Management"," gets a clear picture of enrollment, fee dues, and school performance",[44,4083,4085],{"id":4084},"what-it-covers","What it covers",[11,4087,4088,4091],{},[149,4089,4090],{},"Admissions:"," Online application forms, document uploads, and shortlisting. No more physical files or missed follow-ups.",[11,4093,4094,4097],{},[149,4095,4096],{},"Fee management:"," Define fee structures by class, collect payments, generate receipts, and track dues. Reduces the back-and-forth between parents and the accounts desk.",[11,4099,4100,4103],{},[149,4101,4102],{},"Attendance:"," Daily student and staff attendance with class-wise reports. Late arrivals, absences, and monthly summaries at a glance.",[11,4105,4106,4109],{},[149,4107,4108],{},"Results & gradebook:"," Exam setup, marks entry, and automatic report card generation. Teachers enter marks; the system does the rest.",[11,4111,4112,4115],{},[149,4113,4114],{},"Noticeboard:"," Announcements and circulars reach parents and staff instantly, without relying on the school diary or WhatsApp groups.",[44,4117,4119],{"id":4118},"tech-stack","Tech Stack",[4121,4122,4123,4136],"table",{},[4124,4125,4126],"thead",{},[4127,4128,4129,4133],"tr",{},[4130,4131,4132],"th",{},"Layer",[4130,4134,4135],{},"Technology",[4137,4138,4139,4148,4156,4164,4172,4180],"tbody",{},[4127,4140,4141,4145],{},[4142,4143,4144],"td",{},"Backend",[4142,4146,4147],{},"Node.js + Express",[4127,4149,4150,4153],{},[4142,4151,4152],{},"Frontend",[4142,4154,4155],{},"Vue.js 3 + Vite",[4127,4157,4158,4161],{},[4142,4159,4160],{},"Database",[4142,4162,4163],{},"MySQL (per-school isolation)",[4127,4165,4166,4169],{},[4142,4167,4168],{},"Cache & queues",[4142,4170,4171],{},"Redis",[4127,4173,4174,4177],{},[4142,4175,4176],{},"Object storage",[4142,4178,4179],{},"MinIO",[4127,4181,4182,4184],{},[4142,4183,1702],{},[4142,4185,4186],{},"Kubernetes, ArgoCD, GitHub Actions",{"title":76,"searchDepth":95,"depth":95,"links":4188},[4189,4190,4191],{"id":4054,"depth":95,"text":4055},{"id":4084,"depth":95,"text":4085},{"id":4118,"depth":95,"text":4119},"SaaS · Education","2026-06-28","School management SaaS built for Indian schools. Admissions, fees, attendance, results, and communication in one place, without the spreadsheet chaos.",null,{},"\u002Fprojects\u002Fkedarkul",{"title":4043,"description":4194},"live","projects\u002Fkedarkul\u002Findex",[4202,4203,4204,4171,4179,4205,4206],"Node.js","Vue.js","MySQL","Kubernetes","ArgoCD","kedarkul.com","2volZ2p9glRbKqkJsf4xNTG1p5GcUSOa07h3vYzIEfs",{"id":4210,"title":4211,"body":4212,"category":4285,"date":4286,"description":4287,"draft":1693,"extension":1694,"github":4195,"meta":4288,"navigation":977,"path":4289,"seo":4290,"status":4199,"stem":4291,"tags":4292,"url":4294,"__hash__":4295},"projects\u002Fprojects\u002Fhope-studio\u002Findex.md","Hope Studio",{"type":8,"value":4213,"toc":4280},[4214,4217,4221,4235,4237,4273,4277],[11,4215,4216],{},"Hope Studio is a photography portfolio and booking website. The design is intentionally minimal, putting the work front and centre while making it easy for potential clients to get in touch.",[44,4218,4220],{"id":4219},"what-it-does","What it does",[21,4222,4223,4226,4229,4232],{},[24,4224,4225],{},"Showcases the studio's photography portfolio",[24,4227,4228],{},"Clean, fast-loading gallery pages",[24,4230,4231],{},"Contact and enquiry section for bookings",[24,4233,4234],{},"Fully responsive across mobile and desktop",[44,4236,4119],{"id":4118},[4121,4238,4239,4247],{},[4124,4240,4241],{},[4127,4242,4243,4245],{},[4130,4244,4132],{},[4130,4246,4135],{},[4137,4248,4249,4257,4265],{},[4127,4250,4251,4254],{},[4142,4252,4253],{},"Framework",[4142,4255,4256],{},"Nuxt.js (Vue 3)",[4127,4258,4259,4262],{},[4142,4260,4261],{},"Styling",[4142,4263,4264],{},"Tailwind CSS",[4127,4266,4267,4270],{},[4142,4268,4269],{},"Hosting",[4142,4271,4272],{},"Static, deployed via Nginx",[44,4274,4276],{"id":4275},"design-approach","Design approach",[11,4278,4279],{},"The brief was simple: get out of the way of the photos. The site uses a lot of whitespace, minimal UI chrome, and lets the photography speak for itself. Load times are a priority since large images are common.",{"title":76,"searchDepth":95,"depth":95,"links":4281},[4282,4283,4284],{"id":4219,"depth":95,"text":4220},{"id":4118,"depth":95,"text":4119},{"id":4275,"depth":95,"text":4276},"Web · Photography","2026-06-25","Portfolio and booking site for a photography studio. Minimal design focused on showcasing work and converting visitors into clients.",{},"\u002Fprojects\u002Fhope-studio",{"title":4211,"description":4287},"projects\u002Fhope-studio\u002Findex",[4293,4264,4203],"Nuxt.js","hope.9ovind.in","1boaoIS2ion-kMV4WFW5dfh3IHBJUzZmoIB9exm2DBc",{"id":4297,"title":4298,"body":4299,"category":4519,"date":4520,"description":4521,"draft":1693,"extension":1694,"github":4522,"meta":4523,"navigation":977,"path":4524,"seo":4525,"status":4199,"stem":4526,"tags":4527,"url":4195,"__hash__":4531},"projects\u002Fprojects\u002Fdotfiles\u002Findex.md","Dotfiles",{"type":8,"value":4300,"toc":4514},[4301,4304,4308,4330,4341,4345,4351,4356,4415,4421,4427,4446,4450,4456,4459,4504,4511],[11,4302,4303],{},"A developer machine bootstrap toolkit. Run one command on a fresh machine and get a fully configured development environment in minutes: shell, editor, tmux, Kubernetes tools, runtimes, and GUI apps all set up automatically via Ansible.",[44,4305,4307],{"id":4306},"quick-start","Quick Start",[71,4309,4311],{"className":73,"code":4310,"language":75,"meta":76,"style":76},"curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002F9ovindyadav\u002Fdotfiles\u002Fmain\u002Fbootstrap.sh | bash\n",[78,4312,4313],{"__ignoreMap":76},[81,4314,4315,4318,4321,4324,4328],{"class":83,"line":84},[81,4316,4317],{"class":87},"curl",[81,4319,4320],{"class":91}," -fsSL",[81,4322,4323],{"class":101}," https:\u002F\u002Fraw.githubusercontent.com\u002F9ovindyadav\u002Fdotfiles\u002Fmain\u002Fbootstrap.sh",[81,4325,4327],{"class":4326},"sD7c4"," |",[81,4329,2121],{"class":87},[11,4331,4332,4333,4336,4337,4340],{},"The script installs ",[78,4334,4335],{},"git"," and ",[78,4338,4339],{},"ansible",", clones the repo, and runs the full playbook automatically.",[44,4342,4344],{"id":4343},"what-gets-installed","What gets installed",[11,4346,4347,4350],{},[149,4348,4349],{},"System packages:"," git, vim, tmux, fzf, jq, htop, curl, rsync, podman, build-essential, gnupg",[11,4352,4353],{},[149,4354,4355],{},"Development runtimes",[4121,4357,4358,4371],{},[4124,4359,4360],{},[4127,4361,4362,4365,4368],{},[4130,4363,4364],{},"Runtime",[4130,4366,4367],{},"Manager",[4130,4369,4370],{},"Version",[4137,4372,4373,4383,4394,4405],{},[4127,4374,4375,4377,4380],{},[4142,4376,4202],{},[4142,4378,4379],{},"NVM",[4142,4381,4382],{},"24",[4127,4384,4385,4388,4391],{},[4142,4386,4387],{},"Java",[4142,4389,4390],{},"SDKMAN",[4142,4392,4393],{},"27",[4127,4395,4396,4399,4402],{},[4142,4397,4398],{},"Go",[4142,4400,4401],{},"Direct binary",[4142,4403,4404],{},"1.26.4",[4127,4406,4407,4409,4412],{},[4142,4408,2031],{},[4142,4410,4411],{},"Official script",[4142,4413,4414],{},"Latest",[11,4416,4417,4420],{},[149,4418,4419],{},"Kubernetes tools:"," kubectl, helm, k9s",[11,4422,4423,4426],{},[149,4424,4425],{},"GUI apps:"," Brave, Bitwarden, Zed, Sublime Merge, VLC",[11,4428,4429,4432,4433,3811,4436,3811,4439,3811,4442,4445],{},[149,4430,4431],{},"Dotfiles:"," ",[78,4434,4435],{},".bashrc",[78,4437,4438],{},".vimrc",[78,4440,4441],{},".tmux.conf",[78,4443,4444],{},".gitconfig",", all symlinked via GNU Stow",[44,4447,4449],{"id":4448},"structure","Structure",[71,4451,4454],{"className":4452,"code":4453,"language":507},[505],"ansible\u002F\n└── roles\u002F\n    ├── packages\u002F   # apt packages\n    ├── dotfiles\u002F   # stow symlinks\n    ├── tools\u002F      # runtimes + k8s tools\n    └── apps\u002F       # GUI applications\n",[78,4455,4453],{"__ignoreMap":76},[11,4457,4458],{},"Run selectively with tags:",[71,4460,4462],{"className":73,"code":4461,"language":75,"meta":76,"style":76},"# Fast setup — packages and dotfiles only\nansible-playbook ansible\u002Fplaybook.yml --tags packages,dotfiles\n\n# Kubernetes tools only\nansible-playbook ansible\u002Fplaybook.yml --tags tools\n",[78,4463,4464,4470,4484,4488,4493],{"__ignoreMap":76},[81,4465,4466],{"class":83,"line":84},[81,4467,4469],{"class":4468},"sAwPA","# Fast setup — packages and dotfiles only\n",[81,4471,4472,4475,4478,4481],{"class":83,"line":95},[81,4473,4474],{"class":87},"ansible-playbook",[81,4476,4477],{"class":101}," ansible\u002Fplaybook.yml",[81,4479,4480],{"class":91}," --tags",[81,4482,4483],{"class":101}," packages,dotfiles\n",[81,4485,4486],{"class":83,"line":319},[81,4487,978],{"emptyLinePlaceholder":977},[81,4489,4490],{"class":83,"line":328},[81,4491,4492],{"class":4468},"# Kubernetes tools only\n",[81,4494,4495,4497,4499,4501],{"class":83,"line":891},[81,4496,4474],{"class":87},[81,4498,4477],{"class":101},[81,4500,4480],{"class":91},[81,4502,4503],{"class":101}," tools\n",[11,4505,4506,4507,4510],{},"Versions are centralised in ",[78,4508,4509],{},"ansible\u002Froles\u002Ftools\u002Fvars\u002Fmain.yml",". Change one file to standardise a runtime version across the whole team.",[1631,4512,4513],{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":76,"searchDepth":95,"depth":95,"links":4515},[4516,4517,4518],{"id":4306,"depth":95,"text":4307},{"id":4343,"depth":95,"text":4344},{"id":4448,"depth":95,"text":4449},"DevOps · Open Source","2026-06-21","One command on a fresh machine gets you a fully configured development environment. Shell, editor, tmux, Kubernetes tools, runtimes, and apps, all set up automatically via Ansible.","https:\u002F\u002Fgithub.com\u002F9ovindyadav\u002Fdotfiles",{},"\u002Fprojects\u002Fdotfiles",{"title":4298,"description":4521},"projects\u002Fdotfiles\u002Findex",[4528,4529,4530,4205,2031],"Ansible","Bash","Linux","0p1Ln9vSRR6BhMNf7_85EGU1Be8bREA9_yFguDvQIfk",1782668618372]