-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfeed.json
More file actions
417 lines (336 loc) · 373 KB
/
feed.json
File metadata and controls
417 lines (336 loc) · 373 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
{
"version": "https://jsonfeed.org/version/1.1",
"title": "Edge Cloud",
"home_page_url": "https://www.edge-cloud.net/",
"feed_url": "https://www.edge-cloud.net/feed.json",
"description": "On the edge of cloud computing",
"icon": "https://www.edge-cloud.net/assets/images/edgecloud.png",
"authors": [
{
"name": "Christian Elsen",
"url": "https://www.edge-cloud.net/"
}
],
"items": [
{
"id": "https://www.edge-cloud.net/2021/01/01/tgw-ngw-cost-breakeven",
"url": "https://www.edge-cloud.net/2021/01/01/tgw-ngw-cost-breakeven/",
"title": "Cost considerations for centralized NAT with Transit Gateway",
"content_html": "<p>Intro of what to accomplish</p>\n\n<h1 id=\"heading-1\">Heading 1</h1>\n\n<h2 id=\"heading-11\">Heading 1.1</h2>\n\n<p><strong>Bold</strong></p>\n\n<p class=\"notice--info\"><strong>Note:</strong> This is a notice box</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>#\n# Code\n#\n\n</code></pre></div></div>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetwork.png\" title=\"Figure 1: Setup Overview of EC2-based VPN endpoint for Site-to-Site VPN with AWS \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetwork-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetwork-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetwork-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetwork-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetwork-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetwork-960.webp 960w, \" sizes=\"4032px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetwork-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetwork-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetwork-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetwork-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetwork-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetwork-960.png 960w, \" sizes=\"4032px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetwork-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetwork.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: Setup Overview of EC2-based VPN endpoint for Site-to-Site VPN with AWS \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Setup Overview of EC2-based VPN endpoint for Site-to-Site VPN with AWS\n</figcaption>\n\n</figure>\n\n\\[Price_{NGW}=( 720 hr / month \\cdot Num_{VPC} \\cdot Cost_{NGW-Attachment} ) + (traffic \\cdot Cost_{NGW-Traffic})\\]\n\n\\[Price_{TGW+NGW}=\n ( 720 hr / month \\cdot Num_{VPC} \\cdot Cost_{TGW-Attachment} ) + \\\\\n ( 720 hr / month \\cdot Num_{AZ} \\cdot Cost_{NGW-Attachment} ) + \\\\\n (traffic \\cdot ( Cost_{TGW-Traffic} + Cost_{NGW-Traffic}))\\]\n\n\\[Price_{TGW+NGW} \\leq Price_{NGW}\\]\n\n\\[( 720 hr / month \\cdot Num_{VPC} \\cdot Cost_{TGW-Attachment} ) + \\\\\n ( 720 hr / month \\cdot Num_{AZ} \\cdot Cost_{NGW-Attachment} ) + \\\\\n (traffic \\cdot ( Cost_{TGW-Traffic} + Cost_{NGW-Traffic})) \\\\\n \\leq ( 720 hr / month \\cdot Num_{VPC} \\cdot Cost_{NGW-Attachment} ) + (traffic \\cdot Cost_{NGW-Traffic})\\]\n\n\\[traffic \\cdot Cost_{TGW-Traffic} + traffic \\cdot Cost_{NGW-Traffic} - traffic \\cdot Cost_{NGW-Traffic} \\\\\n \\leq ( 720 hr / month \\cdot Num_{VPC} \\cdot Cost_{NGW-Attachment} ) - \\\\\n ( 720 hr / month \\cdot Num_{VPC} \\cdot Cost_{TGW-Attachment} ) - \\\\\n ( 720 hr / month \\cdot Num_{AZ} \\cdot Cost_{NGW-Attachment} )\\]\n\n\\[traffic \\cdot Cost_{TGW-Traffic} \\\\\n \\leq 720 hr / month \\cdot (( Num_{VPC} \\cdot Num_{AZ} \\cdot Cost_{NGW-Attachment} ) \\\\\n - ( Num_{VPC} \\cdot Cost_{TGW-Attachment} ) - ( Num_{AZ} \\cdot Cost_{NGW-Attachment} ))\\]\n\n\\[traffic \\leq \\frac{720 hr / month}{Cost_{TGW-Traffic}} \\cdot \\\\\n (( Num_{VPC} \\cdot Num_{AZ} \\cdot Cost_{NGW-Attachment} ) - \\\\\n ( Num_{VPC} \\cdot Cost_{TGW-Attachment} ) - ( Num_{AZ} \\cdot Cost_{NGW-Attachment} ))\\]\n",
"summary": "Determining the break-even point when a centralized NAT approach via Transit Gateway outperforms a decentralized NAT approach.",
"date_published": "2026-03-07T16:13:10-08:00",
"date_modified": "2026-03-07T16:13:10-08:00",
"image": "https://www.edge-cloud.net/assets/images/og-image.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network"]
},
{
"id": "https://www.edge-cloud.net/2022/01/01/template",
"url": "https://www.edge-cloud.net/2022/01/01/template/",
"title": "Title goes here",
"content_html": "<p>Intro of what to accomplish</p>\n\n<h1 id=\"heading-1\">Heading 1</h1>\n\n<h2 id=\"heading-11\">Heading 1.1</h2>\n\n<p><strong>Bold</strong></p>\n\n<p class=\"notice--info\"><strong>Note:</strong> This is a notice box</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>#\n# Code\n#\n\n</code></pre></div></div>\n\n<h2 id=\"font-awesome-examples\">Font Awesome Examples</h2>\n<p><i class=\"fas fa-user\"></i>\n<i class=\"fas fa-check\" style=\"color:green;\" title=\"Yes\"></i>\n<i class=\"fas fa-times\" style=\"color:red;\" title=\"No\"></i></p>\n\n<h2 id=\"picture\">Picture</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetwork.png\" title=\"Figure 1: Setup Overview of EC2-based VPN endpoint for Site-to-Site VPN with AWS \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetwork-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetwork-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetwork-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetwork-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetwork-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetwork-960.webp 960w, \" sizes=\"4032px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetwork-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetwork-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetwork-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetwork-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetwork-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetwork-960.png 960w, \" sizes=\"4032px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetwork-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetwork.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: Setup Overview of EC2-based VPN endpoint for Site-to-Site VPN with AWS \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Setup Overview of EC2-based VPN endpoint for Site-to-Site VPN with AWS\n</figcaption>\n\n</figure>\n\n<h2 id=\"math\">Math</h2>\n<p>\\(Buffer (Mbit) = bandwidth (Mbit/s) × delay (s)\\)</p>\n",
"summary": "Brief description goes here",
"date_published": "2026-03-07T16:13:10-08:00",
"date_modified": "2026-03-07T16:13:10-08:00",
"image": "https://www.edge-cloud.net/content/uploads/2022/06/title-dx-overview.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network"]
},
{
"id": "https://www.edge-cloud.net/2020/01/03/securing-your-aws-networks",
"url": "https://www.edge-cloud.net/2020/01/03/securing-your-aws-network/",
"title": "Securing your AWS networks",
"content_html": "<p>Intro of what to accomplish</p>\n\n<h1 id=\"scope\">Scope</h1>\n\n<h2 id=\"aws-well-architected---security-pillar\">AWS Well Architected - Security Pillar</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetwork.png\" title=\"Figure 1: Protecting network and host-level boundaries \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetwork-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetwork-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetwork-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetwork-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetwork-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetwork-960.webp 960w, \" sizes=\"4032px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetwork-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetwork-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetwork-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetwork-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetwork-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetwork-960.png 960w, \" sizes=\"4032px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetwork-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetwork.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: Protecting network and host-level boundaries \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Protecting network and host-level boundaries\n</figcaption>\n\n</figure>\n\n<h1 id=\"toolbox-for-securing-aws-networks\">Toolbox for securing AWS networks</h1>\n\n<h2 id=\"amazon-vpc-security-groups\">Amazon VPC Security Groups</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-SecurityGroups.png\" title=\"Figure 2: Security Groups \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-960.webp 960w, \" sizes=\"3225px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-960.png 960w, \" sizes=\"3225px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-SecurityGroups-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-SecurityGroups.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 2: Security Groups \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Security Groups\n</figcaption>\n\n</figure>\n\n<h2 id=\"amazon-vpc-network-acls-access-control-lists\">Amazon VPC Network ACLs (Access Control Lists)</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-NetworkACLs.png\" title=\"Figure 3: Network Access Control Lists (ACLs) \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-960.webp 960w, \" sizes=\"3025px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-960.png 960w, \" sizes=\"3025px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-NetworkACLs-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-NetworkACLs.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 3: Network Access Control Lists (ACLs) \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Network Access Control Lists (ACLs)\n</figcaption>\n\n</figure>\n\n<h2 id=\"aws-waf-web-application-firewall\">AWS WAF (Web Application Firewall)</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-WAF.png\" title=\"Figure 4: Web Application Firewalls (WAF) \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-WAF-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-960.webp 960w, \" sizes=\"3560px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-WAF-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-WAF-960.png 960w, \" sizes=\"3560px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-WAF-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-WAF.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 4: Web Application Firewalls (WAF) \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: Web Application Firewalls (WAF)\n</figcaption>\n\n</figure>\n\n<h2 id=\"aws-firewall-manager\">AWS Firewall Manager</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-FirewallManager.png\" title=\"Figure 5: Firewall Manager \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-960.webp 960w, \" sizes=\"2400px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-960.png 960w, \" sizes=\"2400px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-FirewallManager-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-FirewallManager.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 5: Firewall Manager \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 5: Firewall Manager\n</figcaption>\n\n</figure>\n\n<h2 id=\"aws-shield\">AWS Shield</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-Shield.png\" title=\"Figure 6: AWS Shield \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-Shield-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-960.webp 960w, \" sizes=\"2635px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-Shield-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-Shield-960.png 960w, \" sizes=\"2635px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-Shield-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-Shield.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 6: AWS Shield \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 6: AWS Shield\n</figcaption>\n\n</figure>\n\n<h2 id=\"aws-transit-gateway-with-3rd-party-firewall-solutions\">AWS Transit Gateway with 3rd party firewall solutions</h2>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-TGW.png\" title=\"Figure 7: Transit Gateway \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-TGW-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-960.webp 960w, \" sizes=\"3469px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-TGW-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-TGW-960.png 960w, \" sizes=\"3469px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-TGW-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-TGW.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 7: Transit Gateway \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 7: Transit Gateway\n</figcaption>\n\n</figure>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/01/SecuringYourAWSNetworks-PAN.png\" title=\"Figure 7: Transit Gateway with Palo Alto Networks Integration \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-PAN-320.webp 320w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-384.webp 384w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-512.webp 512w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-683.webp 683w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-800.webp 800w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-960.webp 960w, \" sizes=\"2466px\" />\n <source data-srcset=\" /content/resized/2020/01/SecuringYourAWSNetworks-PAN-320.png 320w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-384.png 384w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-512.png 512w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-683.png 683w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-800.png 800w, /content/resized/2020/01/SecuringYourAWSNetworks-PAN-960.png 960w, \" sizes=\"2466px\" />\n <img src=\"/content/resized/2020/01/SecuringYourAWSNetworks-PAN-320.png\" data-src=\"/content/uploads/2020/01/SecuringYourAWSNetworks-PAN.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 7: Transit Gateway with Palo Alto Networks Integration \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 7: Transit Gateway with Palo Alto Networks Integration\n</figcaption>\n\n</figure>\n\n<h2 id=\"aws-ingress-routing-with-3rd-party-firewall-solutions\">AWS Ingress Routing with 3rd party firewall solutions</h2>\n\n<p><strong>Bold</strong></p>\n\n<p class=\"notice--info\"><strong>Note:</strong> This is a notice box</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>#\n# Code\n#\n\n</code></pre></div></div>\n",
"summary": "Brief description goes here",
"date_published": "2026-03-07T16:13:10-08:00",
"date_modified": "2026-03-07T16:13:10-08:00",
"image": "https://www.edge-cloud.net/assets/images/og-image.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network"]
},
{
"id": "https://www.edge-cloud.net/2026/02/03/dx-location-details",
"url": "https://www.edge-cloud.net/2026/02/03/dx-location-details/",
"title": "Enhanced AWS Direct Connect Location Directory",
"content_html": "<p>When planning AWS Direct Connect deployments, one of the first challenges customers face is understanding where Direct Connect locations are physically located and what capabilities they offer. While AWS provides a <a href=\"https://aws.amazon.com/directconnect/locations/\">list of Direct Connect locations</a>, this page has several limitations that make it difficult to use for planning and decision-making purposes.</p>\n\n<p>This article introduces the <i class=\"fab fa-github\"></i> <a href=\"https://github.com/chriselsen/dx-location-details\">dx-location-details</a> project, which addresses these limitations by providing an enhanced, interactive directory of AWS Direct Connect locations with geographic data, advanced filtering, and automated updates (see Figure 1).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2026/02/dx-location-details-screenshot.png\" title=\"Figure 1: Interactive AWS Direct Connect Location Directory \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2026/02/dx-location-details-screenshot-320.webp 320w, /content/resized/2026/02/dx-location-details-screenshot-384.webp 384w, /content/resized/2026/02/dx-location-details-screenshot-512.webp 512w, /content/resized/2026/02/dx-location-details-screenshot-683.webp 683w, /content/resized/2026/02/dx-location-details-screenshot-800.webp 800w, /content/resized/2026/02/dx-location-details-screenshot-960.webp 960w, \" sizes=\"1309px\" />\n <source data-srcset=\" /content/resized/2026/02/dx-location-details-screenshot-320.png 320w, /content/resized/2026/02/dx-location-details-screenshot-384.png 384w, /content/resized/2026/02/dx-location-details-screenshot-512.png 512w, /content/resized/2026/02/dx-location-details-screenshot-683.png 683w, /content/resized/2026/02/dx-location-details-screenshot-800.png 800w, /content/resized/2026/02/dx-location-details-screenshot-960.png 960w, \" sizes=\"1309px\" />\n <img src=\"/content/resized/2026/02/dx-location-details-screenshot-320.png\" data-src=\"/content/uploads/2026/02/dx-location-details-screenshot.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: Interactive AWS Direct Connect Location Directory \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Interactive AWS Direct Connect Location Directory\n</figcaption>\n\n</figure>\n\n<h1 id=\"the-problem-with-the-official-aws-page\">The Problem with the Official AWS Page</h1>\n\n<p>The official AWS Direct Connect locations page at <a href=\"https://aws.amazon.com/directconnect/locations/\">https://aws.amazon.com/directconnect/locations/</a> presents several challenges for customers:</p>\n\n<h2 id=\"missing-geographic-information\">Missing Geographic Information</h2>\n\n<p>The AWS page lists Direct Connect locations by name and associated AWS region, but provides no physical addresses, geographic coordinates, or mapping capabilities. This makes it difficult to:</p>\n\n<ul>\n <li>Visualize where locations are physically situated</li>\n <li>Identify the nearest Direct Connect location to your data center or office</li>\n <li>Plan for geographic redundancy across multiple locations</li>\n <li>Understand the physical distance between locations for latency planning</li>\n</ul>\n\n<h2 id=\"regional-misclassification\">Regional Misclassification</h2>\n\n<p>Direct Connect locations are grouped by AWS region associations, which can be misleading. For example:</p>\n\n<ul>\n <li>A location in Tokyo might be listed under “Asia Pacific (Tokyo)” even though it can connect to any AWS region globally via Direct Connect Gateway</li>\n <li>A location in Dubai, UAE might appear under “Europe” due to using Dublin as the associated region, instead of appearing under Middle East</li>\n <li>Locations in the same city might appear under different regional groupings</li>\n <li>The grouping doesn’t reflect the actual geographic distribution of facilities</li>\n</ul>\n\n<p>This regional grouping conflates the concept of “associated region” (used for API calls to manage Direct Connect resources) with physical location, creating confusion about where facilities actually exist.</p>\n\n<h2 id=\"lack-of-data-normalization\">Lack of Data Normalization</h2>\n\n<p>The AWS page presents location information in an inconsistent format:</p>\n\n<ul>\n <li>Location codes use various naming conventions without standardization</li>\n <li>Facility names may differ between AWS documentation and the actual colocation provider</li>\n <li>No structured data format makes it difficult to programmatically process the information</li>\n <li>Port speeds and MACsec support details are maintained manually instead of being retrieved from the API, leading to potential inconsistencies</li>\n <li>Missing details about facility operators</li>\n</ul>\n\n<h1 id=\"the-solution-dx-location-details\">The Solution: dx-location-details</h1>\n\n<p>The <i class=\"fab fa-github\"></i> <a href=\"https://github.com/chriselsen/dx-location-details\">dx-location-details</a> GitHub repository provides an automated solution that addresses these limitations.</p>\n\n<h2 id=\"interactive-map-and-table-interface\">Interactive Map and Table Interface</h2>\n\n<p>The project generates an interactive web page at <a href=\"https://chris.elsen.xyz/dx-location-details/\">https://chris.elsen.xyz/dx-location-details/</a> featuring:</p>\n\n<ul>\n <li><strong>Interactive world map:</strong> Visualize all Direct Connect locations with markers showing their precise geographic coordinates</li>\n <li><strong>Sortable table:</strong> View detailed information about each location in a table format with sorting capabilities</li>\n <li><strong>Advanced filtering:</strong> Filter locations by country, organization, port speeds, MACsec support, and associated AWS region</li>\n <li><strong>Search functionality:</strong> Quickly find specific locations by name, code, or other attributes</li>\n <li><strong>Nearest location finder:</strong> Click anywhere on the map to identify the two closest Direct Connect locations based on geographic distance (see Figure 2). Note that this calculation uses straight-line distance and does not account for physical obstacles like oceans or the availability of existing fiber paths, so it should be used for rough guidance only</li>\n</ul>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2026/02/dx-location-details-nearest.png\" title=\"Figure 2: Nearest location finder showing the two closest Direct Connect locations \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2026/02/dx-location-details-nearest-320.webp 320w, /content/resized/2026/02/dx-location-details-nearest-384.webp 384w, /content/resized/2026/02/dx-location-details-nearest-512.webp 512w, /content/resized/2026/02/dx-location-details-nearest-683.webp 683w, /content/resized/2026/02/dx-location-details-nearest-800.webp 800w, /content/resized/2026/02/dx-location-details-nearest-960.webp 960w, \" sizes=\"1324px\" />\n <source data-srcset=\" /content/resized/2026/02/dx-location-details-nearest-320.png 320w, /content/resized/2026/02/dx-location-details-nearest-384.png 384w, /content/resized/2026/02/dx-location-details-nearest-512.png 512w, /content/resized/2026/02/dx-location-details-nearest-683.png 683w, /content/resized/2026/02/dx-location-details-nearest-800.png 800w, /content/resized/2026/02/dx-location-details-nearest-960.png 960w, \" sizes=\"1324px\" />\n <img src=\"/content/resized/2026/02/dx-location-details-nearest-320.png\" data-src=\"/content/uploads/2026/02/dx-location-details-nearest.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 2: Nearest location finder showing the two closest Direct Connect locations \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Nearest location finder showing the two closest Direct Connect locations\n</figcaption>\n\n</figure>\n\n<h2 id=\"location-data\">Location Data</h2>\n\n<p>For each Direct Connect location, the directory provides:</p>\n\n<ul>\n <li><strong>Geographic coordinates:</strong> Precise latitude and longitude for mapping and distance calculations</li>\n <li><strong>Facility information:</strong> Links to PeeringDB entries for detailed facility and operator information</li>\n <li><strong>AWS location code:</strong> The standardized code used in AWS API calls</li>\n <li><strong>Port speeds:</strong> Available connection speeds (1G, 10G, 100G, 400G)</li>\n <li><strong>MACsec support:</strong> Which port speeds support MACsec encryption</li>\n <li><strong>Associated region:</strong> The AWS region used for managing Direct Connect resources at this location. This helps identify locations associated with opt-in regions that must be enabled in your AWS account before the Direct Connect location can be used</li>\n <li><strong>Organization details:</strong> The colocation provider or facility operator</li>\n</ul>\n\n<h2 id=\"multi-partition-support\">Multi-Partition Support</h2>\n\n<p>The interface includes tabs for different AWS partitions:</p>\n\n<ul>\n <li><strong>AWS Commercial:</strong> Standard AWS regions accessible globally</li>\n <li><strong>AWS GovCloud (US):</strong> US government regions with special compliance requirements</li>\n <li><strong>EU Sovereign Cloud:</strong> Isolated European partition for data sovereignty requirements</li>\n <li><strong>AWS China:</strong> Isolated Chinese partition with separate operations</li>\n</ul>\n\n<p>Each partition displays only the relevant Direct Connect locations, with appropriate filtering and mapping.</p>\n\n<p class=\"notice--info\"><strong>Note:</strong> Most colocation facilities in China are not listed in PeeringDB. For AWS China partition locations, geographic coordinates are obtained from alternative sources, resulting in lower location data fidelity and no PeeringDB facility links.</p>\n\n<h2 id=\"automated-data-collection\">Automated Data Collection</h2>\n\n<p>The repository implements an automated workflow to keep location data current (see Figure 3):</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2026/02/dx-location-details-workflow.png\" title=\"Figure 3: Automated data collection workflow \" class=\"image-popup\">\n<picture>\n <source width=\"561\" height=\"581\" type=\"image/webp\" data-srcset=\" /content/resized/2026/02/dx-location-details-workflow-320.webp 320w, /content/resized/2026/02/dx-location-details-workflow-384.webp 384w, /content/resized/2026/02/dx-location-details-workflow-512.webp 512w, /content/uploads/2026/02/dx-location-details-workflow.webp 561w\" sizes=\"561px\" />\n <source width=\"561\" height=\"581\" data-srcset=\" /content/resized/2026/02/dx-location-details-workflow-320.png 320w, /content/resized/2026/02/dx-location-details-workflow-384.png 384w, /content/resized/2026/02/dx-location-details-workflow-512.png 512w, /content/uploads/2026/02/dx-location-details-workflow.png 561w\" sizes=\"561px\" />\n <img src=\"/content/resized/2026/02/dx-location-details-workflow-320.png\" data-src=\"/content/uploads/2026/02/dx-location-details-workflow.png\" class=\"blur-up lazyautosizes lazyload\" width=\"561\" height=\"581\" alt=\"Figure 3: Automated data collection workflow \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Automated data collection workflow\n</figcaption>\n\n</figure>\n\n<h3 id=\"daily-updates-from-aws\">Daily Updates from AWS</h3>\n\n<p>A GitHub Actions workflow runs daily to:</p>\n\n<ol>\n <li>Query the AWS Direct Connect API across all regions</li>\n <li>Extract location information including codes, names, and available port speeds</li>\n <li>Normalize location codes (removing floor suffixes, MMR designations, etc.)</li>\n <li>Merge data with manually curated mappings to PeeringDB facilities</li>\n</ol>\n\n<h3 id=\"peeringdb-integration\">PeeringDB Integration</h3>\n\n<p>The project maintains mappings between AWS location codes and <a href=\"https://www.peeringdb.com/\">PeeringDB</a> facility IDs.</p>\n\n<p><a href=\"https://www.peeringdb.com/about\">PeeringDB</a> is a freely available, user-maintained database of networks and interconnection data. Originally created to facilitate peering between networks, it has evolved into the de facto global registry of internet infrastructure, including colocation facilities, internet exchanges, and network presence. The database is maintained by over 16,000 registered users representing networks, facilities, and internet exchanges worldwide.</p>\n\n<p>Integrating with PeeringDB makes sense for several reasons:</p>\n\n<ul>\n <li><strong>Industry standard:</strong> PeeringDB is the authoritative source for colocation facility information used across the internet industry</li>\n <li><strong>AWS alignment:</strong> Amazon is a <a href=\"https://www.peeringdb.com/sponsors\">Diamond sponsor of PeeringDB</a> and heavily uses it for public peering coordination through the <a href=\"https://www.peeringdb.com/net/4\">Amazon Global Network</a></li>\n <li><strong>Complete data:</strong> Provides precise geographic coordinates, facility operator details, and links to specifications</li>\n <li><strong>Community maintained:</strong> Regular updates from facility operators ensure data accuracy</li>\n <li><strong>Standardized format:</strong> Structured data enables automated processing and integration</li>\n</ul>\n\n<p>A monthly synchronization process updates:</p>\n\n<ul>\n <li>Geographic coordinates from PeeringDB</li>\n <li>Country codes and city names</li>\n <li>Facility operator details</li>\n <li>Organization information</li>\n</ul>\n\n<h3 id=\"manual-mapping-maintenance\">Manual Mapping Maintenance</h3>\n\n<p>When AWS adds new Direct Connect locations, the repository includes an interactive tool (add_location.py) to:</p>\n\n<ul>\n <li>Identify unmapped location codes</li>\n <li>Search PeeringDB for matching facilities</li>\n <li>Add new mappings to the location database</li>\n <li>Validate coordinate accuracy</li>\n</ul>\n\n<p class=\"notice--info\"><strong>Note:</strong> Although I do work for AWS, no internal data is being used in this repository. Mapping of Direct Connect locations to PeeringDB locations is solely performed manually through public information.</p>\n\n<h1 id=\"use-cases\">Use Cases</h1>\n\n<p>This directory supports several practical use cases:</p>\n\n<h2 id=\"selecting-nearest-locations\">Selecting Nearest Locations</h2>\n\n<p>The interactive map allows customers to:</p>\n\n<ul>\n <li>Click on their data center location to find the nearest Direct Connect facilities</li>\n <li>Compare distances to multiple potential locations</li>\n <li>Evaluate whether to use local Direct Connect or work with a partner for extension</li>\n</ul>\n\n<h2 id=\"evaluating-facility-capabilities\">Evaluating Facility Capabilities</h2>\n\n<p>The detailed information helps customers:</p>\n\n<ul>\n <li>Identify which locations support required port speeds (100G, 400G)</li>\n <li>Determine MACsec availability for encryption requirements</li>\n <li>Research facility operators and their service offerings</li>\n <li>Access PeeringDB for additional facility details</li>\n</ul>\n\n<h2 id=\"multi-region-deployments\">Multi-Region Deployments</h2>\n\n<p>For customers with global AWS deployments:</p>\n\n<ul>\n <li>Filter locations by country or region</li>\n <li>Identify Direct Connect locations near regional offices</li>\n <li>Plan Direct Connect Gateway architectures spanning multiple regions</li>\n <li>Optimize for both cost and performance across geographieses</li>\n</ul>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>The dx-location-details project addresses gaps in the official AWS Direct Connect locations page by providing:</p>\n\n<ul>\n <li><strong>Geographic visualization:</strong> Interactive map showing precise facility locations</li>\n <li><strong>Enhanced filtering:</strong> Search and filter by multiple criteria including country, operator, and capabilities</li>\n <li><strong>Normalized data:</strong> Consistent location codes and structured information</li>\n <li><strong>Automated updates:</strong> Daily synchronization with AWS Direct Connect API</li>\n <li><strong>Multiple export formats:</strong> CSV, KML, and JSON for various use cases</li>\n <li><strong>PeeringDB integration:</strong> Links to detailed facility information</li>\n</ul>\n\n<p>This enhanced directory simplifies Direct Connect planning by making it easy to identify suitable locations, evaluate facility capabilities, and plan for geographic redundancy. The automated update mechanism ensures the information stays current as AWS expands its Direct Connect footprint.</p>\n\n<p>For customers planning AWS Direct Connect deployments, this tool provides the geographic and facility information needed to make informed decisions about location selection, redundancy planning, and partner engagement.</p>\n\n<p>Visit <a href=\"https://chris.elsen.xyz/dx-location-details/\">https://chris.elsen.xyz/dx-location-details/</a> to explore the interactive directory, or access the <a href=\"https://github.com/chriselsen/dx-location-details\">GitHub repository</a> to contribute mappings or use the data programmatically.</p>\n",
"summary": "A searchable directory of AWS Direct Connect locations with geographic data, filtering capabilities, and automated updates",
"date_published": "2026-02-03T00:00:00-08:00",
"date_modified": "2026-02-03T00:00:00-08:00",
"image": "https://www.edge-cloud.net/content/uploads/2026/02/dx-location-details.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Direct-Connect"]
},
{
"id": "https://www.edge-cloud.net/2026/01/13/aws-dx-public-vid-for-s3-only",
"url": "https://www.edge-cloud.net/2026/01/13/aws-dx-public-vid-for-s3-only/",
"title": "Direct Connect Public VIF for S3 traffic only",
"content_html": "<p>When using AWS Direct Connect with a Public Virtual Interface (VIF) to access S3, customers often face a challenge: by default, the Public VIF receives all AWS public IP prefixes via BGP, not just those for S3. This means traffic to all AWS services - including EC2, Lambda, and others - will route over the expensive Direct Connect connection instead of the internet, significantly increasing data transfer costs.</p>\n\n<p>This article explores a solution that allows you to route only S3 traffic over Direct Connect while sending all other AWS traffic over the internet, optimizing both costs and bandwidth usage.</p>\n\n<h1 id=\"the-problem\">The Problem</h1>\n\n<p>AWS Direct Connect Public VIFs are designed to provide access to AWS public services like S3, but they come with a significant limitation: when you establish a BGP session with AWS (AS16509), you receive the complete set of AWS public IP prefixes for the region. This includes prefixes for:</p>\n\n<ul>\n <li>Amazon S3</li>\n <li>Amazon EC2</li>\n <li>AWS Lambda</li>\n <li>All other AWS services with public endpoints</li>\n</ul>\n\n<p>This means your Direct Connect connection will carry traffic not only to your own AWS workloads, but also to other AWS customers’ workloads hosted on these services. With recent estimates showing that up to 80% of the Internet might be running on AWS, this can result in substantial unintended traffic.</p>\n\n<p>For customers who primarily want to use Direct Connect for S3 access - often for large data transfers, backups, or content distribution - this creates two problems:</p>\n\n<ol>\n <li><strong>Increased costs:</strong> All AWS traffic routes over Direct Connect, incurring higher data transfer charges compared to internet egress</li>\n <li><strong>Bandwidth consumption:</strong> Non-S3 traffic consumes valuable Direct Connect bandwidth that could be reserved for S3 transfers</li>\n</ol>\n\n<h1 id=\"the-solution-bgp-prefix-filtering\">The Solution: BGP Prefix Filtering</h1>\n\n<p>The solution involves implementing BGP prefix filtering on your router to accept only S3-specific IP prefixes from AWS while rejecting all others. This creates a hybrid routing scenario where:</p>\n\n<ul>\n <li>S3 traffic → Direct Connect Public VIF (optimized path)</li>\n <li>All other AWS traffic → Internet (cost-effective path)</li>\n</ul>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2026/01/s3-only-pubvif-architecture.png\" title=\"Figure 1: Architecture with S3-only prefix filtering \" class=\"image-popup\">\n<picture>\n <source width=\"1101\" height=\"621\" type=\"image/webp\" data-srcset=\" /content/resized/2026/01/s3-only-pubvif-architecture-320.webp 320w, /content/resized/2026/01/s3-only-pubvif-architecture-384.webp 384w, /content/resized/2026/01/s3-only-pubvif-architecture-512.webp 512w, /content/resized/2026/01/s3-only-pubvif-architecture-683.webp 683w, /content/resized/2026/01/s3-only-pubvif-architecture-800.webp 800w, /content/resized/2026/01/s3-only-pubvif-architecture-960.webp 960w, /content/uploads/2026/01/s3-only-pubvif-architecture.webp 1101w\" sizes=\"1101px\" />\n <source width=\"1101\" height=\"621\" data-srcset=\" /content/resized/2026/01/s3-only-pubvif-architecture-320.png 320w, /content/resized/2026/01/s3-only-pubvif-architecture-384.png 384w, /content/resized/2026/01/s3-only-pubvif-architecture-512.png 512w, /content/resized/2026/01/s3-only-pubvif-architecture-683.png 683w, /content/resized/2026/01/s3-only-pubvif-architecture-800.png 800w, /content/resized/2026/01/s3-only-pubvif-architecture-960.png 960w, /content/uploads/2026/01/s3-only-pubvif-architecture.png 1101w\" sizes=\"1101px\" />\n <img src=\"/content/resized/2026/01/s3-only-pubvif-architecture-320.png\" data-src=\"/content/uploads/2026/01/s3-only-pubvif-architecture.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1101\" height=\"621\" alt=\"Figure 1: Architecture with S3-only prefix filtering \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Architecture with S3-only prefix filtering\n</figcaption>\n\n</figure>\n\n<p>The challenge lies in identifying and maintaining the correct S3 IP prefixes for each AWS region, as these prefixes change over time when AWS expands their infrastructure.</p>\n\n<h1 id=\"automated-solution-s3-only-pubvif-repository\">Automated Solution: s3-only-pubvif Repository</h1>\n\n<p>The <i class=\"fab fa-github\"></i> <a href=\"https://github.com/chriselsen/s3-only-pubvif\">s3-only-pubvif</a> Github repository provides an automated solution to this challenge by:</p>\n\n<h2 id=\"generating-region-specific-prefix-lists\">Generating Region-Specific Prefix Lists</h2>\n\n<p>The repository automatically generates BGP prefix lists for S3 traffic in all AWS regions through an event-driven process:</p>\n\n<ol>\n <li><strong>SNS notification trigger:</strong> AWS <a href=\"https://docs.aws.amazon.com/vpc/latest/userguide/subscribe-notifications.html\">publishes notifications</a> to the SNS topic <code class=\"language-plaintext highlighter-rouge\">arn:aws:sns:us-east-1:806199016981:AmazonIpSpaceChanged</code> whenever changes are made to IP ranges</li>\n <li><strong>Lambda webhook function:</strong> A Lambda function subscribes to this SNS topic and triggers a GitHub Actions workflow via webhook when IP range changes are detected</li>\n <li><strong>Automated processing:</strong> The GitHub Actions workflow downloads the updated <a href=\"https://ip-ranges.amazonaws.com/ip-ranges.json\">ip-ranges.json</a> file from AWS</li>\n <li><strong>Filtering S3 prefixes:</strong> The workflow extracts only the IP prefixes tagged with “service”: “S3” for each region</li>\n <li><strong>Creating router configurations:</strong> Ready-to-use prefix lists are generated for both Cisco IOS and Juniper routers</li>\n</ol>\n\n<p>This event-driven approach ensures that prefix lists are updated immediately when AWS makes infrastructure changes, rather than relying on periodic polling that could miss updates or create delays.</p>\n\n<h2 id=\"supporting-multiple-router-platforms\">Supporting Multiple Router Platforms</h2>\n\n<p>The repository provides configurations for the two most common enterprise router platforms:</p>\n\n<p><strong>Cisco IOS format:</strong></p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ip prefix-list aws-s3-us-east-1 seq 10 permit 52.216.0.0/15 le 24\nip prefix-list aws-s3-us-east-1 seq 20 permit 54.231.0.0/16 le 24\nipv6 prefix-list aws-s3-us-east-1 seq 30 permit 2600:1f60:8000::/39 le 48\n</code></pre></div></div>\n\n<p><strong>Juniper format:</strong></p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>policy-options {\n prefix-list aws-s3-us-east-1 {\n 52.216.0.0/15 orlonger;\n 54.231.0.0/16 orlonger;\n 2600:1f60:8000::/39 orlonger;\n }\n}\n</code></pre></div></div>\n\n<h2 id=\"automated-updates\">Automated Updates</h2>\n\n<p>The repository implements automated updates through:</p>\n\n<ul>\n <li><strong>GitHub Actions workflow:</strong> Automatically triggered when AWS publishes changes to ip-ranges.json</li>\n <li><strong>SNS integration:</strong> AWS publishes notifications to the SNS topic <code class=\"language-plaintext highlighter-rouge\">arn:aws:sns:us-east-1:806199016981:AmazonIpSpaceChanged</code> when IP ranges change</li>\n <li><strong>Lambda webhook:</strong> A Lambda function can subscribe to this SNS topic and trigger the GitHub Actions workflow</li>\n</ul>\n\n<h1 id=\"implementation-considerations\">Implementation Considerations</h1>\n\n<h2 id=\"bgp-prefix-length-filtering\">BGP Prefix Length Filtering</h2>\n\n<p>The generated prefix lists use length restrictions to handle BGP route announcements:</p>\n\n<ul>\n <li><strong>IPv4 prefixes:</strong> Use <code class=\"language-plaintext highlighter-rouge\">le 24</code> (less than or equal to /24) to match more specific announcements</li>\n <li><strong>IPv6 prefixes:</strong> Use <code class=\"language-plaintext highlighter-rouge\">le 48</code> (less than or equal to /48) to match more specific announcements</li>\n</ul>\n\n<p>This ensures that even if AWS announces more specific prefixes than those listed in ip-ranges.json, your router will still accept them. The S3 prefixes announced over Direct Connect Public VIF are identical to those announced over the Internet, ensuring consistent routing behavior.</p>\n\n<h2 id=\"return-traffic-considerations\">Return Traffic Considerations</h2>\n\n<p>An important limitation to understand: these prefix filters only control outbound traffic from your network to AWS. Return traffic from AWS to your network will use whichever path AWS chooses based on the prefixes you announce via BGP.</p>\n\n<p>To minimize exposure while maintaining S3 connectivity, the repository recommends:</p>\n\n<ul>\n <li><strong>Announce minimal prefixes:</strong> Only announce a /32 IPv4 prefix (single IP address) to AWS</li>\n <li><strong>Use NAT/PAT:</strong> Implement Network Address Translation on your router to access S3 from internal networks</li>\n</ul>\n\n<p>This approach ensures that while you can reach S3 over Direct Connect, other AWS services cannot easily reach your internal networks via the Direct Connect path.</p>\n\n<h1 id=\"regional-coverage\">Regional Coverage</h1>\n\n<p>The repository provides prefix lists for all AWS regions, including:</p>\n\n<ul>\n <li>All standard AWS commercial regions (us-east-1, eu-west-1, ap-southeast-1, etc.)</li>\n <li>AWS GovCloud regions (us-gov-east-1, us-gov-west-1)</li>\n <li>Newer regions like Europe Sovereign Cloud (eusc-de-east-1)</li>\n</ul>\n\n<p>Notably excluded are China regions (cn-north-1, cn-northwest-1), which operate under different IP range management.</p>\n\n<h1 id=\"cost-optimization-benefits\">Cost Optimization Benefits</h1>\n\n<p>Implementing S3-only prefix filtering can provide significant cost savings:</p>\n\n<ul>\n <li><strong>Direct Connect data transfer:</strong> Currently $0.02/GB for most regions</li>\n <li><strong>Internet data transfer:</strong> Varies by service but generally lower for non-S3 traffic</li>\n <li><strong>Bandwidth optimization:</strong> Reserve Direct Connect capacity for high-volume S3 transfers</li>\n</ul>\n\n<p>For organizations with large S3 workloads but moderate usage of other AWS services, this approach can reduce overall AWS networking costs while maintaining optimal performance for S3 access.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>The s3-only-pubvif repository solves a common challenge faced by AWS customers using Direct Connect Public VIFs: how to route only S3 traffic over the expensive Direct Connect connection while sending other AWS traffic over the internet.</p>\n\n<p>By providing automated, up-to-date BGP prefix lists for all AWS regions and supporting major router platforms, the repository enables customers to implement cost-effective hybrid routing strategies. The solution is particularly valuable for organizations with significant S3 workloads who want to optimize their AWS networking costs without sacrificing performance.</p>\n\n<p>The automated update mechanism ensures that the prefix lists remain current as AWS expands their infrastructure, providing a maintenance-free solution for long-term deployments.</p>\n",
"summary": "How to use a Direct Connect Public VIF solely for S3 traffic only",
"date_published": "2026-01-13T00:00:00-08:00",
"date_modified": "2026-01-13T00:00:00-08:00",
"image": "https://www.edge-cloud.net/content/uploads/2026/01/aws-dx-public-vid-for-s3-only.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Direct-Connect"]
},
{
"id": "https://www.edge-cloud.net/2023/08/20/video-bring-your-own-ip-for-amazon-vpc",
"url": "https://www.edge-cloud.net/2023/08/20/video-bring-your-own-ip-for-amazon-vpc/",
"title": "Bring your own IP addresses (BYOIP) for Amazon EC2 [Video]",
"content_html": "<p><i class=\"fab fa-fw fa-youtube\"></i> YouTube Videos accompanying the previous blog post <a href=\"https://www.edge-cloud.net/2022/07/19/hands-on-with-aws-byoip/\">Hands-on with AWS Bring your own IP addresses (BYOIP) in Amazon EC2</a>.</p>\n\n<p>Step-by-step guide for moving IP prefixes to AWS with “Bring your own IP addresses” (BYOIP) for Amazon EC2. Steps with the RIRs ARIN and RIPE are shown, including prepartion of address space.</p>\n\n<!-- Courtesy of embedresponsively.com -->\n\n<div class=\"responsive-video-container\">\n <iframe src=\"https://www.youtube-nocookie.com/embed/ynhgzFVe_YM\" frameborder=\"0\" webkitallowfullscreen=\"\" mozallowfullscreen=\"\" allowfullscreen=\"\"></iframe>\n </div>\n\n",
"summary": "YouTube Videos with step-by-step guide for moving IP prefixes to AWS with \"Bring your own IP addresses\" (BYOIP) for Amazon EC2",
"date_published": "2023-08-20T00:00:00-07:00",
"date_modified": "2023-08-20T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2023/08/video-bring-your-own-ip-for-amazon-vpc.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Video"]
},
{
"id": "https://www.edge-cloud.net/2023/07/27/video-move-your-dns-to-route53",
"url": "https://www.edge-cloud.net/2023/07/27/move-your-dns-to-route53/",
"title": "How to move your DNS to Amazon Route 53 [Video]",
"content_html": "<p><i class=\"fab fa-fw fa-youtube\"></i> YouTube Videos accompanying the previous blog post <a href=\"https://www.edge-cloud.net/2023/06/25/move-your-dns-to-route53/\">“How to move your DNS to Amazon Route 53”</a>.</p>\n\n<h2 id=\"part-1-zone-services\">Part 1: Zone Services</h2>\n\n<!-- Courtesy of embedresponsively.com -->\n\n<div class=\"responsive-video-container\">\n <iframe src=\"https://www.youtube-nocookie.com/embed/4B5hDjyFtVg\" frameborder=\"0\" webkitallowfullscreen=\"\" mozallowfullscreen=\"\" allowfullscreen=\"\"></iframe>\n </div>\n\n<h2 id=\"part-2-registration-services\">Part 2: Registration Services</h2>\n\n<!-- Courtesy of embedresponsively.com -->\n\n<div class=\"responsive-video-container\">\n <iframe src=\"https://www.youtube-nocookie.com/embed/qAvwNJOf28Q\" frameborder=\"0\" webkitallowfullscreen=\"\" mozallowfullscreen=\"\" allowfullscreen=\"\"></iframe>\n </div>\n\n",
"summary": "YouTube Videos with step-by-step guide to move your DNS - both registration services and zone file - to Amazon Route 53",
"date_published": "2023-07-25T00:00:00-07:00",
"date_modified": "2023-07-25T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2023/07/video-move-your-dns-to-route53.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Route-53","Video"]
},
{
"id": "https://www.edge-cloud.net/2023/06/25/move-your-dns-to-route53",
"url": "https://www.edge-cloud.net/2023/06/25/move-your-dns-to-route53/",
"title": "How to move your DNS to Amazon Route 53",
"content_html": "<p>This blog post will walk through the migration steps of the DNS setup for a public zone to <a href=\"https://aws.amazon.com/route53/\">Amazon Route 53</a>. It will include steps for both making Route 53 the DNS service for an existing domain, but also transferring the DNS registration for this domain to Route 53. While it will use Google Domains as the DNS service initially providing the zone and registration service, the steps should be easily transferable to any other DNS provider (e.g. GoDaddy) that you would want to migrate away from.</p>\n\n<p class=\"notice\"><strong><i class=\"fab fa-fw fa-youtube\"></i> YouTube Video:</strong> The content presented here is also available as a <a href=\"https://www.edge-cloud.net/2023/07/27/move-your-dns-to-route53/\">series of YouTube videos</a>.</p>\n\n<p class=\"notice--info\"><strong>Note:</strong> While you can accomplish most of the steps in this guide within about 1 hour, waiting for DNSSEC to be fully disabled will take 2 days. Therefore if you are planning to follow this guide you might want to skip ahead to the “Disable DNSSEC” step now and come back for the rest in a few days.</p>\n\n<h1 id=\"motivation\">Motivation</h1>\n\n<p>Recently Google <a href=\"https://support.google.com/domains/answer/13689670\">announced the shutdown of the Google Domains service</a>. While by now Google is certainly known for <a href=\"https://killedbygoogle.com/\">killing off</a> their services with often very little warning, this move came quite unexpected. Google Domains was certainly not perfect, but it offered technical capabilities - like <a href=\"https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions\">DNSSEC</a> - often well before other DNS provider, the user interface was simple and functional, and at least initially there weren’t any attempts to up-sell you to useless services. Therefore it was a great service which will certainly be missed.</p>\n\n<p>Google’s lackluster attempt to quickly put together a replacement with <a href=\"https://cloud.google.com/domains/docs/overview\">Google Cloud Domains</a> does not appear very convincing either. With that it is time to move out of Google Domains and find a new home for my domains.</p>\n\n<h2 id=\"why-amazon-route-53\">Why Amazon Route 53?</h2>\n\n<p>Amazon Route 53 provides a good compromise between <a href=\"https://aws.amazon.com/route53/pricing/\">cost</a>, <a href=\"https://aws.amazon.com/blogs/architecture/a-case-study-in-global-fault-isolation/\">resiliency</a>, <a href=\"https://www.dnsperf.com/#!dns-providers\">performance</a>, <a href=\"https://aws.amazon.com/route53/features/\">feature set</a> and ease of use. \nThe cost for a registered domain is well in line with most other providers. With AWS you pay for what you use and as such you will be charged separately for the numbers of zones you use as well as e.g. number of queries your zone receives or whether you use DNSSEC or not. But these cost are very reasonable. \nAmazon Route 53 is the only AWS service with a <a href=\"https://aws.amazon.com/route53/sla/\">100% uptime SLA</a> on the data plane - meaning responding to DNS queries. And to my knowledge since the service was released in December 2010, this SLA has not been breached. \nAnother huge benefit is the availability of an <a href=\"https://docs.aws.amazon.com/Route53/latest/APIReference/\">API</a>, which allows you to programmatically manage almost all components of the domain lifecycle.</p>\n\n<h1 id=\"background\">Background</h1>\n\n<p>First let’s understand what is actually involved when managing a DNS zone. This will help us better understand what steps are necessary to move the management of these components across providers and also what we need to do to move these management components to another provider. For this example I will use the example domain <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>, where we will change both the zone management and also registration services.</p>\n\n<h2 id=\"zone-management-vs-registration-services\">Zone Management vs. Registration services</h2>\n\n<p>At it’s foundation, DNS allows us to resolve a hostname like <code class=\"language-plaintext highlighter-rouge\">www.movetor53.com</code> into an IP address like <code class=\"language-plaintext highlighter-rouge\">198.51.100.123</code>. This is accomplished by a client - e.g. a browser - using a recursive resolver (See Figure 1). An example for such a recursive resolver is <a href=\"https://developers.google.com/speed/public-dns/docs/using\">Google Public DNS</a>. Simplified speaking the resolver will contact one of the <a href=\"https://en.wikipedia.org/wiki/Root_name_server\">root servers</a> to start the recursion. While the root server doesn’t know the answer for the entire hostname, it does know which top level domain (TLD) servers are responsible for <code class=\"language-plaintext highlighter-rouge\">.com</code> and point the resolver to these servers. Similarly for the next request to one of the TLD servers will it point the resolver towards the authoritative server for <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>. Finally after contacting the authoritative server for <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>, will the resolver receive a response for <code class=\"language-plaintext highlighter-rouge\">www.movetor53.com</code>.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-dns-components.png\" title=\"Figure 1: Components of a typical DNS setup for a domain, enabling recursive lookups of records. \" class=\"image-popup\">\n<picture>\n <source width=\"860\" height=\"423\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-dns-components-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-800.webp 800w, /content/uploads/2023/06/move-your-dns-to-route53-dns-components.webp 860w\" sizes=\"860px\" />\n <source width=\"860\" height=\"423\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-dns-components-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-dns-components-800.png 800w, /content/uploads/2023/06/move-your-dns-to-route53-dns-components.png 860w\" sizes=\"860px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-dns-components-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-dns-components.png\" class=\"blur-up lazyautosizes lazyload\" width=\"860\" height=\"423\" alt=\"Figure 1: Components of a typical DNS setup for a domain, enabling recursive lookups of records. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Components of a typical DNS setup for a domain, enabling recursive lookups of records.\n</figcaption>\n\n</figure>\n\n<p>From a DNS management perspective there are two spots that as the owner of <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> we need to change:</p>\n<ul>\n <li><strong>DNS Zone Management:</strong> The DNS zone management controls the actual entries in the zone <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> itself. It includes creating, changing or deleting records like <code class=\"language-plaintext highlighter-rouge\">www</code> or <code class=\"language-plaintext highlighter-rouge\">mail</code>, which can be of different types like <code class=\"language-plaintext highlighter-rouge\">A</code>, <code class=\"language-plaintext highlighter-rouge\">AAAA</code>, <code class=\"language-plaintext highlighter-rouge\">CNAME</code>, <code class=\"language-plaintext highlighter-rouge\">MX</code>, or others. While in the old days you actually had to setup a set of servers running DNS software like <a href=\"https://www.isc.org/bind/\">BIND</a>, with the availability of DNS services like Route 53, you no longer have to worry about this undifferentiated heavy lifting and can focus on the entries itself. In the case of Route 53 you can thereby make use of DNS server distributed across <a href=\"https://aws.amazon.com/about-aws/global-infrastructure/\">400+ Edge Locations</a>.</li>\n <li><strong>DNS Registration Services</strong> The DNS registration services offer a few main components: 1) Exclusive use of a specific domain name as long as you meet the legal requirements of that particular top level domain, 2) Ability to update the TLD server for that TLD zone with a pointer to the authoritative DNS servers of the domain name, 3) Ability to upload the DNSSEC public key for the specific domain name, to create the chain of trust.</li>\n</ul>\n\n<h2 id=\"api-usage\">API Usage</h2>\n\n<p>While Route 53 offers an <a href=\"https://docs.aws.amazon.com/Route53/latest/APIReference/\">API</a> for both the zone management and the registration services, Google Domains does not offer an API. Therefore besides showing the web-console based approach for the migration, I can only show you how to use the API with Route 53. If you are following this walk-through while using another existing DNS provider, you might be able to use this provider’s API to e.g. export the zone file.</p>\n\n<h1 id=\"initial-setup\">Initial setup</h1>\n\n<p>Let’s have a look at our initial DNS setup in Google Domains before we start making changes (See Figure 2). As mentioned above we will be using the domain <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> for this guide.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-google-domains-zone.png\" title=\"Figure 2: Google Domains DNS information, highlighting the zone name, current zone entries, DNSSEC being enabled and that besides using registration services for this zone, the zone itself is also managed by Google Domains. \" class=\"image-popup\">\n<picture>\n <source width=\"1123\" height=\"1207\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-960.webp 960w, /content/uploads/2023/06/move-your-dns-to-route53-google-domains-zone.webp 1123w\" sizes=\"1123px\" />\n <source width=\"1123\" height=\"1207\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-960.png 960w, /content/uploads/2023/06/move-your-dns-to-route53-google-domains-zone.png 1123w\" sizes=\"1123px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-google-domains-zone-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-google-domains-zone.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1123\" height=\"1207\" alt=\"Figure 2: Google Domains DNS information, highlighting the zone name, current zone entries, DNSSEC being enabled and that besides using registration services for this zone, the zone itself is also managed by Google Domains. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Google Domains DNS information, highlighting the zone name, current zone entries, DNSSEC being enabled and that besides using registration services for this zone, the zone itself is also managed by Google Domains.\n</figcaption>\n\n</figure>\n\n<p>Here we can see a few important facts for the zone <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>:</p>\n<ul>\n <li>Both the zone itself as well as the registration services are with Google Domains.</li>\n <li>DNSSEC is enabled for the zone.</li>\n <li>We can see some typical zone records, including e.g. MX entries for <a href=\"https://workspace.google.com/\">Google Workspaces</a>, also including <a href=\"https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail\">DKIM</a> public keys. And a CNAME entry for <code class=\"language-plaintext highlighter-rouge\">www.movetor53.com</code> pointing towards a <a href=\"https://aws.amazon.com/cloudfront/\">CloudFront</a> distribution is also present.</li>\n</ul>\n\n<h1 id=\"migration-overview\">Migration Overview</h1>\n\n<p>For the migration we will be looking at three main parts that should be performed in this order:</p>\n<ol>\n <li>Move the DNS zone</li>\n <li>Move the registration services</li>\n <li>Optimize DNS records</li>\n</ol>\n\n<p>Each part has multiple steps.</p>\n\n<p class=\"notice--info\"><strong>Note:</strong> Many DNS provider - including Google Domains - will remove the DNS zone, when you move the registration services for that domain to another provider. Therefore doing the above parts out of order or even skipping the first part would cause an outage!</p>\n\n<h1 id=\"move-the-dns-zone\">Move the DNS zone</h1>\n\n<p>In this first part we will move the DNS zone from Google Domains into a <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html\">Public Hosted Zone</a> on Route 53. Once this part is complete, DNS zone management will be performed in Route 53, while DNS registration services are still with Google Domain.</p>\n\n<h2 id=\"disable-dnssec\">Disable DNSSEC</h2>\n\n<p>Google Domains enabled DNSSEC by default for any supported domains. While there is a technical approach for DNSSEC migrations with the Double-DS KSK rollover method described in <a href=\"https://datatracker.ietf.org/doc/html/rfc6781#appendix-D\">RFC 6781 - Appendix D Alternative Rollover Approach for Cooperating Operators</a>, this approach cannot be used here.\nTherefore first we must disable DNSSEC on our domain by removing any DS or DNSKEY from the TLD zone. Later on, once the zone has been migrated to Route 53, we will enable DNSSEC again.</p>\n\n<p>In Google Domains you disable DNSSEC by selecting <strong>Turn off</strong> in the <em>DNSSEC</em> section under the <em>DNS</em> tab (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-disable-dnssec.png\" title=\"Figure 3: Disable DNSSEC in the Google Domains portal. \" class=\"image-popup\">\n<picture>\n <source width=\"1061\" height=\"239\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-960.webp 960w, /content/uploads/2023/06/move-your-dns-to-route53-disable-dnssec.webp 1061w\" sizes=\"1061px\" />\n <source width=\"1061\" height=\"239\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-960.png 960w, /content/uploads/2023/06/move-your-dns-to-route53-disable-dnssec.png 1061w\" sizes=\"1061px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-disable-dnssec-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-disable-dnssec.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1061\" height=\"239\" alt=\"Figure 3: Disable DNSSEC in the Google Domains portal. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Disable DNSSEC in the Google Domains portal.\n</figcaption>\n\n</figure>\n\n<p>At this point you have to wait 48h for DNS TTLs to expire and thereby for DNSSEC to be fully disabled. Google Domains will show the date and time by when this will be the case (See Figure 4).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-wait-dnssec-disabled.png\" title=\"Figure 4: Wait for DNSSEC to be fully disabled, two days after it was disabled. \" class=\"image-popup\">\n<picture>\n <source width=\"1055\" height=\"100\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-960.webp 960w, /content/uploads/2023/06/move-your-dns-to-route53-wait-dnssec-disabled.webp 1055w\" sizes=\"1055px\" />\n <source width=\"1055\" height=\"100\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-960.png 960w, /content/uploads/2023/06/move-your-dns-to-route53-wait-dnssec-disabled.png 1055w\" sizes=\"1055px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-wait-dnssec-disabled-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-wait-dnssec-disabled.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1055\" height=\"100\" alt=\"Figure 4: Wait for DNSSEC to be fully disabled, two days after it was disabled. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: Wait for DNSSEC to be fully disabled, two days after it was disabled.\n</figcaption>\n\n</figure>\n\n<p>While you can continue with the next few steps, we will have to wait for DNSSEC to be fully disable before we can change the nameserver for the zone (final step of this part).\nThere is no way to speed up this wait time and if you choose not to wait you will risk an outage of DNS resolution for your domain.</p>\n\n<h2 id=\"export-the-zone-file\">Export the zone file</h2>\n\n<p>Next we want to export the current zone file in a format that we can later import into Route 53. The standard format to exchange such zone files is the <a href=\"https://en.wikipedia.org/wiki/Zone_file\">BIND format</a>. Therefore most DNS provider offer some kind of capability to export the current zone file within this format. \nFor Google Domains this process is very straight forward: Within the <em>Resource records</em> section on the <em>DNS</em> tab, select <strong>Export DNS records</strong> and select <strong>Export to BIND</strong> on the next popup (See Figure 5).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-export-to-bind.png\" title=\"Figure 5: Export a zone file from Google Domains in BIND format. \" class=\"image-popup\">\n<picture>\n <source width=\"1060\" height=\"361\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-960.webp 960w, /content/uploads/2023/06/move-your-dns-to-route53-export-to-bind.webp 1060w\" sizes=\"1060px\" />\n <source width=\"1060\" height=\"361\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-export-to-bind-960.png 960w, /content/uploads/2023/06/move-your-dns-to-route53-export-to-bind.png 1060w\" sizes=\"1060px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-export-to-bind-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-export-to-bind.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1060\" height=\"361\" alt=\"Figure 5: Export a zone file from Google Domains in BIND format. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 5: Export a zone file from Google Domains in BIND format.\n</figcaption>\n\n</figure>\n\n<p>That’s it! The browser will now download the resulting zone file in BIND format. Once you open it with your favorite text editor you’ll see a result similar to the one below for our zone <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>. Each line represents one DNS record and will be imported as such.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>; A BIND file is a .TXT file that's used to export\n; DNS records from one domain to another. BIND\n; files are commonly used by lots of domain\n; registrars, so they're a good choice if\n; you're exporting resource records to a domain\n; that's managed by a different registrar.\n\nmovetor53.com. 3600 IN MX 1 aspmx.l.google.com.\nmovetor53.com. 3600 IN MX 5 alt1.aspmx.l.google.com.\nmovetor53.com. 3600 IN MX 5 alt2.aspmx.l.google.com.\nmovetor53.com. 3600 IN MX 10 alt3.aspmx.l.google.com.\nmovetor53.com. 3600 IN MX 10 alt4.aspmx.l.google.com.\nmovetor53.com. 3600 IN TXT \"v=spf1 include:_spf.google.com -all\"\n_6bf42c523881808e49a6153e5c63ba6b.movetor53.com. 3600 IN CNAME _d2f51270e8809df9671385766662cf2e.fpwkmzyskh.acm-validations.aws.\n_dmarc.movetor53.com. 3600 IN TXT \"v=DMARC1;p=reject;rua=mailto:rua@example.com;ruf=mailto:ruf@example.com;fo=1\"\ngoogle._domainkey.movetor53.com. 3600 IN TXT \"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAraC3pqvqTkAfXhUn7Kn3JUNMwDkZ65ftwXH58anno/bElnTDAd/idk8kWpslrQIMsvVKAe+mvmBEnpXzJL+0LgTNVTQctUujyilWvcONRd/z37I34y6WUIbFn4ytkzkdoVmeTt32f5LxegfYP4P/w7QGN1mOcnE2Qd5SKIZv3Ia1p9d6uCaVGI8brE/7zM5c/zMthVPE2W\" \"ZKA28+QomQDH7ludLGhXGxpc7kZZCoB5lQiP0o07Ful33fcED73BS9Bt1SNhnrs5v7oq1pIab0LEtHsFHAZmGJDjybPA7OWWaV3L814r/JfU2NK1eNu9xYJwA8YW7WosL45CSkyp4QeQIDAQAB\"\nwww.movetor53.com. 3600 IN CNAME dgwkbb1gumfgi.cloudfront.net.\nmovetor53.com. 3600 IN A 216.239.32.21\nmovetor53.com. 3600 IN A 216.239.34.21\nmovetor53.com. 3600 IN A 216.239.36.21\nmovetor53.com. 3600 IN A 216.239.38.21\nmovetor53.com. 3600 IN AAAA 2001:4860:4802:32::15\nmovetor53.com. 3600 IN AAAA 2001:4860:4802:34::15\nmovetor53.com. 3600 IN AAAA 2001:4860:4802:36::15\nmovetor53.com. 3600 IN AAAA 2001:4860:4802:38::15\n\n</code></pre></div></div>\n\n<h3 id=\"fixing-2048-bit-dkim-records\">Fixing 2048-bit DKIM records</h3>\n<p>There is one little catch that we need to take care of before we can import this zone file into Route 53 and it’s related to DKIM public key records for Google Workspaces. By default Google Workspaces uses 2048-bit DKIM keys, which you can’t enter as a single text string in a DNS record with a 255-character limit. Although Google provides <a href=\"https://support.google.com/a/answer/11613097?hl=en\">guidance</a> on how to deal with these keys, that guidance is not very clear and the provided example is actually wrong. \nIn addition the Route 53 Console doesn’t like the way these 2048-bit DKIM records were exported and ignores them. But there is a very quick and easy fix to it.</p>\n\n<p>If you use the Route 53 API to import the zone file in BIND format (See below), this correction is not necessary. Also if you are not using any 2048-bit DKIM keys or other records longer than 255 characters, there is no correction necessary.</p>\n\n<p>You’ll notice a line for the 2048-bit DKIM record in the format of <code class=\"language-plaintext highlighter-rouge\">google._domainkey.movetor53.com. 3600 IN TXT \"k=rsa; p=<long string>\" \"<another long string>\"</code>. The problem here is the whitespace between the two quotation marks (“). Just remove that whitespace to make it look like this: <code class=\"language-plaintext highlighter-rouge\">google._domainkey.movetor53.com. 3600 IN TXT \"k=rsa; p=<long string>\"\"<another long string>\"</code>.</p>\n\n<p>The final result should look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>...\ngoogle._domainkey.movetor53.com. 3600 IN TXT \"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAraC3pqvqTkAfXhUn7Kn3JUNMwDkZ65ftwXH58anno/bElnTDAd/idk8kWpslrQIMsvVKAe+mvmBEnpXzJL+0LgTNVTQctUujyilWvcONRd/z37I34y6WUIbFn4ytkzkdoVmeTt32f5LxegfYP4P/w7QGN1mOcnE2Qd5SKIZv3Ia1p9d6uCaVGI8brE/7zM5c/zMthVPE2W\"\"ZKA28+QomQDH7ludLGhXGxpc7kZZCoB5lQiP0o07Ful33fcED73BS9Bt1SNhnrs5v7oq1pIab0LEtHsFHAZmGJDjybPA7OWWaV3L814r/JfU2NK1eNu9xYJwA8YW7WosL45CSkyp4QeQIDAQAB\"\n...\n</code></pre></div></div>\n\n<h2 id=\"create-a-public-hosted-zone-in-route-53\">Create a public hosted zone in Route 53</h2>\n\n<p>Next we need to <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingHostedZone.html\">create a new public hosted zone in Route 53</a> for our domain <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>. Head over to the <a href=\"https://console.aws.amazon.com/route53/\">Route 53 console</a> within the AWS Management Console and select <strong>Hosted Zones</strong> from the navigation pane.</p>\n<ul>\n <li>Choose <strong>Create hosted zone</strong>. In the <em>Create Hosted Zone pane</em>, enter the name of the domain that you want to route traffic for. In our case it is <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>. You can also optionally enter a comment.</li>\n <li>For <em>Type</em>, accept the default value of <strong>Public Hosted Zone</strong> and choose <strong>Create</strong>.</li>\n</ul>\n\n<p>Once the zone has been created you’ll automatically be placed inside this new Public Hosted zone. At this point you will only see the NS record with the four Route 53 nameservers as well as the SOA record (See Figure 6).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-new-zone.png\" title=\"Figure 6: Empty Public Hosted Zone in Route 53 with SOA and NS records. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-new-zone-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-960.webp 960w, \" sizes=\"1296px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-new-zone-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-new-zone-960.png 960w, \" sizes=\"1296px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-new-zone-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-new-zone.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 6: Empty Public Hosted Zone in Route 53 with SOA and NS records. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 6: Empty Public Hosted Zone in Route 53 with SOA and NS records.\n</figcaption>\n\n</figure>\n\n<h2 id=\"import-the-zone-file-into-route-53\">Import the zone file into Route 53</h2>\n\n<p>You are ready to import the corrected zone file in BIND format into Route 53. For this select <strong>Import zone file</strong> within the <em>Records</em> pane of the public hosted zone in the Route 53 console. Next copy and paste the entries from the zone file in BIND format into the window that opens (See Figure 7).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-import-zone.png\" title=\"Figure 7: Import a BIND zone file into Route 53. Make sure you have fixed entries that are longer than 255 character, like DKIM public certificates. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-import-zone-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-960.webp 960w, \" sizes=\"1584px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-import-zone-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-import-zone-960.png 960w, \" sizes=\"1584px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-import-zone-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-import-zone.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 7: Import a BIND zone file into Route 53. Make sure you have fixed entries that are longer than 255 character, like DKIM public certificates. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 7: Import a BIND zone file into Route 53. Make sure you have fixed entries that are longer than 255 character, like DKIM public certificates.\n</figcaption>\n\n</figure>\n\n<p>You will see all records that Route 53 was able to identify within the zone file displayed. If you correctly fixed the entry for the 2048-bit DKIM record, by removing the white space, you will also see the corresponding TXT record type entry (See highlighted in red in Figure 7).</p>\n\n<p>Once everything looks good, click on <strong>Import</strong> and Route 53 will create all the records into our public hosted zone (See Figure 8).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-r53-zone.png\" title=\"Figure 8: The new public hosted zone with the imported records. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-r53-zone-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-960.webp 960w, \" sizes=\"1281px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-r53-zone-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-r53-zone-960.png 960w, \" sizes=\"1281px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-r53-zone-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-r53-zone.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 8: The new public hosted zone with the imported records. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 8: The new public hosted zone with the imported records.\n</figcaption>\n\n</figure>\n\n<p>After a few seconds our zone is ready and can serve traffic via the Route 53 authoritative name servers. But at this point nobody other than us knows yet about this new zone on a different authoritative name server.</p>\n\n<h3 id=\"create-and-import-via-route-53-api\">Create and import via Route 53 API</h3>\n\n<p>If you prefer using the Route 53 API - e.g. because you want to do this process for hundreds of domains - you can look at the very valuable open source command line tool for Amazon Route 53, called “<a href=\"https://github.com/barnybug/cli53\">cli53</a>”. You can even run it without any issues within <a href=\"https://aws.amazon.com/cloudshell/\">AWS CloudShell</a>. Just download the latest <a href=\"https://github.com/barnybug/cli53/releases\">release</a> for amd64, make it executable and you’re ready to run it. If you are using AWS CloudShell you can quickly and easily upload the zone file in BIND format via <strong>Action -> Upload file</strong>. Also, when running cli53 in AWS CloudShell, AWS credentials don’t need to be configured.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-23-45 ~]$ wget -q https://github.com/barnybug/cli53/releases/download/0.8.22/cli53-linux-amd64\n[cloudshell-user@ip-10-1-23-45 ~]$ chmod +x cli53-linux-amd64\n[cloudshell-user@ip-10-1-23-45 ~]$ ./cli53-linux-amd64 -v\ncli53 version 0.8.22 \n</code></pre></div></div>\n\n<p>If you are moving multiple zones, you want to make use of a <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html#route-53-concepts-reusable-delegation-set\">reusable delegation set</a> within Route 53. By default, Route 53 assigns a random selection of name servers to each new hosted zone. To make it easier to migrate DNS service to Route 53 for a large number of domains, you can create a reusable delegation set and then associate the reusable delegation set with new hosted zones. Therefore all migrated zones will have the same set of four Route 53 authoritative name servers.</p>\n\n<p>To create a new reusable delegation set with cli53, use the command <code class=\"language-plaintext highlighter-rouge\">cli53 dscreate</code>. Afterwards you can specify the delegation set ID when creating a new public hosted zone with <code class=\"language-plaintext highlighter-rouge\">cli53 create --delegation-set-id <delegation set id> movetor52.com</code>.</p>\n\n<p>Here is how this will look like:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-2-169-87 ~]$ ./cli53-linux-amd64 dscreate\nCreated reusable delegation set ID: '/delegationset/N12345678ABCDEFGH1IJK'\nNameserver: ns-1990.awsdns-56.co.uk\nNameserver: ns-118.awsdns-14.com\nNameserver: ns-551.awsdns-04.net\nNameserver: ns-1366.awsdns-42.org\n[cloudshell-user@ip-10-2-169-87 ~]$ ./cli53-linux-amd64 create --delegation-set-id N12345678ABCDEFGH1IJK movetor52.com\nCreated zone: 'movetor52.com.' ID: '/hostedzone/Z12345678ABC9DEF0GH12'\n</code></pre></div></div>\n\n<p>For subsequent domains you would then re-use the same delegation set via <code class=\"language-plaintext highlighter-rouge\">--delegation-set-id N12345678ABCDEFGH1IJK</code> and receive the same set of Route 53 authoritative name servers for the zones.</p>\n\n<p>To import the zone file in BIND format with cli53, use the parameter <code class=\"language-plaintext highlighter-rouge\">cli53 import --file movetor53.com.zone movetor53.com</code>.</p>\n\n<p>The final result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-23-45 ~]$ ./cli53-linux-amd64 import --file movetor53.com.zone movetor53.com \n18 records imported (8 changes / 8 additions / 0 deletions) \n[cloudshell-user@ip-10-1-23-45 ~]$\n</code></pre></div></div>\n\n<h2 id=\"test-the-new-zone\">Test the new zone</h2>\n\n<p>This is the perfect moment to test whether the Route 53 authoritative name servers will respond to DNS queries for the zone <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> in the way that we expect it. A very quick and easy approach to do so is to use the tool <code class=\"language-plaintext highlighter-rouge\">dig</code> or a <a href=\"https://www.digwebinterface.com/?hostnames=google._domainkey.movetor53.com&type=TXT&ns=self&nameservers=ns-431.awsdns-53.com\">corresponding online service</a>.</p>\n\n<p>If we e.g. want to check whether the above mentioned DKIM record is available in our Route 53 Public hosted zone, we can query one of the Route 53 authoritative name servers for our zone directly:</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ubuntu@ubuntu:~$ dig +short TXT google._domainkey.movetor53.com @ns-431.awsdns-53.com\n\"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAraC3pqvqTkAfXhUn7Kn3JUNMwDkZ65ftwXH58anno/bElnTDAd/idk8kWpslrQIMsvVKAe+mvmBEnpXzJL+0LgTNVTQctUujyilWvcONRd/z37I34y6WUIbFn4ytkzkdoVmeTt32f5LxegfYP4P/w7QGN1mOcnE2Qd5SKIZv3Ia1p9d6uCaVGI8brE/7zM5c/zMthVPE2W\" \"ZKA28+QomQDH7ludLGhXGxpc7kZZCoB5lQiP0o07Ful33fcED73BS9Bt1SNhnrs5v7oq1pIab0LEtHsFHAZmGJDjybPA7OWWaV3L814r/JfU2NK1eNu9xYJwA8YW7WosL45CSkyp4QeQIDAQAB\"\n</code></pre></div></div>\n<p>The nameserver specified via <code class=\"language-plaintext highlighter-rouge\">@</code> is one of the four authoritative Route 53 name servers for our zone that is listed in the NS record. We can see that Route 53 does deliver a response and that it matches the value from our BIND file.</p>\n\n<p>But this approach is very cumbersome, especially if you want to do this for all records in a large BIND zone file. And also comparing the responses - e.g. a long DKIM key - is not very convenient.</p>\n\n<p>Instead have a look at the tool <a href=\"https://github.com/chriselsen/dns_compare\">dns_compare</a>, which automates this task for you. You can either run it locally under Linux or use <a href=\"https://aws.amazon.com/cloudshell/\">AWS CloudShell</a> instead. If you are using AWS CloudShell you can quickly and easily upload our zone file in BIND format via <strong>Action -> Upload file</strong>.</p>\n\n<p>Once you have <em>dns_compare</em> installed, run it while pointing to the local zone file in BIND format and one of the four authoritative Route 53 name servers for the zone.</p>\n\n<p>If everything was imported correctly, <em>dns_compare</em> will report zero mis-matches:</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ubuntu@ubuntu:~$ dns_compare --zone movetor53.com --file movetor53.com.zone --server ns-431.awsdns-53.com\n........done\n\nResults:\nMatches: 8\nMis-matches: 0\n</code></pre></div></div>\n\n<p>In case you e.g. forgot to fix the entry for the 2048-bit DKIM record and it wasn’t imported, the tool will inform you about this mismatch.</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ubuntu@ubuntu:~$ dns_compare --zone movetor53.com --file movetor53.com.zone --server ns-431.awsdns-53.com\n......X\n(MIS-MATCH) query: google._domainkey.movetor53.com.\nExpected: 3600 IN TXT \"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAraC3pqvqTkAfXhUn7Kn3JUNMwDkZ65ftwXH58anno/bElnTDAd/idk8kWpslrQIMsvVKAe+mvmBEnpXzJL+0LgTNVTQctUujyilWvcONRd/z37I34y6WUIbFn4ytkzkdoVmeTt32f5LxegfYP4P/w7QGN1mOcnE2Qd5SKIZv3Ia1p9d6uCaVGI8brE/7zM5c/zMthVPE2W\" \"ZKA28+QomQDH7ludLGhXGxpc7kZZCoB5lQiP0o07Ful33fcED73BS9Bt1SNhnrs5v7oq1pIab0LEtHsFHAZmGJDjybPA7OWWaV3L814r/JfU2NK1eNu9xYJwA8YW7WosL45CSkyp4QeQIDAQAB\"\nReceived: None\n.done\n\nResults:\nMatches: 7\nMis-matches: 1\n</code></pre></div></div>\n\n<p>While Route 53 <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html\">supports a lot of DNS record types</a>, some newer and not frequently used types are not supported yet. Google Domains does already support some of these record types, which are namely: <a href=\"https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-12\">HTTPS</a>, <a href=\"https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-12\">SVCB</a>, <a href=\"https://datatracker.ietf.org/doc/html/rfc4255\">SSHFP</a>, and <a href=\"https://www.rfc-editor.org/rfc/rfc6698\">TLSA</a>. If you see mis-matches involving these record types, you’ll have to forgo using these entries.</p>\n\n<p>Once you have confirmed no other mis-matches exist between the exported zone file and the new Route 53 Public Hosted Zone, we are ready to let the world know about these new Route 53 authoritative name servers.</p>\n\n<h2 id=\"enable-dnssec-optional\">Enable DNSSEC (Optional)</h2>\n\n<p>While enabling DNSSEC again is completely optional, it is highly recommended due to the benefits that DNSSEC brings to the table. And while using DNSSEC with Route 53 incurs an extra cost of US$ 1 / month for storing the AWS Key Management Service (AWS KMS) customer managed key (CMK) for the DNSSEC Key-signing key (KSK), that CMK can be shared across multiple zones to reduce cost.</p>\n\n<p>Also you’ll notice that the complexity and overhead for enabling and using DNSSEC is quite low with Route 53, as almost everything is done for you.</p>\n\n<p>To <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-configuring-dnssec-enable-signing.html#dns-configuring-dnssec-enable\">enable DNSSEC</a> on our zone, head over to the <em>DNSSEC signing</em> tab within the Public Hosted Zone and choose <strong>Enable DNSSEC signing</strong>.</p>\n\n<ul>\n <li>In the <em>Key-signing key (KSK) creation</em> section, enter a name for the KSK that Route 53 will create into the <em>Provide KSK name</em> field.</li>\n <li>Under <em>Customer managed CMK in AWS KMS</em>, choose the customer managed key for Route 53 to use when it creates the KSK for you. You can use an existing customer managed key that applies to DNSSEC signing, or create a new customer managed key. You can re-use the same customer managed CMK for multiple DNS zones in Route 53. \nOnce complete click on <strong>Create KSK and enable signing</strong>.</li>\n</ul>\n\n<p>Next we need to lookup the information to establish the chain of trust. Within the <em>DNSSEC signing</em> tab select <strong>View information to create DS record</strong> and expand the <em>Establish a chain of trust</em> block (See Figure 9).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-lookup-dnssec.png\" title=\"Figure 9: Lookup the new DNSSEC values to be placed into the registration services. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-960.webp 960w, \" sizes=\"1358px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-960.png 960w, \" sizes=\"1358px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-lookup-dnssec-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-lookup-dnssec.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 9: Lookup the new DNSSEC values to be placed into the registration services. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 9: Lookup the new DNSSEC values to be placed into the registration services.\n</figcaption>\n\n</figure>\n\n<p>Out of the many displayed values we will only need four of them for the case of Google Domain:</p>\n<ul>\n <li>Field 1: Key Tag</li>\n <li>Field 2: Algorithm (aka “Signing algorithm type”)</li>\n <li>Field 3: Digest Type (aka “Digest algorithm type”)</li>\n <li>Field 4: Digest</li>\n</ul>\n\n<h2 id=\"change-the-nameserver-for-the-zone\">Change the nameserver for the zone</h2>\n\n<p>We are almost done with moving the DNS zone for <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>. As a last step we need to update the nameserver for that zone within the TLD severs for <code class=\"language-plaintext highlighter-rouge\">.COM</code>.</p>\n\n<p>Make sure to only commence with this step after the 48 hours for disabling DNSSEC in Google Domains have completed (See above).</p>\n\n<p>Within the Route 53 Console lookup the nameservers for the newly created Public Hosted Zone. You will find these four nameservers in the <em>Hosted zone details</em> section (See Figure 10).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-lookup-ns.png\" title=\"Figure 10: Lookup the new nameserver values to be placed into the registration services. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-960.webp 960w, \" sizes=\"1333px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-lookup-ns-960.png 960w, \" sizes=\"1333px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-lookup-ns-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-lookup-ns.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 10: Lookup the new nameserver values to be placed into the registration services. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 10: Lookup the new nameserver values to be placed into the registration services.\n</figcaption>\n\n</figure>\n\n<p>Next, head back to Google Domains to change the nameservers for the zone.</p>\n\n<p>Under the <em>DNS</em> tab select <em>*Custom name servers</em> to start the setup. Enter the following data (See Figure 11):</p>\n<ul>\n <li><strong>Name servers:</strong> Within the <em>Name servers</em> section enter the four nameserver that correspond to the newly created Route 53 Public hosted zone.</li>\n <li><strong>DNSSEC (Optional):</strong> If you want to use DNSSEC, enter the DNSSEC details to establish the chain of trust. You have looked up the corresponding data for the fields <em>Key Tag</em>, <em>Algorithm</em>, <em>Digest Type</em>, and <em>Digest</em> in the previous step.</li>\n</ul>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-custom-ns-setup.png\" title=\"Figure 11: Update your registration services through a “Customer name server” setup. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-960.webp 960w, \" sizes=\"1368px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-960.png 960w, \" sizes=\"1368px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-custom-ns-setup-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-custom-ns-setup.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 11: Update your registration services through a “Customer name server” setup. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 11: Update your registration services through a “Customer name server” setup.\n</figcaption>\n\n</figure>\n\n<p>Once complete, select <strong>Save</strong> for both sections. Afterwards click on <strong>Switch to these settings</strong> in the yellow box at the top of the screen.</p>\n\n<p>At this point it will take up to 48 hours for the zone of the domain to be fully moved from Google Domains to Route 53. During this time you should not make any changes to the records in the zone. Unfortunately Google Domains does not offer you the capability to reduce the TTL for NS records and thereby speed up this migration window.</p>\n\n<h1 id=\"move-the-registration-services\">Move the registration services</h1>\n\n<p>While the zone is being fully moved from Google Domains to Route 53 we can already start moving the registration services from Google Domains to Route 53 as well.</p>\n\n<p>To do so we start in Google Domains on the <em>Registration Settings</em> tab of the domain. In the <em>Domain registration</em> section:</p>\n<ul>\n <li>Under <em>Domain lock</em> make sure your domain is unlocked.</li>\n <li>To the right of <em>Transfer out</em> click <strong>Get auth code</strong>. Select <strong>To a different domain registrar</strong> and click <strong>Continue</strong>.\nCopy the authorization code. We will use it very shortly.</li>\n</ul>\n\n<p>Head over to the <a href=\"https://console.aws.amazon.com/route53/domains/\">Route 53 Domain Registrar Console</a> within the AWS Console.</p>\n<ul>\n <li>Select <strong>Transfer in -> Single domain</strong>.</li>\n <li>Enter the domain name to transfer and click on <strong>Check</strong>.</li>\n</ul>\n\n<p>On the next page you’ll see if the domain can be transferred (See Figure 12).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-registrar-start.png\" title=\"Figure 12: Domain Transfer Availability. \" class=\"image-popup\">\n<picture>\n <source width=\"1108\" height=\"866\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-registrar-start-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-960.webp 960w, /content/uploads/2023/06/move-your-dns-to-route53-registrar-start.webp 1108w\" sizes=\"1108px\" />\n <source width=\"1108\" height=\"866\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-registrar-start-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-registrar-start-960.png 960w, /content/uploads/2023/06/move-your-dns-to-route53-registrar-start.png 1108w\" sizes=\"1108px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-registrar-start-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-registrar-start.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1108\" height=\"866\" alt=\"Figure 12: Domain Transfer Availability. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 12: Domain Transfer Availability.\n</figcaption>\n\n</figure>\n\n<p>If the domain can be transferred, select <strong>I verify that these steps have been completed and I am ready to transfer in the selected domain.</strong> to get started with the transfer process.</p>\n\n<p class=\"notice--info\"><strong>Note:</strong> The Route 53 Domain Transfer process will <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-transfer-to-route-53.html#domain-transfer-to-route-53-change-registrar-settings-dnssec\">ask you to turn off DNSSEC</a> for the domain to be transferred. We can safely ignore this in this scenario here as the nameserver and DNSSEC keys have already been updated to the new Route 53 Public Hosted Zone.</p>\n\n<p>Fill out the subsequent fields, which will ask for the authorization code, or <em>Auth Code</em> that you generated in Google Domains, but also your contact details. Furthermore you should notice that you do not need to update the nameservers during this process, as Route 53 nameservers are already being used for this domain.</p>\n\n<p>Once you have completed all forms and reviewed the entered information, you can select <strong>Submit request</strong>.</p>\n\n<p>After several minutes you will receive an Email from Google Domains asking to either cancel of approve the Transfer (See Figure 13). Click on the link in the Email and select <strong>Approve</strong>.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer.png\" title=\"Figure 13: Email notification about transferring a domain out from Google Domains. \" class=\"image-popup\">\n<picture>\n <source width=\"665\" height=\"748\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-512.webp 512w, /content/uploads/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer.webp 665w\" sizes=\"665px\" />\n <source width=\"665\" height=\"748\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-512.png 512w, /content/uploads/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer.png 665w\" sizes=\"665px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-googledomains-cancelapprovetransfer.png\" class=\"blur-up lazyautosizes lazyload\" width=\"665\" height=\"748\" alt=\"Figure 13: Email notification about transferring a domain out from Google Domains. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 13: Email notification about transferring a domain out from Google Domains.\n</figcaption>\n\n</figure>\n\n<p>After several minutes the Transfer will complete and you will receive a notification from Route 53 about the completion. After a few hours the migrated domain will disappear in the Google Domains portal. Congratulations! At this point all your DNS management needs are done via Route 53.</p>\n\n<h2 id=\"use-the-route-53-api\">Use the Route 53 API</h2>\n\n<p>While cli53 does not support Route 53’s registration services, you can use the <a href=\"https://docs.aws.amazon.com/cli/latest/reference/route53domains/transfer-domain.html\">AWS CLI</a> to move a domain. This is especially useful if you want to move many domains. And as with the previous API examples you can even run it without any issues within <a href=\"https://aws.amazon.com/cloudshell/\">AWS CloudShell</a>.</p>\n\n<p>Usually when migrating many domains the contact details for these domains remain the same and only the domain name and authentication code changes. With that in mind we will split the part that remains the same from what changes.</p>\n\n<p>Everything that remains the same will go into a JSON file - let’s call it <em>r53-domain-registrar.json</em> - and looks like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>{\n \"DurationInYears\": 1,\n \"AutoRenew\": true,\n \"AdminContact\": {\n \"FirstName\": \"Martha\",\n \"LastName\": \"Rivera\",\n \"ContactType\": \"PERSON\",\n \"OrganizationName\": \"Example\",\n \"AddressLine1\": \"1 Main Street\",\n \"City\": \"Anytown\",\n \"State\": \"WA\",\n \"CountryCode\": \"US\",\n \"ZipCode\": \"98101\",\n \"PhoneNumber\": \"+1.8005551212\",\n \"Email\": \"mrivera@example.com\"\n },\n \"RegistrantContact\": {\n \"FirstName\": \"Li\",\n \"LastName\": \"Juan\",\n \"ContactType\": \"PERSON\",\n \"OrganizationName\": \"Example\",\n \"AddressLine1\": \"1 Main Street\",\n \"City\": \"Anytown\",\n \"State\": \"WA\",\n \"CountryCode\": \"US\",\n \"ZipCode\": \"98101\",\n \"PhoneNumber\": \"+1.8005551212\",\n \"Email\": \"ljuan@example.com\"\n },\n \"TechContact\": {\n \"FirstName\": \"Mateo\",\n \"LastName\": \"Jackson\",\n \"ContactType\": \"PERSON\",\n \"OrganizationName\": \"Example\",\n \"AddressLine1\": \"1 Main Street\",\n \"City\": \"Anytown\",\n \"State\": \"WA\",\n \"CountryCode\": \"US\",\n \"ZipCode\": \"98101\",\n \"PhoneNumber\": \"+1.8005551212\",\n \"Email\": \"mjackson@example.com\"\n },\n \"PrivacyProtectAdminContact\": true,\n \"PrivacyProtectRegistrantContact\": true,\n \"PrivacyProtectTechContact\": true\n}\n</code></pre></div></div>\n\n<p>Afterwards we will use the AWS CLI command <code class=\"language-plaintext highlighter-rouge\">aws route53domains transfer-domain</code> to pass this file along with the parameters that need to be adapted for each domain, which is namely the domain name and the “Auth Code”.</p>\n\n<p>Using AWS CloudShell as an example again, result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-23-45 ~]$ aws route53domains transfer-domain --region us-east-1 --domain-name movetor53.com --auth-code \")o!v3dJeXampLe\" --cli-input-json file://r53-domain-registrar.json \n{\n \"OperationId\": \"a012ab3c-d45e-67f9-gh01-i23j4k567lm8\"\n}\n</code></pre></div></div>\n\n<p>Note that even if you are running this AWS CLI command on a Linux-based machine - like AWS CloudShell - you have to specify the file via the <em>file://filename</em> format.</p>\n\n<p>This way we could write a quick shell script that iterates through a list of domain names and “Auth Codes”, calling the above AWS CLI command for each of them.</p>\n\n<h1 id=\"optimize-dns-records-optional\">Optimize DNS records (Optional)</h1>\n\n<p>As a final optional step we should optimize certain records in the Route 53 Public Hosted Zone by making use of <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html\">alias records</a>.</p>\n\n<p>Route 53 alias records are a Route 53–specific extension to DNS functionality. Alias records let you route traffic to selected AWS resources, such as CloudFront distributions or Amazon S3 buckets. They also let you route traffic from one record in a hosted zone to another record.\nUnlike a CNAME record, you can create an alias record at the top node of a DNS namespace, also known as the zone apex. For example, here in our example the zone apex is <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code>. While you cannot create a CNAME record for <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> you can create an alias record for <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> that routes traffic to e.g. a CloudFront distribution.</p>\n\n<p>To showcase one example, where we previously had to use a CNAME record with Google Domains, have a look at the record for <code class=\"language-plaintext highlighter-rouge\">www.movetor53.com</code> <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> (See Figure 14). The drawback of this CNAME is that clients have to make two DNS requests to resolve <code class=\"language-plaintext highlighter-rouge\">www.movetor53.com</code> into an IP address. One for the CNAME and another one for <code class=\"language-plaintext highlighter-rouge\">dgwkbb1gumfgi.cloudfront.net</code> that this CNAME points to.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-r53-cname.png\" title=\"Figure 14: Record for “www” with type CNAME. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-r53-cname-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-960.webp 960w, \" sizes=\"1311px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-r53-cname-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-r53-cname-960.png 960w, \" sizes=\"1311px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-r53-cname-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-r53-cname.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 14: Record for “www” with type CNAME. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 14: Record for “www” with type CNAME.\n</figcaption>\n\n</figure>\n\n<p>With a DNS record of type Alias, the A record for <code class=\"language-plaintext highlighter-rouge\">www.movetor53.com</code> would directly translate into an IPv4 address, while the AAAA record directly translates to an IPv6 address. And now that the domain <code class=\"language-plaintext highlighter-rouge\">movetor53.com</code> is on Route 53, we can replace this CNAME record with an A and AAAA record, making use of the Alias type (See Figure 15).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/move-your-dns-to-route53-r53-alias.png\" title=\"Figure 15: Alias records for “www” with type A and AAAA. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-r53-alias-320.webp 320w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-384.webp 384w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-512.webp 512w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-683.webp 683w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-800.webp 800w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-960.webp 960w, \" sizes=\"1314px\" />\n <source data-srcset=\" /content/resized/2023/06/move-your-dns-to-route53-r53-alias-320.png 320w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-384.png 384w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-512.png 512w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-683.png 683w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-800.png 800w, /content/resized/2023/06/move-your-dns-to-route53-r53-alias-960.png 960w, \" sizes=\"1314px\" />\n <img src=\"/content/resized/2023/06/move-your-dns-to-route53-r53-alias-320.png\" data-src=\"/content/uploads/2023/06/move-your-dns-to-route53-r53-alias.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 15: Alias records for “www” with type A and AAAA. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 15: Alias records for “www” with type A and AAAA.\n</figcaption>\n\n</figure>\n\n<h1 id=\"url-forwarding\">URL Forwarding</h1>\n\n<p>While Google Domains supports URL Forwarding natively, Route 53 doesn’t. That’s because Route 53 purely focuses on DNS functionality, while URL Forwarding is a function of HTTP(s) as outline in a <a href=\"/2023/03/20/http-redirect-with-cloudfront/\">previous blog post</a>. In AWS you can use <a href=\"https://aws.amazon.com/cloudfront/\">Amazon CloudFront</a> to achieve the same. If you want to learn how to do this, head over to my previous blog post on “<a href=\"https://www.edge-cloud.net/2023/03/20/http-redirect-with-cloudfront/\">URL Redirect with Amazon CloudFront and Amazon Route 53</a>”.</p>\n<h1 id=\"summary\">Summary</h1>\n\n<p>This blog post walked you through the migration steps of moving a domain from a DNS service provider like Google Domains to Route 53. It included steps for both moving the DNS zone as well as the registration services. At the end of this guide your domain will be fully moved from Google Domains to Route 53. \nWhile all shown steps and screenshots are specific to Google Domains, the same concept applies when migrating away from other DNS provider as well.</p>\n",
"summary": "Step-by-step guide to move your DNS - both registration services and zone file - to Amazon Route 53",
"date_published": "2023-06-25T00:00:00-07:00",
"date_modified": "2023-06-25T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2023/06/title-move-your-dns-to-route53.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Route-53"]
},
{
"id": "https://www.edge-cloud.net/2023/06/18/r53-random-prefix-attack-mitigation",
"url": "https://www.edge-cloud.net/2023/06/18/r53-random-prefix-attack-mitigation/",
"title": "Random prefix attack mitigation with Amazon Route 53",
"content_html": "<p>This blog post shows how to mitigate a random prefix attack with Amazon Route 53. While such an attack will not have an impact on performance or availability, owners of the corresponding public hosted zone will incur charges for queries to non-existing subdomains or prefixes. These charges can be prevented via the mitigation presented here.</p>\n\n<h1 id=\"background\">Background</h1>\n\n<h2 id=\"what-is-a-random-prefix-attack\">What is a random prefix attack</h2>\n\n<p>With a random prefix attack someone sends large amounts of DNS queries to random subdomains (or prefixes) that most likely do not exist (e.g. “b835n0knic.edge-cloud.net, lkxmwdw13n.edge-cloud.net, ul1xx83vyq.edge-cloud.net, …”). Nevertheless these attacks are still connected to your domain, e.g. edge-cloud.net in the above example. \nUsually the DNS queries to these subdomains or prefixes cannot be cached by DNS resolvers, due to their randomness and that the requests are not repeated. This in return leads to the requests always reaching the authoritative nameservers.</p>\n\n<p>Rate limiting or blocking these requests based on the source address typically introduces a high amount of false positives as these attacks are usually conducted via public resolvers. Therefore these attacks are particularly effective and hard to mitigate.</p>\n\n<h2 id=\"the-impact-with-amazon-route-53\">The impact with Amazon Route 53</h2>\n\n<p>In the case of <a href=\"https://aws.amazon.com/route53/\">Amazon Route 53</a> as the authoritative nameserver, owners of the corresponding public hosted zone will not see an impact on performance or availability from random prefix attacks. But as Amazon Route 53 also <a href=\"https://aws.amazon.com/route53/pricing/#Queries\">charges for queries</a> to non-existing subdomains or prefixes, users will incur cost.</p>\n\n<h2 id=\"cost-model-of-amazon-route-53\">Cost model of Amazon Route 53</h2>\n\n<p>Having a look at the <a href=\"https://aws.amazon.com/route53/pricing/\">Amazon Route 53 pricing</a>, you’ll notice that queries for a record that doesn’t exist are charged at the standard rate for queries. Currently this is US$ 0.40 per million queries for the first 1 billion queries / month. \nUsing the <a href=\"https://calculator.aws/#/addService/Route53\">AWS Pricing Calculator</a> you can therefore see that e.g. 1 billion queries would incur charges of US$ 400.</p>\n\n<p>It’s interesting and important to have a closer look at the pricing for <a href=\"https://aws.amazon.com/route53/pricing/#Alias_Queries\">Alias Queries</a>. You will notice that queries to records where the alias target is an AWS resource other than another Route 53 record are free.</p>\n\n<p>From a cost perspective it would therefore be very beneficial if we could turn any query to a non-existing record into a query for an AWS resource.</p>\n\n<h1 id=\"mitigation\">Mitigation</h1>\n\n<p>For the mitigation of the random prefix attack we want to create an AWS resource that we can safely point any non-existing prefix to. Ideally we want to use a service that can perform an URL redirect in case someone just fat-fingered a valid prefix. For this use case the previous blog post <a href=\"https://www.edge-cloud.net/2023/03/20/http-redirect-with-cloudfront/\">URL Redirect with Amazon CloudFront and Amazon Route 53</a> can be re-used.</p>\n\n<h2 id=\"cloudfront-distribution-with-wildcard-name\">Cloudfront distribution with wildcard name</h2>\n\n<p>You can follow the instructions from the previous blog post <a href=\"https://www.edge-cloud.net/2023/03/20/http-redirect-with-cloudfront/\">URL Redirect with Amazon CloudFront and Amazon Route 53</a>, starting at the section <a href=\"https://www.edge-cloud.net/2023/03/20/http-redirect-with-cloudfront/#cloudfront-for-url-redirect\">CloudFront for URL redirectPermalink</a>.</p>\n\n<p>The only difference is that this time you configure the alternate domain names to be <code class=\"language-plaintext highlighter-rouge\">*.edge-cloud.net</code> (See Figure 1).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname.png\" title=\"Figure 1: CloudFront distribution with wildcard alternate domain name. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-320.webp 320w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-384.webp 384w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-512.webp 512w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-683.webp 683w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-800.webp 800w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-960.webp 960w, \" sizes=\"1616px\" />\n <source data-srcset=\" /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-320.png 320w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-384.png 384w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-512.png 512w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-683.png 683w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-800.png 800w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-960.png 960w, \" sizes=\"1616px\" />\n <img src=\"/content/resized/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname-320.png\" data-src=\"/content/uploads/2023/06/r53-random-prefix-attack-mitigation-random-cloudfront-wildcard-cname.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: CloudFront distribution with wildcard alternate domain name. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: CloudFront distribution with wildcard alternate domain name.\n</figcaption>\n\n</figure>\n\n<p>Everything else can remain the same. Therefore if you already have this CloudFront distribution in place, you can just change the alternate domain name.</p>\n\n<h2 id=\"create-wildcard-record-in-route-53\">Create wildcard record in Route 53</h2>\n\n<p>As a next step we need to setup a wildcard Alias record in Route 53. This <code class=\"language-plaintext highlighter-rouge\">*.edge-cloud.net</code> record will effectively point to the CloudFront distribution created above.</p>\n\n<p><a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html\">Create a new Route 53 record</a>, where the <em>record name</em> is <em>“</em>”* (star), the <em>record type</em> is <em>“A”</em>, <em>“Alias” is enabled, _Route traffic to_ is selected as *“Alias to CloudFront distribution”</em> with the above CloudFront distribution selected (See Figure 2).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create.png\" title=\"Figure 2: Route 53 wildcard record pointing to a CloudFront distribution. \" class=\"image-popup\">\n<picture>\n <source width=\"1093\" height=\"579\" type=\"image/webp\" data-srcset=\" /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-320.webp 320w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-384.webp 384w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-512.webp 512w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-683.webp 683w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-800.webp 800w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-960.webp 960w, /content/uploads/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create.webp 1093w\" sizes=\"1093px\" />\n <source width=\"1093\" height=\"579\" data-srcset=\" /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-320.png 320w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-384.png 384w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-512.png 512w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-683.png 683w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-800.png 800w, /content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-960.png 960w, /content/uploads/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create.png 1093w\" sizes=\"1093px\" />\n <img src=\"/content/resized/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create-320.png\" data-src=\"/content/uploads/2023/06/r53-random-prefix-attack-mitigation-random-r53-alias-create.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1093\" height=\"579\" alt=\"Figure 2: Route 53 wildcard record pointing to a CloudFront distribution. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Route 53 wildcard record pointing to a CloudFront distribution.\n</figcaption>\n\n</figure>\n\n<p>You can repeat the same step for the <em>record type</em> <em>“AAAA”</em> to enable IPv6 support.</p>\n\n<h2 id=\"testing-the-setup\">Testing the setup</h2>\n\n<p>Now it’s time to test our setup. Let’s perform a DNS query against another random subdomain or records underneath the domain in question. While previously such a query should have returned a <em>“NX Domain”</em> response, we should now see IP addresses for CloudFront.</p>\n\n<p>And indeed that’s what we will see.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ubuntu@ubuntu:~$ dig +short hknk5e69s72d2l31cjuw.edge-cloud.net\n65.8.158.5\n65.8.158.21\n65.8.158.83\n65.8.158.100\n\n</code></pre></div></div>\n\n<p>Therefore any attacker trying to resolve random prefixes would be presented with an IP address for CloudFront. As a reminder: We won’t be charged for that request as it’s an Alias record where the alias target is an AWS resource other than another Route 53 record.</p>\n\n<p>Next let’s see what happens if we enter this random hostname into a browser.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ubuntu@ubuntu:~$ curl -sS -D - https://knk5e69s72d2l31cjuw.edge-cloud.net -o /dev/null\nHTTP/2 301 \nserver: CloudFront\ndate: Mon, 12 Jun 2023 00:10:39 GMT\ncontent-length: 0\nlocation: https://www.edge-cloud.net\nx-cache: FunctionGeneratedResponse from cloudfront\nvia: 1.1 1943af12d816afc5bfe1ce2c8b3de416.cloudfront.net (CloudFront)\nx-amz-cf-pop: SFO53-C1\nalt-svc: h3=\":443\"; ma=86400\nx-amz-cf-id: kdnl6bTnfVMSNe7uyRSKEqrqk2djdvP4g1y0XRvMkLee4Iauk8j80w==\n</code></pre></div></div>\n\n<p>Just as with the previous blog post <a href=\"https://www.edge-cloud.net/2023/03/20/http-redirect-with-cloudfront/#testing-the-setup\">URL Redirect with Amazon CloudFront and Amazon Route 53</a>, we are being redirected to the website at <code class=\"language-plaintext highlighter-rouge\">https://aws.edge-cloud.net</code>.</p>\n\n<h2 id=\"further-reduce-cost\">Further reduce cost</h2>\n\n<p>As you will incur charges for HTTP(S) traffic successfully served by CloudFront, you could also chose to only configure your distribution with common mistake hostnames, such as “ww”, or “wwww”. This reduces the cost in case the attacker combines the DNS random prefix attack with an HTTP(S) based attack.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This blog post showed you how to mitigate a random prefix attack with Amazon Route 53. While such an attack will not have an impact to performance or availability, owners of the corresponding public hosted zone will incur charges for queries to non-existing subdomains or prefixes. \nBy creating a wildcard CloudFront distribution along with an Amazon Route 53 wildcard record, using this CloudFront distribution as the target, cost for queries to non-existing subdomains or prefixes will be removed.</p>\n",
"summary": "How to mitigate random prefix attacks - when someone send a lot of traffic to subdomains of your main domain - with Amazon Route 53",
"date_published": "2023-06-18T00:00:00-07:00",
"date_modified": "2023-06-18T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2023/06/title-r53-random-prefix-attack-mitigation.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Route-53"]
},
{
"id": "https://www.edge-cloud.net/2023/03/20/url-redirect-with-cloudfront",
"url": "https://www.edge-cloud.net/2023/03/20/http-redirect-with-cloudfront/",
"title": "URL Redirect with Amazon CloudFront and Amazon Route 53",
"content_html": "<p>A <a href=\"https://en.wikipedia.org/wiki/URL_redirection\">URL redirect</a>, also called URL forwarding, allows you to make a web page available under more than one URL. When a web browser attempts to open a URL that has been redirected, a page with a different URL is opened. This is also indicated in the web browser itself by showing the new URL in the navigation bar. As an example: You might enter the URL <code class=\"language-plaintext highlighter-rouge\">https://about.example.com</code> into the browser and be redirected to <code class=\"language-plaintext highlighter-rouge\">https://www.example.com/about/</code>.</p>\n\n<p>While often misunderstood as a function or DNS, a URL redirect is actually a function of HTTP and therefore of a web server. Therefore if we want to implement such a redirect, we need a web server to perform such a URL redirect.</p>\n\n<p>This blog post shows you how to use <a href=\"https://aws.amazon.com/cloudfront/\">Amazon CloudFront</a>, the content delivery network (CDN) of AWS, to perform such a redirect.</p>\n\n<h1 id=\"background\">Background</h1>\n\n<h2 id=\"how-does-a-url-redirect-work\">How does a URL redirect work</h2>\n\n<p>While a URL redirect mainly uses the <a href=\"https://en.wikipedia.org/wiki/HTTP\">Hypertext Transfer Protocol (HTTP)</a>, the <a href=\"https://en.wikipedia.org/wiki/Domain_Name_System\">Domain Name System (DNS)</a> naturally also plays a role when using HTTP. In order to understand what we need to configure it’s a good idea to understand the flow between these two protocol when it comes to a URL redirect.</p>\n\n<p>Consider Figure 1, which displays the conceptual overview of a redirect from <code class=\"language-plaintext highlighter-rouge\">https://www.example.com</code> to <code class=\"language-plaintext highlighter-rouge\">https://www.example.org</code>. The end-user will here initially enter <code class=\"language-plaintext highlighter-rouge\">https://www.example.com</code> into the browser, but be redirected to <code class=\"language-plaintext highlighter-rouge\">https://www.example.org</code> and displayed that website’s content.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-how-it-works.png\" title=\"Figure 1: Conceptional overview of a URL redirect with the DNS request and responses as well as the HTTP request and responses. \" class=\"image-popup\">\n<picture>\n <source width=\"702\" height=\"487\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-how-it-works-320.webp 320w, /content/resized/2023/03/url-redirect-how-it-works-384.webp 384w, /content/resized/2023/03/url-redirect-how-it-works-512.webp 512w, /content/resized/2023/03/url-redirect-how-it-works-683.webp 683w, /content/uploads/2023/03/url-redirect-how-it-works.webp 702w\" sizes=\"702px\" />\n <source width=\"702\" height=\"487\" data-srcset=\" /content/resized/2023/03/url-redirect-how-it-works-320.png 320w, /content/resized/2023/03/url-redirect-how-it-works-384.png 384w, /content/resized/2023/03/url-redirect-how-it-works-512.png 512w, /content/resized/2023/03/url-redirect-how-it-works-683.png 683w, /content/uploads/2023/03/url-redirect-how-it-works.png 702w\" sizes=\"702px\" />\n <img src=\"/content/resized/2023/03/url-redirect-how-it-works-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-how-it-works.png\" class=\"blur-up lazyautosizes lazyload\" width=\"702\" height=\"487\" alt=\"Figure 1: Conceptional overview of a URL redirect with the DNS request and responses as well as the HTTP request and responses. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Conceptional overview of a URL redirect with the DNS request and responses as well as the HTTP request and responses.\n</figcaption>\n\n</figure>\n\n<p>Let’s have a look the involved steps:</p>\n<ol>\n <li>The browser performs a DNS lookup for <code class=\"language-plaintext highlighter-rouge\">www.example.com</code>.</li>\n <li>The local DNS resolver responds with the IP address for <code class=\"language-plaintext highlighter-rouge\">www.example.com</code>. Note, that the recursive behavior of the DNS resolver is not depicted here, to keep the example simple.</li>\n <li>The browser performs an HTTP “GET” request against te web server for <code class=\"language-plaintext highlighter-rouge\">www.example.com</code>, using the IP address it just received.</li>\n <li>The web server for <code class=\"language-plaintext highlighter-rouge\">www.example.com</code> responds with a “301 Permanent Redirect” response, also delivering the new location as <code class=\"language-plaintext highlighter-rouge\">https://www.example.org</code> via HTTP.</li>\n <li>The browser performs a DNS lookup for <code class=\"language-plaintext highlighter-rouge\">www.example.org</code>. The new URL <code class=\"language-plaintext highlighter-rouge\">https://www.example.org</code> is also displayed in the browser’s address bar.</li>\n <li>The local DNS resolver responds with the IP address for <code class=\"language-plaintext highlighter-rouge\">www.example.org</code>. Again, the recursive behavior of the DNS resolver is not depicted.</li>\n <li>The browser performs an HTTP “GET” request against the web server for <code class=\"language-plaintext highlighter-rouge\">www.example.org</code>, using the IP address it just received.</li>\n <li>The web server for <code class=\"language-plaintext highlighter-rouge\">www.example.org</code> responds with the actual data for this website.</li>\n</ol>\n\n<h2 id=\"host-header-and-server-name-indication-sni\">Host header and Server Name Indication (SNI)</h2>\n\n<p>Sometimes the question comes up why it is not sufficient to just configure a <a href=\"https://en.wikipedia.org/wiki/CNAME_record\">Canonical Name (CNAME) record</a> in DNS instead of a full URL redirect.</p>\n\n<p>Imagine you want to allow your company’s users to access the AWS Console under <code class=\"language-plaintext highlighter-rouge\">https://aws.mycompany.com</code> instead of <code class=\"language-plaintext highlighter-rouge\">https://console.aws.amazon.com</code>. Why isn’t it enough to create a CNAME in the DNS zone of <code class=\"language-plaintext highlighter-rouge\">mycompany.com</code> that points to <code class=\"language-plaintext highlighter-rouge\">console.aws.amazon.com</code>?</p>\n\n<p>For this we have to look back at the early days of HTTP with its first version of HTTP/1.0. This version neither included the ability of “Host” headers, nor Server Name Indication (SNI), which is necessary to use “Host” headers with TLS. With this HTTP version, each webserver required a unique IP address for each site it was hosting (See Figure 2).</p>\n\n<p>This is obviously very inefficient with regards to IP address usages and issues such as the <a href=\"https://en.wikipedia.org/wiki/IPv4_address_exhaustion\">IPv4 address exhaustion</a> forced the need for solutions. To do so, <a href=\"https://www.rfc-editor.org/rfc/rfc2616\">HTTP/1.1</a> introduced the concept the “Host” header, where the client indicates to the server the hostname of the actual website it wants to access. This allows to host multiple different websites with different hostnames on the same web server with the same IP address.</p>\n\n<p>With the <a href=\"https://en.wikipedia.org/wiki/HTTPS\">Hypertext Transfer Protocol Secure (HTTPS)</a> becoming more common, this concept had to be extended as any of the request headers - from the client to the server - which includes the “Host” header are part of the TLS encryption. Therefore the web server was in a “catch 22” situation, where it needed to know the website being targeted so that it could pick the right certificate without looking at the HTTP session data. That’s where <a href=\"https://en.wikipedia.org/wiki/Server_Name_Indication\">Server Name Indication (SNI)</a> comes into the picture and allows the browser to indicate which hostname it wants to talk to (Figure 2).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-how-sni-works.png\" title=\"Figure 2: The role of Server Name Indication (SNI) on a web server. \" class=\"image-popup\">\n<picture>\n <source width=\"1230\" height=\"515\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-how-sni-works-320.webp 320w, /content/resized/2023/03/url-redirect-how-sni-works-384.webp 384w, /content/resized/2023/03/url-redirect-how-sni-works-512.webp 512w, /content/resized/2023/03/url-redirect-how-sni-works-683.webp 683w, /content/resized/2023/03/url-redirect-how-sni-works-800.webp 800w, /content/resized/2023/03/url-redirect-how-sni-works-960.webp 960w, /content/uploads/2023/03/url-redirect-how-sni-works.webp 1230w\" sizes=\"1230px\" />\n <source width=\"1230\" height=\"515\" data-srcset=\" /content/resized/2023/03/url-redirect-how-sni-works-320.png 320w, /content/resized/2023/03/url-redirect-how-sni-works-384.png 384w, /content/resized/2023/03/url-redirect-how-sni-works-512.png 512w, /content/resized/2023/03/url-redirect-how-sni-works-683.png 683w, /content/resized/2023/03/url-redirect-how-sni-works-800.png 800w, /content/resized/2023/03/url-redirect-how-sni-works-960.png 960w, /content/uploads/2023/03/url-redirect-how-sni-works.png 1230w\" sizes=\"1230px\" />\n <img src=\"/content/resized/2023/03/url-redirect-how-sni-works-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-how-sni-works.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1230\" height=\"515\" alt=\"Figure 2: The role of Server Name Indication (SNI) on a web server. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: The role of Server Name Indication (SNI) on a web server.\n</figcaption>\n\n</figure>\n\n<p>What does all of that have to do with our CNAME? Today use of SNI and Host headers is the norm and as such the web server that delivers the website for <code class=\"language-plaintext highlighter-rouge\">https://console.aws.amazon.com</code> expects to see that hostname as part of the SNI handshake. Any other hostname will be rejected for security reasons. \nBut creating a CNAME from <code class=\"language-plaintext highlighter-rouge\">https://aws.mycompany.com</code> to <code class=\"language-plaintext highlighter-rouge\">https://console.aws.amazon.com</code> and subsequently entering <code class=\"language-plaintext highlighter-rouge\">https://aws.mycompany.com</code> into the browser would do exactly this: It would attempt to talk to the web server for <code class=\"language-plaintext highlighter-rouge\">https://console.aws.amazon.com</code>, while including <code class=\"language-plaintext highlighter-rouge\">https://aws.mycompany.com</code> in the SNI. Therefore the web server for <code class=\"language-plaintext highlighter-rouge\">https://console.aws.amazon.com</code> will prevent this communication.</p>\n\n<h1 id=\"example-use-case\">Example use case</h1>\n\n<p>For this blog post we will use an example to demonstrate the power of URL redirects. You can see that this blog site has main navigation elements in the upper right corner. Besides the item “Home”, which will bring you back to the Homepage, there are also items for “AWS”, “IPv6”, “Tags”, and “About”, which will directly bring you to certain pages.</p>\n\n<p>What if we could add the following URLs that will bring you to the same pages:</p>\n\n<ul>\n <li><code class=\"language-plaintext highlighter-rouge\">https://aws.edge-cloud.net</code></li>\n <li><code class=\"language-plaintext highlighter-rouge\">https://ipv6.edge-cloud.net</code></li>\n <li><code class=\"language-plaintext highlighter-rouge\">https://tags.edge-cloud.net</code></li>\n <li><code class=\"language-plaintext highlighter-rouge\">https://about.edge-cloud.net</code></li>\n</ul>\n\n<p>Each of these URL will be a redirect to the main page at <code class=\"language-plaintext highlighter-rouge\">https://www.edge-cloud.net/<target></code>, where <code class=\"language-plaintext highlighter-rouge\"><target></code> matches the current URI for that item.</p>\n\n<h1 id=\"cloudfront-for-url-redirect\">CloudFront for URL redirect</h1>\n\n<p>Let’s setup an example to showcase a URL redirect with Amazon CloudFront as the web server and Amazon Route 53 for the DNS records.</p>\n\n<h2 id=\"cloudfront-distribution-and-dummy-origin\">Cloudfront distribution and dummy origin</h2>\n\n<p>As a first step we will <a href=\"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-creating-console.html\">create a new CloudFront distribution</a>.</p>\n\n<p>One of the items that you need to specify when creating a CloudFront distribution is the origin domain or the source of the content that will be served by CloudFront. In our case we have no such origin and no actual objects will ever be served. Therefore it’s safe to enter the origin domain <strong>invalid.invalid</strong>, while choosing the Protocol as <strong>Match viewer</strong> (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-dummy-origin.png\" title=\"Figure 3: CloudFront distribution with hostname ‘invalid.invalid’ as dummy origin. \" class=\"image-popup\">\n<picture>\n <source width=\"797\" height=\"292\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-dummy-origin-320.webp 320w, /content/resized/2023/03/url-redirect-dummy-origin-384.webp 384w, /content/resized/2023/03/url-redirect-dummy-origin-512.webp 512w, /content/resized/2023/03/url-redirect-dummy-origin-683.webp 683w, /content/uploads/2023/03/url-redirect-dummy-origin.webp 797w\" sizes=\"797px\" />\n <source width=\"797\" height=\"292\" data-srcset=\" /content/resized/2023/03/url-redirect-dummy-origin-320.png 320w, /content/resized/2023/03/url-redirect-dummy-origin-384.png 384w, /content/resized/2023/03/url-redirect-dummy-origin-512.png 512w, /content/resized/2023/03/url-redirect-dummy-origin-683.png 683w, /content/uploads/2023/03/url-redirect-dummy-origin.png 797w\" sizes=\"797px\" />\n <img src=\"/content/resized/2023/03/url-redirect-dummy-origin-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-dummy-origin.png\" class=\"blur-up lazyautosizes lazyload\" width=\"797\" height=\"292\" alt=\"Figure 3: CloudFront distribution with hostname ‘invalid.invalid’ as dummy origin. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: CloudFront distribution with hostname ‘invalid.invalid’ as dummy origin.\n</figcaption>\n\n</figure>\n\n<p>All other settings can remain as default for now.</p>\n\n<h2 id=\"certificates-and-cnames\">Certificates and CNAMEs</h2>\n\n<p>Next we need to configure the new CloudFront distribution for <a href=\"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html\">alternate domain names</a>.</p>\n\n<p>As a first step this means using ideally <a href=\"https://aws.amazon.com/certificate-manager/\">AWS Certificate Manager</a> to <a href=\"https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html\">create a wildcard certificate</a> for <code class=\"language-plaintext highlighter-rouge\">*.edge-cloud.net</code>. As an alternative we could create a Subject Alternative Name (SAN) certificate for just the four hostnames.</p>\n\n<p>Next, we will add the certificate and the alternate domain names to the CloudFront distribution (See Figure 4).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-alternate-domain-names.png\" title=\"Figure 4: Configuring alternate domain names in a CloudFront distribution. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-alternate-domain-names-320.webp 320w, /content/resized/2023/03/url-redirect-alternate-domain-names-384.webp 384w, /content/resized/2023/03/url-redirect-alternate-domain-names-512.webp 512w, /content/resized/2023/03/url-redirect-alternate-domain-names-683.webp 683w, /content/resized/2023/03/url-redirect-alternate-domain-names-800.webp 800w, /content/resized/2023/03/url-redirect-alternate-domain-names-960.webp 960w, \" sizes=\"1276px\" />\n <source data-srcset=\" /content/resized/2023/03/url-redirect-alternate-domain-names-320.png 320w, /content/resized/2023/03/url-redirect-alternate-domain-names-384.png 384w, /content/resized/2023/03/url-redirect-alternate-domain-names-512.png 512w, /content/resized/2023/03/url-redirect-alternate-domain-names-683.png 683w, /content/resized/2023/03/url-redirect-alternate-domain-names-800.png 800w, /content/resized/2023/03/url-redirect-alternate-domain-names-960.png 960w, \" sizes=\"1276px\" />\n <img src=\"/content/resized/2023/03/url-redirect-alternate-domain-names-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-alternate-domain-names.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 4: Configuring alternate domain names in a CloudFront distribution. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: Configuring alternate domain names in a CloudFront distribution.\n</figcaption>\n\n</figure>\n\n<h2 id=\"cloudfront-function\">CloudFront function</h2>\n\n<p>Now it’s time for the actual magic: The logic to execute in CloudFront and perform the URL redirect. For this CloudFront offers “CloudFront Functions”. With CloudFront Functions, you can write lightweight functions in JavaScript for high-scale, latency-sensitive CDN customizations. In our case that customization will be returning a “301 Permanent Redirect”.</p>\n\n<p>Start by <a href=\"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/create-function.html\">creating the CloudFront function</a> via the AWS Console (See Figure 5).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-cloudfront-function.png\" title=\"Figure 5: Creating an Amazon CloudFront function. \" class=\"image-popup\">\n<picture>\n <source width=\"1087\" height=\"1122\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-cloudfront-function-320.webp 320w, /content/resized/2023/03/url-redirect-cloudfront-function-384.webp 384w, /content/resized/2023/03/url-redirect-cloudfront-function-512.webp 512w, /content/resized/2023/03/url-redirect-cloudfront-function-683.webp 683w, /content/resized/2023/03/url-redirect-cloudfront-function-800.webp 800w, /content/resized/2023/03/url-redirect-cloudfront-function-960.webp 960w, /content/uploads/2023/03/url-redirect-cloudfront-function.webp 1087w\" sizes=\"1087px\" />\n <source width=\"1087\" height=\"1122\" data-srcset=\" /content/resized/2023/03/url-redirect-cloudfront-function-320.png 320w, /content/resized/2023/03/url-redirect-cloudfront-function-384.png 384w, /content/resized/2023/03/url-redirect-cloudfront-function-512.png 512w, /content/resized/2023/03/url-redirect-cloudfront-function-683.png 683w, /content/resized/2023/03/url-redirect-cloudfront-function-800.png 800w, /content/resized/2023/03/url-redirect-cloudfront-function-960.png 960w, /content/uploads/2023/03/url-redirect-cloudfront-function.png 1087w\" sizes=\"1087px\" />\n <img src=\"/content/resized/2023/03/url-redirect-cloudfront-function-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-cloudfront-function.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1087\" height=\"1122\" alt=\"Figure 5: Creating an Amazon CloudFront function. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 5: Creating an Amazon CloudFront function.\n</figcaption>\n\n</figure>\n\n<p>Below is the actual CloudFront Functions code. It extracts the host header value from the request and performs a “switch” based on the value of the found header, assigning the target URL for each expected host header value. \nNext the function responds with a redirect, using the status code “301” for permanent redirect and the response header “location” to indicate the new URL.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>#\n# Amazon CloudFront function for selective URL redirect\n#\nfunction handler(event) {\n var request = event.request;\n var headers = request.headers;\n var host = request.headers.host.value;\n var newurl = `https://www.edge-cloud.net` // Default value for redirect target\n\n switch(host) {\n case \"aws.edge-cloud.net\": {\n newurl = `https://www.edge-cloud.net/tags/#aws`\n break;\n }\n case \"ipv6.edge-cloud.net\": {\n newurl = `https://www.edge-cloud.net/tags/#ipv6`\n break;\n }\n case \"tags.edge-cloud.net\": {\n newurl = `https://www.edge-cloud.net/tags/`\n break;\n }\n case \"about.edge-cloud.net\": {\n newurl = `https://www.edge-cloud.net/about/`\n break;\n }\n default: {\n break;\n }\n }\n \n var response = {\n statusCode: 301,\n statusDescription: 'Moved Permanently',\n headers:\n { \"location\": { \"value\": newurl } }\n }\n \n return response;\n}\n\n</code></pre></div></div>\n\n<p>After publishing the above CloudFront Function, return to the CloudFront distribution that we initially created and <a href=\"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/create-function.html\">update the viewer request with this CloudFront function</a> (See Figure 6).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-viewer-function.png\" title=\"Figure 6: Selecting a CloudFront function as a Viewer Action. \" class=\"image-popup\">\n<picture>\n <source width=\"797\" height=\"327\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-viewer-function-320.webp 320w, /content/resized/2023/03/url-redirect-viewer-function-384.webp 384w, /content/resized/2023/03/url-redirect-viewer-function-512.webp 512w, /content/resized/2023/03/url-redirect-viewer-function-683.webp 683w, /content/uploads/2023/03/url-redirect-viewer-function.webp 797w\" sizes=\"797px\" />\n <source width=\"797\" height=\"327\" data-srcset=\" /content/resized/2023/03/url-redirect-viewer-function-320.png 320w, /content/resized/2023/03/url-redirect-viewer-function-384.png 384w, /content/resized/2023/03/url-redirect-viewer-function-512.png 512w, /content/resized/2023/03/url-redirect-viewer-function-683.png 683w, /content/uploads/2023/03/url-redirect-viewer-function.png 797w\" sizes=\"797px\" />\n <img src=\"/content/resized/2023/03/url-redirect-viewer-function-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-viewer-function.png\" class=\"blur-up lazyautosizes lazyload\" width=\"797\" height=\"327\" alt=\"Figure 6: Selecting a CloudFront function as a Viewer Action. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 6: Selecting a CloudFront function as a Viewer Action.\n</figcaption>\n\n</figure>\n\n<h1 id=\"dns-setup-with-route-53\">DNS setup with Route 53</h1>\n\n<p>As a last step we have to setup the DNS records in Amazon Route 53 for the host names <code class=\"language-plaintext highlighter-rouge\">aws.edge-cloud.net</code>, <code class=\"language-plaintext highlighter-rouge\">ipv6.edge-cloud.net</code>, <code class=\"language-plaintext highlighter-rouge\">tags.edge-cloud.net</code>, and <code class=\"language-plaintext highlighter-rouge\">about.edge-cloud.net</code>. To do so, we will <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-cloudfront-distribution.html\">create an Alias records</a> with the above CloudFront distribution as the target (See Figure 7). Create both an “A” record for IPv4 and an “AAAA’ record for IPv6 for each of the host names. Thereby we need to create a total of 8 DNS records.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-r53-create-alias.png\" title=\"Figure 7: Creating an Amazon Route 53 Alias record. \" class=\"image-popup\">\n<picture>\n <source width=\"1080\" height=\"568\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-r53-create-alias-320.webp 320w, /content/resized/2023/03/url-redirect-r53-create-alias-384.webp 384w, /content/resized/2023/03/url-redirect-r53-create-alias-512.webp 512w, /content/resized/2023/03/url-redirect-r53-create-alias-683.webp 683w, /content/resized/2023/03/url-redirect-r53-create-alias-800.webp 800w, /content/resized/2023/03/url-redirect-r53-create-alias-960.webp 960w, /content/uploads/2023/03/url-redirect-r53-create-alias.webp 1080w\" sizes=\"1080px\" />\n <source width=\"1080\" height=\"568\" data-srcset=\" /content/resized/2023/03/url-redirect-r53-create-alias-320.png 320w, /content/resized/2023/03/url-redirect-r53-create-alias-384.png 384w, /content/resized/2023/03/url-redirect-r53-create-alias-512.png 512w, /content/resized/2023/03/url-redirect-r53-create-alias-683.png 683w, /content/resized/2023/03/url-redirect-r53-create-alias-800.png 800w, /content/resized/2023/03/url-redirect-r53-create-alias-960.png 960w, /content/uploads/2023/03/url-redirect-r53-create-alias.png 1080w\" sizes=\"1080px\" />\n <img src=\"/content/resized/2023/03/url-redirect-r53-create-alias-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-r53-create-alias.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1080\" height=\"568\" alt=\"Figure 7: Creating an Amazon Route 53 Alias record. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 7: Creating an Amazon Route 53 Alias record.\n</figcaption>\n\n</figure>\n\n<p>As a final result we should see the 8 entries for the host names <code class=\"language-plaintext highlighter-rouge\">aws.edge-cloud.net</code>, <code class=\"language-plaintext highlighter-rouge\">ipv6.edge-cloud.net</code>, <code class=\"language-plaintext highlighter-rouge\">tags.edge-cloud.net</code>, and <code class=\"language-plaintext highlighter-rouge\">about.edge-cloud.net</code> as an Alias record (See Figure 8).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2023/03/url-redirect-r53-setup.png\" title=\"Figure 8: Completed Amazon Route 53 Setup. \" class=\"image-popup\">\n<picture>\n <source width=\"823\" height=\"364\" type=\"image/webp\" data-srcset=\" /content/resized/2023/03/url-redirect-r53-setup-320.webp 320w, /content/resized/2023/03/url-redirect-r53-setup-384.webp 384w, /content/resized/2023/03/url-redirect-r53-setup-512.webp 512w, /content/resized/2023/03/url-redirect-r53-setup-683.webp 683w, /content/resized/2023/03/url-redirect-r53-setup-800.webp 800w, /content/uploads/2023/03/url-redirect-r53-setup.webp 823w\" sizes=\"823px\" />\n <source width=\"823\" height=\"364\" data-srcset=\" /content/resized/2023/03/url-redirect-r53-setup-320.png 320w, /content/resized/2023/03/url-redirect-r53-setup-384.png 384w, /content/resized/2023/03/url-redirect-r53-setup-512.png 512w, /content/resized/2023/03/url-redirect-r53-setup-683.png 683w, /content/resized/2023/03/url-redirect-r53-setup-800.png 800w, /content/uploads/2023/03/url-redirect-r53-setup.png 823w\" sizes=\"823px\" />\n <img src=\"/content/resized/2023/03/url-redirect-r53-setup-320.png\" data-src=\"/content/uploads/2023/03/url-redirect-r53-setup.png\" class=\"blur-up lazyautosizes lazyload\" width=\"823\" height=\"364\" alt=\"Figure 8: Completed Amazon Route 53 Setup. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 8: Completed Amazon Route 53 Setup.\n</figcaption>\n\n</figure>\n\n<h1 id=\"testing-the-setup\">Testing the setup</h1>\n\n<p>Let’s test our URL redirect with the Curl command. <code class=\"language-plaintext highlighter-rouge\">curl -sS -D - https://aws.edge-cloud.net -o /dev/null</code>.</p>\n\n<p>The output will look as follows:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>ubuntu@ubuntu:~$ curl -sS -D - https://aws.edge-cloud.net -o /dev/null\nHTTP/2 301\nserver: CloudFront\ndate: Mon, 20 Mar 2023 23:27:50 GMT\ncontent-length: 0\nlocation: https://www.edge-cloud.net/tags/#aws\nx-cache: FunctionGeneratedResponse from cloudfront\nvia: 1.1 f6e2aa8788731292478df0dab2377dd8.cloudfront.net (CloudFront)\nx-amz-cf-pop: AKL50-C1\nalt-svc: h3=\":443\"; ma=86400\nx-amz-cf-id: MVmSx7lhwJ8IcXqcv-sPZb1CD2kYB8GHjWKWlcHYs__EiWtqd25Dcg==\n</code></pre></div></div>\n\n<p>The key lines to look for are:</p>\n<ul>\n <li>The response in the first line, with the HTTP/2 status code of “301” indicating a permanent redirect</li>\n <li>The “location” line, which shows the target URL of the redirect.</li>\n</ul>\n\n<p>That’s it. Everything is working as expected.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This blog post walked you through utilizing Amazon CloudFront with <a href=\"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html\">CloudFront functions</a> to perform a URL redirect.</p>\n",
"summary": "How to use Amazon CloudFront and Amazon Route 53 to perform a URL redirect, e.g. from http://about.example.com to http://www.example.com/about.",
"date_published": "2023-03-20T00:00:00-07:00",
"date_modified": "2023-03-20T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2023/03/title-url-redirect-with-cloudfront.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","CloudFront","Web"]
},
{
"id": "https://www.edge-cloud.net/2022/07/19/hands-on-with-aws-byoip",
"url": "https://www.edge-cloud.net/2022/07/19/hands-on-with-aws-byoip/",
"title": "Hands-on with AWS Bring your own IP addresses (BYOIP) in Amazon EC2",
"content_html": "<p>This blog post will walk you through the <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html\">Bring your own IP addresses (BYOIP) for Amazon EC2</a> feature, using a real-life example. With BYOIP you can bring part or all of your publicly routable IPv4 or IPv6 address ranges to your AWS account. While you continue to own the address range, AWS advertises it on the internet for you under the Amazon <a href=\"https://en.wikipedia.org/wiki/Autonomous_system_(Internet)\">Autonomous System Numbers (ASNs)</a>. Within your AWS account, these BYOIP address ranges appear as an <a href=\"https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html\">address pool</a>.</p>\n\n<p class=\"notice\"><strong><i class=\"fab fa-fw fa-youtube\"></i> YouTube Video:</strong> The content presented here is also available as a <a href=\"https://www.edge-cloud.net/2023/08/20/video-bring-your-own-ip-for-amazon-vpc/\">YouTube video</a>.</p>\n\n<p>While <a href=\"https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-bring-your-own-ip-byoip-for-amazon-vpc/\">other blog posts on AWS BYOIP</a> exist, they are usually completely theoretical, using Documentation IP ranges and thereby hard to follow. In this blog post I will use real IPv6 address space instead, allowing you to validate most of the steps through various publicly available databases and systems yourself.</p>\n\n<h1 id=\"benefits\">Benefits</h1>\n\n<p>You might wonder what the benefits of using BYOIP for Amazon EC2 is. They include among others:</p>\n\n<ul>\n <li><strong>Trusted IP space:</strong> You might be using trusted IP space for your service, such as a transactional e-Mail service that requires a high reputation of IP space, or a VPN service.</li>\n <li><strong>Avoid blocking of IP space:</strong> <a href=\"https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html\">AWS publishes its current IP address ranges in JSON format</a>, which makes it very easy for various content or service provider to block all of this address space. This often happens for unknown or unclear reasons. Address space used for BYOIP is not published via this JSON file.</li>\n <li><strong>Hard-coded IP addresses:</strong> There is a wide set of devices in the field that might be using hard-coded IP addresses to contact a service instead of relying on <a href=\"https://en.wikipedia.org/wiki/Domain_Name_System\">DNS</a>. Therefore when moving such a service to AWS, it is often necessary to move the corresponding IP address and its IP block along to AWS. Most frequently this proves easier than updating hundreds if not thousands of devices in the field.</li>\n</ul>\n\n<h1 id=\"requirements\">Requirements</h1>\n\n<p>The AWS documentation lists various <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html#byoip-requirements\">requirements</a> for using BYOIP. One key requirement is to be able to demonstrate “control” over the IP space in question.</p>\n\n<p>It’s widely recognized within the Internet community that you can demonstrate sufficient control over IP address space for the purpose of announcement from another ASN, by being able to create the corresponding Route Origin Authorization (ROA) record. Later within the process you will see how you can demonstrate control over your IP space by creating the necessary ROA record.</p>\n\n<h1 id=\"overall-process\">Overall process</h1>\n\n<p>The overall process to bring IPv4 or IPv6 address space to AWS via the BYOIP process consists of multiple steps and is outlined in figure 1.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-AWS-Process.png\" title=\"Figure 1: AWS Process to prepare and provision VPC BYOIP. \" class=\"image-popup\">\n<picture>\n <source width=\"1055\" height=\"901\" type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-AWS-Process-320.webp 320w, /content/resized/2022/07/BYOIP-AWS-Process-384.webp 384w, /content/resized/2022/07/BYOIP-AWS-Process-512.webp 512w, /content/resized/2022/07/BYOIP-AWS-Process-683.webp 683w, /content/resized/2022/07/BYOIP-AWS-Process-800.webp 800w, /content/resized/2022/07/BYOIP-AWS-Process-960.webp 960w, /content/uploads/2022/07/BYOIP-AWS-Process.webp 1055w\" sizes=\"1055px\" />\n <source width=\"1055\" height=\"901\" data-srcset=\" /content/resized/2022/07/BYOIP-AWS-Process-320.png 320w, /content/resized/2022/07/BYOIP-AWS-Process-384.png 384w, /content/resized/2022/07/BYOIP-AWS-Process-512.png 512w, /content/resized/2022/07/BYOIP-AWS-Process-683.png 683w, /content/resized/2022/07/BYOIP-AWS-Process-800.png 800w, /content/resized/2022/07/BYOIP-AWS-Process-960.png 960w, /content/uploads/2022/07/BYOIP-AWS-Process.png 1055w\" sizes=\"1055px\" />\n <img src=\"/content/resized/2022/07/BYOIP-AWS-Process-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-AWS-Process.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1055\" height=\"901\" alt=\"Figure 1: AWS Process to prepare and provision VPC BYOIP. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: AWS Process to prepare and provision VPC BYOIP.\n</figcaption>\n\n</figure>\n\n<ul>\n <li>\n <p><strong>Step 1: Configuration of IP address space via your RIR/LIR</strong> - This includes creating appropriate RIR Resource DB records (aka. “Allocation” in the case of RIPE), as well as a Route Origin Authorization (ROA) record. This step represents good hygiene when using IP address space in general. Creation of a ROA record is only necessary for IPv4 address space and publicly advertised IPv6 address space.</p>\n </li>\n <li>\n <p><strong>Step 2: Preparation of Self-signed X.509 certificates</strong> - While ROA is used to demonstrate control over the IP address space, it cannot be used to match a particular IP space to a certain AWS account ID. This is done via steps 2 - 5, whereas Step 2 generates a self-signed X.509 certificate pair for later usage.</p>\n </li>\n <li>\n <p><strong>Step 3: Uploading the public key to the RIR Resource DB (RDAP record)</strong> - Placing the public key portion of the self-signed X.509 certificate into the description field of the IP address space’s RDAP record allows AWS to validate the mapping of the corresponding address space to an AWS account. This approach assumes that only someone with control over the IP address space can make changes to the corresponding RIR Resource DB record.</p>\n </li>\n <li>\n <p><strong>Step 4: Creating a signed message</strong> - In this step you tie the IP address space to a certain AWS account ID. This is done by creating a signed message that by itself creates information about the IP address space and the AWS account ID and is signed using the above mentioned self-signed X.509 certificates.</p>\n </li>\n <li>\n <p><strong>Step 5: Provision and adverstise address space</strong> - The signed message from step 4 is used to request the provisioning of the IP address space within the AWS Virtual Private Cloud (VPC) services. AWS validates the request against the RIR Resources DB and the RPKI publication point to ensure that you have sufficient control over the space. As a last item - which is only necessary for IPv4 address space and publicly advertised IPv6 address space - the IP address space is advertised via BGP to the Internet from the selected AWS region.</p>\n </li>\n</ul>\n\n<h1 id=\"onboarding-your-byoip-space\">Onboarding your BYOIP space</h1>\n\n<h2 id=\"step-1-configuration-of-ip-address-space-via-your-rirlir\">Step 1: Configuration of IP address space via your RIR/LIR</h2>\n\n<p>In this blog post I will use IPv6 space allocated by my Local Internet Registry (LIR) <a href=\"https://snapserv.net/\">SnapServ</a> from the Regional Internet Registry (RIR) <a href=\"https://www.ripe.net/\">RIPE NCC</a>.</p>\n\n<p>RIPE policy (<a href=\"https://www.ripe.net/publications/docs/ripe-733\">IPv4</a>, <a href=\"https://www.ripe.net/publications/docs/ripe-738\">IPv6</a>) states that any IP address sub-block that is used in a different network must be sub-allocated by the RIR or assigned by the end-user within the RIPE database.</p>\n\n<p>For this particular example we will focus on the red circle in Figure 2:</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-RIPE-Assignment.png\" title=\"Figure 2: RIPE Assignment for IPv4 and IPv6 address space with example highlighted in red. \" class=\"image-popup\">\n<picture>\n <source width=\"1131\" height=\"465\" type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-RIPE-Assignment-320.webp 320w, /content/resized/2022/07/BYOIP-RIPE-Assignment-384.webp 384w, /content/resized/2022/07/BYOIP-RIPE-Assignment-512.webp 512w, /content/resized/2022/07/BYOIP-RIPE-Assignment-683.webp 683w, /content/resized/2022/07/BYOIP-RIPE-Assignment-800.webp 800w, /content/resized/2022/07/BYOIP-RIPE-Assignment-960.webp 960w, /content/uploads/2022/07/BYOIP-RIPE-Assignment.webp 1131w\" sizes=\"1131px\" />\n <source width=\"1131\" height=\"465\" data-srcset=\" /content/resized/2022/07/BYOIP-RIPE-Assignment-320.png 320w, /content/resized/2022/07/BYOIP-RIPE-Assignment-384.png 384w, /content/resized/2022/07/BYOIP-RIPE-Assignment-512.png 512w, /content/resized/2022/07/BYOIP-RIPE-Assignment-683.png 683w, /content/resized/2022/07/BYOIP-RIPE-Assignment-800.png 800w, /content/resized/2022/07/BYOIP-RIPE-Assignment-960.png 960w, /content/uploads/2022/07/BYOIP-RIPE-Assignment.png 1131w\" sizes=\"1131px\" />\n <img src=\"/content/resized/2022/07/BYOIP-RIPE-Assignment-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-RIPE-Assignment.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1131\" height=\"465\" alt=\"Figure 2: RIPE Assignment for IPv4 and IPv6 address space with example highlighted in red. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: RIPE Assignment for IPv4 and IPv6 address space with example highlighted in red.\n</figcaption>\n\n</figure>\n\n<p>As mentioned before all these IPv6 prefixes are real and you can follow along the process by checking yourself what is published via the RIPE DB.</p>\n\n<h3 id=\"rir-assignment\">RIR Assignment</h3>\n\n<p>While the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:7300::%2F40&type=inet6num\">/40 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:7300::/40</code> with the status “Allocated-By-LIR” already exists at this point, I need to create a new assignment for the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:73ff::%2F48&type=inet6num\">/48 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73ff::/48</code> with the status “Assigned” to fulfill the RIPE policy.</p>\n\n<p>Without going into full details of how to <a href=\"https://www.ripe.net/manage-ips-and-asns/db/support/documentation/documenting-ipv6-assignments-in-the-ripe-database\">document IPv6 assignments in the RIPE database</a>, or what attributes the <a href=\"https://www.ripe.net/manage-ips-and-asns/db/support/documentation/ripe-database-documentation/rpsl-object-types/4-2-descriptions-of-primary-objects/4-2-3-description-of-the-inet6num-object\">inet6num object</a> can include, the resulting inet6num object in RPSL format will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>inet6num: 2a06:e881:73ff::/48\nnetname: EU-CHRISTIANELSEN-AWS\ncountry: EU\nadmin-c: CE2932-RIPE\ntech-c: CE2932-RIPE\nstatus: ASSIGNED\nmnt-by: Christian_Elsen-MNT\nsource: RIPE\n\n</code></pre></div></div>\n\n<p>For now we have merely created this inet6num object in the RIPE database for documentation purposes and to fulfill the RIPE policy. Later on you’ll see that we will come back to this object and update it with the self-signed X.509 certificate.</p>\n\n<h3 id=\"resource-public-key-infrastructure-rpki\">Resource Public Key Infrastructure (RPKI)</h3>\n\n<p>Next we need to create a Route Origin Authorization (ROA), a cryptographically signed object that states which Autonomous System (AS) is authorized to originate a particular IP address prefix.</p>\n\n<p>For address objects with the status of “Assigned PI” for Provider Independent (See Figure 2), one would accomplish this via the Regional Internet Registry (RIR). In my case that would be the <a href=\"https://my.ripe.net/#/rpki\">RIPE RPKI Dashboard</a> and look like depicted in Figure 3.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-RIPE-RPKI.png\" title=\"Figure 3: RIPE RPKI dashboard for managing Provider Independent (PI) resources. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-RIPE-RPKI-320.webp 320w, /content/resized/2022/07/BYOIP-RIPE-RPKI-384.webp 384w, /content/resized/2022/07/BYOIP-RIPE-RPKI-512.webp 512w, /content/resized/2022/07/BYOIP-RIPE-RPKI-683.webp 683w, /content/resized/2022/07/BYOIP-RIPE-RPKI-800.webp 800w, /content/resized/2022/07/BYOIP-RIPE-RPKI-960.webp 960w, \" sizes=\"1320px\" />\n <source data-srcset=\" /content/resized/2022/07/BYOIP-RIPE-RPKI-320.png 320w, /content/resized/2022/07/BYOIP-RIPE-RPKI-384.png 384w, /content/resized/2022/07/BYOIP-RIPE-RPKI-512.png 512w, /content/resized/2022/07/BYOIP-RIPE-RPKI-683.png 683w, /content/resized/2022/07/BYOIP-RIPE-RPKI-800.png 800w, /content/resized/2022/07/BYOIP-RIPE-RPKI-960.png 960w, \" sizes=\"1320px\" />\n <img src=\"/content/resized/2022/07/BYOIP-RIPE-RPKI-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-RIPE-RPKI.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 3: RIPE RPKI dashboard for managing Provider Independent (PI) resources. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: RIPE RPKI dashboard for managing Provider Independent (PI) resources.\n</figcaption>\n\n</figure>\n\n<p>But you’ll remember from above that for this post I’m not using a Provider Independent IP block, but rather an IPv6 block in the “Assigned” state. Therefore I have to turn to my LIR in order to create the ROA. Luckily my LIR provides a web interface to accomplish this task (See Figure 4).</p>\n\n<p>This allows me to create two ROA entries to map the /48 prefix in question to both the origin ASN of AS14618 and AS16509. As the prefix is a /48 , selecting a “Maximum Length” of 48 for the ROA object is the only choice.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-LIR-RPKI.png\" title=\"Figure 4: LIR RPKI dashboard for managing Assigned resources. \" class=\"image-popup\">\n<picture>\n <source width=\"841\" height=\"404\" type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-LIR-RPKI-320.webp 320w, /content/resized/2022/07/BYOIP-LIR-RPKI-384.webp 384w, /content/resized/2022/07/BYOIP-LIR-RPKI-512.webp 512w, /content/resized/2022/07/BYOIP-LIR-RPKI-683.webp 683w, /content/resized/2022/07/BYOIP-LIR-RPKI-800.webp 800w, /content/uploads/2022/07/BYOIP-LIR-RPKI.webp 841w\" sizes=\"841px\" />\n <source width=\"841\" height=\"404\" data-srcset=\" /content/resized/2022/07/BYOIP-LIR-RPKI-320.png 320w, /content/resized/2022/07/BYOIP-LIR-RPKI-384.png 384w, /content/resized/2022/07/BYOIP-LIR-RPKI-512.png 512w, /content/resized/2022/07/BYOIP-LIR-RPKI-683.png 683w, /content/resized/2022/07/BYOIP-LIR-RPKI-800.png 800w, /content/uploads/2022/07/BYOIP-LIR-RPKI.png 841w\" sizes=\"841px\" />\n <img src=\"/content/resized/2022/07/BYOIP-LIR-RPKI-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-LIR-RPKI.png\" class=\"blur-up lazyautosizes lazyload\" width=\"841\" height=\"404\" alt=\"Figure 4: LIR RPKI dashboard for managing Assigned resources. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: LIR RPKI dashboard for managing Assigned resources.\n</figcaption>\n\n</figure>\n\n<p>AWS recommends to create a ROA object for both AS14618 - which is used for the US-East-1 (N.Virginia) region - as well as AS16509 - which is used for all other commercial AWS regions. If you want to use BYOIP with GovCloud (US) select AS8987 in your ROA object instead.</p>\n\n<p class=\"notice--info\"><strong>Notice:</strong> In this example, where I only want to bring the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:73ff::%2F48&type=inet6num\">/48 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73ff::/48</code> to AWS via BYOIP, The ROA entry is created for this particular /48 only along with the only possible “Maximum Length” size of 48. If I were to bring multiple /48 blocks over to AWS via BYOIP - e.g. for additional AWS regions - I could also create a single ROA entry for the “parent block” - which would be the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:7300::%2F40&type=inet6num\">/40 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:7300::/40</code> - instead of each individual /48 block. In this case the “Maximum Length” still needs to be set to 48 as each individual block would be a /48.</p>\n\n<h2 id=\"step-2-preparation-of-self-signed-x509-certificates\">Step 2: Preparation of Self-signed X.509 certificates</h2>\n\n<p>Next we need to create a self-signed X.509 certificate, for which the <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html#byoip-certificate\">AWS documentation</a> provides the necessary steps using OpenSSL on a Linux based system. A quick and easy way to get access to such a Linux based system is to use <a href=\"https://aws.amazon.com/cloudshell/\">AWS CloudShell</a> in one of the supported AWS Regions. In this demo I’ll be using the EU-Central-1 (Frankfurt) region (See Figure 5).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-CloudShell.png\" title=\"Figure 5: Using AWS CloudShell. \" class=\"image-popup\">\n<picture>\n <source width=\"276\" height=\"56\" type=\"image/webp\" data-srcset=\" /content/uploads/2022/07/BYOIP-CloudShell.webp 276w\" sizes=\"276px\" />\n <source width=\"276\" height=\"56\" data-srcset=\" /content/uploads/2022/07/BYOIP-CloudShell.png 276w\" sizes=\"276px\" />\n <img src=\"/\" data-src=\"/content/uploads/2022/07/BYOIP-CloudShell.png\" class=\"blur-up lazyautosizes lazyload\" width=\"276\" height=\"56\" alt=\"Figure 5: Using AWS CloudShell. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 5: Using AWS CloudShell.\n</figcaption>\n\n</figure>\n\n<p>While AWS CloudShell does not provide OpenSSL out of the box, it can be installed quickly and easily via <code class=\"language-plaintext highlighter-rouge\">sudo yum -y install openssl</code>.</p>\n\n<p>The result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ sudo yum -y install openssl\nLoaded plugins: ovl, priorities\nResolving Dependencies\n--> Running transaction check\n---> Package openssl.x86_64 1:1.0.2k-24.amzn2.0.3 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n==================================================================================================================================================================================================================================================\n Package Arch Version Repository Size\n==================================================================================================================================================================================================================================================\nInstalling:\n openssl x86_64 1:1.0.2k-24.amzn2.0.3 amzn2-core 496 k\n\nTransaction Summary\n==================================================================================================================================================================================================================================================\nInstall 1 Package\n\nTotal download size: 496 k\nInstalled size: 830 k\nDownloading packages:\nopenssl-1.0.2k-24.amzn2.0.3.x86_64.rpm | 496 kB 00:00:00 \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : 1:openssl-1.0.2k-24.amzn2.0.3.x86_64 1/1 \n Verifying : 1:openssl-1.0.2k-24.amzn2.0.3.x86_64 1/1 \n\nInstalled:\n openssl.x86_64 1:1.0.2k-24.amzn2.0.3 \n\nComplete!\n</code></pre></div></div>\n<p>Next we can generate the private key via <code class=\"language-plaintext highlighter-rouge\">openssl genpkey -aes256 -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private-key.pem</code>, which will then look like this as a result.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ openssl genpkey -aes256 -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private-key.pem\n...................+++\n..........................................+++\nEnter PEM pass phrase:\nVerifying - Enter PEM pass phrase:\n[cloudshell-user@ip-10-1-2-3 ~]$ ls\nprivate-key.pem\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n\n<p>Next we have to create the corresponding public certificate with <code class=\"language-plaintext highlighter-rouge\">openssl req -new -x509 -key private-key.pem -days 365 | tr -d \"\\n\" > certificate.pem</code>. None of the values asked for “Country Name” through “Common Name” or “Email Address” matter and can be randomly chosen.</p>\n\n<p>The result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ openssl req -new -x509 -key private-key.pem -days 365 | tr -d \"\\n\" > certificate.pem\nEnter pass phrase for private-key.pem:\nYou are about to be asked to enter information that will be incorporated\ninto your certificate request.\nWhat you are about to enter is what is called a Distinguished Name or a DN.\nThere are quite a few fields but you can leave some blank\nFor some fields there will be a default value,\nIf you enter '.', the field will be left blank.\n-----\nCountry Name (2 letter code) [XX]:NZ\nState or Province Name (full name) []:\nLocality Name (eg, city) [Default City]:Auckland\nOrganization Name (eg, company) [Default Company Ltd]:Edge-Cloud\nOrganizational Unit Name (eg, section) []:\nCommon Name (eg, your name or your server's hostname) []:AWS-BYOIP\nEmail Address []:\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n<p class=\"notice--info\"><strong>Notice:</strong> Due to the parameter <code class=\"language-plaintext highlighter-rouge\">-days 365</code> the public certificate will have a validity of 365 days. The certificate will only be used during the initial provisioning steps for an IP range. You might want to place the certificate into the parent block of an IP range - e.g. the the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:7300::%2F40&type=inet6num\">/40 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:7300::/40</code> in my case - in order to later bring additional IP ranges to AWS, e.g. for additional regions. In this case make sure you don’t loose the corresponding private key within your AWS CloudShell and keep an eye on the expiration date of the certificate. The ROA on the other hand has to remain in place!</p>\n\n<h2 id=\"step-3-uploading-the-public-key-to-the-rir-resource-db-rdap-record\">Step 3: Uploading the public key to the RIR Resource DB (RDAP record)</h2>\n\n<p>Next we need to upload the resulting public certificate from above into the RIR resource data base as an RDAP record. In the case of RIPE - which is the RIR that we are using for this example - the public certificate has to be placed into the “descr” field of the address range.</p>\n\n<p class=\"notice--info\"><strong>Notice:</strong> In this example, where I only want to bring the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:73ff::%2F48&type=inet6num\">/48 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73ff::/48</code> to AWS via BYOIP, I will place it within this address ranges RIR record. If I were to bring multiple /48 blocks over to AWS via BYOIP - e.g. for additional AWS regions - I could also place the public certificate into the “parent block” which would be the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:7300::%2F40&type=inet6num\">/40 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:7300::/40</code> in this case.</p>\n\n<p>First we will grab the content of the public certificate via the command <code class=\"language-plaintext highlighter-rouge\">cat certificate.pem</code>.</p>\n\n<p>The result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-0-76-195 ~]$ cat certificate.pem\n-----BEGIN CERTIFICATE-----MIIDyTCCArGgAwIBAgIUR2P0aLZtfm2L9QZI5muMqtCQcM0wDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhFMRIwEAYDVQQHDAlGcmFua2Z1cnQxFTATBgNVBAoMDEFTMjEzMTUxIExMQzEMMAoGA1UECwwDTk9DMR8wHQYJKoZIhvcNAQkBFhBub2NAYXMyMTMxNTEubmV0MB4XDTIxMDgzMTIxNTg1MFoXDTIyMDgzMTIxNTg1MFowdDELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhFMRIwEAYDVQQHDAlGcmFua2Z1cnQxFTATBgNVBAoMDEFTMjEzMTUxIExMQzEMMAoGA1UECwwDTk9DMR8wHQYJKoZIhvcNAQkBFhBub2NAYXMyMTMxNTEubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuVeZfmkEPM2Oh5K9vISgoBFJP/xuCrZE81VTErGjrPAeXfQaKXJzTf4xL4QZPBJmAbtSD91d4ubGEwVv8FIH8vg712opgLefMDYwv1SoAV0YUG0C23Zadm31MHOWtYX/KgEXOtUkAUuL8QEUH2fgU/6F+0PEBWC985zKTCMxEu2GmyEdjPT0dcun2F/eLFaEjtkZ5Il+ruhoN9grhBWWqau4DG0EyBnkARSmB8zpqSFte6IO+XypSpEglc3792xnLQFVUc1N7jynIMXXIf9fnPKP87jTcxmyDszFfguC9nsdmSDB9VMe3rnnJmDN13nkGWWgtve0grM8yULBb93IwIDAQABo1MwUTAdBgNVHQ4EFgQUaLbwp0B6sJR9bhlQOAFE9Ts/BKkwHwYDVR0jBBgwFoAUaLbwp0B6sJR9bhlQOAFE9Ts/BKkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAIbvgfqQgCDkKi35Gj0St0aOk1+h8iOdqrW3/JXvNUsIRJJcPpwJyA/kBOuy64YWc9kk7lod+TxFXdMZiUKUFKJtC5FDY2RaR5YpstLNG/+T19ydNLjPQ2WBrUqUyCL9T195/TmZ437k/Rg1VMGisHPlLrOON8IPFg/G3Xy/9fTEQIIZczWlWAprtxacgCMHgZvr31vDEgSNbJux6s+P8YZA7j8M2GclAX13gtim9IeTGgQTjRX9YtlGSP8hHj9vVIxktyyJFF9PphMjlEKuNvlj5rG9YWjjqXUUPrhihlC53MmH7p1dtDKL63f3XAqJPTjJYvj7joBXz4evVVohjEg==-----END CERTIFICATE-----[cloudshell-user@ip-10-0-76-195 ~]$\n</code></pre></div></div>\n\n<p>Next we update the inet6num object for the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:73ff::%2F48&type=inet6num\">/48 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73ff::/48</code> with this certificate. Ensure to also include the <code class=\"language-plaintext highlighter-rouge\">----BEGIN CERTIFICATE-----</code> and <code class=\"language-plaintext highlighter-rouge\">-----END CERTIFICATE-----</code> portions and not to include any newlines.</p>\n\n<p>The resulting inet6num object in RPSL format will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>inet6num: 2a06:e881:73ff::/48\nnetname: EU-CHRISTIANELSEN-AWS\ncountry: EU\nadmin-c: CE2932-RIPE\ntech-c: CE2932-RIPE\nstatus: ASSIGNED\ndescr: -----BEGIN CERTIFICATE-----MIIDyTCCArGgAwIBAgIUR2P0aLZtfm2L9QZI5muMqtCQcM0wDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhFMRIwEAYDVQQHDAlGcmFua2Z1cnQxFTATBgNVBAoMDEFTMjEzMTUxIExMQzEMMAoGA1UECwwDTk9DMR8wHQYJKoZIhvcNAQkBFhBub2NAYXMyMTMxNTEubmV0MB4XDTIxMDgzMTIxNTg1MFoXDTIyMDgzMTIxNTg1MFowdDELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhFMRIwEAYDVQQHDAlGcmFua2Z1cnQxFTATBgNVBAoMDEFTMjEzMTUxIExMQzEMMAoGA1UECwwDTk9DMR8wHQYJKoZIhvcNAQkBFhBub2NAYXMyMTMxNTEubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuVeZfmkEPM2Oh5K9vISgoBFJP/lxuCrZE81VTErGjrPAeXfQaKXJzTf4xL4QZPBJmAbtSD91d4ubGEwVv8FIH8vg712opgLefMDYwv1SoAV0YUG0C23Zadm31MHOWtYX/KgEXOtUkAUuL8QEUH2fgU/6F+0PEBWC985zKTCMxEu2GmyEdjPT0dcun2F/eLFaEjtkZ5Il+ruhoN9grhBWWqau4DG0EyBnkARSmB8zpqSFte6IO+XypSpEglc3792xnLQFVUc1N7jynIMXXIf9fnPKP87jTcxmyDszFfguC9nsdmSDB9VMe3rnnJmDN13nkGWWgtve0grM8yULBb93IwIDAQABo1MwUTAdBgNVHQ4EFgQUaLbwp0B6sJR9bhlQOAFE9Ts/BKkwHwYDVR0jBBgwFoAUaLbwp0B6sJR9bhlQOAFE9Ts/BKkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAIbvgfqQgCDkKi35Gj0St0aOk1+h8iOdqrW3/JXvNUsIRJJcPpwJyA/kBOuy64YWc9kk7lod+TxFXdMZiUKUFKJtC5FDY2RaR5YpstLNG/+T19ydNLjPQ2WBrUqUyCL9T195/TmZ437k/Rg1VMGisHPlLrOON8IPFg/G3Xy/9fTEQIIZczWlWAprtxacgCMHgZvr31vDEgSNbJux6s+P8YZA7j8M2GclAX13gtim9IeTGgQTjRX9YtlGSP8hHj9vVIxktyyJFF9PphMjlEKuNvlj5rG9YWjjqXUUPrhihlC53MmH7p1dtDKL63f3XAqJPTjJYvj7joBXz4evVVohjEg==-----END CERTIFICATE-----\nmnt-by: Christian_Elsen-MNT\nsource: RIPE\n</code></pre></div></div>\n\n<h2 id=\"step-4-creating-a-signed-message\">Step 4: Creating a signed message</h2>\n\n<p>Now we can create our signed message that will tie the CIDR to be brought into AWS via BYOIP to the account ID under which it shall later live. As outlined in the <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html#byoip-provision\">AWS documentation</a>, the format of the corresponding plain text message looks like <code class=\"language-plaintext highlighter-rouge\">1|aws|<account>|<cidr>|<expiration date>|SHA256|RSAPSS</code></p>\n\n<p>Assuming an AWS account id of <code class=\"language-plaintext highlighter-rouge\">1234-5678-9012</code> and an expiration date of 1 year out from today - to give us enough time for the next steps - the resulting way to assign the plain text message would look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ text_message=\"1|aws|123456789012|2a06:e881:73ff::/48|20220711|SHA256|RSAPSS\"\n[cloudshell-user@ip-10-1-2-3 ~]$ echo $text_message\n1|aws|123456789012|2a06:e881:73ff::/48|20220711|SHA256|RSAPSS\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n<p>Next we will create the signed message using the command <code class=\"language-plaintext highlighter-rouge\">signed_message=$( echo -n $text_message | openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -sign private-key.pem -keyform PEM | openssl base64 | tr -- '+=/' '-_~' | tr -d \"\\n\")</code></p>\n\n<p>The result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ signed_message=$( echo -n $text_message | openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -sign private-key.pem -keyform PEM | openssl base64 | tr -- '+=/' '-_~' | tr -d \"\\n\")\nEnter pass phrase for private-key.pem:\n[cloudshell-user@ip-10-1-2-3 ~]$ echo $signed_message\nNcj8Yrm~6gbPuqDokOh9-tLsiCuMqzid5CxlseO87sRSG1DAhuz2RmL9Dw6TQA83lhiyhcLuHdiY34xojYxcFLHHHpona0l8Ul2MlkppehFP5qN11O4VlN78COzC37JqnuIqfngc~3juFY9u4Wt4qBqzAb08AzhaWf3v9Fu9qut5Hr3NRWtRaHfgeGvIYWZ2C864RvWPLEW6RmdXdHDojszcgxCfV-O5jCaafu8v~~m~vASq~-xOnlanqNsZ9D66l4r-MMLhYXccMyBgBKP3qhluR0FsQ~LfcBQbyEwEtS-wxWPG8~Dm9o67rkI19bVT16p~cGCBAQA17nefK3o-kw__\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n\n<h2 id=\"step-5-provision-and-advertise-address-space\">Step 5: Provision and advertise address space</h2>\n\n<h3 id=\"provision-the-cidr-with-an-aws-region\">Provision the CIDR with an AWS region</h3>\n\n<p>Next we have to provision the above CIDR into the desired AWS region - here EU-Central-1 (Frankfurt). \nThis is done via the AWS CLI command <code class=\"language-plaintext highlighter-rouge\">aws ec2 provision-byoip-cidr --cidr <cidr> --cidr-authorization-context Message=\"$text_message\",Signature=\"$signed_message\" --region <region></code>. As AWS CloudShell has the <a href=\"https://aws.amazon.com/cli/\">AWS Command Line Interface (CLI)</a> already installed no further preparation is necessary and the result will look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ aws ec2 provision-byoip-cidr --cidr 2a06:e881:73ff::/48 --cidr-authorization-context Message=\"$text_message\",Signature=\"$signed_message\" --region eu-central-1\n{\n \"ByoipCidr\": {\n \"Cidr\": \"2a06:e881:73ff::/48\",\n \"State\": \"pending-provision\"\n }\n}\n[cloudshell-user@ip-10-1-2-3 ~]$ \n</code></pre></div></div>\n\n<p>It can take between minutes to days for the provisioning to be successful. You can use the command <code class=\"language-plaintext highlighter-rouge\">aws ec2 describe-byoip-cidrs --max-results 5 --region <region></code> to monitor the progress.</p>\n\n<p>For the above example the successful result would look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ aws ec2 describe-byoip-cidrs --max-results 5 --region eu-central-1\n{\n \"ByoipCidrs\": [\n {\n \"Cidr\": \"2a06:e881:73ff::/48\",\n \"StatusMessage\": \"Cidr successfully provisioned into Ipv6Pool: ipv6pool-ec2-0123456789abcdefgh\",\n \"State\": \"provisioned\"\n }\n ]\n}\n[cloudshell-user@ip-10-1-2-3 ~]$ \n</code></pre></div></div>\n\n<p class=\"notice--info\"><strong>Notice:</strong> At this point the public certificate no longer needs to be placed within the inet6num object of the RIR DB - in this case for RIPE within the “descr:” field. You can therefore remove it. On the other hand if you created the public certificate for a parent IP block and plan to provision additional child blocks later on, you can keep the public certificate in place. In this case make sure you don loose the corresponding private key within your AWS CloudShell and keep an eye on the expiration date of the certificate. The ROA on the other hand has to remain in place!</p>\n\n<h3 id=\"advertise-the-address-space\">Advertise the address space</h3>\n\n<p>We are almost done and as a last step need to instruct AWS to advertise the BYOIP CIDR from the AWS region into which the address space was provisioned. This is done via the AWS CLI command <code class=\"language-plaintext highlighter-rouge\">aws ec2 advertise-byoip-cidr --cidr <cidr> --region <region></code>.</p>\n\n<p>The result would look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ aws ec2 advertise-byoip-cidr --cidr 2a06:e881:73ff::/48 --region eu-central-1\n{\n \"ByoipCidr\": {\n \"Cidr\": \"2a06:e881:73ff::/48\",\n \"State\": \"advertised\"\n }\n}\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n<p>At this point we are done with bringing over the desired IPv6 address space to AWS via BYOIP. But is that address space actually working as expected and how do we use it? Read on in the next paragraph for answers to these questions.</p>\n\n<h1 id=\"validation\">Validation</h1>\n\n<p>This section will walk you through the validation of your BYOIP setup. As I’m using real IPv6 address space and not documentation ranges, you will be able to follow along with the below steps on your own.</p>\n\n<h2 id=\"roa-object-for-rpki\">ROA object for RPKI</h2>\n\n<p>You can validate the successful creation of the ROA objects using the <a href=\"https://stat.ripe.net/docs/02.data-api/rpki-validation.html\">RIPEstat Data API</a>, irrespective if the address space in question is administered by RIPE or not. If you are using one of the AWS commercial regions, be sure to test your address range against the Amazon ASNs 16509 and 14618, plus the ASNs that are currently authorized to advertise the address range. If you are using BYOIP with GovCloud (US) check your ROA against the ASN 8987.</p>\n\n<p>You can inspect the ROA objects from different Amazon ASNs with your address range by using the following command: <code class=\"language-plaintext highlighter-rouge\">curl --location --request GET \"https://stat.ripe.net/data/rpki-validation/data.json?resource=<ASN>&prefix=<CIDR>\"</code></p>\n\n<p>The successful output for the <a href=\"https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&key=2a06:e881:73ff::%2F48&type=inet6num\">/48 block</a> of <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73ff::/48</code> that is being used in this example looks like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ curl --location --request GET \"https://stat.ripe.net/data/rpki-validation/data.json?resource=16509&prefix=2a06:e881:73ff::/48\"\n{\n \"messages\": [],\n \"see_also\": [],\n \"version\": \"0.3\",\n \"data_call_name\": \"rpki-validation\",\n \"data_call_status\": \"supported\",\n \"cached\": false,\n \"data\": {\n \"validating_roas\": [\n {\n \"origin\": \"16509\",\n \"prefix\": \"2a06:e881:73ff::/48\",\n \"max_length\": 48,\n \"validity\": \"valid\"\n },\n {\n \"origin\": \"14618\",\n \"prefix\": \"2a06:e881:73ff::/48\",\n \"max_length\": 48,\n \"validity\": \"invalid_asn\"\n },\n {\n \"origin\": \"213151\",\n \"prefix\": \"2a06:e881:7300::/40\",\n \"max_length\": 48,\n \"validity\": \"invalid_asn\"\n }\n ],\n \"status\": \"valid\",\n \"validator\": \"routinator\",\n \"resource\": \"16509\",\n \"prefix\": \"2a06:e881:73ff::/48\"\n },\n \"query_id\": \"20220711193722-64c20e2b-55af-499e-9975-e6e60b24cf6a\",\n \"process_time\": 37,\n \"server_id\": \"app112\",\n \"build_version\": \"live.2022.7.11.99\",\n \"status\": \"ok\",\n \"status_code\": 200,\n \"time\": \"2022-07-11T19:37:22.292101\"\n}\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n\n<p>In this example output, the response has a result of <em>“status”: “valid”</em> for the Amazon ASN 16509. This indicates the ROA object for the address range was created successfully.</p>\n\n<p>If on the other side the response includes a response of <em>“status”: “unknown”</em>, it indicates the ROA object for the address range has not been created. And a response of <em>“status”: “invalid_asn”</em> shows that the ROA object for the address range was not created successfully.</p>\n\n<p>With that the following example would indicate that the required ROA for the address space <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73fe::/48</code> and the ASN 16509 was not created:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ curl --location --request GET \"https://stat.ripe.net/data/rpki-validation/data.json?resource=16509&prefix=2a06:e881:73fe::/48\"\n{\n \"messages\": [],\n \"see_also\": [],\n \"version\": \"0.3\",\n \"data_call_name\": \"rpki-validation\",\n \"data_call_status\": \"supported\",\n \"cached\": false,\n \"data\": {\n \"validating_roas\": [\n {\n \"origin\": \"213151\",\n \"prefix\": \"2a06:e881:7300::/40\",\n \"max_length\": 48,\n \"validity\": \"invalid_asn\"\n }\n ],\n \"status\": \"invalid_asn\",\n \"validator\": \"routinator\",\n \"resource\": \"16509\",\n \"prefix\": \"2a06:e881:73fe::/48\"\n },\n \"query_id\": \"20220711194025-926889c0-973e-4f0a-bfb6-ba38551f467c\",\n \"process_time\": 3045,\n \"server_id\": \"app142\",\n \"build_version\": \"live.2022.7.11.99\",\n \"status\": \"ok\",\n \"status_code\": 200,\n \"time\": \"2022-07-11T19:40:28.961834\"\n}\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n\n<p>That makes sense as it doesn’t match the IP range from this example.</p>\n\n<h2 id=\"public-certificate-in-rir-resource-database\">Public certificate in RIR resource database</h2>\n\n<p>Next, let’s validate whether the public certificate has been correctly placed into the RIR’s resource database. This certificate is used by AWS in the provisioning step to validate which AWS account a certain CIDR should be allocated to.</p>\n\n<p>As we are using the RIR RIPE for this example, the command to lookup the public certificate is <code class=\"language-plaintext highlighter-rouge\">whois -r -h whois.ripe.net <CIDR> | grep descr | grep BEGIN</code>. Before we can do so, we have to install the command <em>whois</em> within our AWS CloudShell environment via <code class=\"language-plaintext highlighter-rouge\">sudo yum -y install whois</code></p>\n\n<p>With this we should expect the following output for this example:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ sudo yum -y install whois\nLoaded plugins: ovl, priorities\namzn2-core | 3.7 kB 00:00:00 \nResolving Dependencies\n--> Running transaction check\n---> Package whois.x86_64 0:5.1.1-2.amzn2.0.1 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n==================================================================================================================================================================================================================================================\n Package Arch Version Repository Size\n==================================================================================================================================================================================================================================================\nInstalling:\n whois x86_64 5.1.1-2.amzn2.0.1 amzn2-core 72 k\n\nTransaction Summary\n==================================================================================================================================================================================================================================================\nInstall 1 Package\n\nTotal download size: 72 k\nInstalled size: 218 k\nDownloading packages:\nwhois-5.1.1-2.amzn2.0.1.x86_64.rpm | 72 kB 00:00:00 \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : whois-5.1.1-2.amzn2.0.1.x86_64 1/1 \n Verifying : whois-5.1.1-2.amzn2.0.1.x86_64 1/1 \n\nInstalled:\n whois.x86_64 0:5.1.1-2.amzn2.0.1 \n\nComplete!\n[cloudshell-user@ip-10-1-2-3 ~]$ whois -r -h whois.ripe.net 2a06:e881:73ff::/48 | grep descr | grep BEGIN\ndescr: -----BEGIN CERTIFICATE-----MIIDyTCCArGgAwIBAgIUR2P0aLZtfm2L9QZI5muMqtCQcM0wDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhFMRIwEAYDVQQHDAlGcmFua2Z1cnQxFTATBgNVBAoMDEFTMjEzMTUxIExMQzEMMAoGA1UECwwDTk9DMR8wHQYJKoZIhvcNAQkBFhBub2NAYXMyMTMxNTEubmV0MB4XDTIxMDgzMTIxNTg1MFoXDTIyMDgzMTIxNTg1MFowdDELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhFMRIwEAYDVQQHDAlGcmFua2Z1cnQxFTATBgNVBAoMDEFTMjEzMTUxIExMQzEMMAoGA1UECwwDTk9DMR8wHQYJKoZIhvcNAQkBFhBub2NAYXMyMTMxNTEubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuVeZfmkEPM2Oh5K9vISgoBFJP/lxuCrZE81VTErGjrPAeXfQaKXJzTf4xL4QZPBJmAbtSD91d4ubGEwVv8FIH8vg712opgLefMDYwv1SoAV0YUG0C23Zadm31MHOWtYX/KgEXOtUkAUuL8QEUH2fgU/6F+0PEBWC985zKTCMxEu2GmyEdjPT0dcun2F/eLFaEjtkZ5Il+ruhoN9grhBWWqau4DG0EyBnkARSmB8zpqSFte6IO+XypSpEglc3792xnLQFVUc1N7jynIMXXIf9fnPKP87jTcxmyDszFfguC9nsdmSDB9VMe3rnnJmDN13nkGWWgtve0grM8yULBb93IwIDAQABo1MwUTAdBgNVHQ4EFgQUaLbwp0B6sJR9bhlQOAFE9Ts/BKkwHwYDVR0jBBgwFoAUaLbwp0B6sJR9bhlQOAFE9Ts/BKkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAIbvgfqQgCDkKi35Gj0St0aOk1+h8iOdqrW3/JXvNUsIRJJcPpwJyA/kBOuy64YWc9kk7lod+TxFXdMZiUKUFKJtC5FDY2RaR5YpstLNG/+T19ydNLjPQ2WBrUqUyCL9T195/TmZ437k/Rg1VMGisHPlLrOON8IPFg/G3Xy/9fTEQIIZczWlWAprtxacgCMHgZvr31vDEgSNbJux6s+P8YZA7j8M2GclAX13gtim9IeTGgQTjRX9YtlGSP8hHj9vVIxktyyJFF9PphMjlEKuNvlj5rG9YWjjqXUUPrhihlC53MmH7p1dtDKL63f3XAqJPTjJYvj7joBXz4evVVohjEg==-----END CERTIFICATE-----\n[cloudshell-user@ip-10-1-2-3 ~]$\n</code></pre></div></div>\n\n<p>You should ensure that the result in the line marked with <em>“descr:”</em> includes both the leading <code class=\"language-plaintext highlighter-rouge\">-----BEGIN CERTIFICATE-----</code> and the trailing <code class=\"language-plaintext highlighter-rouge\">-----END CERTIFICATE-----</code> part of the certificate and that the certificate itself matches the certificate you created.</p>\n\n<p>You can also copy & paste the result into a online <a href=\"https://certificatedecoder.dev/\">Certificate Decoder</a> to validate that the certificate itself is valid and not expired.</p>\n\n<p>In case you are using one of the other supported RIR, the above command will look slightly different. In the case of ARIN it will be <code class=\"language-plaintext highlighter-rouge\">whois -h whois.arin.net r + <CIDR> | grep Comment | grep BEGIN</code>, while for APNIC it is <code class=\"language-plaintext highlighter-rouge\">whois -h whois.apnic.net <CIDR> | grep remarks | grep BEGIN</code>.</p>\n\n<h2 id=\"aws-provisioning-outcome\">AWS Provisioning outcome</h2>\n\n<p><a href=\"#step-5-provision-and-advertise-address-space\">Above</a> we already saw how the successful provisioning of the BYOIP address space via the <code class=\"language-plaintext highlighter-rouge\">aws ec2 provision-byoip-cidr</code> looks like. Here let’s have a look at an unsuccessful provisioning example:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>[cloudshell-user@ip-10-1-2-3 ~]$ aws ec2 describe-byoip-cidrs --max-results 5 --region eu-central-1\n{\n \"ByoipCidrs\": [\n {\n \"Cidr\": \"2a06:e881:73fe::/48\",\n \"StatusMessage\": \"No X509 certificate could be found in the Whois remarks\",\n \"State\": \"failed-provision\"\n }\n ]\n}\n[cloudshell-user@ip-10-1-2-3 ~]$ \n</code></pre></div></div>\n\n<p>In this case you can see that the provisioning failed, because AWS was unable to find the public certificate for this IP space within the RIR’s database. And if you look closer, that result does make sense, as we (on purpose) attempted to provision an IP space that hasn’t been prepared.</p>\n\n<h2 id=\"bgp-advertisement\">BGP advertisement</h2>\n\n<p>After <a href=\"#step-5-provision-and-advertise-address-space\">succesfully provisioning the IP space above</a> we asked AWS to advertise the IP space via the <code class=\"language-plaintext highlighter-rouge\">aws ec2 advertise-byoip-cidr</code> command. But how can we tell that this advertisement is actually happening? We can use the <a href=\"https://en.wikipedia.org/wiki/Looking_Glass_server\">Looking Glass server</a> of a major Tier 1 transit provider like the <a href=\"https://lg.he.net/\">Hurricane Electric Looking Glass</a> service.</p>\n\n<p>Selecting any of the Hurricane Electric Router locations along with the command <code class=\"language-plaintext highlighter-rouge\">BGP Route</code> and the Argument <code class=\"language-plaintext highlighter-rouge\">2a06:e881:73ff::/48</code> for the address space in question will show us the following result.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-LG-Success.png\" title=\"Figure 6: Looking glass result for a successfully advertised BYOIP CIDR. \" class=\"image-popup\">\n<picture>\n <source width=\"1036\" height=\"727\" type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-LG-Success-320.webp 320w, /content/resized/2022/07/BYOIP-LG-Success-384.webp 384w, /content/resized/2022/07/BYOIP-LG-Success-512.webp 512w, /content/resized/2022/07/BYOIP-LG-Success-683.webp 683w, /content/resized/2022/07/BYOIP-LG-Success-800.webp 800w, /content/resized/2022/07/BYOIP-LG-Success-960.webp 960w, /content/uploads/2022/07/BYOIP-LG-Success.webp 1036w\" sizes=\"1036px\" />\n <source width=\"1036\" height=\"727\" data-srcset=\" /content/resized/2022/07/BYOIP-LG-Success-320.png 320w, /content/resized/2022/07/BYOIP-LG-Success-384.png 384w, /content/resized/2022/07/BYOIP-LG-Success-512.png 512w, /content/resized/2022/07/BYOIP-LG-Success-683.png 683w, /content/resized/2022/07/BYOIP-LG-Success-800.png 800w, /content/resized/2022/07/BYOIP-LG-Success-960.png 960w, /content/uploads/2022/07/BYOIP-LG-Success.png 1036w\" sizes=\"1036px\" />\n <img src=\"/content/resized/2022/07/BYOIP-LG-Success-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-LG-Success.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1036\" height=\"727\" alt=\"Figure 6: Looking glass result for a successfully advertised BYOIP CIDR. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 6: Looking glass result for a successfully advertised BYOIP CIDR.\n</figcaption>\n\n</figure>\n\n<p>As expected you can see that Hurricane Electric network learns the prefix 2a06:e881:73ff::/48 via multiple different routes. Looking at the <em>path</em> column shows us that some of these routes are directly connected (where path only includes “16509”), while others are via other networks (E.g. the best route via <a href=\"https://bgp.he.net/AS6453\">AS6453 - Tata Communications</a>).</p>\n\n<p>Now let’s have a look at a looking glass example for an IP range that was not successfully announced. Let’s use our example from above again for an IP prefix that is not used with AWS BYOIP:</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-LG-Failure.png\" title=\"Figure 7: Looking glass result for a BYOIP CIDR that is not being advertised. \" class=\"image-popup\">\n<picture>\n <source width=\"1036\" height=\"457\" type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-LG-Failure-320.webp 320w, /content/resized/2022/07/BYOIP-LG-Failure-384.webp 384w, /content/resized/2022/07/BYOIP-LG-Failure-512.webp 512w, /content/resized/2022/07/BYOIP-LG-Failure-683.webp 683w, /content/resized/2022/07/BYOIP-LG-Failure-800.webp 800w, /content/resized/2022/07/BYOIP-LG-Failure-960.webp 960w, /content/uploads/2022/07/BYOIP-LG-Failure.webp 1036w\" sizes=\"1036px\" />\n <source width=\"1036\" height=\"457\" data-srcset=\" /content/resized/2022/07/BYOIP-LG-Failure-320.png 320w, /content/resized/2022/07/BYOIP-LG-Failure-384.png 384w, /content/resized/2022/07/BYOIP-LG-Failure-512.png 512w, /content/resized/2022/07/BYOIP-LG-Failure-683.png 683w, /content/resized/2022/07/BYOIP-LG-Failure-800.png 800w, /content/resized/2022/07/BYOIP-LG-Failure-960.png 960w, /content/uploads/2022/07/BYOIP-LG-Failure.png 1036w\" sizes=\"1036px\" />\n <img src=\"/content/resized/2022/07/BYOIP-LG-Failure-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-LG-Failure.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1036\" height=\"457\" alt=\"Figure 7: Looking glass result for a BYOIP CIDR that is not being advertised. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 7: Looking glass result for a BYOIP CIDR that is not being advertised.\n</figcaption>\n\n</figure>\n\n<p>As this particular prefix is not announced on the Internet at all - only its parent block is announced - Hurricane Electric will not have any routes for this particular prefix.</p>\n\n<h1 id=\"using-byoip-address-space\">Using BYOIP address space</h1>\n\n<p>We have not only provisioned the IP address space, but also validate that everything is correctly working. What remains is the question about how to use this IP prefix in AWS.</p>\n\n<h2 id=\"aws-console-view-of-byoip-cidr\">AWS Console view of BYOIP CIDR</h2>\n\n<p>AWS BYOIP prefixes become regular CIDR pools within the AWS VPC (See Figure 8).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/07/BYOIP-AWS-VPC-Pool.png\" title=\"Figure 8: Resulting IPv6 pool within a VPC. \" class=\"image-popup\">\n<picture>\n <source width=\"603\" height=\"373\" type=\"image/webp\" data-srcset=\" /content/resized/2022/07/BYOIP-AWS-VPC-Pool-320.webp 320w, /content/resized/2022/07/BYOIP-AWS-VPC-Pool-384.webp 384w, /content/resized/2022/07/BYOIP-AWS-VPC-Pool-512.webp 512w, /content/uploads/2022/07/BYOIP-AWS-VPC-Pool.webp 603w\" sizes=\"603px\" />\n <source width=\"603\" height=\"373\" data-srcset=\" /content/resized/2022/07/BYOIP-AWS-VPC-Pool-320.png 320w, /content/resized/2022/07/BYOIP-AWS-VPC-Pool-384.png 384w, /content/resized/2022/07/BYOIP-AWS-VPC-Pool-512.png 512w, /content/uploads/2022/07/BYOIP-AWS-VPC-Pool.png 603w\" sizes=\"603px\" />\n <img src=\"/content/resized/2022/07/BYOIP-AWS-VPC-Pool-320.png\" data-src=\"/content/uploads/2022/07/BYOIP-AWS-VPC-Pool.png\" class=\"blur-up lazyautosizes lazyload\" width=\"603\" height=\"373\" alt=\"Figure 8: Resulting IPv6 pool within a VPC. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 8: Resulting IPv6 pool within a VPC.\n</figcaption>\n\n</figure>\n\n<p>IPv4 prefixes can be used the same way as <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html\">Elastic IP addresses (EIP)</a> and IPv6 prefixes can be <a href=\"https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#vpc-associate-ipv6-cidr\">associated with VPCs</a> the same way as AWS provided IPv6 addresses.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This article provide you a walk-through example of bringing IPv6 address space to AWS via the <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html\">Bring your own IP addresses (BYOIP) for Amazon EC2</a> feature. It used a real address space example, so that you can follow along the onboarding and validation of the IP space.</p>\n",
"summary": "Using AWS Bring your own IP addresses (BYOIP) in Amazon EC2 capability with a real life example of an IPv6 prefix, showing provisioning and troubleshooting steps.",
"date_published": "2022-07-19T00:00:00-07:00",
"date_modified": "2022-07-19T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2022/07/title-hands-on-with-aws-byoip.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","IPv6"]
},
{
"id": "https://www.edge-cloud.net/2022/06/28/dx-overview",
"url": "https://www.edge-cloud.net/2022/06/28/dx-overview/",
"title": "AWS Direct Connect overview",
"content_html": "<p><a href=\"https://aws.amazon.com/directconnect/\">AWS Direct Connect</a> (DX) makes it easy to establish a dedicated connection from an on-premises network to AWS. Using AWS Direct Connect, you can establish private connectivity between AWS and your data center, office, factory or collocated environment. Such connectivity can reduce network costs, increase bandwidth, and provide a more consistent network experience than internet-based connections.</p>\n\n<p>This article will provide an overview of AWS Direct Connect, outlining the various elements, touch upon resiliency recommendations, connectivity options to on-premises and demystify the commercial workflow and associated costs.</p>\n\n<h1 id=\"overview\">Overview</h1>\n\n<p>AWS Direct Connect provides direct physical connectivity to the AWS Network via 3rd party <a href=\"https://aws.amazon.com/directconnect/locations/\">colocation facilities (DX locations)</a>, using a cross-connect between an AWS-owned device and either a customer- or partner-owned device (See figure 1).</p>\n\n<figure class=\"webfeedsFeaturedVisual\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/DX-Physical.png\" title=\"Figure 1: Direct Connect Overview \" class=\"image-popup\">\n<picture>\n <source width=\"1128\" height=\"341\" type=\"image/webp\" data-srcset=\" /content/resized/2022/06/DX-Physical-320.webp 320w, /content/resized/2022/06/DX-Physical-384.webp 384w, /content/resized/2022/06/DX-Physical-512.webp 512w, /content/resized/2022/06/DX-Physical-683.webp 683w, /content/resized/2022/06/DX-Physical-800.webp 800w, /content/resized/2022/06/DX-Physical-960.webp 960w, /content/uploads/2022/06/DX-Physical.webp 1128w\" sizes=\"1128px\" />\n <source width=\"1128\" height=\"341\" data-srcset=\" /content/resized/2022/06/DX-Physical-320.png 320w, /content/resized/2022/06/DX-Physical-384.png 384w, /content/resized/2022/06/DX-Physical-512.png 512w, /content/resized/2022/06/DX-Physical-683.png 683w, /content/resized/2022/06/DX-Physical-800.png 800w, /content/resized/2022/06/DX-Physical-960.png 960w, /content/uploads/2022/06/DX-Physical.png 1128w\" sizes=\"1128px\" />\n <img src=\"/content/resized/2022/06/DX-Physical-320.png\" data-src=\"/content/uploads/2022/06/DX-Physical.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1128\" height=\"341\" alt=\"Figure 1: Direct Connect Overview \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Direct Connect Overview\n</figcaption>\n\n</figure>\n\n<p>These <a href=\"https://aws.amazon.com/directconnect/locations/\">DX locations</a> are not AWS data centers, but rather colocation facilities operated by 3rd part providers such as <a href=\"https://www.equinix.com/\">Equinix</a>, <a href=\"https://www.coresite.com/\">CoreSite</a>, <a href=\"https://cologix.com/\">Cologix</a>, <a href=\"https://www.digitalrealty.com/\">Digital Realty</a>, and others. A colocation facility or colocation data center, often referred to as a “colo”, is a large datacenter facility that rents out rack space to third parties for their servers or other network equipment. This is a very popular service that is used by businesses that may not have the resources needed to maintain their own data center, but still want to enjoy all the benefits. Or it is used by Network Service Providers to interconnect with partners - such as cloud providers - or customers.</p>\n\n<h1 id=\"benefits\">Benefits</h1>\n\n<p>The benefits of using AWS Direct Connect instead of the open Internet can be categorized into:</p>\n\n<ul>\n <li>\n <p><strong>Improved Performance and Reliability:</strong> Improve application performance by connecting directly to AWS and bypassing the public internet. Using DX typically reduces the number of network hops and therefore reduces latency.</p>\n </li>\n <li>\n <p><strong>Reduced costs:</strong> Reduced networking costs with low data transfer rates out of AWS compared to <a href=\"https://aws.amazon.com/ec2/pricing/on-demand/#Data_Transfer\">AWS data egress fees over the Internet</a>.</p>\n </li>\n <li>\n <p><strong>Increased security:</strong> Secure data as it moves between on-premises networks and AWS with multiple encryption options, such as <a href=\"https://docs.aws.amazon.com/directconnect/latest/UserGuide/MACsec.html\">MACsec (IEEE 802.1ae)</a>.</p>\n </li>\n</ul>\n\n<h1 id=\"elements\">Elements</h1>\n\n<p>AWS Direct Connect consists of two elements: The physical connection and the logical virtual interfaces:</p>\n\n<h2 id=\"physical-elements-connection\">Physical Elements: Connection</h2>\n\n<p>Three different connection options exist with “Dedicated Connections”, “Hosted Connections” and the legacy model of “Hosted Virtual Interfaces”. This legacy connection option is no longer available for new connections.</p>\n\n<table>\n <thead>\n <tr>\n <th> </th>\n <th>Dedicated Connections</th>\n <th>Hosted Connections</th>\n <th>Hosted Virtual Interfaces (Legacy)</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td><strong>AWS asigned capacity</strong></td>\n <td>1 Gbps, 10 Gbps or 100 Gbps</td>\n <td>50 Mbps to 10 Gbps</td>\n <td>None</td>\n </tr>\n <tr>\n <td><strong>Private or Public Virtual Interfaces (VIFs)</strong></td>\n <td>50</td>\n <td>1</td>\n <td>1</td>\n </tr>\n <tr>\n <td><strong>Transit Virtual Interface (VIF)</strong></td>\n <td>1</td>\n <td>1 (if assigned capacity >= 1 Gbps)</td>\n <td>None</td>\n </tr>\n <tr>\n <td><strong>Partner-only offering</strong></td>\n <td><i class=\"fas fa-times\" style=\"color:red;\" title=\"No\"></i></td>\n <td><i class=\"fas fa-check\" style=\"color:green;\" title=\"Yes\"></i></td>\n <td><i class=\"fas fa-check\" style=\"color:green;\" title=\"Yes\"></i></td>\n </tr>\n <tr>\n <td><strong>Covered under SLA</strong></td>\n <td><i class=\"fas fa-check\" style=\"color:green;\" title=\"Yes\"></i></td>\n <td><i class=\"fas fa-times\" style=\"color:red;\" title=\"No\"></i></td>\n <td><i class=\"fas fa-times\" style=\"color:red;\" title=\"No\"></i></td>\n </tr>\n <tr>\n <td><strong>Supports MACsec (802.1ae)</strong></td>\n <td><i class=\"fas fa-check\" style=\"color:green;\" title=\"Yes\"></i> (10 Gbps or 100 Gbps at select locations)</td>\n <td><i class=\"fas fa-times\" style=\"color:red;\" title=\"No\"></i></td>\n <td><i class=\"fas fa-times\" style=\"color:red;\" title=\"No\"></i></td>\n </tr>\n </tbody>\n</table>\n\n<h3 id=\"dedicated-connection\">Dedicated Connection</h3>\n\n<p>In the case of a “Dedicated Connection”, the customer or partner is provided with dedicated Ethernet over single-mode fiber, providing an 802.1q trunk (VLANs) via a cross-connect within a DX location. \nCustomers can request a dedicated connection through the AWS Direct Connect console, the CLI, or the API. Each dedicated connection can provide 50 Private or Public Virtual Interfaces, as well as 1 Transit Virtual Interface.</p>\n\n<p>As depicted in figure 1, the customer or partner will order the colo operator to create a cross-connect from a meet-me room to the customer’s or partner’s space - also somethimes called cage.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/meet-me-room.jpg\" title=\"Figure 2: Meet-me room in a colocation facility \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2022/06/meet-me-room-320.webp 320w, /content/resized/2022/06/meet-me-room-384.webp 384w, /content/resized/2022/06/meet-me-room-512.webp 512w, /content/resized/2022/06/meet-me-room-683.webp 683w, /content/resized/2022/06/meet-me-room-800.webp 800w, /content/resized/2022/06/meet-me-room-960.webp 960w, \" sizes=\"1920px\" />\n <source data-srcset=\" /content/resized/2022/06/meet-me-room-320.jpg 320w, /content/resized/2022/06/meet-me-room-384.jpg 384w, /content/resized/2022/06/meet-me-room-512.jpg 512w, /content/resized/2022/06/meet-me-room-683.jpg 683w, /content/resized/2022/06/meet-me-room-800.jpg 800w, /content/resized/2022/06/meet-me-room-960.jpg 960w, \" sizes=\"1920px\" />\n <img src=\"/content/resized/2022/06/meet-me-room-320.jpg\" data-src=\"/content/uploads/2022/06/meet-me-room.jpg\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 2: Meet-me room in a colocation facility \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Meet-me room in a colocation facility\n</figcaption>\n\n</figure>\n\n<p>A meet-me room is part of a colo that you will most likely never get to see in real life (See figure 2). It is a room where only authorized personell of the colo operator is allowed access to and where data connections are established between customers of the colo. To do so, one customer has to obtain a Letter of Authorization - Connecting Facility Assignment (LOA-CFA) from the other customer - in this case AWS - and provide it to the colo operator. This LOA-CFA document specifies which pre-cabled connection from AWS to the meet-me room is to be used for this particular customer connection.</p>\n\n<p>The colo operator will then typically terminate the cross connect within the customer or partner space at the top of a particular rack in form of a patch panel (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/DX-Cross-Connect.png\" title=\"Figure 3: Direct Connect Cross Connect within a customer’s rack \" class=\"image-popup\">\n<picture>\n <source width=\"922\" height=\"565\" type=\"image/webp\" data-srcset=\" /content/resized/2022/06/DX-Cross-Connect-320.webp 320w, /content/resized/2022/06/DX-Cross-Connect-384.webp 384w, /content/resized/2022/06/DX-Cross-Connect-512.webp 512w, /content/resized/2022/06/DX-Cross-Connect-683.webp 683w, /content/resized/2022/06/DX-Cross-Connect-800.webp 800w, /content/uploads/2022/06/DX-Cross-Connect.webp 922w\" sizes=\"922px\" />\n <source width=\"922\" height=\"565\" data-srcset=\" /content/resized/2022/06/DX-Cross-Connect-320.png 320w, /content/resized/2022/06/DX-Cross-Connect-384.png 384w, /content/resized/2022/06/DX-Cross-Connect-512.png 512w, /content/resized/2022/06/DX-Cross-Connect-683.png 683w, /content/resized/2022/06/DX-Cross-Connect-800.png 800w, /content/uploads/2022/06/DX-Cross-Connect.png 922w\" sizes=\"922px\" />\n <img src=\"/content/resized/2022/06/DX-Cross-Connect-320.png\" data-src=\"/content/uploads/2022/06/DX-Cross-Connect.png\" class=\"blur-up lazyautosizes lazyload\" width=\"922\" height=\"565\" alt=\"Figure 3: Direct Connect Cross Connect within a customer’s rack \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Direct Connect Cross Connect within a customer’s rack\n</figcaption>\n\n</figure>\n\n<p>Depending on the chosen speed of the DX connection, different <a href=\"https://en.wikipedia.org/wiki/Optical_module\">optical transceiver</a> are then used on the customer or partner side to terminate the DX connection on network equipment:</p>\n\n<ul>\n <li>1 Gigabit Ethernet: 1000BASE-LX (1310 nm) transceiver</li>\n <li>10 Gigabit Ethernet: 10GBASE-LR (1310 nm) transceiver</li>\n <li>100 gigabit Ethernet: 100GBASE-LR4 transceiver</li>\n</ul>\n\n<p>Multiple Connectivity options between the cross connect termination point and the customer’s routers and workloads exist. Refer to the <a href=\"#connectivity\">Connectivity</a> section below to find out more about these options</p>\n\n<h3 id=\"hosted-connection\">Hosted Connection</h3>\n\n<p>In the case of a Hosted Connection, the above described Dedicated Connection is operated by an <a href=\"https://aws.amazon.com/directconnect/partners/\">AWS Direct Connect Delivery Partner</a> - often a Network Service Provider - which then maps multiple virtual connections to a single physical connection. \nCustomers request a Hosted Connection by contacting the AWS Direct Connect Delivery Partner directly. A hosted connection can provide 1 Private Virtual Interface or 1 Public Virtual Interface or 1 Transit Virtual Interface (If the connection speed is 1 Gbps or higher).</p>\n\n<p>These AWS Direct Connect Delivery Partners can also often offer network connectivity from an AWS Direct Connect location to an off-site location, such as an office building, factory or other data center. Therefore in such a scenario all equipment within the AWS Direct Connect location would be owned and operated by the AWS Direct Connect Delivery Partner and shared among multiple customers, usually resulting in lower operational cost and quicker initial implementation times.</p>\n\n<p>In this case also multiple Connectivity options between the cross connect termination point on the partner’s equipment and the customer’s routers and workloads exist. Refer to the <a href=\"#connectivity\">Connectivity</a> section below to find out more about these options</p>\n\n<p>Note that this connection type is not covered under the AWS <a href=\"https://aws.amazon.com/directconnect/sla/\">Direct Connect Service Level Agreement (SLA)</a>.</p>\n\n<h3 id=\"hosted-virtual-interface-legacy\">Hosted Virtual Interface (Legacy)</h3>\n\n<p>This is a legacy offering which is no longer available for new provisioning by AWS Direct Connect Delivery Partners, but might still be found in use among existing customers. While at a first glance looking similar to a “Hosted Connection”, this connection type does not provide a dedicated bandwidth allocation on AWS side and is therefore at risk of oversubscription. It only provides 1 Private Virtual Interface or 1 Public Virtual Interface. No Transit Virtual Interface can be provided. This connection type is not covered under the <a href=\"https://aws.amazon.com/directconnect/sla/\">Direct Connect Service Level Agreement (SLA)</a>.</p>\n\n<h2 id=\"logical-elements-virtual-interfaces-vif\">Logical Elements: Virtual Interfaces (VIF)</h2>\n\n<p>A Direct Connect connection supports one or multiple Virtual Interfaces (VIF) as logical component. Refer to the above table to understand which DX connection type offers what kind and how many virtual interfaces.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/DX-VIFs-Overview.png\" title=\"Figure 4: Direct Connect Logical Overview \" class=\"image-popup\">\n<picture>\n <source width=\"1060\" height=\"331\" type=\"image/webp\" data-srcset=\" /content/resized/2022/06/DX-VIFs-Overview-320.webp 320w, /content/resized/2022/06/DX-VIFs-Overview-384.webp 384w, /content/resized/2022/06/DX-VIFs-Overview-512.webp 512w, /content/resized/2022/06/DX-VIFs-Overview-683.webp 683w, /content/resized/2022/06/DX-VIFs-Overview-800.webp 800w, /content/resized/2022/06/DX-VIFs-Overview-960.webp 960w, /content/uploads/2022/06/DX-VIFs-Overview.webp 1060w\" sizes=\"1060px\" />\n <source width=\"1060\" height=\"331\" data-srcset=\" /content/resized/2022/06/DX-VIFs-Overview-320.png 320w, /content/resized/2022/06/DX-VIFs-Overview-384.png 384w, /content/resized/2022/06/DX-VIFs-Overview-512.png 512w, /content/resized/2022/06/DX-VIFs-Overview-683.png 683w, /content/resized/2022/06/DX-VIFs-Overview-800.png 800w, /content/resized/2022/06/DX-VIFs-Overview-960.png 960w, /content/uploads/2022/06/DX-VIFs-Overview.png 1060w\" sizes=\"1060px\" />\n <img src=\"/content/resized/2022/06/DX-VIFs-Overview-320.png\" data-src=\"/content/uploads/2022/06/DX-VIFs-Overview.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1060\" height=\"331\" alt=\"Figure 4: Direct Connect Logical Overview \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: Direct Connect Logical Overview\n</figcaption>\n\n</figure>\n\n<p>While each Virtual Interface type serves a different purpose, they are all provided as an IEEE 802.1q VLAN over a trunk and require use of BGP via IPv4 and/or IPv6 (See Figure 4):</p>\n\n<ul>\n <li><strong>Private virtual interface:</strong> Access an Amazon VPC using private IP addresses. Can be combined with a <a href=\"https://www.edge-cloud.net/2019/09/06/dx-gateway-deep-dive/\">Direct Connect Gateway</a> to access VPCs outside the associated AWS region.</li>\n <li><strong>Public virtual interface:</strong> Access AWS services from your on-premises data center. Allow AWS services, or AWS customers access your public networks over the interface instead of traversing the internet. Does not leverage Direct Connect Gateways (DX-GW) or Virtual Private Gateways (VGW).</li>\n <li><strong>Transit virtual interface:</strong> Access one or more Amazon VPC Transit Gateways associated with Direct Connect Gateways (DX-GW). You can use transit virtual interfaces with 1/2/5/10/100 Gbps AWS Direct Connect connections. Use of a <a href=\"https://www.edge-cloud.net/2019/09/06/dx-gateway-deep-dive/\">Direct Connect Gateway</a> is mandatory.</li>\n</ul>\n\n<h1 id=\"resiliency\">Resiliency</h1>\n\n<p>In order to achieve high resiliency, AWS recommends customers to follow the <a href=\"https://aws.amazon.com/directconnect/resiliency-recommendation/\">AWS Direct Connect Resiliency Recommendations</a>. These recommendations outline three different topoly types that are mapped to the coresponding AWS <a href=\"https://aws.amazon.com/directconnect/sla/\">Direct Connect Service Level Agreement (SLA)</a>:</p>\n\n<ul>\n <li><strong>High Resiliency for Critical Workloads:</strong> 2x Direct Connect connections across 2x different Direct Connect locations</li>\n <li><strong>Maximum Resiliency for Critical Workloads:</strong> 4x Direct Connect connections across 2x different Direct Connect locations with 2x connections in each location.</li>\n <li><strong>Non-Critical Production Workloads or Development Workloads:</strong> 2x Direct Connect connections across a single Direct Connect locations</li>\n</ul>\n\n<p>Redundant Direct Connect connections are highly recommended as AWS need to perform regular <a href=\"https://aws.amazon.com/premiumsupport/knowledge-center/prepare-direct-connect-maintenance/\">maintenance</a> on individual connections.</p>\n\n<p>For resiliency purposes a <a href=\"https://docs.aws.amazon.com/directconnect/latest/UserGuide/lags.html\">Link aggregation group (LAG)</a> should be treated as a single connection, irrespective of the number of group members, as it terminates on the same physical AWS device.</p>\n\n<p>Also ensure that the “AWS logical device” identifier differs across your redundant DX connections within a location (See Figure 5). This value identifies the physical device on the AWS side and two DX connections terminating on the same AWS device would not provide resiliency.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/DX-LogicakDeviceID.png\" title=\"Figure 5: AWS Logical Device ID for identifying the resiliency of the connection. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2022/06/DX-LogicakDeviceID-320.webp 320w, /content/resized/2022/06/DX-LogicakDeviceID-384.webp 384w, /content/resized/2022/06/DX-LogicakDeviceID-512.webp 512w, /content/resized/2022/06/DX-LogicakDeviceID-683.webp 683w, /content/resized/2022/06/DX-LogicakDeviceID-800.webp 800w, /content/resized/2022/06/DX-LogicakDeviceID-960.webp 960w, \" sizes=\"1410px\" />\n <source data-srcset=\" /content/resized/2022/06/DX-LogicakDeviceID-320.png 320w, /content/resized/2022/06/DX-LogicakDeviceID-384.png 384w, /content/resized/2022/06/DX-LogicakDeviceID-512.png 512w, /content/resized/2022/06/DX-LogicakDeviceID-683.png 683w, /content/resized/2022/06/DX-LogicakDeviceID-800.png 800w, /content/resized/2022/06/DX-LogicakDeviceID-960.png 960w, \" sizes=\"1410px\" />\n <img src=\"/content/resized/2022/06/DX-LogicakDeviceID-320.png\" data-src=\"/content/uploads/2022/06/DX-LogicakDeviceID.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 5: AWS Logical Device ID for identifying the resiliency of the connection. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 5: AWS Logical Device ID for identifying the resiliency of the connection.\n</figcaption>\n\n</figure>\n\n<p>If you decide to use a Site-to-Site (IPSec) VPN as backup to your DX, while using AWS Transit Gateway, refer to <a href=\"https://www.edge-cloud.net/2019/08/16/aws-dxgw-with-ipsec-vpn-backup/\">this previous article</a> on how to setup the routing correctly.</p>\n\n<h1 id=\"connectivity\">Connectivity</h1>\n\n<p>Customers have multiple options to connect their own network equipment via a Direct Connect location (See Figure 6).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/DX-Connectivity.png\" title=\"Figure 6: Direct Connect Connectivity Options \" class=\"image-popup\">\n<picture>\n <source width=\"821\" height=\"718\" type=\"image/webp\" data-srcset=\" /content/resized/2022/06/DX-Connectivity-320.webp 320w, /content/resized/2022/06/DX-Connectivity-384.webp 384w, /content/resized/2022/06/DX-Connectivity-512.webp 512w, /content/resized/2022/06/DX-Connectivity-683.webp 683w, /content/resized/2022/06/DX-Connectivity-800.webp 800w, /content/uploads/2022/06/DX-Connectivity.webp 821w\" sizes=\"821px\" />\n <source width=\"821\" height=\"718\" data-srcset=\" /content/resized/2022/06/DX-Connectivity-320.png 320w, /content/resized/2022/06/DX-Connectivity-384.png 384w, /content/resized/2022/06/DX-Connectivity-512.png 512w, /content/resized/2022/06/DX-Connectivity-683.png 683w, /content/resized/2022/06/DX-Connectivity-800.png 800w, /content/uploads/2022/06/DX-Connectivity.png 821w\" sizes=\"821px\" />\n <img src=\"/content/resized/2022/06/DX-Connectivity-320.png\" data-src=\"/content/uploads/2022/06/DX-Connectivity.png\" class=\"blur-up lazyautosizes lazyload\" width=\"821\" height=\"718\" alt=\"Figure 6: Direct Connect Connectivity Options \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 6: Direct Connect Connectivity Options\n</figcaption>\n\n</figure>\n\n<ul>\n <li>\n <p><strong>In-location cross connect (Option 1):</strong> If the customer has resources deployed in the same colo facility as the DX location, the colo facility can provide a cross-connect between the AWS DX equipment and the customer resources. The customer has to provide a <a href=\"https://docs.aws.amazon.com/directconnect/latest/UserGuide/Colocation.html\">Letter of Authorization and Connecting Facility Assignment (LOA-CFA)</a> to the facility for this. This option is only available for Dedicated Connections.</p>\n </li>\n <li>\n <p><strong>Layer 2 circuit (Option 2):</strong> Customers can work with <a href=\"https://aws.amazon.com/directconnect/partners/\">AWS Direct Connect Delivery Partners</a> to extend the AWS DX connection at Layer 2 (Data link layer) via a “circuit” from the DX location to the customer location. The router installed at the customer location will directly form a BGP session with the AWS equipment. Example technologies used are <a href=\"https://en.wikipedia.org/wiki/Metro_Ethernet\">Metro Ethernet</a>, <a href=\"https://en.wikipedia.org/wiki/Dark_fibre\">Dark fibre</a>, or <a href=\"https://en.wikipedia.org/wiki/Wavelength-division_multiplexing\">Wavelength</a>. This option can be used with Dedicated Connections as well as Hosted Connections.</p>\n </li>\n <li>\n <p><strong>Layer 3 network (Option 3):</strong> Customers can work with <a href=\"https://aws.amazon.com/directconnect/partners/\">AWS Direct Connect Delivery Partners</a> to extend the AWS DX connection at Layer 3 (Network layer) from the DX location to the customer location. In this case the the AWS Direct Connect Partner provides a router within the DX location that will form a BGP session with the AWS equipment. The DX partner then establishes another BGP with the customer, e.g. over an <a href=\"https://en.wikipedia.org/wiki/Multiprotocol_Label_Switching\">MPLS</a>. This option can be used with Dedicated Connections as well as Hosted Connections.</p>\n </li>\n</ul>\n\n<p>If the customer is located in a data center or colo facility that is not a DX location, it is best to check with that data center or colo facility for a list of preferred <a href=\"https://aws.amazon.com/directconnect/partners/\">AWS Direct Connect Delivery Partners</a> that can provide DX connectivity into this particular data center or colo facility. Such “on-net” partners can typically provide connectivity faster.</p>\n\n<h1 id=\"commercial-workflow\">Commercial Workflow</h1>\n\n<p>End-customers have a direct business relationship with AWS and are charged directly for all consumed <a href=\"https://aws.amazon.com/directconnect/pricing/\">AWS services</a>. AWS Direct Connect is priced by AWS based on two criteria:</p>\n\n<ul>\n <li><strong>Port hours:</strong> This is determined based on the capacity and the type of connection (It could be dedicated or hosted connection).</li>\n <li><strong>Outbound data transfer:</strong> The outbound charges are calculated for private virtual interfaces and transit virtual interfaces. This refers to the data which is transferred over the AWS Direct Connect in terms of GB. No additional charges are inferred when a multi-account Direct Connect gateway is used.</li>\n</ul>\n\n<p>In addition end-customers will need to engage with <a href=\"https://aws.amazon.com/directconnect/partners/\">Direct Connect Delivery Partners</a> such as carriers, network service providers (NSP), or colocation providers to provide them with network connectivity to AWS. For this they will have a separate contract with this partner and the partner will invoice end-customers for the connectivity services they provide.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2022/06/Direct-Connect-Commercial-Workflow.png\" title=\"Figure 7: Commercial Workflow \" class=\"image-popup\">\n<picture>\n <source width=\"637\" height=\"464\" type=\"image/webp\" data-srcset=\" /content/resized/2022/06/Direct-Connect-Commercial-Workflow-320.webp 320w, /content/resized/2022/06/Direct-Connect-Commercial-Workflow-384.webp 384w, /content/resized/2022/06/Direct-Connect-Commercial-Workflow-512.webp 512w, /content/uploads/2022/06/Direct-Connect-Commercial-Workflow.webp 637w\" sizes=\"637px\" />\n <source width=\"637\" height=\"464\" data-srcset=\" /content/resized/2022/06/Direct-Connect-Commercial-Workflow-320.png 320w, /content/resized/2022/06/Direct-Connect-Commercial-Workflow-384.png 384w, /content/resized/2022/06/Direct-Connect-Commercial-Workflow-512.png 512w, /content/uploads/2022/06/Direct-Connect-Commercial-Workflow.png 637w\" sizes=\"637px\" />\n <img src=\"/content/resized/2022/06/Direct-Connect-Commercial-Workflow-320.png\" data-src=\"/content/uploads/2022/06/Direct-Connect-Commercial-Workflow.png\" class=\"blur-up lazyautosizes lazyload\" width=\"637\" height=\"464\" alt=\"Figure 7: Commercial Workflow \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 7: Commercial Workflow\n</figcaption>\n\n</figure>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This article provided an overview of <a href=\"https://aws.amazon.com/directconnect/\">AWS Direct Connect</a> (DX), including the physical element of Dedicated and Hosted Connections as well as the logical elements of Virtual Interfaces (VIF). It touched upoen resiliency recommendations, connectivity options between AWS Direct Connect locations and on-premises locations as well as demystified the commercial workflow and associated costs.</p>\n\n<p>You should now be in a position to understand how AWS DX makes it easy to establish a dedicated connection from an on-premises network to AWS. Using AWS Direct Connect, you can establish private connectivity between AWS and your data center, office, factory or collocated environment. A DX connection can reduce network costs, increase bandwidth throughput, and provide a more consistent network experience than internet-based connections.</p>\n",
"summary": "Overview of AWS Direct Connect, with which you can establish private connectivity between AWS and your data center, office, factory or collocated environment.",
"date_published": "2022-06-28T00:00:00-07:00",
"date_modified": "2022-06-28T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2022/06/title-dx-overview.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Direct-Connect"]
},
{
"id": "https://www.edge-cloud.net/2020/09/28/understanding-bgp",
"url": "https://www.edge-cloud.net/2020/09/28/understanding-bgp/",
"title": "Better understanding BGP",
"content_html": "<p>In a <a href=\"https://www.edge-cloud.net/2020/09/18/understanding-routing/\">previous post</a> we took a look at some of the fundamental principles of IP routing. Today we want to look at some more details of related BGP Routing protocol concepts. While these principles and concepts are generic, we will again use examples based on AWS networking, along with examples from running an <a href=\"https://en.wikipedia.org/wiki/Autonomous_system_(Internet)\">Autonomous System</a> on the Internet.</p>\n\n<p>This blog post is not intended to be an all encompassing primer on BGP. Instead I’ve seen numerous people confused by some of these principles and concepts while either designing networks or troubleshooting them. Therefore it appears to be a good idea to select and explain them explicitly.</p>\n\n<h1 id=\"routing-protocols\">Routing Protocols</h1>\n\n<p>A <a href=\"https://en.wikipedia.org/wiki/Routing_protocol\">Routing Protocol</a> specifies how routers communicate with each other to exchange information about the network and as a result populate and update the local route tables. While there are many different routing protocols, they all fall into the categories of either Interior gateway protocols or Exterior gateway protocols. <a href=\"https://en.wikipedia.org/wiki/Interior_gateway_protocol\">Interior gateway protocols (IGPs)</a>, such as e.g. <a href=\"https://en.wikipedia.org/wiki/Open_Shortest_Path_First\">OSPF</a>, <a href=\"https://en.wikipedia.org/wiki/Routing_Information_Protocol\">RIP</a>, or <a href=\"https://en.wikipedia.org/wiki/IS-IS\">IS-IS</a>, exchange routing information within a single routing domain, thereby under the control of a single administration. <a href=\"https://en.wikipedia.org/wiki/Exterior_gateway_protocol\">Exterior gateway protocols (EGP)</a>, such as e.g. <a href=\"https://en.wikipedia.org/wiki/Border_Gateway_Protocol\">BGP</a> exchange routing information between autonomous systems.</p>\n\n<h1 id=\"bgp\">BGP</h1>\n\n<p>Border Gateway Protocol (BGP) is an <a href=\"https://en.wikipedia.org/wiki/Exterior_gateway_protocol\">Exterior gateway protocols (EGP)</a> designed to exchange routing and reachability information across Autonomous Systems (AS) on an Internet scale. It can be used for routing within an autonomous system, which is called Interior Border Gateway Protocol / Internal BGP (iBGP). Or it can be used - as on the Internet - to route between AS, which is called Exterior Border Gateway Protocol / External BGP (eBGP). Here we will focus on the eBGP use case.</p>\n\n<h1 id=\"bgp-best-path-selection-algorithm\">BGP Best Path Selection Algorithm</h1>\n\n<p>Within BGP the <a href=\"https://www.noction.com/blog/bgp-best-path-selection-algorithm\">Best Path Selection Algorithm</a> is used to select the best route, which is then installed into the local route table. As the Internet route table - used in the <a href=\"https://en.wikipedia.org/wiki/Default-free_zone\">Default Free Zone</a> - holds approximately 850,000 IPv4 and 95,000 IPv6 routes as of today and because some of these routes might be received from multiple peer - e.g. Transit Provider and direct peering, this selection is no easy task.\nUnless the default settings within a BGP enabled router are changed, the Best Path Selection Algorithm selects the shortest path as the best path, where shortest path means the least amount of AS in the path.</p>\n\n<p>In the following we want to look in more detail at the three most important selection criteria within the BGP Best Path Selection Algorithm:</p>\n<ul>\n <li><strong>Local Preference</strong> or often “Local_Pref” for short is the second criteria that is considered. The default Local_Pref is 100 and routes with a higher local preference are preferred.</li>\n <li><strong>AS_PATH</strong> is the fourth criteria considered. Routes with the shortest AS_PATH attribute are preferred.</li>\n <li><strong>Multi-exit discriminator (MED)</strong> is the sixth selection criteria considered. Here routes with a lower MED value are preferred with 0 being the default value.</li>\n</ul>\n\n<h2 id=\"local_pref\">Local_Pref</h2>\n\n<p>As previously seen, Local_Pref is one of the first Best Path Selection Algorithm criteria that a router looks at. It is evaluated before the AS path length. While the default value of Local_Pref is 100, routes that have a higher Local_Pref value are preferred. An important characteristic to consider is that Local_Pref is local in the sense that the attribute is only propagated over iBGP sessions (within your AS) and not over eBGP sessions (to external ASes). You might see BGP route tables with empty entries for Local_Pref for a given route, sometimes along with other routes that do have an explicit entry. In this case the empty entries just mean that the deafult value of 100 applies.</p>\n\n<p>In practice Local_Pref can be used to specify how traffic should leave our AS, therefore it can guide the exit path (See Figure 1). Here ASN 1 prefers the path to ASN2, as the Local_Pref on the corresponding interface has a higher value.</p>\n\n<figure class=\"webfeedsFeaturedVisual\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/Understanding-BGP-Local_Pref.png\" title=\"Figure 1: Local_Pref dictates how traffic leaves a local ASN, where path with a higher Local_Pref value being preferred. \" class=\"image-popup\">\n<picture>\n <source width=\"521\" height=\"331\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/Understanding-BGP-Local_Pref-320.webp 320w, /content/resized/2020/09/Understanding-BGP-Local_Pref-384.webp 384w, /content/resized/2020/09/Understanding-BGP-Local_Pref-512.webp 512w, /content/uploads/2020/09/Understanding-BGP-Local_Pref.webp 521w\" sizes=\"521px\" />\n <source width=\"521\" height=\"331\" data-srcset=\" /content/resized/2020/09/Understanding-BGP-Local_Pref-320.png 320w, /content/resized/2020/09/Understanding-BGP-Local_Pref-384.png 384w, /content/resized/2020/09/Understanding-BGP-Local_Pref-512.png 512w, /content/uploads/2020/09/Understanding-BGP-Local_Pref.png 521w\" sizes=\"521px\" />\n <img src=\"/content/resized/2020/09/Understanding-BGP-Local_Pref-320.png\" data-src=\"/content/uploads/2020/09/Understanding-BGP-Local_Pref.png\" class=\"blur-up lazyautosizes lazyload\" width=\"521\" height=\"331\" alt=\"Figure 1: Local_Pref dictates how traffic leaves a local ASN, where path with a higher Local_Pref value being preferred. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Local_Pref dictates how traffic leaves a local ASN, where path with a higher Local_Pref value being preferred.\n</figcaption>\n\n</figure>\n\n<p>This is typically used for traffic engineering purposes, where an ASN wants to prefer a certain kind of peer over another. Usually this is done for financial reasons, as traffic exchanged over e.g. a Transit peering might incur cost, while traffic exchanged over a direct peering might be settlement free.</p>\n\n<p>As a result a typical mapping of BGP session types to Local_Pref values could look like this:</p>\n\n<table>\n <thead>\n <tr>\n <th>BGP Session</th>\n <th>Local_Pref</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td><strong>Private Peering</strong></td>\n <td>500</td>\n </tr>\n <tr>\n <td><strong>Direct Peering via IXP</strong></td>\n <td>400</td>\n </tr>\n <tr>\n <td><strong>Peering via IXP Route Server</strong></td>\n <td>300</td>\n </tr>\n <tr>\n <td><strong>Transit</strong></td>\n <td>200</td>\n </tr>\n </tbody>\n</table>\n\n<p>Here we generally prefer settlement-free peering with higher Local_Pref over paid transit with lower Local_Pref.</p>\n\n<h2 id=\"as_path-length\">AS_PATH length</h2>\n\n<p>A common mechanism to manage traffic across AS with BGP is to make a BGP AS_PATH longer via <a href=\"https://www.noction.com/blog/as-path-and-as-path-prepending\">AS path prepending</a>. Prepending means adding one or more AS numbers to the left side of the AS path. Normally this is done using one’s own AS number, while announcing routes to another AS.</p>\n\n<p>With that we can influence how traffic will reach our ASN. Similar to what I described before we might not only have a commercial interest in reducing the cost that we pay for Transit for traffic leaving our ASN, but also for traffic entering our ASN. We have seen that we can perform traffic engineering for egress traffic via Local_Pref, using AS path prepending can be used for traffic engineering on ingress traffic (See Figure 2). Here ASN 1 makes its path artificially longer towards ASN 3 by prepending its own ASN once.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/Understanding-BGP-AS-Path-Prepending.png\" title=\"Figure 2: AS_PATH prepending makes the AS path length artificially longer, therefore influencing inbound traffic to an ASN. \" class=\"image-popup\">\n<picture>\n <source width=\"521\" height=\"521\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-320.webp 320w, /content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-384.webp 384w, /content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-512.webp 512w, /content/uploads/2020/09/Understanding-BGP-AS-Path-Prepending.webp 521w\" sizes=\"521px\" />\n <source width=\"521\" height=\"521\" data-srcset=\" /content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-320.png 320w, /content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-384.png 384w, /content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-512.png 512w, /content/uploads/2020/09/Understanding-BGP-AS-Path-Prepending.png 521w\" sizes=\"521px\" />\n <img src=\"/content/resized/2020/09/Understanding-BGP-AS-Path-Prepending-320.png\" data-src=\"/content/uploads/2020/09/Understanding-BGP-AS-Path-Prepending.png\" class=\"blur-up lazyautosizes lazyload\" width=\"521\" height=\"521\" alt=\"Figure 2: AS_PATH prepending makes the AS path length artificially longer, therefore influencing inbound traffic to an ASN. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: AS_PATH prepending makes the AS path length artificially longer, therefore influencing inbound traffic to an ASN.\n</figcaption>\n\n</figure>\n\n<p>With this we could use AS path prepending for IP prefixes originated or announced by our ASN over various types of BGP session types like this to optimize for cost:</p>\n\n<table>\n <thead>\n <tr>\n <th>BGP Session</th>\n <th>AS path prepending</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td><strong>Private Peering</strong></td>\n <td>None</td>\n </tr>\n <tr>\n <td><strong>Direct Peering via IXP</strong></td>\n <td>1x</td>\n </tr>\n <tr>\n <td><strong>Peering via IXP Route Server</strong></td>\n <td>2x</td>\n </tr>\n <tr>\n <td><strong>Transit</strong></td>\n <td>3x</td>\n </tr>\n </tbody>\n</table>\n\n<p>In this case we tell other ASNs to prefer path via our settlement-free peering through lower AS_PATH length over paid transit through longer AS_PATH length.</p>\n\n<h2 id=\"multi-exit-discriminator-med\">Multi-Exit Discriminator (MED)</h2>\n\n<p>Multi-Exit Discriminator (MED) is used for the case that more than one link between two ASN exists. I can be used to influence which of these links is then used (See Figure 3). It is important to point out that the MED value is not transitive. Therefore it is not passed on by the receiving AS and therefore can solely be used to influence traffic between directly neighboring AS.</p>\n\n<p>In this case traffic from the neighboring ASN 2 will ingress via device R1 as the MED on the corresponding link is lower.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/Understanding-BGP-MED.png\" title=\"Figure 3: Multi-Exit Discriminator (MED) suggests how traffic should enter an ASN. Path with lower MED value are preferred. \" class=\"image-popup\">\n<picture>\n <source width=\"381\" height=\"378\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/Understanding-BGP-MED-320.webp 320w, /content/uploads/2020/09/Understanding-BGP-MED.webp 381w\" sizes=\"381px\" />\n <source width=\"381\" height=\"378\" data-srcset=\" /content/resized/2020/09/Understanding-BGP-MED-320.png 320w, /content/uploads/2020/09/Understanding-BGP-MED.png 381w\" sizes=\"381px\" />\n <img src=\"/content/resized/2020/09/Understanding-BGP-MED-320.png\" data-src=\"/content/uploads/2020/09/Understanding-BGP-MED.png\" class=\"blur-up lazyautosizes lazyload\" width=\"381\" height=\"378\" alt=\"Figure 3: Multi-Exit Discriminator (MED) suggests how traffic should enter an ASN. Path with lower MED value are preferred. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Multi-Exit Discriminator (MED) suggests how traffic should enter an ASN. Path with lower MED value are preferred.\n</figcaption>\n\n</figure>\n\n<p>When using AWS you will encounter MED when using a BGP-based Site-to-Site (IPSec) VPN connection while using a Virtual Private Gateway (VGW). In this case only one of the two tunnels is used by AWS to actively send traffic from the VPC to the Customer Gateway (CGW). As AWS customers very frequently leverage Firewall devices as Customer Gateway (CGW) devices and not L3 routers, asymmetric traffic might cause issues with stateful firewall rules. To prevent these issues, AWS indicates the active VPN tunnel through MED, thereby encouraging customers to use that same tunnel for return traffic.</p>\n\n<p>You can see below that the IPSec tunnel with the next hop address <em>169.254.63.25</em> has a lower MED - displayed as Metric. Therefore this is the active tunnel within the connection.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>CSR1000V#sh ip bgp\nBGP table version is 292, local router ID is 1.1.1.1\nStatus codes: s suppressed, d damped, h history, * valid, > best, i - internal,\n r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,\n x best-external, a additional-path, c RIB-compressed,\n t secondary path, L long-lived-stale,\nOrigin codes: i - IGP, e - EGP, ? - incomplete\nRPKI validation codes: V valid, I invalid, N Not found\n\n Network Next Hop Metric LocPrf Weight Path\n 0.0.0.0 0.0.0.0 0 i\n *> 10.0.1.0/24 0.0.0.0 0 32768 i\n *> 10.0.16.0/24 0.0.0.0 0 32768 i\n *> 172.16.0.0/24 169.254.63.25 100 0 64512 i\n * 169.254.39.225 200 0 64512 i\n</code></pre></div></div>\n\n<h2 id=\"traffic-engineering-example\">Traffic engineering example</h2>\n\n<p>If you’re not using stateful rules on your CGW, you might be tempted to override the MED value with a Local_Pref to force return traffic through the standby tunnel and thereby increasing the overall throughput. While doing this you might hope that now one tunnel - serving traffic from AWS VPC to on-premises - will provide you a throughput of ~ 1.25 Gbps, while the other tunnel - serving traffic from on-premises to the AWS VPC - will provide you an additional throughput of ~1.25 Gbps. The result should be an increased thoughput at ~ 2.5 Gbps.</p>\n\n<p>This train of thought shows that you understood the fundamental principles of BGP and how to use them to influence traffic. Congratulation!</p>\n\n<p>Unfortunately the AWS Site-to-Site (IPSec) VPN specific throughput limitation of ~ 1.25 Gbps is per connection and not per tunnel as the VGW is the forcing element. Therefore this approach will not yield the desired results.</p>\n\n<h1 id=\"best-path-selectiom-algorithm-relaxation\">Best Path selectiom algorithm relaxation</h1>\n\n<p>Various router platforms offer different sets if capabilities to relax the rules around the BGP best path selection algorithm. While by default e.g. MED are only considered across path with the same neighboring ASN, the Cisco IOS command <em>bgp always-compare-med</em> ignores the ASN when considering MEDs. We saw in the previous blog post <a href=\"https://www.edge-cloud.net/2019/08/16/aws-dxgw-with-ipsec-vpn-backup/#multi-exit-discriminator-med\">AWS Transit Gateway with Direct Connect Gateway and Site-to-Site (IPSec) VPN Backup</a> how this can used in the case of AWS.</p>\n\n<h1 id=\"bgp-multipath\">BGP Multipath</h1>\n\n<p>With regards to what we learned in the <a href=\"https://www.edge-cloud.net/2020/09/18/understanding-routing/\">previous post</a> about route tables, it is important to understand that only the best path is installed in the route table. Only if the BGP best path selection algorithm results in a “tie”, more than one route can be installed into the route table.</p>\n\n<p>This is called BGP Multipath and it is independent of whether the underlying route table has <a href=\"https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing\">Equal-cost multi-path routing (ECMP)</a> capabilities. In other words: To have full ECMP capability on a BGP enabled router, BGP needs to deliver parallel path to the routing table and the router needs to make use of them.</p>\n\n<p>Therefore if we want to use ECMP with prefixes learned over BGP, we have to enforce such a “tie”. This means we need to ensure the following BGP attributes are kept same on each paths:</p>\n<ul>\n <li>Weight</li>\n <li>Local Preference</li>\n <li>AS Path (both AS number and AS path length)</li>\n <li>Origin code</li>\n <li>MED</li>\n <li>IGP metric</li>\n</ul>\n\n<p>Various routing platforms offer ways to relax some of the attributes as tie breaker. As an example, the Cisco IOS command <em>bgp bestpath as-path multipath-relax</em> will ignore the actual AS numbers and only consider the AS path length. This allows ECMP across multiple upstream provider.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>Today’s blog post builds on what you’ve learned in the previous blog post on <a href=\"https://www.edge-cloud.net/2020/09/18/understanding-routing/\">Better understanding IP Routing</a>. It provides an introduction into the BGP Best Path Selection Algorithm and how to use some of the valued to influence traffic flowing into (ingress) and out of (egress) your ASN.</p>\n",
"summary": "Primer to better understanding BGP",
"date_published": "2020-09-28T00:00:00-07:00",
"date_modified": "2020-09-28T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2020/09/title-understanding-bgp.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["BGP","Network"]
},
{
"id": "https://www.edge-cloud.net/2020/09/18/understanding-routing",
"url": "https://www.edge-cloud.net/2020/09/18/understanding-routing/",
"title": "Better understanding IP Routing",
"content_html": "<p>Today we will look at some of the fundamental principles of IP routing. While these principles and concepts are generic, we will use examples based on AWS networking.</p>\n\n<p>This blog post is not intended to be an all encompassing primer on IP routing. Instead I’ve seen numerous people confused by some of these principles and concepts while either designing networks or troubleshooting them. Therefore it appears to be a good idea to highlight and explain them explicitly.</p>\n\n<p>In a future related blog post we will look at BGP routing in more detail.</p>\n\n<p class=\"notice--info\">Please keep in mind that we will be using AWS VPCs and TGWs to illustrate routing principles. The resulting AWS networking designs are therefore used for illustration purposes and are not suited or recommended for production deployments.</p>\n\n<h1 id=\"routing\">Routing</h1>\n\n<p><a href=\"https://en.wikipedia.org/wiki/Routing\">Routing</a> and more specifically here, <a href=\"https://en.wikipedia.org/wiki/IP_routing\">IP routing</a>, deals with selecting a path for traffic in an IP network. Routing directs a “hop” within a network on how to forward IP packets based on a <a href=\"https://en.wikipedia.org/wiki/Routing_table\">routing tables</a> and the destination IP address within the packet.</p>\n\n<p>As we will see later, routing tables maintain information on how to reach various network destinations. Typically they are either configured manually (also known as “Static Routing”) or with the help of a routing protocol (e.g. BGP).</p>\n\n<h2 id=\"hop-by-hop-routing\">Hop-by-Hop Routing</h2>\n\n<p>One of the most fundamental concepts to understand in IP routing is that the actual forwarding decision is made on a hop-by-hop basis. This means that within each hop of the network path, a router makes a forwarding decision based on the local route table. Image this to be like a board game, where at each step in the game it is decided where to go next. Neither the previous nor the next step have any influence on the local decision.</p>\n\n<p>Taking AWS VPCs and <a href=\"https://aws.amazon.com/transit-gateway/?aws-transit-gateway-wn.sort-by=item.additionalFields.postDateTime&aws-transit-gateway-wn.sort-order=desc\">Transit Gateways (TGWs)</a> as an example, we can quickly understand how this hop-by-hop decision making plays out, while looking at the routing tables of the VPCs and TGWs (See Figure 1).</p>\n\n<figure class=\"webfeedsFeaturedVisual\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop.png\" title=\"Figure 1: IP Hop-by-Hop routing with VPCs and multiple Transit Gateways (TGW) \" class=\"image-popup\">\n<picture>\n <source width=\"871\" height=\"341\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-320.webp 320w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-384.webp 384w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-512.webp 512w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-683.webp 683w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-800.webp 800w, /content/uploads/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop.webp 871w\" sizes=\"871px\" />\n <source width=\"871\" height=\"341\" data-srcset=\" /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-320.png 320w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-384.png 384w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-512.png 512w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-683.png 683w, /content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-800.png 800w, /content/uploads/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop.png 871w\" sizes=\"871px\" />\n <img src=\"/content/resized/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop-320.png\" data-src=\"/content/uploads/2020/09/Understanding-Routing-and-BGP-Hop-by-Hop.png\" class=\"blur-up lazyautosizes lazyload\" width=\"871\" height=\"341\" alt=\"Figure 1: IP Hop-by-Hop routing with VPCs and multiple Transit Gateways (TGW) \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: IP Hop-by-Hop routing with VPCs and multiple Transit Gateways (TGW)\n</figcaption>\n\n</figure>\n\n<p>Traffic from an EC2 instance in VPC 1 wanting to reach another EC2 instance in VPC 2 will have to follow this hop-by-hop process through the five routing tables involved here. What do you think? Will traffic from VPC 1 reach VPC 2? Or is there a mistake in the route tables?</p>\n\n<p>Let’s look at each hop, step-by-step:</p>\n<ul>\n <li><strong>VPC 1:</strong> Traffic for destinations within VPC 2’s CIDR of 10.2.0.0/16 are send to the TGW 1 over the VPC attachment.</li>\n <li><strong>TGW 1:</strong> Inspecting the route table of TGW 1, we can see that traffic for 10.2.0.0/16 is send via a TGW peering to TGW 2.</li>\n <li><strong>TGW 2:</strong> Looking at the route table of TGW 2, we can also find an entry for the destination of 10.2.0.0/16. It specifies that traffic should be send via another TGW peering to TGW 3.</li>\n <li><strong>TGW 3:</strong> At this point our traffic has already made it into the correct AWS regions. Let’s see what happens next: The route table of TGW 3 indicates that traffic for 10.2.0.0/16 will be forwarded to VPC 2.</li>\n <li><strong>VPC 2:</strong> Last but not least, the route table of VPC 2 shows that traffic for the locally used CIDR 10.2.0.0/16 remains within the VPC and is delivered to the corresponding EC2 instance.</li>\n</ul>\n\n<p>But what about the return traffic from VPC 2 to VPC 1? Read on to see how another important principle of IP routing plays a role here.</p>\n\n<h2 id=\"directional\">Directional</h2>\n\n<p>Another important principle of IP routing, effectively caused by the hop-by-hop decision making behavior is that path determination is directional. Looking back at the provided example in the previous section (See Figure 1), we only validated that traffic from VPC 1 can reach VPC 2. But we did not validate any information on whether traffic from VPC 2 can reach VPC 1.</p>\n\n<p>I leave it up to you as an exercise to determine if the route tables across the VPCs and TGWs are setup correctly to allow return traffic and thereby enable bidirectional communication. Comment below in case you find a mistake.</p>\n\n<p>When designing route tables or troubleshooting network connectivity it’s always important that you look at traffic flows in both directions and plan or check route table independently for both directions.\nAlso when talking with co-workers, customer, support staff, or anyone alike it is also important that you indicate the direction of the traffic flow that you are referring to.</p>\n\n<h3 id=\"asymmetric-routing\">Asymmetric Routing</h3>\n\n<p>What’s even more interesting is that the directional nature of IP forwarding can lead to asymmetric traffic flows. But there is nothing wrong about asymmetric traffic flows and the majority of the Internet relies on it while exchanging traffic between <a href=\"https://en.wikipedia.org/wiki/Autonomous_system_(Internet)\">ASNs</a> via Peering or Transit. Think of asymmetric IP traffic flow as a hiking trail loop (See Figure 2). Such hiking trails are often more fascinating than an out-and-return path as you get to see a different set of landscape, plants and animals on the way back as compared to the way out.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/understanding-routing-and-bgp-trail-map.jpg\" title=\"Figure 2: Asymmetric routing is like a hiking-trail loop. \" class=\"image-popup\">\n<picture>\n <source width=\"800\" height=\"628\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/understanding-routing-and-bgp-trail-map-320.webp 320w, /content/resized/2020/09/understanding-routing-and-bgp-trail-map-384.webp 384w, /content/resized/2020/09/understanding-routing-and-bgp-trail-map-512.webp 512w, /content/resized/2020/09/understanding-routing-and-bgp-trail-map-683.webp 683w, /content/uploads/2020/09/understanding-routing-and-bgp-trail-map.webp 800w\" sizes=\"800px\" />\n <source width=\"800\" height=\"628\" data-srcset=\" /content/resized/2020/09/understanding-routing-and-bgp-trail-map-320.jpg 320w, /content/resized/2020/09/understanding-routing-and-bgp-trail-map-384.jpg 384w, /content/resized/2020/09/understanding-routing-and-bgp-trail-map-512.jpg 512w, /content/resized/2020/09/understanding-routing-and-bgp-trail-map-683.jpg 683w, /content/uploads/2020/09/understanding-routing-and-bgp-trail-map.jpg 800w\" sizes=\"800px\" />\n <img src=\"/content/resized/2020/09/understanding-routing-and-bgp-trail-map-320.jpg\" data-src=\"/content/uploads/2020/09/understanding-routing-and-bgp-trail-map.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"800\" height=\"628\" alt=\"Figure 2: Asymmetric routing is like a hiking-trail loop. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Asymmetric routing is like a hiking-trail loop.\n</figcaption>\n\n</figure>\n\n<p>And as long as you make the correct decision at your “routing hops” - aka. a trail fork - you will return to your trail head as well.</p>\n\n<p>Let’s extend the above example using AWS VPCs and TGWs to showcase asymmetric routing. For this we add another TGW and two more TGW peering connections along with changes to the route table (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing.png\" title=\"Figure 3: Asymmetric routing with VPCs and multiple Transit Gateways (TGW) \" class=\"image-popup\">\n<picture>\n <source width=\"871\" height=\"681\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-320.webp 320w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-384.webp 384w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-512.webp 512w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-683.webp 683w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-800.webp 800w, /content/uploads/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing.webp 871w\" sizes=\"871px\" />\n <source width=\"871\" height=\"681\" data-srcset=\" /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-320.png 320w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-384.png 384w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-512.png 512w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-683.png 683w, /content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-800.png 800w, /content/uploads/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing.png 871w\" sizes=\"871px\" />\n <img src=\"/content/resized/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing-320.png\" data-src=\"/content/uploads/2020/09/Understanding-Routing-and-BGP-Asymmetric-Routing.png\" class=\"blur-up lazyautosizes lazyload\" width=\"871\" height=\"681\" alt=\"Figure 3: Asymmetric routing with VPCs and multiple Transit Gateways (TGW) \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Asymmetric routing with VPCs and multiple Transit Gateways (TGW)\n</figcaption>\n\n</figure>\n\n<p>Now, if you follow the path of traffic from VPC 1 to VPC 2, you’ll notice that nothing has changed. Traffic still traverses TGW 1, TGW 2, and TGW 3 on the way to VPC 2. But at the same time look at traffic from VPC 2 to VPC 1. What do you notice?\nLooking at the route tables of the TGWs you should notice that traffic on the return path from VPC 2 to VPC 1 will traverse TGW 3, TGW 4, and TGW 1, thereby creating and asymmetric path.</p>\n\n<p>This asymmetric traffic flow is depicted with the green arrows.</p>\n\n<h2 id=\"route-tables\">Route Tables</h2>\n\n<p>Next we will look at route tables in a bit more detail. Being able to read and understand route tables, will help you understand the routing decision of the hops within each path.</p>\n\n<p>The most simple route tables have already been depicted in Figure 1 and Figure 3. These routes show a simple mapping between the destination CIDR - also called prefix or network - and the next hop.</p>\n\n<p>Translated into a route table on a Cisco device this might look like this:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>CSR1000V-01#sh ip bgp\nBGP table version is 297, local router ID is 1.1.1.1\nStatus codes: s suppressed, d damped, h history, * valid, > best, i - internal,\n r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,\n x best-external, a additional-path, c RIB-compressed,\n t secondary path, L long-lived-stale,\nOrigin codes: i - IGP, e - EGP, ? - incomplete\nRPKI validation codes: V valid, I invalid, N Not found\n\n Network Next Hop Metric LocPrf Weight Path\n 0.0.0.0 0.0.0.0 0 i\n *> 10.0.1.0/24 0.0.0.0 0 32768 i\n *> 10.0.16.0/24 0.0.0.0 0 32768 i\n *> 10.1.0.0/16 169.254.15.221 100 0 64512 i\n</code></pre></div></div>\n\n<p>Focus on the last line, which effectively translates into: Packets for the prefix “10.1.0.0/16” should be send to the next hop with the IP address of “169.254.15.221”.</p>\n\n<h3 id=\"longest-prefix-match\">Longest prefix match</h3>\n\n<p>After this let’s look at <a href=\"https://en.wikipedia.org/wiki/Longest_prefix_match\">longest prefix match</a>, sometimes also referred to as “more specific routing”. This algorithm specifies which entry to be chosen from the IP routing table in case of destination addresses matching more than one entry. For IP routing the most specific of the matching table entries — the one with the longest subnet mask — is called the longest prefix match and is the one chosen.</p>\n\n<p>Consider the below routing table on a Cisco device as an example and especially focus on the last five lines:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>CSR1000V-01#sh ip bgp\nBGP table version is 297, local router ID is 1.1.1.1\nStatus codes: s suppressed, d damped, h history, * valid, > best, i - internal,\n r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,\n x best-external, a additional-path, c RIB-compressed,\n t secondary path, L long-lived-stale,\nOrigin codes: i - IGP, e - EGP, ? - incomplete\nRPKI validation codes: V valid, I invalid, N Not found\n\n Network Next Hop Metric LocPrf Weight Path\n 0.0.0.0 0.0.0.0 0 i\n *> 10.0.1.0/24 0.0.0.0 0 32768 i\n *> 10.0.16.0/24 0.0.0.0 0 32768 i\n *> 10.1.0.0/16 169.254.15.221 100 0 64512 i\n *> 10.1.1.0/24 169.254.16.222 100 0 64513 i\n *> 10.1.2.0/24 169.254.17.223 100 0 64514 i\n *> 10.1.3.0/24 169.254.18.224 100 0 64515 i\n *> 10.1.4.0/24 169.254.19.225 100 0 64516 i\n</code></pre></div></div>\n\n<p>Here we can see that the destination IP address of “10.1.1.1” would match both the entry for “10.1.0.0/16”, as well as the entry for “10.1.1.0/24”. As the entry for “10.1.1.0/24” has a longer subnet mask - it is more specific - and therefore the chosen entry. With that this entry would be chosen and matching traffic send to 169.254.16.222 as the next hop.</p>\n\n<h3 id=\"equal-cost-multipath-ecmp\">Equal Cost Multipath (ECMP)</h3>\n\n<p>Usually with IP forwarding there is one egress or outbound path per hop for a given destination IP. This rule can be softened via a routing strategy called <a href=\"https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing\">Equal-cost multi-path routing (ECMP)</a>. With ECMP, packet forwarding to a single destination IP can occur over multiple “best path”.</p>\n\n<p>Again, let’s have a look at an example and consider the below routing table on a Cisco router, especially the last two lines:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>CSR1000V#sh ip bgp\nBGP table version is 297, local router ID is 1.1.1.1\nStatus codes: s suppressed, d damped, h history, * valid, > best, i - internal,\n r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,\n x best-external, a additional-path, c RIB-compressed,\n t secondary path, L long-lived-stale,\nOrigin codes: i - IGP, e - EGP, ? - incomplete\nRPKI validation codes: V valid, I invalid, N Not found\n\n Network Next Hop Metric LocPrf Weight Path\n 0.0.0.0 0.0.0.0 0 i\n *> 10.0.1.0/24 0.0.0.0 0 32768 i\n *> 10.0.16.0/24 0.0.0.0 0 32768 i\n *m 10.0.255.0/24 169.254.13.253 100 0 64512 i\n *> 169.254.15.221 100 0 64512 i\n</code></pre></div></div>\n\n<p>In this case we can see that we have a multipath route for the destination prefix of “10.0.255.0/24”, where both “169.254.13.253” and “169.254.15.221” are considered as the next best hop. In this case the router device will randomly send out traffic for this destination network over either next hop, while using a 5-tuple hash. A 5-tuple hash refers to a set of five different values that comprise a Transmission Control Protocol/Internet Protocol (TCP/IP) connection. It includes a source IP address/port number, destination IP address/port number and the protocol in use. Here with ECMP and 5-tuple hashing, packets belonging to the same 5-tuple travel to the same next hop, while packets from different 5-tuple may be send to another next hop.</p>\n\n<h1 id=\"analogy\">Analogy</h1>\n\n<p>IP routing is actually very simple, once you realize that it is similar to hiking without a map:</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/bear-tree.jpg\" title=\"Figure 4: IP routing is similar to hiking without a map. Here: Packet loss. (Photo courtesy of USDA Forest Service) \" class=\"image-popup\">\n<picture>\n <source width=\"400\" height=\"266\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/bear-tree-320.webp 320w, /content/resized/2020/09/bear-tree-384.webp 384w, /content/uploads/2020/09/bear-tree.webp 400w\" sizes=\"400px\" />\n <source width=\"400\" height=\"266\" data-srcset=\" /content/resized/2020/09/bear-tree-320.jpg 320w, /content/resized/2020/09/bear-tree-384.jpg 384w, /content/uploads/2020/09/bear-tree.jpg 400w\" sizes=\"400px\" />\n <img src=\"/content/resized/2020/09/bear-tree-320.jpg\" data-src=\"/content/uploads/2020/09/bear-tree.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"400\" height=\"266\" alt=\"Figure 4: IP routing is similar to hiking without a map. Here: Packet loss. (Photo courtesy of USDA Forest Service) \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: IP routing is similar to hiking without a map. Here: Packet loss. (Photo courtesy of USDA Forest Service)\n</figcaption>\n\n</figure>\n\n<ul>\n <li>You start at the trailhead (source) and want to reach some target (destination).</li>\n <li>Move along the hiking trail to the next fork (router) and look at the signs (route table). Decide which trail (next hop) to chose, in order to reach your destination.\nIf the sign at the fork lacks an entry to the desired destination, you’re stuck forever and will eventually get eaten by a bear (dropped packet; See Figure 4).\n <ul>\n <li>If you pass the same fork more than once, you’re lost (packet looping) and will eventually run out of food (see below).</li>\n <li>If you pass by more than 64 forks you run out of food, starve and get eaten by a bear (TTL expired).</li>\n <li>If you made it to your desired target (destination), you succeeded. Good job!</li>\n </ul>\n </li>\n <li>Like IP routing, hiking is bidirectional: You want to get home again, don’t you? Therefore consider the return path as well and follow the above steps.</li>\n</ul>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>In today’s post we took a look at some of the fundamental principles of IP routing. A future post will look in more detail at BGP Routing protocol concepts. Neither of these blog posts is intended to be an all encompassing primer on IP routing or BGP. Instead I’ve seen numerous people confused by some of these principles and concepts while either designing networks or troubleshooting them. Hopefully after reading through this post you feel a bit more confident to design, troubleshoot or just talk about IP networks.</p>\n",
"summary": "Look at fundamental principles of IP routing to better design and troubleshoot networks",
"date_published": "2020-09-18T00:00:00-07:00",
"date_modified": "2020-09-18T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2020/09/title-understanding-routing.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["BGP","Network"]
},
{
"id": "https://www.edge-cloud.net/2020/09/11/aws-ipsec-vpn-ipv6",
"url": "https://www.edge-cloud.net/2020/09/11/aws-ipsec-vpn-ipv6/",
"title": "AWS Site-to-Site VPN (IPSec) with IPv6",
"content_html": "<p>Recently AWS <a href=\"https://aws.amazon.com/about-aws/whats-new/2020/08/aws-site-to-site-vpn-supports-ipv6-traffic/\">released support for IPv6 traffic over the AWS Site-to-Site VPN (IPSec)</a>. The <a href=\"https://docs.aws.amazon.com/vpn/latest/s2svpn/SetUpVPNConnections.html\">setup of the AWS Site-to-Site VPN</a> has always been quite straight forward and thanks to the <a href=\"https://docs.aws.amazon.com/vpn/latest/s2svpn/SetUpVPNConnections.html#vpn-download-config\">downloadable configuration files</a> at times even trivial.\nWith the introduction of IPv6 support this is unfortunately no longer the case. Therefore this blog post will guide you around some of the pitfalls of setting up an AWS Site-to-Site VPN with IPv6 support, hoping that they will eventually be removed and this post become unnecessary.</p>\n\n<h1 id=\"constraints\">Constraints</h1>\n\n<p>A few <a href=\"https://docs.aws.amazon.com/vpn/latest/s2svpn/ipv4-ipv6.html\">constraints apply</a> when using AWS Site-to-Site VPN (IPSec) with IPv6:</p>\n<ul>\n <li>The outside tunnel IP addresses - which are the public non-RFC1918 addresses - still only support IPv4. You can only use IPv6 on the inside of the tunnel, in order to carry IPv6 traffic between your on-premises network and AWS.</li>\n <li>You have to use an <a href=\"https://aws.amazon.com/transit-gateway/\">AWS Transit Gateway (TGW)</a> as the AWS termination of your VPN. Site-to-Site VPNs to a Virtual Private Gateways (VGW) do not support IPv6.</li>\n <li>You cannot retrofit existing Site-to-Site connections with IPv6, but need to create a new connection.</li>\n <li>A Site-to-Site VPN connection can only support IPv4, or IPv6. This means that if you need to carry both IPv4 and IPv6 traffic between AWS and on-premises you need to create two separate connections, one for IPv4 and one for IPv6 (See Figure 1).</li>\n</ul>\n\n<figure class=\"webfeedsFeaturedVisual\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/S2S-VPN-with-IPv6-1.png\" title=\"Figure 1: AWS Site-to-Site VPN setup with IPv4 and IPv6 support. \" class=\"image-popup\">\n<picture>\n <source width=\"901\" height=\"463\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/S2S-VPN-with-IPv6-1-320.webp 320w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-384.webp 384w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-512.webp 512w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-683.webp 683w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-800.webp 800w, /content/uploads/2020/09/S2S-VPN-with-IPv6-1.webp 901w\" sizes=\"901px\" />\n <source width=\"901\" height=\"463\" data-srcset=\" /content/resized/2020/09/S2S-VPN-with-IPv6-1-320.png 320w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-384.png 384w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-512.png 512w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-683.png 683w, /content/resized/2020/09/S2S-VPN-with-IPv6-1-800.png 800w, /content/uploads/2020/09/S2S-VPN-with-IPv6-1.png 901w\" sizes=\"901px\" />\n <img src=\"/content/resized/2020/09/S2S-VPN-with-IPv6-1-320.png\" data-src=\"/content/uploads/2020/09/S2S-VPN-with-IPv6-1.png\" class=\"blur-up lazyautosizes lazyload\" width=\"901\" height=\"463\" alt=\"Figure 1: AWS Site-to-Site VPN setup with IPv4 and IPv6 support. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: AWS Site-to-Site VPN setup with IPv4 and IPv6 support.\n</figcaption>\n\n</figure>\n\n<p>As each AWS Site-to-Site VPN connection consist of two tunnels, in the case of supporting IPv4/IPv6 Dualstack traffic you will therefore end up with a total of four tunnels, two for IPv4 traffic and two for IPv6 traffic.\nAlso note that this means you’ll be paying separately for the tunnel carrying the IPv4 traffic as well as for the tunnel carrying the IPv6 traffic.</p>\n\n<h1 id=\"configuration\">Configuration</h1>\n\n<h2 id=\"aws-setup\">AWS Setup</h2>\n\n<p>The <a href=\"https://docs.aws.amazon.com/vpn/latest/s2svpn/SetUpVPNConnections.html#vpn-create-vpn-connection\">creation of a Site-to-Site VPN connection</a> is straight forward and only differs from its IPv4 counterpart by setting the “Tunnel Inside IP version” to IPv6 instead of IPv4 (See Figure 2).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/S2S-VPN-with-IPv6-2.png\" title=\"Figure 2: Creating a new AWS Site-to-Site VPN with IPv6 support. \" class=\"image-popup\">\n<picture>\n <source width=\"1061\" height=\"750\" type=\"image/webp\" data-srcset=\" /content/resized/2020/09/S2S-VPN-with-IPv6-2-320.webp 320w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-384.webp 384w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-512.webp 512w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-683.webp 683w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-800.webp 800w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-960.webp 960w, /content/uploads/2020/09/S2S-VPN-with-IPv6-2.webp 1061w\" sizes=\"1061px\" />\n <source width=\"1061\" height=\"750\" data-srcset=\" /content/resized/2020/09/S2S-VPN-with-IPv6-2-320.png 320w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-384.png 384w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-512.png 512w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-683.png 683w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-800.png 800w, /content/resized/2020/09/S2S-VPN-with-IPv6-2-960.png 960w, /content/uploads/2020/09/S2S-VPN-with-IPv6-2.png 1061w\" sizes=\"1061px\" />\n <img src=\"/content/resized/2020/09/S2S-VPN-with-IPv6-2-320.png\" data-src=\"/content/uploads/2020/09/S2S-VPN-with-IPv6-2.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1061\" height=\"750\" alt=\"Figure 2: Creating a new AWS Site-to-Site VPN with IPv6 support. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Creating a new AWS Site-to-Site VPN with IPv6 support.\n</figcaption>\n\n</figure>\n\n<p>The IPv6 enabled Site-to-Site VPN connection also supports defining the IPv6 addresses used within the tunnel yourself. If you want to make use of this capability you have to select a /126 IPv6 subent out of the fd00::/8 <a href=\"https://en.wikipedia.org/wiki/Unique_local_address\">Unique local address</a> address range. This is useful to prevent IP address collisions across multiple tunnels. Although with IPv6 addresses, such a collision is much less likely than with IPv4.</p>\n\n<h2 id=\"customer-side-configuration\">Customer-side Configuration</h2>\n\n<h3 id=\"basic-configuration-information\">Basic configuration information</h3>\n\n<p>When configuring the costumer-side of the solution, the challenges will start. Having a look at the Tunnel details for a newly created AWS Site-to-Site VPN with IPv6 support will yield some surprising results (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/09/S2S-VPN-with-IPv6-3.png\" title=\"Figure 3: Tunnel details for AWS Site-to-Site VPN with IPv6 support. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/09/S2S-VPN-with-IPv6-3-320.webp 320w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-384.webp 384w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-512.webp 512w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-683.webp 683w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-800.webp 800w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-960.webp 960w, \" sizes=\"1438px\" />\n <source data-srcset=\" /content/resized/2020/09/S2S-VPN-with-IPv6-3-320.png 320w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-384.png 384w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-512.png 512w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-683.png 683w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-800.png 800w, /content/resized/2020/09/S2S-VPN-with-IPv6-3-960.png 960w, \" sizes=\"1438px\" />\n <img src=\"/content/resized/2020/09/S2S-VPN-with-IPv6-3-320.png\" data-src=\"/content/uploads/2020/09/S2S-VPN-with-IPv6-3.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 3: Tunnel details for AWS Site-to-Site VPN with IPv6 support. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Tunnel details for AWS Site-to-Site VPN with IPv6 support.\n</figcaption>\n\n</figure>\n\n<p>You’ll see that for both tunnels “Inside IPv4 CIDRs” from the 169.254.0.0/16 <a href=\"https://en.wikipedia.org/wiki/Link-local_address\">Link-local address</a> range will be shown. As mentioned previously an AWS Site-to-Site connection - and thereby its tunnels - only supports either IPv4 or IPv6. As this is an IPv6 enabled tunnel, the displayed Inner IPv4 CIDRs are irrelevant from a tunnel transport perspective. You can completely ignore them when configuring the tunnel itself.\nThe provided information does come in handy with regards to the BGP router ID. In the above case, with Tunnel 1 the AWS side of the BGP session uses the BGP router ID of 169.254.123.<strong>89</strong>. To prevent collisions you should therefore not use the same BGP router ID on your side.</p>\n\n<p>Next you will notice that for the “Inside IPv6 CIDRs” the addresses are provided with a /128 netmask - which is the IPv6 equivalent of /32 and therefore a “host-only” netmask. This netmask therefore only contains a single IP address. Yet the <a href=\"https://docs.aws.amazon.com/vpn/latest/s2svpn/ipv4-ipv6.html\">documentation clearly calls out</a> that these “Inside IPv6 CIDRs” should be a /126 IPv6 CIDR block, which includes 4 IPv6 addresses. A /126 IPv6 CIDR is the equivalent of a /30 IPv4 CIDR.\nAlso the provided IPv6 address from the fd00::/8 <a href=\"https://en.wikipedia.org/wiki/Unique_local_address\">Unique local address</a> address range ends in an odd number and is therefore not a network address, which always end in even numbers.\nTurns out that the displayed IPv6 address is actually the AWS side of the inner connection.</p>\n\n<p>So with the value of “fdbe:1a26:45b0:4631:ca60:3307:371b:631<strong>5</strong>/128” displayed in the provided example, the relevant IPv6 information would be:</p>\n<ul>\n <li>Subnet (aka CIDR): fdbe:1a26:45b0:4631:ca60:3307:371b:631<strong>4</strong>/12<strong>6</strong></li>\n <li>AWS-side interface address: fdbe:1a26:45b0:4631:ca60:3307:371b:631<strong>5</strong>/12<strong>6</strong></li>\n <li>Customer-side address: fdbe:1a26:45b0:4631:ca60:3307:371b:631<strong>6</strong>/12<strong>6</strong></li>\n</ul>\n\n<p>You should notice the pattern for constructing the necessary IPv6 information:</p>\n<ul>\n <li>Subnet (aka CIDR): Provided IPv6 address - 1</li>\n <li>AWS-side interface address: Provided IPv6 address</li>\n <li>Customer-side address: Provided IPv6 address + 1</li>\n</ul>\n\n<p>Just keep in mind that IPv6 addresses use hex digits, which start with 0,1,2,.. then continue with ..,8,9,A,B,.. and end with ..,E,F.</p>\n\n<p>You can double check your conversion math knowing that the used netmask is a /128, allowing IPv6 subnets with 4 addresses. Therefore 4 different combinations of trailing IPv6 digits exist:</p>\n<ul>\n <li>Subnet (aka CIDR): Must always end in 0,4,8,C</li>\n <li>AWS-side interface address: Must always end in 1,5,9,D</li>\n <li>Customer-side address: Must always end in 2,6,A,E</li>\n</ul>\n\n<p class=\"notice--info\"><strong>Notice:</strong> In the meantime the representation of the Inside IPv6 CIDR in the AWS Console has been fixed. You should notice that now the Subnet (AKA CIDR) is displayed with the correcet subnet mask of /126. Therefore in the above example the AWS Console would now display fdbe:1a26:45b0:4631:ca60:3307:371b:631<strong>4</strong>/12<strong>6</strong>.</p>\n\n<h3 id=\"configuration-download\">Configuration download</h3>\n\n<p>The next challenge you will notice is that when downloading the <a href=\"https://docs.aws.amazon.com/vpn/latest/s2svpn/SetUpVPNConnections.html#vpn-download-config\">downloadable configuration files</a> from the AWS Console, it does not include any IPv6 address information. Instead for the inner address it includes IPv4 address information that are irrelevant as already pointed out.</p>\n\n<p>Nevertheless you can leverage the downloadable configuration file for the Internet Key Exchange (IKE) and IPSec Configuration of your tunnels. These two sections within the file can be used without any changes, unless you diverted with your IKE or IPSec settings from the default values. Because these downloadable configuration files are only baseline examples that assume default values.</p>\n\n<h3 id=\"tunnel-interface-configuration\">Tunnel Interface Configuration</h3>\n\n<p>With that the Tunnel Interface Configuration has to be adapted from IPv4 to IPv6. Using a Cisco IOS configuration as an example, the downloadable configuration file will provide the following Interface Configuration.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>interface Tunnel1\n ip address 169.254.123.90 255.255.255.252\n ip virtual-reassembly\n tunnel source 198.51.100.123\n tunnel destination 54.68.62.136\n tunnel mode ipsec ipv4\n tunnel protection ipsec profile ipsec-vpn-0b1561f60da62e5eb-0\n ip tcp adjust-mss 1379\n\n</code></pre></div></div>\n\n<p>Within this configuration we have to replace the inner IPv4 address with an IPv6 address and also specify that IPv6 should be used within the inside of the tunnel. The outer IP address remains to be an IPv4 address. The resulting corrected configuration using the IPv6 address as outlined in the previous section becomes as follows.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>interface Tunnel1\n no ip address\n ip virtual-reassembly\n ipv6 address FDBE:1A26:45B0:4631:CA60:3307:371B:6316/126\n tunnel source 198.51.100.123\n tunnel destination 54.68.62.136\n tunnel mode ipsec ipv4 v6-overlay\n tunnel protection ipsec profile ipsec-vpn-0b1561f60da62e5eb-0\n ip tcp adjust-mss 1379\n\n</code></pre></div></div>\n\n<h3 id=\"border-gateway-protocol-bgp-configuration\">Border Gateway Protocol (BGP) Configuration</h3>\n\n<p>Next the Border Gateway Protocol (BGP) Configuration also needs to be adapted, replacing the IPv4 configuration with a corresponding IPv6 configuration.</p>\n\n<p>The downloadable configuration will provide the following BGP configuration.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>router bgp 65000\n neighbor 169.254.123.89 remote-as 64512\n neighbor 169.254.123.89 activate\n neighbor 169.254.123.89 timers 10 30 30\n address-family ipv4 unicast\n neighbor 169.254.123.89 remote-as 64512\n neighbor 169.254.123.89 timers 10 30 30\n neighbor 169.254.123.89 activate\n neighbor 169.254.123.89 soft-reconfiguration inbound\n</code></pre></div></div>\n\n<p>As we want to run BGP over the inner IPv6 connection, we again have to replace all IPv4 configuration items with the corresponding IPv6 addresses.\nThe result will look as follows.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>router bgp 65000\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 remote-as 64512\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 activate\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 timers 10 30 30\n address-family ipv6 unicast\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 remote-as 64512\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 timers 10 30 30\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 activate\n neighbor FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1 soft-reconfiguration inbound\n</code></pre></div></div>\n\n<p>Here you effectively have to replace the unusable IPv4 address for the neighbor with the correct IPv6 address of that neighbor and change the address-family section from IPv4 to IPv6.</p>\n\n<h1 id=\"validation\">Validation</h1>\n\n<p>As a final step, we can validate that IPv6 routes are being learned from the TGW via the Site-to-Site VPN.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>CSR1000V-01#sh ipv6 route bgp\nIPv6 Routing Table - default - 13 entries\nCodes: C - Connected, L - Local, S - Static, U - Per-user Static route\n B - BGP, R - RIP, H - NHRP, I1 - ISIS L1\n I2 - ISIS L2, IA - ISIS interarea, IS - ISIS summary, D - EIGRP\n EX - EIGRP external, ND - ND Default, NDp - ND Prefix, DCE - Destination\n NDr - Redirect, RL - RPL, O - OSPF Intra, OI - OSPF Inter\n OE1 - OSPF ext 1, OE2 - OSPF ext 2, ON1 - OSPF NSSA ext 1\n ON2 - OSPF NSSA ext 2, la - LISP alt, lr - LISP site-registrations\n ld - LISP dyn-eid, lA - LISP away, le - LISP extranet-policy\n lp - LISP publications, a - Application, m - OMP\nB 2600:1234::/64 [20/100]\n via FDBE:1A26:45B0:4631:CA60:3307:371B:6315\n via FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1\nB 2600:1A14:5DE:DB00::/56 [20/100]\n via FDBE:1A26:45B0:4631:CA60:3307:371B:6315\n via FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1\nB 2600:1A16:807:3A00::/56 [20/100]\n via FDBE:1A26:45B0:4631:CA60:3307:371B:6315\n via FDB0:C9AB:9EC7:3934:EE0:9873:54BC:C8F1\n\n</code></pre></div></div>\n\n<p>In this case we can see that a total of three prefixes is learned, whereas the first prefix is originated on the TGW via a <a href=\"https://www.edge-cloud.net/2019/08/07/bgp-route-summary-with-tgw/\">summary route</a>, while the other two prefixes correspond to VPCs.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This blog post guided you around some of the pitfalls when setting up an IPv6 capable AWS Site-to-Site VPN connection. It covered some of the rather cosmetic imperfections within the AWS Console around unusable IPv4 addresses, as well as generating a working Customer Gateway (CGW) configuration based on the downloadable configuration files.</p>\n",
"summary": "How to setup the AWS Site-to-Site VPN (IPSec) with IPv6",
"date_published": "2020-09-11T00:00:00-07:00",
"date_modified": "2020-09-11T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2020/09/title-aws-ipsec-vpn-ipv6.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","IPv6","VPN"]
},
{
"id": "https://www.edge-cloud.net/2020/05/01/tgw-multicast-intro",
"url": "https://www.edge-cloud.net/2020/05/01/tgw-multicast-intro/",
"title": "Multicast with AWS Transit Gateway",
"content_html": "<p>At the beginning of December 2019, AWS released <a href=\"https://aws.amazon.com/blogs/aws/aws-transit-gateway-adds-multicast-and-inter-regional-peering/\">Multicast support</a> within the <a href=\"https://aws.amazon.com/transit-gateway/\">AWS Transit Gateway</a>. This marked the beginning of being able to use applications that require support for <a href=\"https://en.wikipedia.org/wiki/IP_multicast\">IP Multicast</a> within AWS.</p>\n\n<p>The following article will give you a brief overview of how to use IP Multicast with the AWS Transit Gateway and especially how to validate that your setup is working correctly.</p>\n\n<h1 id=\"multicast\">Multicast</h1>\n\n<p>Let’s have a look at the basics of IP Multicasting and IP Multicast on AWS.</p>\n\n<h2 id=\"what-is-ip-multicasting\">What is IP Multicasting</h2>\n\n<p>With IP Multicasting a source host can send a single packet to hundreds or thousands of hosts at the same time. All this works over a route network - e.g. the Internet. The replication of the source packet along with tracking of destination membership happens inside of the network itself, instead of the application (See Figure 1).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/05/Multicast-IPMulticast.png\" title=\"Figure 1: IP Multicasting with source host, rendezvous point and multicast receiver. \" class=\"image-popup\">\n<picture>\n <source width=\"789\" height=\"478\" type=\"image/webp\" data-srcset=\" /content/resized/2020/05/Multicast-IPMulticast-320.webp 320w, /content/resized/2020/05/Multicast-IPMulticast-384.webp 384w, /content/resized/2020/05/Multicast-IPMulticast-512.webp 512w, /content/resized/2020/05/Multicast-IPMulticast-683.webp 683w, /content/uploads/2020/05/Multicast-IPMulticast.webp 789w\" sizes=\"789px\" />\n <source width=\"789\" height=\"478\" data-srcset=\" /content/resized/2020/05/Multicast-IPMulticast-320.png 320w, /content/resized/2020/05/Multicast-IPMulticast-384.png 384w, /content/resized/2020/05/Multicast-IPMulticast-512.png 512w, /content/resized/2020/05/Multicast-IPMulticast-683.png 683w, /content/uploads/2020/05/Multicast-IPMulticast.png 789w\" sizes=\"789px\" />\n <img src=\"/content/resized/2020/05/Multicast-IPMulticast-320.png\" data-src=\"/content/uploads/2020/05/Multicast-IPMulticast.png\" class=\"blur-up lazyautosizes lazyload\" width=\"789\" height=\"478\" alt=\"Figure 1: IP Multicasting with source host, rendezvous point and multicast receiver. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: IP Multicasting with source host, rendezvous point and multicast receiver.\n</figcaption>\n\n</figure>\n\n<p>For this to work the source host addresses the packet with a Multicast Address from the range of 224.0.0.0 through 239.255.255.255. Each Multicast Address specifies a Multicast group to which other hosts can subscribe to. Such a group can have between one and an unlimited number of members as neither hosts nor routers maintain a list of all members. Instead the source host send the packet to an initial router, called the rendezvous point (RP), which serves as the root of a tree-like multicast distribution.\nThe most common <a href=\"https://en.wikipedia.org/wiki/Transport_layer\">transport layer</a> protocol to use multicast addressing is <a href=\"https://en.wikipedia.org/wiki/User_Datagram_Protocol\">User Datagram Protocol (UDP)</a>.</p>\n\n<h2 id=\"multicast-and-aws-transit-gateway\">Multicast and AWS Transit Gateway</h2>\n\n<p>While an AWS VPC by itself does not support Multicast, AWS Transit Gateway can provide this new capability. The Transit Gateway will act as the rendezvous point, receiving the packets from the Multicast source, replicate it and send it to the Multicast Receiver. With the Multicast-enabled Transit Gateway, source and receiver can be in the same VPC or in different VPCs.</p>\n\n<h1 id=\"constraints\">Constraints</h1>\n\n<p>Today Multicast on AWS Transit Gateway comes with a few restrictions that need to be considered:</p>\n<ul>\n <li>Creation and usage of Multicast-enabled TGW is currently only supported in the AWS Region us-east-1 (N. Virginia).</li>\n <li>You must create a new TGW to enable Multicast. It is not possible to enable Multicast on an existing Transit Gateway. In case you are already using a Transit Gateway, you can create another instance that will just serve the purpose of distributing Multicast traffic (See Figure 2). As neither VPC nor TGW route tables are used to handle multicast traffic, this deployment model will not interfere with your existing traditional TGW or VPC route tables.</li>\n <li>Self-Management of Multicast group membership by hosts through the <a href=\"https://en.wikipedia.org/wiki/Internet_Group_Management_Protocol\">Internet Group Management Protocol (IGMP)</a> is not yet supported. Instead Multicast group membership is solely managed using Amazon VPC Console or the AWS CLI.</li>\n <li>Only <a href=\"https://aws.amazon.com/ec2/nitro/\">AWS Nitro</a> instances can be a Multicast source. If you use a non-Nitro instance as a receiver, you must disable the <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#change_source_dest_check\">Source/Dest check</a>.</li>\n <li>While the AWS Transit Gateway has a default limit of only supporting <a href=\"https://docs.aws.amazon.com/vpc/latest/tgw/transit-gateway-quotas.html#multicast-quota\">1x TGW source per group</a>, this limit can be increased.</li>\n</ul>\n\n<figure class=\"webfeedsFeaturedVisual\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/05/Multicast-Multicast-TGW.png\" title=\"Figure 2: Multicast-enabled TGW besides traditional TGW. \" class=\"image-popup\">\n<picture>\n <source width=\"1009\" height=\"581\" type=\"image/webp\" data-srcset=\" /content/resized/2020/05/Multicast-Multicast-TGW-320.webp 320w, /content/resized/2020/05/Multicast-Multicast-TGW-384.webp 384w, /content/resized/2020/05/Multicast-Multicast-TGW-512.webp 512w, /content/resized/2020/05/Multicast-Multicast-TGW-683.webp 683w, /content/resized/2020/05/Multicast-Multicast-TGW-800.webp 800w, /content/resized/2020/05/Multicast-Multicast-TGW-960.webp 960w, /content/uploads/2020/05/Multicast-Multicast-TGW.webp 1009w\" sizes=\"1009px\" />\n <source width=\"1009\" height=\"581\" data-srcset=\" /content/resized/2020/05/Multicast-Multicast-TGW-320.png 320w, /content/resized/2020/05/Multicast-Multicast-TGW-384.png 384w, /content/resized/2020/05/Multicast-Multicast-TGW-512.png 512w, /content/resized/2020/05/Multicast-Multicast-TGW-683.png 683w, /content/resized/2020/05/Multicast-Multicast-TGW-800.png 800w, /content/resized/2020/05/Multicast-Multicast-TGW-960.png 960w, /content/uploads/2020/05/Multicast-Multicast-TGW.png 1009w\" sizes=\"1009px\" />\n <img src=\"/content/resized/2020/05/Multicast-Multicast-TGW-320.png\" data-src=\"/content/uploads/2020/05/Multicast-Multicast-TGW.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1009\" height=\"581\" alt=\"Figure 2: Multicast-enabled TGW besides traditional TGW. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Multicast-enabled TGW besides traditional TGW.\n</figcaption>\n\n</figure>\n\n<h1 id=\"setup\">Setup</h1>\n\n<p>Before kicking the tires on Multicast, it needs to be setup. At a minimum this requires the network setup within the Transit Gateway, as well as at least one Multicast Source and one Multicast Receiver instance.</p>\n\n<h2 id=\"source-and-receiver-instances\">Source and Receiver Instances</h2>\n\n<p>First setup the EC2 instances that we will use in our testing as the Multicast Source and Multicast Receiver. To better understand how Multicast works, you should create at least one Multicast Source and two Multicast Receiver. Also keep the constraint around usage of AWS Nitro instances in mind and select a Nitro-based EC2 instance for the three EC2 instances.\nThis blog post will assume use of Ubuntu Linux instances for the EC2 instances and you should install <a href=\"https://iperf.fr/\">iPerf</a> on these instances. On Ubuntu Linux you will do this via <code class=\"language-plaintext highlighter-rouge\">sudo apt get install iperf</code>.</p>\n\n<p>Last, but not least ensure that port UDP 5001 is opened within the <a href=\"https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html\">security group</a> associated with the Multicast Receiver instances. The source IP will be the IPv4 address of the ENI associated with the Multicast Source EC2 instance.</p>\n\n<h2 id=\"transit-gateway-tgw\">Transit Gateway (TGW)</h2>\n\n<p>You can follow the <a href=\"https://docs.aws.amazon.com/vpc/latest/tgw/working-with-multicast.html\">AWS instructions</a> for setting up a Multicast-enabled TGW, along with a multicast domain.\nNext associate any of the VPCs and subnets that will include Multicast Sources and Receivers to this TGW. Multicast Source and Receiver can either be in the same VPC, or in different VPCs. Then associate the individual Multicast Sources and Receiver via their Elastic Network Interface (ENI) with a Multicast Group (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/05/TGW-Multicast-Group.jpg\" title=\"Figure 3: Multicast-Group with single source and multiple receiver. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/05/TGW-Multicast-Group-320.webp 320w, /content/resized/2020/05/TGW-Multicast-Group-384.webp 384w, /content/resized/2020/05/TGW-Multicast-Group-512.webp 512w, /content/resized/2020/05/TGW-Multicast-Group-683.webp 683w, /content/resized/2020/05/TGW-Multicast-Group-800.webp 800w, /content/resized/2020/05/TGW-Multicast-Group-960.webp 960w, \" sizes=\"1455px\" />\n <source data-srcset=\" /content/resized/2020/05/TGW-Multicast-Group-320.jpg 320w, /content/resized/2020/05/TGW-Multicast-Group-384.jpg 384w, /content/resized/2020/05/TGW-Multicast-Group-512.jpg 512w, /content/resized/2020/05/TGW-Multicast-Group-683.jpg 683w, /content/resized/2020/05/TGW-Multicast-Group-800.jpg 800w, /content/resized/2020/05/TGW-Multicast-Group-960.jpg 960w, \" sizes=\"1455px\" />\n <img src=\"/content/resized/2020/05/TGW-Multicast-Group-320.jpg\" data-src=\"/content/uploads/2020/05/TGW-Multicast-Group.jpg\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 3: Multicast-Group with single source and multiple receiver. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Multicast-Group with single source and multiple receiver.\n</figcaption>\n\n</figure>\n\n<p>The above example shows the Multicast Group 224.1.1.1 with one Multicast Source and two Multicast Receivers.</p>\n\n<h1 id=\"testing\">Testing</h1>\n\n<p>Now that the setup is complete, it’s time to test our setup. We expect that a packet send by the Multicast Source to the Multicast group 224.1.1.1 should be simultaneously received by both Multicast Receivers.</p>\n\n<h2 id=\"multicast-receiver\">Multicast Receiver</h2>\n\n<p>First get the two Multicast Receiver ready by starting iPerf in “Server” mode against the Multicast group IP of “224.1.1.1” and using the protocol UDP. iPerf will use the default port of 5001.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>% iperf -s -u -B 224.1.1.1 -i 1\n------------------------------------------------------------\nServer listening on UDP port 5001\nBinding to local address 224.1.1.1\nJoining multicast group 224.1.1.1\nReceiving 1470 byte datagrams\nUDP buffer size: 110 KByte (default)\n------------------------------------------------------------\n</code></pre></div></div>\n\n<p>iPerf will recognize the provided address as an IP Multicast address and join this group. After that iPerf will wait for incoming traffic over UDP port 5001 and display it accordingly.</p>\n\n<h2 id=\"multicast-source\">Multicast Source</h2>\n\n<p>Now that the Multicast Receiver are ready to accept traffic, it’s time to get the Multicast Source ready. On the Multicast Source EC2 instance, we will start iPerf in client mode against the above Multicast group.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>% iperf -c 224.1.1.1 -u -T 32 -t 3 -i 1\n------------------------------------------------------------\nClient connecting to 224.1.1.1, UDP port 5001\nSending 1470 byte datagrams\nSetting multicast TTL to 32\nUDP buffer size: 110 KByte (default)\n------------------------------------------------------------\n[ 3] local 192.168.220.20 port 59347 connected with 224.1.1.1 port 5001\n[ ID] Interval Transfer Bandwidth\n[ 3] 0.0- 1.0 sec 129 KBytes 1.06 Mbits/sec\n[ 3] 1.0- 2.0 sec 128 KBytes 1.05 Mbits/sec\n[ 3] 2.0- 3.0 sec 128 KBytes 1.05 Mbits/sec\n[ 3] 0.0- 3.0 sec 386 KBytes 1.05 Mbits/sec\n[ 3] Sent 269 datagrams\n\n</code></pre></div></div>\n\n<p>This way iPerf will generate traffic and send it to the Multicast group 224.1.1.1 over UDP to port 5001, which is the default setting.</p>\n\n<h2 id=\"result\">Result</h2>\n\n<p>While the Multicast Source is generating traffic, we can head over to the two Multicast Receiver instances. There we should notice that both of the instances are receiving the test traffic at the same time.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>...\n[ 3] local 224.1.1.1 port 5001 connected with 192.168.220.20 port 59347\n[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams\n[ 3] 0.0- 1.0 sec 128 KBytes 1.05 Mbits/sec 0.035 ms 0/ 89 (0%)\n[ 3] 1.0- 2.0 sec 128 KBytes 1.05 Mbits/sec 0.015 ms 0/ 89 (0%)\n[ 3] 2.0- 3.0 sec 128 KBytes 1.05 Mbits/sec 0.025 ms 0/ 89 (0%)\n[ 3] 0.0- 3.0 sec 386 KBytes 1.05 Mbits/sec 0.068 ms 0/ 269 (0%)\n\n</code></pre></div></div>\n\n<p>As expected the underlying network replicated the test traffic from the Multicast Source and delivered it to both Multicast Receiver at the same time.</p>\n\n<h1 id=\"troubleshooting\">Troubleshooting</h1>\n\n<p>Here are a few things to look at in case something is not working</p>\n<ul>\n <li><strong>Security Groups and Firewalls:</strong> Make sure that the Security Group associated with the Multicast Receiver EC2 instance allows the Multicast test traffic in. We will be using the transport protocol UDP and by default iPerf uses the port 5001. Also, the source IP of the received traffic will be the IPv4 address of the ENI that is the Multicast Source. In case you are using multiple Multicast Sources, this will translate to multiple IPv4 addresses.</li>\n <li><strong>TGW Multicast Domain groups:</strong> Make sure that the Multicast group IP address that you are using with iPerf matches the setup in TGW. Also make sure that you specified the correct EC2 instances - via their ENI - as the source and receiver.</li>\n</ul>\n\n<p>If things still don’t work, fire up <a href=\"https://www.tcpdump.org/\">tcpdump</a> on the Source and Receiver side and see what packets you’re seeing.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This article walked you through the setup and configuration of a Multicast-enabled Transit Gateway and showed you how to quickly test functionality using iPerf.</p>\n",
"summary": "Walkthrough for setup and testing IP Multicast with AWS Transit Gateway (TGW)",
"date_published": "2020-05-01T00:00:00-07:00",
"date_modified": "2020-05-01T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2020/05/title-tgw-multicast-intro.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Transit-Gateway"]
},
{
"id": "https://www.edge-cloud.net/2020/04/19/drawing-monitor-for-network-diagrams",
"url": "https://www.edge-cloud.net/2020/04/19/drawing-monitor-for-network-diagrams/",
"title": "Drawing monitor for network diagrams",
"content_html": "<p>As a Senior Solutions Architect Specialist for Networking at <a href=\"https://aws.amazon.com/\">AWS</a>, I spent a lot of time in online meetings with customers, helping them design networks or understand AWS networking better. Part of these meetings usually involves whiteboarding network diagrams. While visualizing ideas or concepts is something very common and straight forward on a physical whiteboard, it is not trivial in an online meeting.</p>\n\n<p>As I often get asked about my setup during or after calls, I want to shed some light on what I’m using and what’s working for me.</p>\n\n<h1 id=\"home-office-setup\">Home office setup</h1>\n\n<p>As I primarily work from home, my home office setup (See Figure 1) provides everything I need to get through the day.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/04/HomeOffice1.jpg\" title=\"Figure 1: Home office setup with Huion Kamvas Pro 12 Drawing Monitor. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/04/HomeOffice1-320.webp 320w, /content/resized/2020/04/HomeOffice1-384.webp 384w, /content/resized/2020/04/HomeOffice1-512.webp 512w, /content/resized/2020/04/HomeOffice1-683.webp 683w, /content/resized/2020/04/HomeOffice1-800.webp 800w, /content/resized/2020/04/HomeOffice1-960.webp 960w, \" sizes=\"4032px\" />\n <source data-srcset=\" /content/resized/2020/04/HomeOffice1-320.jpg 320w, /content/resized/2020/04/HomeOffice1-384.jpg 384w, /content/resized/2020/04/HomeOffice1-512.jpg 512w, /content/resized/2020/04/HomeOffice1-683.jpg 683w, /content/resized/2020/04/HomeOffice1-800.jpg 800w, /content/resized/2020/04/HomeOffice1-960.jpg 960w, \" sizes=\"4032px\" />\n <img src=\"/content/resized/2020/04/HomeOffice1-320.jpg\" data-src=\"/content/uploads/2020/04/HomeOffice1.jpg\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: Home office setup with Huion Kamvas Pro 12 Drawing Monitor. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Home office setup with Huion Kamvas Pro 12 Drawing Monitor.\n</figcaption>\n\n</figure>\n\n<p>This article will focus on the Drawing monitor, visible in the lower left.</p>\n\n<h2 id=\"hardware\">Hardware</h2>\n\n<p>The key component of my home office setup is a <a href=\"https://amzn.to/3afaZhe\">Huion Kamvas Pro 12 Drawing Monitor</a>, connected via HDMI and USB to the docking station of my notebook. On my PC it shows up as a secondary screen in addition to my primary <a href=\"https://amzn.to/2RQheSq\">Dell U3419 Ultrasharp monitor</a>. Pen input on the Huion monitor is translated into standard mouse input.</p>\n\n<p>It’s important to point out that in contrary to touch enabled notebooks, this monitor does not provide touch input. It only reacts to the provided pen. Therefore you can touch it with the balm of your hand while drawing (See Figure 2). Although that does leave smudges and you’ll have to clean the screen with a good <a href=\"https://amzn.to/2KjB3xe\">microfiber clearning cloth</a> from time to time.</p>\n\n<figure class=\"webfeedsFeaturedVisual\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/04/HomeOffice3.jpg\" title=\"Figure 2: Drawing on Huion Kamvas Pro 12 Drawing Monitor with balm on screen. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/04/HomeOffice3-320.webp 320w, /content/resized/2020/04/HomeOffice3-384.webp 384w, /content/resized/2020/04/HomeOffice3-512.webp 512w, /content/resized/2020/04/HomeOffice3-683.webp 683w, /content/resized/2020/04/HomeOffice3-800.webp 800w, /content/resized/2020/04/HomeOffice3-960.webp 960w, \" sizes=\"4032px\" />\n <source data-srcset=\" /content/resized/2020/04/HomeOffice3-320.jpg 320w, /content/resized/2020/04/HomeOffice3-384.jpg 384w, /content/resized/2020/04/HomeOffice3-512.jpg 512w, /content/resized/2020/04/HomeOffice3-683.jpg 683w, /content/resized/2020/04/HomeOffice3-800.jpg 800w, /content/resized/2020/04/HomeOffice3-960.jpg 960w, \" sizes=\"4032px\" />\n <img src=\"/content/resized/2020/04/HomeOffice3-320.jpg\" data-src=\"/content/uploads/2020/04/HomeOffice3.jpg\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 2: Drawing on Huion Kamvas Pro 12 Drawing Monitor with balm on screen. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Drawing on Huion Kamvas Pro 12 Drawing Monitor with balm on screen.\n</figcaption>\n\n</figure>\n\n<h2 id=\"software\">Software</h2>\n\n<p>As mentioned before the pen input on the drawing monitor is translated to standard mouse input. You can therefore use any software that allows drawing with a mouse, ranging from common software such as Acrobat Reader to Microsoft PowerPoint.</p>\n\n<p>For my particular use case the software <a href=\"https://openboard.ch/index.en.html\">OpenBoard</a> has proven to be most effective. OpenBoard is an open source teaching software for interactive whiteboards designed primarily for use in schools and universities. It is maintained by the Education Department (DIP) of the canton of Geneva, in Switzerland.</p>\n\n<p>OpenBoard not only allows free-hand drawing, but you can also quickly and easily import existing customer design documents or pull up pre-made diagrams to draw over (See Figure 3).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/04/HomeOffice2.jpg\" title=\"Figure 3: Huion Kamvas Pro 12 Drawing Monitor with pre-made diagrams and free-hand drawings. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2020/04/HomeOffice2-320.webp 320w, /content/resized/2020/04/HomeOffice2-384.webp 384w, /content/resized/2020/04/HomeOffice2-512.webp 512w, /content/resized/2020/04/HomeOffice2-683.webp 683w, /content/resized/2020/04/HomeOffice2-800.webp 800w, /content/resized/2020/04/HomeOffice2-960.webp 960w, \" sizes=\"3853px\" />\n <source data-srcset=\" /content/resized/2020/04/HomeOffice2-320.jpg 320w, /content/resized/2020/04/HomeOffice2-384.jpg 384w, /content/resized/2020/04/HomeOffice2-512.jpg 512w, /content/resized/2020/04/HomeOffice2-683.jpg 683w, /content/resized/2020/04/HomeOffice2-800.jpg 800w, /content/resized/2020/04/HomeOffice2-960.jpg 960w, \" sizes=\"3853px\" />\n <img src=\"/content/resized/2020/04/HomeOffice2-320.jpg\" data-src=\"/content/uploads/2020/04/HomeOffice2.jpg\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 3: Huion Kamvas Pro 12 Drawing Monitor with pre-made diagrams and free-hand drawings. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Huion Kamvas Pro 12 Drawing Monitor with pre-made diagrams and free-hand drawings.\n</figcaption>\n\n</figure>\n\n<p>Effectively having two mice as input along with two monitors can cause unwanted situations in the form of not finding the mouse pointer. Under Windows 10 you can enable the setting “Show location of pointer when I press the CTRL key” under the mouse properties to mitigate this challenge (See Figure 4).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2020/04/HomeOffice4.jpg\" title=\"Figure 4: Windows 10 setting for ‘Show location of pointer when I press the CTRL key’. \" class=\"image-popup\">\n<picture>\n <source width=\"552\" height=\"468\" type=\"image/webp\" data-srcset=\" /content/resized/2020/04/HomeOffice4-320.webp 320w, /content/resized/2020/04/HomeOffice4-384.webp 384w, /content/resized/2020/04/HomeOffice4-512.webp 512w, /content/uploads/2020/04/HomeOffice4.webp 552w\" sizes=\"552px\" />\n <source width=\"552\" height=\"468\" data-srcset=\" /content/resized/2020/04/HomeOffice4-320.jpg 320w, /content/resized/2020/04/HomeOffice4-384.jpg 384w, /content/resized/2020/04/HomeOffice4-512.jpg 512w, /content/uploads/2020/04/HomeOffice4.jpg 552w\" sizes=\"552px\" />\n <img src=\"/content/resized/2020/04/HomeOffice4-320.jpg\" data-src=\"/content/uploads/2020/04/HomeOffice4.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"552\" height=\"468\" alt=\"Figure 4: Windows 10 setting for ‘Show location of pointer when I press the CTRL key’. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: Windows 10 setting for ‘Show location of pointer when I press the CTRL key’.\n</figcaption>\n\n</figure>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This article showed you my home office setup for visualizing ideas and concepts during customer calls with a drawing monitor and interactive whiteboard software. If you wonder who these birds on the pictures are. That’s <a href=\"https://www.rainbowsprings.co.nz/\">Jenny the Kea</a> and <a href=\"https://www.youtube.com/watch?v=dykrPi9P_Ak\">Pete the Pukeko</a>.</p>\n",
"summary": "Home office setup with Huion Kamvas Pro 12 drawing monitor for network diagrams",
"date_published": "2020-04-19T00:00:00-07:00",
"date_modified": "2020-04-19T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2020/04/HomeOffice3.jpg",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network"]
},
{
"id": "https://www.edge-cloud.net/2019/12/27/aws-dx-connect-on-premises",
"url": "https://www.edge-cloud.net/2019/12/27/aws-dx-connect-on-premises/",
"title": "Enabling connectivity between on-premises locations connected to AWS through Direct Connect",
"content_html": "<p class=\"notice--danger\"><strong>Note:</strong> This post is outdated as AWS has released alternative mechanism - such as <a href=\"https://aws.amazon.com/blogs/aws/new-site-to-site-connectivity-with-aws-direct-connect-sitelink/\">AWS Direct Connect SiteLink</a> or <a href=\"https://aws.amazon.com/cloud-wan/\">AWS CloudWAN</a> - in the meantime.</p>\n\n<p>This post covers the caveats of data flow between on-premises locations that are each connected to AWS via <a href=\"https://aws.amazon.com/directconnect/\">AWS Direct Connect</a>. In case you have multiple on-premise locations connected to AWS via Direct Connect, enabling the data flow between these locations is not always trivial. Therefore this blog post highlights some of the pitfalls and outlines possible solutions.</p>\n\n<h1 id=\"introduction\">Introduction</h1>\n\n<p>This blog post assumes the fundamental design as depicted in Figure 1. One or more on-premises locations such as offices connect via carrier ethernet or another local connectivity option to two Direct Connect locations within close proximity.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/AWS-Interconnect.png\" title=\"Figure 1: Design to enable connectivity between on-premises locations and AWS within a geo. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect-320.webp 320w, /content/resized/2019/12/AWS-Interconnect-384.webp 384w, /content/resized/2019/12/AWS-Interconnect-512.webp 512w, /content/resized/2019/12/AWS-Interconnect-683.webp 683w, /content/resized/2019/12/AWS-Interconnect-800.webp 800w, /content/resized/2019/12/AWS-Interconnect-960.webp 960w, \" sizes=\"1311px\" />\n <source data-srcset=\" /content/resized/2019/12/AWS-Interconnect-320.png 320w, /content/resized/2019/12/AWS-Interconnect-384.png 384w, /content/resized/2019/12/AWS-Interconnect-512.png 512w, /content/resized/2019/12/AWS-Interconnect-683.png 683w, /content/resized/2019/12/AWS-Interconnect-800.png 800w, /content/resized/2019/12/AWS-Interconnect-960.png 960w, \" sizes=\"1311px\" />\n <img src=\"/content/resized/2019/12/AWS-Interconnect-320.png\" data-src=\"/content/uploads/2019/12/AWS-Interconnect.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 1: Design to enable connectivity between on-premises locations and AWS within a geo. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Design to enable connectivity between on-premises locations and AWS within a geo.\n</figcaption>\n\n</figure>\n\n<p>Traffic from on-premises destined to AWS is routed via one of the two Direct locations, while the other location serves as backup path. Alternatively both Direct Connect locations can be used in an Active/Active setup.</p>\n\n<h1 id=\"caveats\">Caveats</h1>\n\n<p>While implementing this approach of enabling connect between on-premises locations there are a few caveats that need to be considered.</p>\n\n<h2 id=\"intra-region-traffic\">Intra Region traffic</h2>\n\n<p>Keep <a href=\"https://edge-cloud-net.web.app/2019/09/06/dx-gateway-deep-dive/\">in mind</a> that the AWS Direct Connect Gateway does not allow you to route traffic from one Virtual Interface to another Virtual Interface. Therefore the traffic flow as despicted in Figure 2 is not currently possible.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/AWS-Interconnect-Non-Working.png\" title=\"Figure 2: Unsupported VIF to VIF routing with Direct Connect Gateway. \" class=\"image-popup\">\n<picture>\n <source width=\"1221\" height=\"517\" type=\"image/webp\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect-Non-Working-320.webp 320w, /content/resized/2019/12/AWS-Interconnect-Non-Working-384.webp 384w, /content/resized/2019/12/AWS-Interconnect-Non-Working-512.webp 512w, /content/resized/2019/12/AWS-Interconnect-Non-Working-683.webp 683w, /content/resized/2019/12/AWS-Interconnect-Non-Working-800.webp 800w, /content/resized/2019/12/AWS-Interconnect-Non-Working-960.webp 960w, /content/uploads/2019/12/AWS-Interconnect-Non-Working.webp 1221w\" sizes=\"1221px\" />\n <source width=\"1221\" height=\"517\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect-Non-Working-320.png 320w, /content/resized/2019/12/AWS-Interconnect-Non-Working-384.png 384w, /content/resized/2019/12/AWS-Interconnect-Non-Working-512.png 512w, /content/resized/2019/12/AWS-Interconnect-Non-Working-683.png 683w, /content/resized/2019/12/AWS-Interconnect-Non-Working-800.png 800w, /content/resized/2019/12/AWS-Interconnect-Non-Working-960.png 960w, /content/uploads/2019/12/AWS-Interconnect-Non-Working.png 1221w\" sizes=\"1221px\" />\n <img src=\"/content/resized/2019/12/AWS-Interconnect-Non-Working-320.png\" data-src=\"/content/uploads/2019/12/AWS-Interconnect-Non-Working.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1221\" height=\"517\" alt=\"Figure 2: Unsupported VIF to VIF routing with Direct Connect Gateway. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Unsupported VIF to VIF routing with Direct Connect Gateway.\n</figcaption>\n\n</figure>\n\n<p>If you have a need to route traffic between on-premise locations in a certain region through the same AWS region, you need to leverage a separate Direct Connect Gateway, Transit VIF, and Direct Connect connection for each of your offices. The resulting design is depicted in Figure 3.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/AWS-Interconnect-Working.png\" title=\"Figure 3: Workaround to leverage Transit Gateway for intra-office routing. \" class=\"image-popup\">\n<picture>\n <source width=\"1221\" height=\"517\" type=\"image/webp\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect-Working-320.webp 320w, /content/resized/2019/12/AWS-Interconnect-Working-384.webp 384w, /content/resized/2019/12/AWS-Interconnect-Working-512.webp 512w, /content/resized/2019/12/AWS-Interconnect-Working-683.webp 683w, /content/resized/2019/12/AWS-Interconnect-Working-800.webp 800w, /content/resized/2019/12/AWS-Interconnect-Working-960.webp 960w, /content/uploads/2019/12/AWS-Interconnect-Working.webp 1221w\" sizes=\"1221px\" />\n <source width=\"1221\" height=\"517\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect-Working-320.png 320w, /content/resized/2019/12/AWS-Interconnect-Working-384.png 384w, /content/resized/2019/12/AWS-Interconnect-Working-512.png 512w, /content/resized/2019/12/AWS-Interconnect-Working-683.png 683w, /content/resized/2019/12/AWS-Interconnect-Working-800.png 800w, /content/resized/2019/12/AWS-Interconnect-Working-960.png 960w, /content/uploads/2019/12/AWS-Interconnect-Working.png 1221w\" sizes=\"1221px\" />\n <img src=\"/content/resized/2019/12/AWS-Interconnect-Working-320.png\" data-src=\"/content/uploads/2019/12/AWS-Interconnect-Working.png\" class=\"blur-up lazyautosizes lazyload\" width=\"1221\" height=\"517\" alt=\"Figure 3: Workaround to leverage Transit Gateway for intra-office routing. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Workaround to leverage Transit Gateway for intra-office routing.\n</figcaption>\n\n</figure>\n\n<p>This approach could make sense in case you have the requirement of inspecting and filtering traffic between on-premises locations via an AWS-based device. In case you have no such requirement, it makes more sense to route traffic between locations directly via e.g. a local Carrier Ethernet connectivity (Figure 4), completely leaving it out of AWS.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/AWS-Interconnect_RegionalOffice.png\" title=\"Figure 4: Intra-office connectivity within the same region. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect_RegionalOffice-320.webp 320w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-384.webp 384w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-512.webp 512w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-683.webp 683w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-800.webp 800w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-960.webp 960w, \" sizes=\"1311px\" />\n <source data-srcset=\" /content/resized/2019/12/AWS-Interconnect_RegionalOffice-320.png 320w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-384.png 384w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-512.png 512w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-683.png 683w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-800.png 800w, /content/resized/2019/12/AWS-Interconnect_RegionalOffice-960.png 960w, \" sizes=\"1311px\" />\n <img src=\"/content/resized/2019/12/AWS-Interconnect_RegionalOffice-320.png\" data-src=\"/content/uploads/2019/12/AWS-Interconnect_RegionalOffice.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 4: Intra-office connectivity within the same region. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: Intra-office connectivity within the same region.\n</figcaption>\n\n</figure>\n\n<h2 id=\"inter-region-traffic\">Inter Region traffic</h2>\n\n<p>Thanks to the recently released capability of <a href=\"https://aws.amazon.com/about-aws/whats-new/2019/12/aws-transit-gateway-supports-inter-region-peering/\">Inter-Region Peering</a> for the Transit Gateway you can extend the above described model and connect your on-premises locations across the globe to AWS using AWS Direct Connect and Transit Gateway (Figure 5).</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/AWS-Interconnect_GlobalOffice.png\" title=\"Figure 5: Intra-office connectivity outside a region over the AWS backbone. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2019/12/AWS-Interconnect_GlobalOffice-320.webp 320w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-384.webp 384w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-512.webp 512w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-683.webp 683w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-800.webp 800w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-960.webp 960w, \" sizes=\"1312px\" />\n <source data-srcset=\" /content/resized/2019/12/AWS-Interconnect_GlobalOffice-320.png 320w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-384.png 384w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-512.png 512w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-683.png 683w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-800.png 800w, /content/resized/2019/12/AWS-Interconnect_GlobalOffice-960.png 960w, \" sizes=\"1312px\" />\n <img src=\"/content/resized/2019/12/AWS-Interconnect_GlobalOffice-320.png\" data-src=\"/content/uploads/2019/12/AWS-Interconnect_GlobalOffice.png\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 5: Intra-office connectivity outside a region over the AWS backbone. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 5: Intra-office connectivity outside a region over the AWS backbone.\n</figcaption>\n\n</figure>\n\n<p>This approach is also useful in case you want to connect your on-premises locations to more than three AWS regions. Due to the limitation of only being able to connect <a href=\"https://www.edge-cloud.net/2019/09/06/dx-gateway-deep-dive/\">up to three Transit Gateways per Direct Connect Gateway</a> regionalizing your Direct Connect Gateways this way allows you to scale very elegantly.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>In this article we discuss the caveats of data path between your on-premises locations while using <a href=\"https://aws.amazon.com/directconnect/\">AWS Direct Connect</a>.</p>\n",
"summary": "Caveats for data flow between multiple on-premises locations, when using AWS with Direct Connect and Transit Gateway",
"date_published": "2019-12-27T00:00:00-08:00",
"date_modified": "2019-12-27T00:00:00-08:00",
"image": "https://www.edge-cloud.net/content/uploads/2019/12/AWS-Interconnect.png",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Direct-Connect"]
},
{
"id": "https://www.edge-cloud.net/2019/12/09/block-countries-with-route53",
"url": "https://www.edge-cloud.net/2019/12/09/block-countries-with-route53/",
"title": "Block access from certain countries with Route 53 Geolocation",
"content_html": "<p>This article walks you through using <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-geo\">Amazon Route 53 Geolocation Routing</a>, in order to block access to your services from certain countries. In addition <a href=\"https://atlas.ripe.net/\">RIPE Atlas</a> is used in a subsequent step to validate the setup.</p>\n\n<h1 id=\"motivation\">Motivation</h1>\n\n<p>There are multiple reasons why you might want to block access to your website or API from certain countries. If you are a US based company, you are required to comply with <a href=\"https://www.bis.doc.gov/index.php/policy-guidance/country-guidance/sanctioned-destinations\">US regulations regarding sanctions</a> against countries such as Cuba, Iran, North Korea, Sudan, or Syria. This could result in the requirement to block access to your website or API from these countries.</p>\n\n<p>Another motivation could be to prevent illicit traffic from countries that you do not conduct business with. Especially <a href=\"https://www.zdnet.com/article/china-resurrects-great-cannon-for-ddos-attacks-on-hong-kong-forum/\">China</a> and <a href=\"https://en.wikipedia.org/wiki/Russian_web_brigades\">Russia</a> are known to be a prime source of illicit traffic. Therefore blocking access from these traffic might be wanted in your situation.</p>\n\n<h1 id=\"configuration-setup\">Configuration setup</h1>\n\n<p>Here, we are using <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-geo\">Amazon Route 53 Geolocation Routing</a> to direct traffic from China for one or multiple domain names to either an invalid target IP or a static error page.</p>\n\n<p>Using an invalid IP address, such as a Loopback address like 127.0.0.1 would cause traffic destined for web site or API not to even reach your or your provider’s network. Instead it will already be discarded on the client device.</p>\n\n<h2 id=\"route-53-geolocation-routing\">Route 53 Geolocation routing</h2>\n\n<p>In this setup we solely create a DNS test entry to validate functionality of <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-geo\">Amazon Route 53 Geolocation Routing</a> for our desired purpose. We will do so by creating a DNS entry of the type “TXT”, that will respond with “China”, when queried from within China, and with “Default” when queried from all other countries.</p>\n\n<p>Geolocation works by mapping IP addresses to locations. However, some IP addresses aren’t mapped to geographic locations, so even if you create geolocation records that cover all seven continents, Amazon Route 53 will receive some DNS queries from locations that it can’t identify. These locations are mapped to the default record. This default record handles both queries from IP addresses that aren’t mapped to any location and queries that come from locations that you haven’t created geolocation records for.</p>\n\n<p>First we create a Route 53 record for the hostname “geoblock” of the type “TXT” (See Figure 1). As depicted the routing policy is specified as “Geolocation”, with the location of “China”. The value for this record is “China”.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/GeoBlock_China.jpg\" title=\"Figure 1: Create TXT record with a ‘Geolocation’ routing policy for the origin country ‘China’. \" class=\"image-popup\">\n<picture>\n <source width=\"515\" height=\"820\" type=\"image/webp\" data-srcset=\" /content/resized/2019/12/GeoBlock_China-320.webp 320w, /content/resized/2019/12/GeoBlock_China-384.webp 384w, /content/resized/2019/12/GeoBlock_China-512.webp 512w, /content/uploads/2019/12/GeoBlock_China.webp 515w\" sizes=\"515px\" />\n <source width=\"515\" height=\"820\" data-srcset=\" /content/resized/2019/12/GeoBlock_China-320.jpg 320w, /content/resized/2019/12/GeoBlock_China-384.jpg 384w, /content/resized/2019/12/GeoBlock_China-512.jpg 512w, /content/uploads/2019/12/GeoBlock_China.jpg 515w\" sizes=\"515px\" />\n <img src=\"/content/resized/2019/12/GeoBlock_China-320.jpg\" data-src=\"/content/uploads/2019/12/GeoBlock_China.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"515\" height=\"820\" alt=\"Figure 1: Create TXT record with a ‘Geolocation’ routing policy for the origin country ‘China’. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Create TXT record with a ‘Geolocation’ routing policy for the origin country ‘China’.\n</figcaption>\n\n</figure>\n\n<p>Next, we create another Route 53 for the same hostname of “geoblock” and the type “TXT” (See Figure 2). As depicted the routing policy is also specified as “Geolocation”. But this time the location is configured as “Default” with the record value being “Default”.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/GeoBlock_Default.jpg\" title=\"Figure 2: Create TXT record with a ‘Geolocation’ routing policy for all other countries. \" class=\"image-popup\">\n<picture>\n <source width=\"517\" height=\"821\" type=\"image/webp\" data-srcset=\" /content/resized/2019/12/GeoBlock_Default-320.webp 320w, /content/resized/2019/12/GeoBlock_Default-384.webp 384w, /content/resized/2019/12/GeoBlock_Default-512.webp 512w, /content/uploads/2019/12/GeoBlock_Default.webp 517w\" sizes=\"517px\" />\n <source width=\"517\" height=\"821\" data-srcset=\" /content/resized/2019/12/GeoBlock_Default-320.jpg 320w, /content/resized/2019/12/GeoBlock_Default-384.jpg 384w, /content/resized/2019/12/GeoBlock_Default-512.jpg 512w, /content/uploads/2019/12/GeoBlock_Default.jpg 517w\" sizes=\"517px\" />\n <img src=\"/content/resized/2019/12/GeoBlock_Default-320.jpg\" data-src=\"/content/uploads/2019/12/GeoBlock_Default.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"517\" height=\"821\" alt=\"Figure 2: Create TXT record with a ‘Geolocation’ routing policy for all other countries. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 2: Create TXT record with a ‘Geolocation’ routing policy for all other countries.\n</figcaption>\n\n</figure>\n\n<p>That’s it! In our simple case only two entries are needed. The resulting two Route 53 Geolocation records ar show in Figure 3.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/GeoBlock_Result.jpg\" title=\"Figure 3: Resulting TXT record sets for a ‘Geolocation’ routing policy. \" class=\"image-popup\">\n<picture>\n <source type=\"image/webp\" data-srcset=\" /content/resized/2019/12/GeoBlock_Result-320.webp 320w, /content/resized/2019/12/GeoBlock_Result-384.webp 384w, /content/resized/2019/12/GeoBlock_Result-512.webp 512w, /content/resized/2019/12/GeoBlock_Result-683.webp 683w, /content/resized/2019/12/GeoBlock_Result-800.webp 800w, /content/resized/2019/12/GeoBlock_Result-960.webp 960w, \" sizes=\"1411px\" />\n <source data-srcset=\" /content/resized/2019/12/GeoBlock_Result-320.jpg 320w, /content/resized/2019/12/GeoBlock_Result-384.jpg 384w, /content/resized/2019/12/GeoBlock_Result-512.jpg 512w, /content/resized/2019/12/GeoBlock_Result-683.jpg 683w, /content/resized/2019/12/GeoBlock_Result-800.jpg 800w, /content/resized/2019/12/GeoBlock_Result-960.jpg 960w, \" sizes=\"1411px\" />\n <img src=\"/content/resized/2019/12/GeoBlock_Result-320.jpg\" data-src=\"/content/uploads/2019/12/GeoBlock_Result.jpg\" class=\"blur-up lazyautosizes lazyload\" alt=\"Figure 3: Resulting TXT record sets for a ‘Geolocation’ routing policy. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 3: Resulting TXT record sets for a ‘Geolocation’ routing policy.\n</figcaption>\n\n</figure>\n\n<p>Once we have used the above “TXT” records to validate the setup, we can setup a corresponding production record of e.g. our website or API endpoint. This setup will look almost the same, but use a Route 53 record type of “A” instead along with the correct IP addresses.</p>\n\n<h2 id=\"error-page-using-cloudfront-and-s3\">Error page using CloudFront and S3</h2>\n\n<p>As mentioned above you can easily blackhole traffic from undesired locations, by responding with the <a href=\"https://en.wikipedia.org/wiki/Loopback\">Loopback</a> IPv4 address of 127.0.0.1. As a result traffic from these clients destined for your endpoint would never leave their system.\nBut as mentioned before, geolocation routing works by mapping IP addresses to locations. And this approach comes with <a href=\"/2019/03/01/limitations-of-geo-dns/\">inherent inaccuracies</a>.</p>\n\n<p>Therefore a better approach would be to direct blocked users to a static website, which outlines the reason of the block and also provides an appeal-process. In its simplest form this process could ask users to contact your technical support for help.</p>\n\n<p>You can easily use CloudFront and S3 to <a href=\"https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/\">serve this static error page</a>.</p>\n\n<h1 id=\"testing-the-setup\">Testing the Setup</h1>\n\n<p>Let’s get back to testing our <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-geo\">Amazon Route 53 Geolocation Routing</a> setup and validate that users in China are indeed served with a separate answer than users outside China. To do so, we will be using RIPE Atlas probes.</p>\n\n<h2 id=\"ripe-atlas\">RIPE Atlas</h2>\n\n<p><a href=\"https://atlas.ripe.net/\">RIPE Atlas</a> is a global network of hardware devices, called probes and anchors, that actively measure Internet connectivity. Anyone can access this data via Internet traffic maps, streaming data visualisations, and an API. RIPE Atlas users can also perform customised measurements to gain valuable data about their own networks.</p>\n\n<p>I highly recommend you to consider <a href=\"https://atlas.ripe.net/get-involved/become-a-host/\">hosting a RIPE Atlas probe</a> yourself. Not only will you benefit from the data that it collects on your Internet connection, but it will also allow you to run customized measurements against various Internet targets. And in the end every additional RIPE Atlas probe will benefit the overall Internet community.</p>\n\n<p>For our purposes we will create a one-off <a href=\"https://atlas.ripe.net/measurements/\">RIPE Atlas measurement</a> of type DNS with the above configured hostname as the target (See Figure 4). Make sure to configure usage of the probe’s resolver and force DNS resolution on the probe. Also we want to select all available RIPE Atlas probes within China, as well as a set of probes outside China.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/12/RIPE_Atlas_GeoBlock.jpg\" title=\"Figure 4: RIPE Atlas measurement setup to test Geoblocking in China. \" class=\"image-popup\">\n<picture>\n <source width=\"816\" height=\"1141\" type=\"image/webp\" data-srcset=\" /content/resized/2019/12/RIPE_Atlas_GeoBlock-320.webp 320w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-384.webp 384w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-512.webp 512w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-683.webp 683w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-800.webp 800w, /content/uploads/2019/12/RIPE_Atlas_GeoBlock.webp 816w\" sizes=\"816px\" />\n <source width=\"816\" height=\"1141\" data-srcset=\" /content/resized/2019/12/RIPE_Atlas_GeoBlock-320.jpg 320w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-384.jpg 384w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-512.jpg 512w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-683.jpg 683w, /content/resized/2019/12/RIPE_Atlas_GeoBlock-800.jpg 800w, /content/uploads/2019/12/RIPE_Atlas_GeoBlock.jpg 816w\" sizes=\"816px\" />\n <img src=\"/content/resized/2019/12/RIPE_Atlas_GeoBlock-320.jpg\" data-src=\"/content/uploads/2019/12/RIPE_Atlas_GeoBlock.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"816\" height=\"1141\" alt=\"Figure 4: RIPE Atlas measurement setup to test Geoblocking in China. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 4: RIPE Atlas measurement setup to test Geoblocking in China.\n</figcaption>\n\n</figure>\n\n<p>A few minutes after running the one-off RIPE Atlas measurement you should be able to see and download your results. In order to analyze the results and figure out whether our configuration is working, we need to write a small script.</p>\n\n<h2 id=\"results\">Results</h2>\n\n<p>After downloading your RIPE Atlas measurement results in the nd-json (fragmented) format, the below script will allow you to analyze the results.</p>\n\n<p>This script iterates through the results and for each probe determines:</p>\n<ul>\n <li>The location country of the probe as specified by the probe’s host.</li>\n <li>The result of the DNS lookup, which is either “China” or “Default”.</li>\n <li>Whether probes identified to be</li>\n <li>in China receive the result “China”</li>\n <li>outside China receive the result “Default”</li>\n</ul>\n\n<p>Please note that this script uses two custom RIPE Atlas libraries, which you first need to install with <code class=\"language-plaintext highlighter-rouge\">pip install ripe.atlas.sagan --user</code> and <code class=\"language-plaintext highlighter-rouge\">pip install ripe.atlas.cousteau --user</code>.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>#!/usr/bin/env python3\n\nfrom ripe.atlas.sagan import Result\nfrom ripe.atlas.cousteau import Probe\n\nmy_results_file = \"./RIPE-Atlas-measurement-fraq.json\"\nwith open(my_results_file) as results:\n for result in results.readlines():\n parsed_result = Result.get(result)\n probe = Probe(id=parsed_result.probe_id)\n probe_country = probe.country_code\n probe_id = parsed_result.probe_id\n try:\n probe_result = parsed_result.responses[0].abuf.answers[0].address\n except:\n probe_result = \"None\"\n status = \"Not OK <====\"\n if (probe_country == \"CN\" and probe_result == \"China\"):\n status = \"OK\"\n if (probe_country != \"CN\" and probe_result == \"Default\"):\n status = \"OK\"\n if (probe_result == \"None\"):\n status = \"Unknown\"\n\n print(probe_country + \": \" + str(probe_id) + \": \" + probe_result + \": \" + status)\n</code></pre></div></div>\n\n<p>Running the above script will yield the following results:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>user@host:~$ ./geo-loc-atlas.py\nCN: 1000050: China: OK\nEC: 10032: Default: OK\nCN: 1008: China: OK\nAM: 11623: Default: OK\nRS: 12835: Default: OK\nCN: 14584: None: Unknown\nBA: 14628: Default: OK\nGB: 14775: Default: OK\nCN: 16562: China: OK\nGB: 18321: Default: OK\nHU: 18355: Default: OK\nCZ: 18611: Default: OK\nTR: 20019: Default: OK\nUS: 20418: Default: OK\nSK: 20970: Default: OK\nCN: 21744: Default: Not OK <====\nCN: 21832: China: OK\nRS: 22363: Default: OK\nFI: 23163: Default: OK\nFR: 23939: Default: OK\n...\n</code></pre></div></div>\n\n<h2 id=\"findings\">Findings</h2>\n\n<p>Using the above script along with the RIPE Atlas measurement results, you’ll notice that a few probes - identified by their hosts to be located in China - are not receiving a DNS resolution of “China” for the geoblock DNS entry. Instead they are receiving the “Default” entry, as Route 53 does not identify them to be in China.\nLooking closer at these probes we can see that the probes are indeed located in Hong Kong. Keep in mind that Route 53 treats Hong Kong as a separate country and also RIPE Atlas allows specifying Hong Kong as a probe’s country. In this case the probe’s host felt that the probe - even though located in Hong Kong - should be labeled as being in China.</p>\n\n<h1 id=\"summary\">Summary</h1>\n\n<p>This blog post walked you through using <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-geo\">Amazon Route 53 Geolocation Routing</a>, in order to block access to services from certain countries. Furthermore it showed how <a href=\"https://atlas.ripe.net/\">RIPE Atlas</a> can be used to validate the geoblocking setup.</p>\n",
"summary": "Use Amazon Route 53 Geolocation Routing to block access to services from certain countries. Leverage RIPE Atlas to validate the setup.",
"date_published": "2019-12-09T00:00:00-08:00",
"date_modified": "2019-12-09T00:00:00-08:00",
"image": "https://www.edge-cloud.net/content/uploads/2019/12/GeoBlock_China.jpg",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Route-53"]
},
{
"id": "https://www.edge-cloud.net/2019/09/09/troubleshooting-bgp-session-hosted-vif",
"url": "https://www.edge-cloud.net/2019/09/09/troubleshooting-bgp-session-hosted-vif/",
"title": "Troubleshooting BGP neighbor problem with a Direct Connect Hosted VIF",
"content_html": "<p>Here is a quick look at an issue with a BGP session between a customer router (customer-premises equipment; CPE) and an AWS Direct Connect peer.</p>\n\n<h1 id=\"problem\">Problem</h1>\n\n<p>While it was possible to ping the AWS Direct Connect peer interface from the customer peer interface the BGP remained in the <em>Idle</em> state. Local and remote ASNs matched up and IP addresses also matched up.</p>\n\n<p>Turning on <em>“debug ip bgp”</em> gave the following insight, which solely showed that the BGP peer connection was timing out.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>10.1.103.34 active went from Idle to Active\n10.1.103.34 open active, local address 10.1.103.33\n10.1.103.34 open failed: Connection timed out; remote host not responding\n10.1.103.34 Active open failed - tcb is not available, open active delayed 12288ms (35000ms max, 60% jitter)\nses global 10.1.103.34 act Reset (Active open failed).\n10.1.103.34 active went from Active to Idle\n\n</code></pre></div></div>\n\n<h1 id=\"setup\">Setup</h1>\n\n<p>The customer router was connected to a <a href=\"https://aws.amazon.com/directconnect/partners/\">Hosted Virtual Interface</a> from the provider <a href=\"https://www.megaport.com/\">Megaport</a>.</p>\n\n<p>The view of this Hosted Virtual Interface within the AWS Console is shown in Figure 1. Notice that the <em>BGP Authentication key</em> shows as empty.</p>\n\n<figure class=\"\">\n\n\n\n\n\n\n\n\n<a href=\"/content/uploads/2019/09/Hosted-VIF.jpg\" title=\"Figure 1: Hosted VIF showing no BGP Auth Key configured. \" class=\"image-popup\">\n<picture>\n <source width=\"993\" height=\"437\" type=\"image/webp\" data-srcset=\" /content/resized/2019/09/Hosted-VIF-320.webp 320w, /content/resized/2019/09/Hosted-VIF-384.webp 384w, /content/resized/2019/09/Hosted-VIF-512.webp 512w, /content/resized/2019/09/Hosted-VIF-683.webp 683w, /content/resized/2019/09/Hosted-VIF-800.webp 800w, /content/resized/2019/09/Hosted-VIF-960.webp 960w, /content/uploads/2019/09/Hosted-VIF.webp 993w\" sizes=\"993px\" />\n <source width=\"993\" height=\"437\" data-srcset=\" /content/resized/2019/09/Hosted-VIF-320.jpg 320w, /content/resized/2019/09/Hosted-VIF-384.jpg 384w, /content/resized/2019/09/Hosted-VIF-512.jpg 512w, /content/resized/2019/09/Hosted-VIF-683.jpg 683w, /content/resized/2019/09/Hosted-VIF-800.jpg 800w, /content/resized/2019/09/Hosted-VIF-960.jpg 960w, /content/uploads/2019/09/Hosted-VIF.jpg 993w\" sizes=\"993px\" />\n <img src=\"/content/resized/2019/09/Hosted-VIF-320.jpg\" data-src=\"/content/uploads/2019/09/Hosted-VIF.jpg\" class=\"blur-up lazyautosizes lazyload\" width=\"993\" height=\"437\" alt=\"Figure 1: Hosted VIF showing no BGP Auth Key configured. \" />\n</picture>\n</a>\n\n\n\n <figcaption>Figure 1: Hosted VIF showing no BGP Auth Key configured.\n</figcaption>\n\n</figure>\n\n<p>With this the corresponding BGP setup on the Cisco-based customer router should be quite trivial.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>router bgp 64970\nneighbor 10.1.103.34 remote-as AWS_ASN\n</code></pre></div></div>\n\n<h1 id=\"troubleshooting\">Troubleshooting</h1>\n\n<p>As mentioned before it was possible to ping the AWS Direct Connect peer interface successfully:</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Router1#ping 10.1.103.34\nType escape sequence to abort.\nSending 5, 100-byte ICMP Echos to 10.1.103.34, timeout is 2 seconds:\n!!!!!\nSuccess rate is 100 percent (5/5), round-trip min/avg/max = 12/12/13 ms\n</code></pre></div></div>\n\n<p>Next, came checking via Telnet whether the BGP daemon was accessible on port TCP/179 on the AWS Direct Connect peer side.\nA successful connection would eventually be closed by the remote side and therefore look like this:</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Router1#telnet 10.1.103.34 179\nTrying 10.1.103.34, 179 ... Open\n\n[Connection to 10.1.103.34 closed by foreign host]\n</code></pre></div></div>\n\n<p>Just as a reference: In case the remote host was not accessible due to lack of Layer 3 connectivity, the result would like like this:</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Router1#telnet 10.1.103.34 179\nTrying 10.1.103.34, 179 ...\n% Connection timed out; remote host not responding\n</code></pre></div></div>\n\n<p>And if connectivity to port TCP/179 was blocked by e.g. an access control list (ACL), the result would look like this:</p>\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Router1#telnet 10.1.103.34 179\nTrying 10.1.103.34, 179 ...\n% Connection refused by remote host\n</code></pre></div></div>\n\n<p>After validating that the BGP peer could be reached successfully, it was time to look further.</p>\n\n<p>Turns out that looking at the Megaport portal gave a slightly different view with the BGP Auth Key showing up. To be fair, Megaport clearly <a href=\"https://knowledgebase.megaport.com/cloud-connectivity/aws-cloud/\">documents</a> this behavior of the BGP Auth key solely showing up in the Megaport portal, but not the AWS Console.</p>\n\n<p>Using some more advanced Cisco IOS troubleshooting commands then confirmed that the AWS Direct Connect peer router was indeed setting an BGP Auth MD5, which the local router was not accepting.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Router1#debug ip tcp transactions address 10.1.103.34\nMD5 received, but NOT expected from 10.1.103.34:24834 to 10.1.103.33:179\n\n</code></pre></div></div>\n\n<h1 id=\"fix\">Fix</h1>\n\n<p>After adding the MD5 Auth key to the customer’s BGP config, the BGP peer session came up right away.</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>router bgp 64970\nneighbor 10.1.103.34 remote-as AWS_ASN\nneighbor 10.1.103.34 password My5UpeR5eCRetPA55W0rD\n</code></pre></div></div>\n\n<p>I would have expected the above <em>“debug ip bgp”</em> command would have showed us some information regarding the missing BGP Auth key. But as there was no BGP Auth setup on the local node, there was no information about the Auth mismatch in the debug output.</p>\n\n<h1 id=\"improvements\">Improvements</h1>\n\n<p>Keep in mind, that in this case two AWS accounts are involved in this setup. Megaport owns account “A”, which includes the DX connection. Megaport then creates a Private VIF on this connection and shares it out with the customer into account “B”.\nIn this case account “A” can see the BGP MD5 auth key - which is needed to configure the physical router - while account “B” cannot.</p>\n\n<p>It is understandable that AWS does not necessarily want to show the actual MD5 auth value of a shared private VIF within the receiving. In e.g. Enterprise customer scenarios it is common, that account “A” would be owned by the network team - which configures the physical router, while account “B” is owned by an infrastructure team.</p>\n\n<p>Yet it would make sense that account “B” could at least see that an MD5 hash is set instead of making the user believe that it is empty.</p>\n",
"summary": "Troubleshooting a BGP neighbor issue of \"active open failed - tcb is not available\" on a Megaport Hosted VIF due to unset BGP MD5 Auth key",
"date_published": "2019-09-10T00:00:00-07:00",
"date_modified": "2019-09-10T00:00:00-07:00",
"image": "https://www.edge-cloud.net/content/uploads/2019/09/Hosted-VIF.jpg",
"authors": [
{
"name": "Christian Elsen"
}
],
"tags": ["AWS","Network","Direct-Connect"]
}
]
}