[{"data":1,"prerenderedAt":820},["ShallowReactive",2],{"nav_featured_podcast":3,"nav_featured_press_release":21,"navigation_content":30,"engineering_blog_post:nat-and-proxies-part-1":378},{"uid":4,"title":5,"episodeLabel":6,"dateLabel":7,"episodeArt":8,"href":20},"from-payment-rails-to-connectivity","From Payment Rails to Connectivity, with The Clearing House's David Watson","EPISODE 5","August 18, 2026",{"dimensions":9,"alt":12,"copyright":13,"url":14,"id":15,"edit":16},{"width":10,"height":11},1064,652,"Payments Cannot Fail — Episode 05 with David Watson",null,"\u002F_prismic-media\u002Fd80df2e47c3ecb6f-cFcyPAgzKCMQEaND_Episode-05-David.jpg","cFcyPAgzKCMQEaND",{"x":17,"y":17,"zoom":18,"background":19},0,1,"transparent","\u002Fresources\u002Fpodcasts\u002Ffrom-payment-rails-to-connectivity",{"uid":22,"title":23,"tag":24,"dateLabel":25,"imageUrl":26,"imageAlt":27,"href":28,"imageFit":29},"form3-expands-strategic-partnership-with-sumup","Form3 expands strategic partnership with SumUp to bring real-time SEPA payments to millions of European small businesses","EU","February 25, 2026","\u002F_prismic-media\u002F3e91177f91478610-QA44Gzev0_tdg3ZI_SumUp.jpg","sumup","\u002Fresources\u002Fpress-releases\u002Fform3-expands-strategic-partnership-with-sumup","cover",{"header":31,"platform":59,"solutions":91,"developers":133,"company":155,"resources":184,"partnerships":208,"footer":220,"mobile":325},{"ctaLabel":32,"ctaHref":33,"topNav":34},"TALK TO OUR TEAM","\u002Fcontact",[35,39,43,47,51,55],{"label":36,"href":37,"key":38},"Platform","\u002Fplatform","platform",{"label":40,"href":41,"key":42},"Solutions","\u002Fsolutions","solutions",{"label":44,"href":45,"key":46},"Developers","\u002Fdevelopers","developers",{"label":48,"href":49,"key":50},"Company","\u002Fcompany","company",{"label":52,"href":53,"key":54},"Resources","\u002Fresources","resources",{"label":56,"href":57,"key":58},"Partnerships","\u002Fpartnerships","partnerships",{"sectionEyebrow":60,"primary":61,"productLinks":65,"enterprise":81,"trustFabric":86},"Explore the Platform",{"heading":62,"body":63,"ctaLabel":64,"ctaHref":37},"Our Payments Platform","A resilient, cloud-native platform powering real-time account-to-account payments at global scale.","See How It Works",[66,69,72,75,78],{"label":67,"href":68},"Payments Processing & Gateway","\u002Fpayments-processing-gateway",{"label":70,"href":71},"Orchestration & Intelligent Routing","\u002Forchestration-intelligent-routing",{"label":73,"href":74},"Payments Simulator","\u002Fpayments-simulator",{"label":76,"href":77},"Sponsor Bank Enablement","\u002Fsponsor-bank-enablement",{"label":79,"href":80},"Informed UI","\u002Finformed-ui",{"heading":82,"body":83,"ctaLabel":84,"ctaHref":85},"Form3 Enterprise","Deploy and manage proven cloud-native payments technology in the environment that works for your institution.","Deploy Enterprise","\u002Fplatform\u002Fenterprise",{"heading":87,"body":88,"ctaLabel":89,"ctaHref":90},"Form3 Trust Fabric","Manage TLS certificates, cryptographic vulnerabilities and quantum readiness at scale, with continuous visibility.","Deploy Trust Fabric","\u002Fplatform\u002Ftrust-fabric",{"regionsIntro":92,"regions":98,"industries":118},{"eyebrow":93,"heading":94,"headingLine2":95,"body":96,"ctaLabel":64,"ctaHref":97},"Regions","Global Reach.","Regional Expertise.","A proven payments platform serving organizations worldwide, with specialized experience across North America, United Kingdom, and Europe.","\u002Fglobal",[99,108,113],{"label":100,"description":101,"ctaLabel":102,"href":103,"extraLinks":104},"North America","Real-time infrastructure, through a resilient, multi-cloud platform built for scale and regulatory confidence.","US HOME","\u002Fsolutions\u002Funited-states",[105],{"label":106,"href":107},"CANADA HOME","\u002Fsolutions\u002Fcanada",{"label":109,"description":110,"ctaLabel":111,"href":112},"United Kingdom","Powering account-to-account payments at the heart of the UK financial ecosystem, with proven resilience.","UK HOME","\u002Fsolutions\u002Funited-kingdom",{"label":114,"description":115,"ctaLabel":116,"href":117},"Europe","Enabling secure, real-time and SEPA payments across European markets through a unified, cloud-native platform.","EUROPE HOME","\u002Fsolutions\u002Feurope",{"eyebrow":119,"links":120},"Industries",[121,125,129],{"label":122,"href":123,"iconSrc":124},"Financial Services","\u002Fsolutions\u002Findustries\u002Ffinancial-services","\u002F_prismic-media\u002F29c09c45caa89db9-kbUHZmgTmuIMbo1t_FinancialServices_menu.svg",{"label":126,"href":127,"iconSrc":128},"Fintech","\u002Fsolutions\u002Findustries\u002Ffintech","\u002F_prismic-media\u002F6de3e7cb4dd8d874-SjwNe6Nh-bbuTi0P_Fintech_menu.svg",{"label":130,"href":131,"iconSrc":132},"Government","\u002Fsolutions\u002Findustries\u002Fgovernment","\u002F_prismic-media\u002Fe71bc3a74a1d2142-kaGgdituzKDnVTbm_Government_menu.svg",{"engineering":134,"api":142,"pressEyebrow":154},{"eyebrow":135,"links":136},"Engineering",[137,139],{"label":135,"href":138},"\u002Fengineering",{"label":140,"href":141},"Accreditations","\u002Faccreditations",{"eyebrow":143,"links":144},"API",[145,148,151],{"label":146,"href":147},"API Docs","https:\u002F\u002Fwww.api-docs.form3.tech\u002F",{"label":149,"href":150},"API Tutorials","https:\u002F\u002Fwww.api-docs.form3.tech\u002Fapi\u002Ftutorials\u002Fgetting-started\u002Fintroduction",{"label":152,"href":153},"API Status","https:\u002F\u002Fstatus.form3.tech\u002F","Latest Press Release",{"about":156,"people":171,"podcastEyebrow":183},{"eyebrow":157,"links":158},"About",[159,162,165,168],{"label":160,"href":161},"Our Story","\u002Fcompany\u002Four-story",{"label":163,"href":164},"Our Team","\u002Fcompany\u002Fteam",{"label":166,"href":167},"Our Success & Strategic Approach","\u002Fcompany\u002Four-success",{"label":169,"href":170},"Customer Stories","\u002Fcompany\u002Fcustomer-stories",{"eyebrow":172,"links":173},"People",[174,177,180],{"label":175,"href":176},"Careers","\u002Fcompany\u002Fcareers",{"label":178,"href":179},"Vacancies","\u002Fcompany\u002Fvacancies",{"label":181,"href":182},"Culture","\u002Fcompany\u002Fculture","Latest Podcast",{"intro":185,"links":189,"pressEyebrow":154,"podcastEyebrow":183},{"eyebrow":52,"heading":186,"body":187,"ctaLabel":188,"ctaHref":53},"Form3 Resources","Our Resources bring together thought leadership, engineering insights, payments expertise, webinars, podcasts, whitepapers, company news and stories from our teams—all in one place.","LEARN MORE",[190,193,196,199,202,205],{"label":191,"href":192},"Payments Cannot Fail Podcast","\u002Fresources\u002Fpodcasts",{"label":194,"href":195},"Press Releases","\u002Fresources\u002Fpress-releases",{"label":197,"href":198},"Payment Insights","\u002Fresources\u002Fpayment-insights",{"label":200,"href":201},"Culture Blog","\u002Fresources\u002Fculture-blog",{"label":203,"href":204},"Engineering Blog","\u002Fresources\u002Fengineering-blog",{"label":206,"href":207},"Events","\u002Fevents",{"intro":209,"links":213,"pressEyebrow":154},{"eyebrow":56,"heading":210,"body":211,"ctaLabel":212,"ctaHref":57},"Partner with Form3","Explore how Form3 works with banks, fintechs, cloud providers, technology platforms and system integrators to accelerate payment modernization, strengthen customer offerings and unlock new opportunities for growth.","Let's Partner Together",[214,217],{"label":215,"href":216},"Technical & Ecosystem Partners","\u002Fpartnerships\u002Ftechnical-ecosystem",{"label":218,"href":219},"Channel & Distribution Partners","\u002Fpartnerships\u002Fchannel-distribution",{"platform":221,"region":229,"development":240,"company":248,"resources":259,"partnerships":267,"stayConnected":272,"legalLinks":292,"certifications":314},{"title":36,"links":222},[223,224,225,226,227,228],{"label":62,"href":37},{"label":67,"href":68},{"label":70,"href":71},{"label":73,"href":74},{"label":76,"href":77},{"label":79,"href":80},{"title":230,"links":231},"Region",[232,234,236,237,238],{"label":233,"href":97},"Global",{"label":235,"href":103},"United States",{"label":109,"href":112},{"label":114,"href":117},{"label":239,"href":107},"Canada",{"title":241,"links":242},"Development",[243,244,245,246,247],{"label":135,"href":138},{"label":140,"href":141},{"label":146,"href":147},{"label":149,"href":150},{"label":152,"href":153},{"title":48,"links":249},[250,251,252,253,254,255,256],{"label":160,"href":161},{"label":163,"href":164},{"label":169,"href":170},{"label":175,"href":176},{"label":178,"href":179},{"label":181,"href":182},{"label":257,"href":258},"Net Zero","\u002Fcompany\u002Fnet-zero",{"title":52,"links":260},[261,262,263,264,265,266],{"label":186,"href":53},{"label":191,"href":192},{"label":194,"href":195},{"label":200,"href":201},{"label":203,"href":204},{"label":206,"href":207},{"title":56,"links":268},[269,270,271],{"label":210,"href":57},{"label":215,"href":216},{"label":218,"href":219},{"title":273,"body":274,"ctaLabel":32,"ctaHref":33,"social":275},"Stay Connected","Form3 is a global account-to-account financial fabric delivering a proven payments platform trusted by banks and fintechs to deliver resilient, real-time payment experiences for their customers at scale.",[276,280,284,288],{"label":277,"href":278,"icon":279},"LinkedIn","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fform3-financial-cloud\u002F","linkedin",{"label":281,"href":282,"icon":283},"X","https:\u002F\u002Fwww.x.com\u002FForm3Cloud","x",{"label":285,"href":286,"icon":287},"YouTube","https:\u002F\u002Fwww.youtube.com\u002F@Form3Cloud","youtube",{"label":289,"href":290,"icon":291},"Instagram","https:\u002F\u002Fwww.instagram.com\u002Fform3.tech","instagram",[293,296,299,302,305,308,311],{"label":294,"href":295},"Terms & Conditions","\u002Flegal\u002Fterms-and-conditions",{"label":297,"href":298},"Privacy Policy","\u002Flegal\u002Fdata-privacy-statement",{"label":300,"href":301},"Recruitment Data Policy","\u002Flegal\u002Frecruitment-data-policy",{"label":303,"href":304},"Modern Slavery Statement","\u002Flegal\u002Fmodern-slavery",{"label":306,"href":307},"License","\u002Flegal\u002Flicense",{"label":309,"href":310},"Cookie Policy","\u002Flegal\u002Fcookie-policy",{"label":312,"href":313},"Manage Cookies","#cookies",[315,317,319,321,323],{"label":316},"ISO 27001",{"label":318},"ISO 27017",{"label":320},"ISO 27018",{"label":322},"ISAE 3000 SOC 2 Type II",{"label":324},"ISO 22301",{"platform":326,"solutions":341,"developers":355,"company":365,"resources":366,"partnerships":374},[327,329,339,340],{"kind":328,"label":62,"href":37},"link",{"kind":330,"label":60,"children":331},"group",[332,333,334,335,337],{"label":67,"href":68},{"label":70,"href":71},{"label":73,"href":74},{"label":76,"href":336},"\u002Fplatform\u002Fsponsor-bank-enablement",{"label":79,"href":338},"\u002Fplatform\u002Finform3d-ui",{"kind":328,"label":82,"href":85},{"kind":328,"label":87,"href":90},[342,344,350],{"kind":328,"label":233,"href":343},"\u002Fsolutions\u002Fglobal",{"kind":330,"label":93,"children":345},[346,347,348,349],{"label":235,"href":103},{"label":239,"href":107},{"label":109,"href":112},{"label":114,"href":117},{"kind":330,"label":119,"children":351},[352,353,354],{"label":122,"href":123},{"label":126,"href":127},{"label":130,"href":131},[356,360],{"kind":330,"label":135,"children":357},[358,359],{"label":135,"href":138},{"label":140,"href":141},{"kind":330,"label":143,"children":361},[362,363,364],{"label":146,"href":147},{"label":149,"href":150},{"label":152,"href":153},[],[367,368,369,370,371,372,373],{"kind":328,"label":186,"href":53},{"kind":328,"label":191,"href":192},{"kind":328,"label":194,"href":195},{"kind":328,"label":197,"href":198},{"kind":328,"label":200,"href":201},{"kind":328,"label":203,"href":204},{"kind":328,"label":206,"href":207},[375,376,377],{"kind":328,"label":210,"href":57},{"kind":328,"label":215,"href":216},{"kind":328,"label":218,"href":219},{"id":379,"uid":380,"url":381,"type":382,"href":383,"tags":384,"first_publication_date":385,"last_publication_date":386,"slugs":387,"linked_documents":389,"lang":390,"alternate_languages":391,"data":392},"alz1IREAAC0AUWgG","nat-and-proxies-part-1","\u002Fresources\u002Fengineering-blog\u002Fnat-and-proxies-part-1","engineering_blog_post","https:\u002F\u002Fform3-website.cdn.prismic.io\u002Fapi\u002Fv2\u002Fdocuments\u002Fsearch?ref=apnMZxEAACcAKWxv&q=%5B%5B%3Ad+%3D+at%28document.id%2C+%22alz1IREAAC0AUWgG%22%29+%5D%5D",[],"2026-07-19T16:21:53+0000","2026-08-27T02:06:53+0000",[388],"tcp-over-ip",[],"en-us",[],{"title":393,"excerpt":394,"card_image":395,"published_date":401,"reading_time":402,"tag":403,"dek":404,"featured_image":405,"about_form3":412,"client_about_heading":13,"client_about_body":413,"author_name":414,"author_title":415,"author_photo":416,"author_bio":424,"author_linkedin":437,"slices":440,"meta_title":393,"meta_description":394},"Network Address Translation (NAT) and Proxies (part 1)","Exposing pools of machines to clients, or routing network traffic via an intermediary, are common techniques in distributed computing, and large networks. Network Address Translation, forward proxies, and reverse proxies, are three common techniques for managing network traffic at scale. However, I've always found each of these topics to be somewhat mystical, and I've never understood the fundamentals of how each technique works. This blog post will attempt to distil each idea into its simplest form, and write a code example where possible.",{"dimensions":396,"alt":393,"copyright":13,"url":398,"id":399,"edit":400},{"width":397,"height":397},800,"\u002F_prismic-media\u002F44dbee4b699cabbc-eMKN_hRP9wBBdJIt_nat-and-proxies-part-1.png","eMKN_hRP9wBBdJIt",{"x":17,"y":17,"zoom":18,"background":19},"2022-05-04",8,"Blogs","Exposing pools of machines to clients, or routing network traffic via an intermediary, are common techniques in distributed computing, and large networks. Network Address Translation, forward proxies, and reverse proxies, are three common techniques for managing network traffic at scale. However, each of these topics can be somewhat mystical, and I've never understood the fundamentals of how each technique works. This blog post will attempt to distil each idea into its simplest form, and write a code example where possible.",{"dimensions":406,"alt":13,"copyright":13,"url":409,"id":410,"edit":411},{"width":407,"height":408},1200,627,"\u002F_prismic-media\u002F262c362bc05b220e-C-lSzGUBjEm2kzKU_17dc1378-af0e-4824-84e3-be52dc6.png","C-lSzGUBjEm2kzKU",{"x":17,"y":17,"zoom":18,"background":19},[],[],"Andy Kuszyk","Staff Engineer",{"dimensions":417,"alt":414,"copyright":13,"url":420,"id":421,"edit":422},{"width":418,"height":419},317,473,"\u002F_prismic-media\u002Fc371d17a59432918-GFOBoL2Tovd3zPoj_27d09fad-dd24-483c-92fc-1ac2a07.jpeg","GFOBoL2Tovd3zPoj",{"x":17,"y":17,"zoom":18,"background":423},"#ffffff",[425],{"type":426,"text":427,"spans":428},"paragraph","Andy Kuszyk is a Staff Engineer at Form3, based in Southampton. He's been working as a software engineer for 8 years with a variety of technologies, including .NET, Python and most recently Go. Check out more of his tech articles on his blog.",[429],{"start":430,"end":431,"type":432,"data":433},233,241,"hyperlink",{"link_type":434,"url":435,"target":436},"Web","http:\u002F\u002Fandykuszyk.github.io\u002F","_blank",{"link_type":434,"key":438,"url":439,"target":436},"0b83538e-5f1c-43ec-9bb4-4a7426a5cbb2","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fandy-kuszyk",[441,482,506,516,527,535,549,557,574,603,620,631,645,653,743,775,789,806],{"variation":442,"version":443,"items":444,"primary":445,"id":480,"slice_type":481,"slice_label":13},"default","initial",[],{"body":446},[447,450,454,457,460,463,466,469,472],{"type":426,"text":448,"spans":449},"This first blog post will:",[],{"type":451,"text":452,"spans":453},"list-item","Introduce TCP\u002FIP at a high level, and demonstrate TCP communication in Go.",[],{"type":451,"text":455,"spans":456},"Take a deeper look at IP communication, and the Linux networking stack.",[],{"type":451,"text":458,"spans":459},"Introduce Network Address Translation, and illustrate how it works.",[],{"type":426,"text":461,"spans":462},"A second blog post will:",[],{"type":451,"text":464,"spans":465},"Examine forward proxies, and show a simple example in Go.",[],{"type":451,"text":467,"spans":468},"Examine reverse proxies, and show a simple example in Go.",[],{"type":451,"text":470,"spans":471},"Summarise the differences and similarities between NATs and proxies, and provide examples of their use cases.",[],{"type":426,"text":473,"spans":474},"This blog post assumes the reader has an understanding of IP addresses, and CIDR ranges.",[475],{"start":476,"end":477,"type":432,"data":478},76,80,{"link_type":434,"url":479,"target":436},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FClassless_Inter-Domain_Routing","rich_text$350df5f0-f3e9-471d-a4bf-506961b6c813","rich_text",{"variation":442,"version":443,"items":483,"primary":484,"id":505,"slice_type":481,"slice_label":13},[],{"body":485},[486,490,493,496],{"type":487,"text":488,"spans":489},"heading2","TCP over IP",[],{"type":426,"text":491,"spans":492},"TCP is a connection-oriented protocol, which normally uses the Internet Protocol (IP) to transmit data. This combination is often referred to as TCP\u002FIP. TCP underpins most network traffic on the internet, so before we go any further it's useful to get a grasp of how it works from a practical point of view.",[],{"type":426,"text":494,"spans":495},"In TCP, servers listen for new connections on a specific port. Clients establish connections to server's port from a random port on their host, allocated by the operating system. This combination of the IP\u002Fport of the client, and the IP\u002Fport of the server, uniquely identifies the connection between the two machines.",[],{"type":426,"text":497,"spans":498},"In Go, listening for new connections (like a server would) is easy using the net package. The net package offers a high-level interface for listening for, accepting, and reading from new connections. The example below shows a simple example of a process listening for new connections, and waiting to accept them.",[499,502],{"start":500,"end":477,"type":501},77,"em",{"start":503,"end":504,"type":501},94,97,"rich_text$ed03cf72-05bd-4872-8039-fab552f3f17c",{"variation":442,"version":443,"items":507,"primary":508,"id":514,"slice_type":515,"slice_label":13},[],{"language_label":13,"code":509},[510],{"type":511,"text":512,"spans":513},"preformatted","func main() {\n    \u002F\u002F The server listens for TCP connections on the port 8080. If a client\n    \u002F\u002F tried to establish a connection with the host this process was running on,\n    \u002F\u002F on port 8080, they would be directed to this process.\n    listener, err := net.Listen(\"tcp\", \":8080\")\n    if err != nil {\n        panic(err)\n    }\n\n    for {\n        \u002F\u002F The server waits to accept new connections. It can handle multiple\n        \u002F\u002F connections, from multiple clients. As a result, it can handle each\n        \u002F\u002F connection in the background, and the continue to wait for new connections\n        \u002F\u002F to be established.\n        connection, err := listener.Accept()\n        if err != nil {\n            panic(err)\n        }\n\n        \u002F\u002F Handle the connection in the background.\n        go handleConnection(connection)\n    }\n}",[],"code_block$46b66623-8e1e-488d-8b2b-cbd8d9541835","code_block",{"variation":442,"version":443,"items":517,"primary":518,"id":526,"slice_type":481,"slice_label":13},[],{"body":519},[520],{"type":426,"text":521,"spans":522},"The handleConnection() function can handle new connections by reading any data sent along the connection, and writing any data that needs to be returned. The example below illustrates reading and writing data, before closing the connection:",[523],{"start":524,"end":525,"type":501},3,22,"rich_text$84a7616e-1d87-4083-b85b-9cd1036dcaa9",{"variation":442,"version":443,"items":528,"primary":529,"id":534,"slice_type":515,"slice_label":13},[],{"language_label":13,"code":530},[531],{"type":511,"text":532,"spans":533},"func handleConnection(connection net.Conn) {\n    \u002F\u002F The server reads data from the connection. This data is just a stream of bytes, and\n    \u002F\u002F could represent a common application-level protocol such as HTTP, or a custom\n    \u002F\u002F protocol of your choosing.\n    b, err := io.ReadAll(connection)\n    if err != nil {\n        panic(err)\n    }\n\n    \u002F\u002F The server can also send data back along the connection. In this case,\n    \u002F\u002F it always sends the same data.\n    _, err = connection.Write([]byte(\"hello world!\\n\"))\n    if err != nil {\n        panic(err)\n    }\n\n    \u002F\u002F The server can keep the connection open for as long as it likes, and\n    \u002F\u002F continue to send and receive data indefinitely. In this example,\n    \u002F\u002F having read and written data, the server closes the connection. If the\n    \u002F\u002F client wanted to continue communicating with the server, it would have\n    \u002F\u002F to establish a new connection.\n    connection.Close()\n}",[],"code_block$fd46f1d0-a610-4bad-9cc1-ddc7472652c3",{"variation":442,"version":443,"items":536,"primary":537,"id":548,"slice_type":481,"slice_label":13},[],{"body":538},[539],{"type":426,"text":540,"spans":541},"Running this sample application will start a process listening on port 8080, and allow you to establish TCP connections with localhost:8080. A TCP connection can be established from a client using a command line tool: nc(netcat). In the following example, a TCP connection is established, some data sent, and some data received:",[542,545],{"start":543,"end":544,"type":501},125,139,{"start":546,"end":547,"type":501},218,228,"rich_text$abed6fb2-2151-41da-8fe4-d715fddf7de8",{"variation":442,"version":443,"items":550,"primary":551,"id":556,"slice_type":515,"slice_label":13},[],{"language_label":13,"code":552},[553],{"type":511,"text":554,"spans":555},"$ echo -n \"hello\" | nc localhost 8080\nhello world!",[],"code_block$2059d9cf-9208-4b56-b1a5-5a8f21d84f96",{"variation":442,"version":443,"items":558,"primary":559,"id":573,"slice_type":481,"slice_label":13},[],{"body":560},[561,564,567,570],{"type":487,"text":562,"spans":563},"TCP over IP summary",[],{"type":451,"text":565,"spans":566},"TCP is a connection-oriented protocol, allowing a client to establish a reliable line of communication with a server.",[],{"type":451,"text":568,"spans":569},"TCP is a transport-layer protocol, and requires a network-layer protocol to handle underlying network transmission.",[],{"type":451,"text":571,"spans":572},"TCP is usually transmitted via the Internet Protocol (IP), and this combination is normally referred to as TCP\u002FIP.",[],"rich_text$e635f186-6ced-4e07-b57a-31de391b265f",{"variation":442,"version":443,"items":575,"primary":576,"id":602,"slice_type":481,"slice_label":13},[],{"body":577},[578,581,584,587,590,593,596],{"type":487,"text":579,"spans":580},"IP and the Linux networking stack",[],{"type":426,"text":582,"spans":583},"The Internet Protocol itself is a low-level protocol used to transmit data packets across an internet network. It is used to encapsulate higher-level protocols (like TCP and UDP). IP packets consist of a header and a payload. The payload is where the encapsulated packets from the higher-level protocol are transmitted. The IP header contains a number of fields, but the following ones are of interest to this post:",[],{"type":451,"text":585,"spans":586},"Source address: the IP address of the sender.",[],{"type":451,"text":588,"spans":589},"Destination address: the IP address of the intended recipient.",[],{"type":426,"text":591,"spans":592},"These fields contain the source and destination IP addresses of the packets, and nothing else. You may notice that there is no information in here about ports, which are part of higher-level protocols (e.g. ports are part of the TCP implementation).",[],{"type":426,"text":594,"spans":595},"Now, when it comes to sending and receiving IP packets from an application it isn't as straightforward as it sounds. IP is a low-level networking protocol, and is normally handled directly by the operating system. In Linux, the socket-based networking stack takes care of all TCP\u002FIP and UDP\u002FIP communication. The sending and receiving of raw IP network packets is handled in kernel space, and user space applications are presented with a high-level interface (a file descriptor to read\u002Fwrite data to).",[],{"type":426,"text":597,"spans":598},"As a result, it's difficult to illustrate IP packet handling in a simple user space application, because the details of packet handling are normally handled by the kernel's network stack. In the TCP example above, the networking primitives exposed by the Go net package are somewhat similar to the syscalls the Linux kernel exposes to applications. Interacting with IP packets directly isn't something a user space application would normally need to worry about.",[599],{"start":600,"end":601,"type":501},258,261,"rich_text$e1083d83-ac5b-4072-a504-79ce824eebab",{"variation":442,"version":443,"items":604,"primary":605,"id":619,"slice_type":481,"slice_label":13},[],{"body":606},[607,610,613,616],{"type":487,"text":608,"spans":609},"IP and Linux networking summary",[],{"type":451,"text":611,"spans":612},"IP is a low-level protocol, concerned with the IP addresses of hosts on a network (but not ports).",[],{"type":451,"text":614,"spans":615},"IP packet transmission is normally handled by the operating system.",[],{"type":451,"text":617,"spans":618},"The Linux kernel offers applications a networking abstraction at the transport-level (e.g. TCP, UDP), and handles IP packet transmission internally.",[],"rich_text$b7b10fe4-ac52-4831-8f27-e283a71a6296",{"variation":442,"version":443,"items":621,"primary":622,"id":630,"slice_type":481,"slice_label":13},[],{"body":623},[624,627],{"type":487,"text":625,"spans":626},"Network Address Translation",[],{"type":426,"text":628,"spans":629},"Network Address Translation is a procedure commonly employed on routers to hide the IP network space of one network when connecting it to another. A good example of this is your home network router. Your router probably applies NAT to network traffic destined for the internet. If you check out your public IP address, you will find out the IP address of your router on the internet, rather than the private IP address allocated to your machine on your home network. This process is illustrated in the diagram below:",[],"rich_text$bb772a36-553d-44ec-91f1-58453f8afe88",{"variation":442,"version":443,"items":632,"primary":633,"id":644,"slice_type":481,"slice_label":13},[],{"body":634},[635],{"type":426,"text":636,"spans":637},"In this example, your router has a public IP address on the internet (80.123.123.123), and all of the devices on your local network have local IP addresses (192.168.0.0\u002F24). Whenever network traffic destined for the internet passes through your router, your router modifies the IP packets to use its public IP address as the source IP. When return packets are sent, they are addressed back to your router's public IP address. You router maintains a local mapping of your original IP address on the private network, so that when it receives return packets it can send them back to the correct local IP address. Precisely how the mapping works depends on the type of network traffic being transmitted. In the case of UDP and TCP, this consists of the unique IP address\u002Fport combinations of the source and destination. This combination allows IP packets between the same source and destination IP addresses to be differentiated based on their transport-layer characteristics (e.g. the source\u002Fdestination ports of the TCP connection).",[638,641],{"start":639,"end":640,"type":501},70,84,{"start":642,"end":643,"type":501},157,171,"rich_text$0d099708-3100-416b-b310-d187eac3bdb9",{"variation":442,"version":443,"items":646,"primary":647,"id":652,"slice_type":481,"slice_label":13},[],{"body":648},[649],{"type":426,"text":650,"spans":651},"Network Address Translation can hide private IP addresses from the public internet, and replace them with a single public IP address instead.",[],"rich_text$a213726c-1a98-4872-8096-dd7ff5ed77b4",{"variation":442,"version":443,"items":654,"primary":655,"id":742,"slice_type":481,"slice_label":13},[],{"body":656},[657,660,663,666,669,672,675,681,689,692,695,700,705,710,713,718,721,731,734,739],{"type":487,"text":658,"spans":659},"Reasons to use NAT",[],{"type":426,"text":661,"spans":662},"There are a variety of reasons you might want to use NAT, including:",[],{"type":451,"text":664,"spans":665},"Preserving IP address space between multiple private networks (and on the internet).",[],{"type":451,"text":667,"spans":668},"Ensuring consistent source IP addresses--your network traffic will always appear to originate from the IP address of the device performing NAT.",[],{"type":451,"text":670,"spans":671},"Ensuring consistent destination IP addresses--your network traffic will always appear to be received at the IP address of the device performing NAT.",[],{"type":426,"text":673,"spans":674},"Each of these reasons are explored in more detail below.",[],{"type":426,"text":676,"spans":677},"Preserving IP address space",[678],{"start":17,"end":679,"type":680},27,"strong",{"type":426,"text":682,"spans":683},"IPv4 addresses are limited to 4.3 billion unique addresses, which means that without some kind of solution we would soon suffer from IP address exhaustion. There are a number of solutions to IP address exhaustion--including the introduction of IPv6--but NAT limits the impact of the relatively small size of IPv4 address space.",[684],{"start":685,"end":686,"type":432,"data":687},133,154,{"link_type":434,"url":688,"target":436},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIPv4_address_exhaustion",{"type":426,"text":690,"spans":691},"If a private network is connected to the internet via NAT, then it doesn't matter how many IP addresses are allocated on the private network, they will only ever use as many public IP addresses as there are routers that NAT traffic.",[],{"type":426,"text":693,"spans":694},"It's conventional to use the following IP address spaces for private networks:",[],{"type":451,"text":696,"spans":697},"10.0.0.0\u002F8",[698],{"start":17,"end":699,"type":501},10,{"type":451,"text":701,"spans":702},"172.16.0.0\u002F12",[703],{"start":17,"end":704,"type":501},13,{"type":451,"text":706,"spans":707},"192.168.0.0\u002F16",[708],{"start":17,"end":709,"type":501},14,{"type":426,"text":711,"spans":712},"Between these IP address ranges, there are more than 17 million private addresses that can be allocated. As a result, NAT allows large private networks to be constructed without exhausting IPv4 space on the public internet.",[],{"type":426,"text":714,"spans":715},"Consistent source IP addresses",[716],{"start":17,"end":717,"type":680},30,{"type":426,"text":719,"spans":720},"It's often useful to secure access to a system by maintaining an allowlist of IP addresses that are permitted to reach it. This might form the basis of firewall rules that permit inbound traffic into a network. Permitting traffic based on the source IP address of network traffic is difficult if there are a large number of possibilities for that source IP address.",[],{"type":426,"text":722,"spans":723},"For example, if you ran machines in your corporate network in 10.0.0.0\u002F8, and you gave your external software vendor this CIDR range to add to their allowlist, it wouldn't be a very restrictive security measure!",[724,727],{"start":725,"end":726,"type":501},62,72,{"start":728,"end":729,"type":432,"data":730},122,126,{"link_type":434,"url":479,"target":436},{"type":426,"text":732,"spans":733},"NAT can be a useful technique to mask the IP addresses of your internal systems and ensure a consistent source IP address when connecting to other network resources or external systems. In this instance, NAT is used to translate traffic from private addresses in your internal network so that they appear to have originated from your router's public IP address instead.",[],{"type":426,"text":735,"spans":736},"Consistent destination IP addresses",[737],{"start":17,"end":738,"type":680},35,{"type":426,"text":740,"spans":741},"You might also be in a position where you have a private network resource that you want to expose on a public network. NAT can be used in this instance to translate traffic addressed to your public address to your private addresses instead. This is sometimes referred to as \"port forwarding\", and you might have seen features like this on your home router to expose resources on your local machine (on your private home network) to the internet.",[],"rich_text$b0bc908a-f84c-4b00-9809-4aa5df480546",{"variation":442,"version":443,"items":744,"primary":745,"id":774,"slice_type":481,"slice_label":13},[],{"body":746},[747,750,753,757,760,763,766,771],{"type":487,"text":748,"spans":749},"How NAT works",[],{"type":426,"text":751,"spans":752},"So, how does NAT actually work? Well, it's simple...and it's not!",[],{"type":426,"text":754,"spans":755},"The simple explanation",[756],{"start":17,"end":525,"type":680},{"type":426,"text":758,"spans":759},"The simple part, is that NAT works by re-writing the source or destination headers in the IP packets based on which way round NAT is being applied to your traffic. In the case where you home router uses NAT to present a single source IP address to the internet, all of your outgoing IP packets have their source IP address changed to match your router's address. That way, return packets can be addressed back to your router over the internet.",[],{"type":426,"text":761,"spans":762},"Your router knows it needs to adjust the source IP address of your IP packets, so it keeps a record of your original source IP address. When it receives return packets, it re-writes the destination IP address to match your original address and then forwards the packets over your private network.",[],{"type":426,"text":764,"spans":765},"This process is completely transparent to the sender and receiver, and is normally completed by a hardware network device (e.g. a router).",[],{"type":426,"text":767,"spans":768},"The not-so-simple explanation",[769],{"start":17,"end":770,"type":680},29,{"type":426,"text":772,"spans":773},"The less simple part of this process is that source and destination address information isn't just used at the IP level of network transmission. It's also used in TCP and UDP, where it forms part of the message checksum calculations to avoid errors in transmission. This means that the device performing NAT needs to be aware of the higher-level protocols being transmitted in the IP packets. It needs to decode the contents of the IP packet's payload, modify it accordingly, and re-write it so that it still contain valid TCP\u002FUDP packets. When the packets are decoded and passed up the network stack to user space applications, they still appear to contain valid TCP or UDP packets, which have been modified transparently from the point of view of the application.",[],"rich_text$fa47c037-2c7b-412c-9d75-aaef12359e63",{"variation":442,"version":443,"items":776,"primary":777,"id":788,"slice_type":481,"slice_label":13},[],{"body":778},[779,782,785],{"type":487,"text":780,"spans":781},"Where's the code example?",[],{"type":426,"text":783,"spans":784},"This whole process is difficult to demonstrate in a simple coding example, because the processing of IP packets is normally handled by the networking stack in an OS, and user space application code typically deals with higher-level abstractions based around TCP and UDP protocols.",[],{"type":426,"text":786,"spans":787},"NAT is normally performed by specialised networking devices (like routers), whose sole purpose is to process IP packets and route them to their next network hop.",[],"rich_text$a443a564-f510-47b8-a83d-2934041226c4",{"variation":442,"version":443,"items":790,"primary":791,"id":805,"slice_type":481,"slice_label":13},[],{"body":792},[793,796,799,802],{"type":487,"text":794,"spans":795},"NAT summary",[],{"type":451,"text":797,"spans":798},"NAT involves re-writing source and destination addresses in IP packets, so that all network traffic from a network appears to have originated from a single IP address.",[],{"type":451,"text":800,"spans":801},"NAT can be used to mask source or destination IP addresses.",[],{"type":451,"text":803,"spans":804},"NAT is a useful way of connecting private and public networks together, whilst still preserving IP address space.",[],"rich_text$4eb09f79-948c-4d2e-9d84-d83d64d1e9c4",{"variation":442,"version":443,"items":807,"primary":808,"id":819,"slice_type":481,"slice_label":13},[],{"body":809},[810,813,816],{"type":487,"text":811,"spans":812},"Summary",[],{"type":426,"text":814,"spans":815},"This blog post has introduced TCP\u002FIP, the Linux networking stack, and how Network Address Translation can be used to connect large networks.",[],{"type":426,"text":817,"spans":818},"The second half of this post will continue by covering forward and reverse proxies, before summarising all three techniques.",[],"rich_text$866efae2-9cb1-4583-ab8e-a1b7a96564bf",1788466508449]