-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add hybrid internet examples and byoi example
- Loading branch information
Showing
29 changed files
with
752 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Hybrid Internet | ||
|
||
This is a example that can connect to the realworld. It creates 6 Internet exchanges, | ||
5 transit ASes, and 12 stub ASes same as mini-internet example. | ||
One of the ASes (`AS-99999`) is a hybrid autonomous system, | ||
which announces these prefixes; [`0.0.0.0/1`, `128.0.0.0/1`] | ||
to the emulator. Packets to these prefixes will be routed out to the | ||
real Internet. | ||
|
||
The emulator generated from this example is saved to a component file, | ||
and be used by several other examples as the basis. | ||
|
||
## Hybrid Autonomous System | ||
|
||
The example creates a real-world AS (`AS-99999`), which is | ||
a hybrid autonomous system for the emulator. The prefixes of the AS | ||
are configured as [`0.0.0.0/1`, `128.0.0.0/1`] and announce | ||
them inside the emulator. Packets (from inside the emulator) | ||
going to these networks will be routed to this AS, and | ||
then be forwarded to the real world. Returning packets | ||
will come back from the outside, enter the emulator at | ||
this AS, and be routed to its final destination inside | ||
the emulator. | ||
|
||
``` | ||
# Create hybrid AS. | ||
# AS99999 is the emulator's autonomous system that routes the traffics to the real-world internet | ||
as99999 = base.createAutonomousSystem(99999) | ||
as99999.createRealWorldRouter('rw-real-world', prefixes=['0.0.0.0/1', '128.0.0.0/1']).joinNetwork('ix100', '10.100.0.99') | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#!/usr/bin/env python3 | ||
# encoding: utf-8 | ||
|
||
from seedemu import * | ||
|
||
|
||
############################################################################### | ||
emu = Emulator() | ||
base = Base() | ||
routing = Routing() | ||
ebgp = Ebgp() | ||
ibgp = Ibgp() | ||
ospf = Ospf() | ||
web = WebService() | ||
ovpn = OpenVpnRemoteAccessProvider() | ||
|
||
|
||
############################################################################### | ||
|
||
ix100 = base.createInternetExchange(100) | ||
ix101 = base.createInternetExchange(101) | ||
ix102 = base.createInternetExchange(102) | ||
ix103 = base.createInternetExchange(103) | ||
ix104 = base.createInternetExchange(104) | ||
ix105 = base.createInternetExchange(105) | ||
|
||
# Customize names (for visualization purpose) | ||
ix100.getPeeringLan().setDisplayName('NYC-100') | ||
ix101.getPeeringLan().setDisplayName('San Jose-101') | ||
ix102.getPeeringLan().setDisplayName('Chicago-102') | ||
ix103.getPeeringLan().setDisplayName('Miami-103') | ||
ix104.getPeeringLan().setDisplayName('Boston-104') | ||
ix105.getPeeringLan().setDisplayName('Huston-105') | ||
|
||
|
||
############################################################################### | ||
# Create Transit Autonomous Systems | ||
|
||
## Tier 1 ASes | ||
Makers.makeTransitAs(base, 2, [100, 101, 102, 105], | ||
[(100, 101), (101, 102), (100, 105)] | ||
) | ||
|
||
Makers.makeTransitAs(base, 3, [100, 103, 104, 105], | ||
[(100, 103), (100, 105), (103, 105), (103, 104)] | ||
) | ||
|
||
Makers.makeTransitAs(base, 4, [100, 102, 104], | ||
[(100, 104), (102, 104)] | ||
) | ||
|
||
## Tier 2 ASes | ||
Makers.makeTransitAs(base, 11, [102, 105], [(102, 105)]) | ||
Makers.makeTransitAs(base, 12, [101, 104], [(101, 104)]) | ||
|
||
|
||
############################################################################### | ||
# Create single-homed stub ASes. "None" means create a host only | ||
|
||
Makers.makeStubAs(emu, base, 150, 100, [web, None]) | ||
Makers.makeStubAs(emu, base, 151, 100, [web, None]) | ||
|
||
Makers.makeStubAs(emu, base, 152, 101, [None, None]) | ||
Makers.makeStubAs(emu, base, 153, 101, [web, None, None]) | ||
|
||
Makers.makeStubAs(emu, base, 154, 102, [None, web]) | ||
|
||
Makers.makeStubAs(emu, base, 160, 103, [web, None]) | ||
Makers.makeStubAs(emu, base, 161, 103, [web, None]) | ||
Makers.makeStubAs(emu, base, 162, 103, [web, None]) | ||
|
||
Makers.makeStubAs(emu, base, 163, 104, [web, None]) | ||
Makers.makeStubAs(emu, base, 164, 104, [None, None]) | ||
|
||
Makers.makeStubAs(emu, base, 170, 105, [web, None]) | ||
Makers.makeStubAs(emu, base, 171, 105, [None]) | ||
|
||
# Create real-world AS. | ||
# AS11872 is the Syracuse University's autonomous system | ||
|
||
as11872 = base.createAutonomousSystem(11872) | ||
as11872.createRealWorldRouter('rw-11872-syr').joinNetwork('ix102', '10.102.0.118') | ||
|
||
|
||
############################################################################### | ||
# Create hybrid AS. | ||
# AS99999 is the emulator's autonomous system that routes the traffics to the real-world internet | ||
as99999 = base.createAutonomousSystem(99999) | ||
as99999.createRealWorldRouter('rw-real-world', prefixes=['0.0.0.0/1', '128.0.0.0/1']).joinNetwork('ix100', '10.100.0.99') | ||
############################################################################### | ||
|
||
|
||
############################################################################### | ||
# Peering via RS (route server). The default peering mode for RS is PeerRelationship.Peer, | ||
# which means each AS will only export its customers and their own prefixes. | ||
# We will use this peering relationship to peer all the ASes in an IX. | ||
# None of them will provide transit service for others. | ||
|
||
ebgp.addRsPeers(100, [2, 3, 4]) | ||
ebgp.addRsPeers(102, [2, 4]) | ||
ebgp.addRsPeers(104, [3, 4]) | ||
ebgp.addRsPeers(105, [2, 3]) | ||
|
||
# To buy transit services from another autonomous system, | ||
# we will use private peering | ||
|
||
ebgp.addPrivatePeerings(100, [2], [150, 151], PeerRelationship.Provider) | ||
ebgp.addPrivatePeerings(100, [3], [150, 99999], PeerRelationship.Provider) | ||
|
||
ebgp.addPrivatePeerings(101, [2], [12], PeerRelationship.Provider) | ||
ebgp.addPrivatePeerings(101, [12], [152, 153], PeerRelationship.Provider) | ||
|
||
ebgp.addPrivatePeerings(102, [2, 4], [11, 154], PeerRelationship.Provider) | ||
ebgp.addPrivatePeerings(102, [11], [154, 11872], PeerRelationship.Provider) | ||
|
||
ebgp.addPrivatePeerings(103, [3], [160, 161, 162 ], PeerRelationship.Provider) | ||
|
||
ebgp.addPrivatePeerings(104, [3, 4], [12], PeerRelationship.Provider) | ||
ebgp.addPrivatePeerings(104, [4], [163], PeerRelationship.Provider) | ||
ebgp.addPrivatePeerings(104, [12], [164], PeerRelationship.Provider) | ||
|
||
ebgp.addPrivatePeerings(105, [3], [11, 170], PeerRelationship.Provider) | ||
ebgp.addPrivatePeerings(105, [11], [171], PeerRelationship.Provider) | ||
|
||
|
||
############################################################################### | ||
|
||
# Add layers to the emulator | ||
emu.addLayer(base) | ||
emu.addLayer(routing) | ||
emu.addLayer(ebgp) | ||
emu.addLayer(ibgp) | ||
emu.addLayer(ospf) | ||
emu.addLayer(web) | ||
|
||
|
||
# Save it to a component file, so it can be used by other emulators | ||
emu.dump('base-component.bin') | ||
|
||
# Uncomment the following if you want to generate the final emulation files | ||
emu.render() | ||
#print(dns.getZone('.').getRecords()) | ||
emu.compile(Docker(), './output', override=True) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Building a DNS Infrastructure Component for Hybrid Internet | ||
|
||
This example demonstrates how we can build a DNS infrastructure as a component. | ||
We generate a hybrid DNS infrastructure and save it into a file as | ||
a DNS component. This component can be loaded into other emulators, which | ||
means deploying the DNS infrastructure in those emulators. | ||
|
||
In this hybrid DNS, we created the following nameservers: | ||
(TLD Name server is not exist in this hybrid DNS | ||
and the emulator only have second-level zones.) | ||
|
||
- Root server: `a-root-server` - shadows a real root server's records | ||
- `twitter.com` nameserver: `ns-twitter-com` | ||
- `google.com` nameserver: `ns-google-com` | ||
|
||
|
||
## Creating Virtual Nameserver for Root Server | ||
|
||
We will create the DNS infrastructure at the DNS layer, | ||
so each node created is a virtual node, which is not bound to | ||
any physical node. The example creates a real-world Root NameServer. | ||
Using .setRealRootNS(), we can announce the root server a real one. | ||
|
||
``` | ||
# Create a nameserver for the root zone. | ||
# Make it shadow the real root zone. | ||
dns.install('a-root-server').addZone('.').setRealRootNS() | ||
``` | ||
|
||
If it is set to the real root server, it will collect the records | ||
from the real world root server. | ||
|
||
``` | ||
path : seedemu/services/DomainNameService.py | ||
def __getRealRootRecords(self): | ||
"""! | ||
@brief Helper tool, get real-world prefix list for the current ans by | ||
RIPE RIS. | ||
@throw AssertionError if API failed. | ||
""" | ||
rules = [] | ||
rslt = requests.get(ROOT_ZONE_URL) | ||
assert rslt.status_code == 200, 'RIPEstat API returned non-200' | ||
rules_byte = rslt.iter_lines() | ||
for rule_byte in rules_byte: | ||
line_str:str = rule_byte.decode('utf-8') | ||
if not line_str.startswith('.'): | ||
rules.append(line_str) | ||
return rules | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/usr/bin/env python3 | ||
# encoding: utf-8 | ||
|
||
from seedemu import * | ||
|
||
emu = Emulator() | ||
|
||
# DNS | ||
########################################################### | ||
# Create a DNS layer | ||
dns = DomainNameService() | ||
|
||
# Create a nameserver for the root zone. | ||
# Make it shadow the real root zone. | ||
dns.install('a-root-server').addZone('.').setRealRootNS() | ||
|
||
# Create nameservers for second-level zones | ||
dns.install('ns-twitter-com').addZone('twitter.com.') | ||
dns.install('ns-google-com').addZone('google.com.') | ||
|
||
# Add records to zones | ||
dns.getZone('twitter.com.').addRecord('@ A 1.1.1.1') | ||
dns.getZone('google.com.').addRecord('@ A 2.2.2.2') | ||
|
||
# Customize the display names (for visualization purpose) | ||
emu.getVirtualNode('a-root-server').setDisplayName('Root-A') | ||
emu.getVirtualNode('b-root-server').setDisplayName('Root-B') | ||
emu.getVirtualNode('ns-twitter-com').setDisplayName('twitter.com') | ||
emu.getVirtualNode('ns-google-com').setDisplayName('google.com') | ||
|
||
########################################################### | ||
emu.addLayer(dns) | ||
emu.dump('hybrid-dns-component.bin') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Deploying DNS Infrastructure in Emulator | ||
|
||
This example demonstrates how we can build a DNS infrastructure as a | ||
component, and then deploy this infrastructure onto a pre-built | ||
emulator. This is based on the B02-mini-internet-with-dns. | ||
You can refer to the examples/B02-mini-internet-with-dns/Readme.md for detailed explain. | ||
The change from the mini-internet-with-dns to hybrid-internet-with-dns is | ||
the configuration of ldns. | ||
|
||
## Creating Local DNS Server for Hybrid Internet | ||
|
||
Creating a local DNS server is similar to creating | ||
other types of services. The local dns in hybrid internet emulator should | ||
add the emulator's zones to its forward zone. | ||
By doing this, the query can be forward to the | ||
name servers inside the emulator. | ||
|
||
``` | ||
##################################################################################### | ||
# Create a local DNS servers (virtual nodes). | ||
# Add forward zone so that the DNS queries from emulator can be forwarded to the emulator's Nameserver not the real ones. | ||
ldns = DomainNameCachingService() | ||
ldns.install('global-dns-1').addForwardZone('google.com.', 'ns-google-com').addForwardZone('twitter.com.', 'ns-twitter-com') | ||
``` |
66 changes: 66 additions & 0 deletions
66
examples/C02-hybrid-internet-with-dns/hybrid-internet-with-dns.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#!/usr/bin/env python3 | ||
# encoding: utf-8 | ||
|
||
from seedemu.core import Emulator, Binding, Filter, Action | ||
from seedemu.mergers import DEFAULT_MERGERS | ||
from seedemu.hooks import ResolvConfHook | ||
from seedemu.compiler import Docker | ||
from seedemu.services import DomainNameService, DomainNameCachingService, DomainNameCachingServer | ||
from seedemu.layers import Base | ||
|
||
emuA = Emulator() | ||
emuB = Emulator() | ||
|
||
# Load the pre-built components and merge them | ||
emuA.load('../00-hybrid-internet/base-component.bin') | ||
emuB.load('../01-hybrid-dns-component/hybrid-dns-component.bin') | ||
emu = emuA.merge(emuB, DEFAULT_MERGERS) | ||
|
||
|
||
##################################################################################### | ||
# Bind the virtual nodes in the DNS infrastructure layer to physical nodes. | ||
# Action.FIRST will look for the first acceptable node that satisfies the filter rule. | ||
# There are several other filters types that are not shown in this example. | ||
|
||
emu.addBinding(Binding('a-root-server', filter=Filter(asn=171), action=Action.FIRST)) | ||
emu.addBinding(Binding('ns-google-com', filter=Filter(asn=153), action=Action.FIRST)) | ||
emu.addBinding(Binding('ns-twitter-com', filter=Filter(asn=161), action=Action.FIRST)) | ||
##################################################################################### | ||
|
||
##################################################################################### | ||
# Create a local DNS servers (virtual nodes). | ||
# Add forward zone so that the DNS queries from emulator can be forwarded to the emulator's Nameserver not the real ones. | ||
ldns = DomainNameCachingService() | ||
ldns.install('global-dns-1').addForwardZone('google.com.', 'ns-google-com').addForwardZone('twitter.com.', 'ns-twitter-com') | ||
|
||
# Customize the display name (for visualization purpose) | ||
emu.getVirtualNode('global-dns-1').setDisplayName('Global DNS-1') | ||
|
||
# Create a new host in AS-153, use it to host the local DNS server. | ||
# We can also host it on an existing node. | ||
base: Base = emu.getLayer('Base') | ||
as153 = base.getAutonomousSystem(153) | ||
as153.createHost('local-dns-1').joinNetwork('net0', address = '10.153.0.53') | ||
|
||
# Bind the Local DNS virtual nodes to physical nodes | ||
emu.addBinding(Binding('global-dns-1', filter = Filter(asn=153, nodeName="local-dns-1"))) | ||
|
||
# Add 10.153.0.53 as the local DNS server for all the other nodes | ||
base.setNameServers(['10.153.0.53']) | ||
|
||
# Add the ldns layer | ||
emu.addLayer(ldns) | ||
|
||
# Dump to a file | ||
emu.dump('hybrid_base_with_dns.bin') | ||
|
||
|
||
############################################### | ||
# Render the emulation and further customization | ||
emu.render() | ||
|
||
############################################### | ||
# Render the emulation | ||
|
||
emu.compile(Docker(), './output', override=True) | ||
|
Oops, something went wrong.