Skip to content

Commit

Permalink
Merge pull request #148 from seed-labs/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
wonkr authored Apr 17, 2023
2 parents c513c77 + a917022 commit 9f3ac08
Show file tree
Hide file tree
Showing 47 changed files with 2,782 additions and 277 deletions.
2 changes: 1 addition & 1 deletion client/backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ import apiV1Router from './api/v1/main';
app.use(express.static('../frontend/public'));
app.use('/api/v1', apiV1Router);

app.listen(8080, '0.0.0.0');
app.listen(8080, '0.0.0.0');
7 changes: 7 additions & 0 deletions docker_images/seedemu-base/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM ubuntu:20.04

ARG DEBIAN_FRONTEND=noninteractive
RUN echo 'exec zsh' > /root/.bashrc

RUN apt-get update && apt-get install -y --no-install-recommends curl dnsutils ipcalc iproute2 iputils-ping jq mtr-tiny nano netcat tcpdump termshark vim-nox zsh
RUN curl -L https://grml.org/zsh/zshrc > /root/.zshrc
9 changes: 9 additions & 0 deletions docker_images/seedemu-base/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: "3.4"
services:
test:
build:
context: .
dockerfile: Dockerfile
image: handsonsecurity/seedemu-base


6 changes: 5 additions & 1 deletion docker_images/seedemu-ethereum/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ RUN make install
RUN make install-lcli
WORKDIR /

FROM ubuntu:20.04
FROM handsonsecurity/seedemu-base

RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common python3 python3-pip
RUN pip install web3

COPY --from=builder1 /go-ethereum/build/bin/geth /usr/bin
COPY --from=builder1 /go-ethereum/build/bin/bootnode /usr/bin
COPY --from=builder2 /usr/local/cargo/bin/lcli /usr/bin
Expand Down
7 changes: 7 additions & 0 deletions docker_images/seedemu-router/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM handsonsecurity/seedemu-base

ARG DEBIAN_FRONTEND=noninteractive

RUN mkdir -p /usr/share/doc/bird2/examples/
RUN touch /usr/share/doc/bird2/examples/bird.conf
RUN apt-get update && apt-get install -y --no-install-recommends bird2
9 changes: 9 additions & 0 deletions docker_images/seedemu-router/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: "3.4"
services:
test:
build:
context: .
dockerfile: Dockerfile
image: handsonsecurity/seedemu-router


120 changes: 120 additions & 0 deletions examples/C03-bring-your-own-internet/bring-your-own-internet-client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python3
# encoding: utf-8

from seedemu import *

for i in range(0, 4):
###############################################################################
emu = Emulator()
base = Base()
routing = Routing()
ebgp = Ebgp()
ibgp = Ibgp()
ospf = Ospf()
web = WebService()
dhcp = DHCPService()
ovpn = OpenVpnRemoteAccessProvider()

A=3*i
B=3*i
C=2*i
D=10*(i-1)

###############################################################################

ix100 = base.createInternetExchange(100)
ix101 = base.createInternetExchange(101)
ix102 = base.createInternetExchange(102+A)
ix103 = base.createInternetExchange(103+A)
ix104 = base.createInternetExchange(104+A)

###############################################################################
# Create Transit Autonomous Systems

## Tier 1 ASes
Makers.makeTransitAs(base, 2+B, [100, 101, 102+A],
[(100, 101), (101, 102+A)]
)

Makers.makeTransitAs(base, 3+B, [100, 103+A, 104+A],
[(100, 103+A), (103+A, 104+A)]
)

Makers.makeTransitAs(base, 4+B, [100, 102+A, 104+A],
[(100, 104+A), (102+A, 104+A)]
)

## Tier 2 ASes
Makers.makeTransitAs(base, 51+C, [102+A, 103+A], [(102+A, 103+A)])
Makers.makeTransitAs(base, 52+C, [101, 104+A], [(101, 104+A)])


###############################################################################
# Create single-homed stub ASes. "None" means create a host only

Makers.makeStubAs(emu, base, 165+D, 100, [web, None])
Makers.makeStubAs(emu, base, 166+D, 100, [web, dhcp, None])

Makers.makeStubAs(emu, base, 167+D, 101, [None, None])
Makers.makeStubAs(emu, base, 168+D, 101, [web, None, None])

Makers.makeStubAs(emu, base, 169+D, 102+A, [None, web])

Makers.makeStubAs(emu, base, 170+D, 103+A, [web, None])
Makers.makeStubAs(emu, base, 171+D, 103+A, [web, dhcp, None])
Makers.makeStubAs(emu, base, 172+D, 103+A, [web, None])

Makers.makeStubAs(emu, base, 173+D, 104+A, [web, None])
Makers.makeStubAs(emu, base, 174+D, 104+A, [None, None])

###############################################################################
# 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(102+A, [2+B, 4+B])
ebgp.addRsPeers(104+A, [3+B, 4+B])

# To buy transit services from another autonomous system,
# we will use private peering
ebgp.addPrivatePeering(100, 2+B, 3+B, PeerRelationship.Peer)
ebgp.addPrivatePeering(100, 3+B, 4+B, PeerRelationship.Peer)
ebgp.addPrivatePeering(100, 2+B, 4+B, PeerRelationship.Peer)


ebgp.addPrivatePeerings(100, [2+B], [165+D, 166+D], PeerRelationship.Provider)
ebgp.addPrivatePeerings(100, [3+B], [165+D], PeerRelationship.Provider)

ebgp.addPrivatePeerings(101, [2+B], [52+C], PeerRelationship.Provider)
ebgp.addPrivatePeerings(101, [52+C], [167+D, 168+D], PeerRelationship.Provider)

ebgp.addPrivatePeerings(102+A, [2+B, 4+B], [51+C, 169+D], PeerRelationship.Provider)
ebgp.addPrivatePeerings(102+A, [51+C], [169+D], PeerRelationship.Provider)

ebgp.addPrivatePeerings(103+A, [3+B], [170+D, 171+D, 172+D ], PeerRelationship.Provider)

ebgp.addPrivatePeerings(104+A, [3+B, 4+B], [52+C], PeerRelationship.Provider)
ebgp.addPrivatePeerings(104+A, [4+B], [173+D], PeerRelationship.Provider)
ebgp.addPrivatePeerings(104+A, [52+C], [174+D], PeerRelationship.Provider)

###############################################################################
base.setNameServers(['10.153.0.53'])

# Add layers to the emulator
emu.addLayer(base)
emu.addLayer(routing)
emu.addLayer(ebgp)
emu.addLayer(ibgp)
emu.addLayer(ospf)
emu.addLayer(web)
emu.addLayer(dhcp)

# 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_'+str(i), override=True)

13 changes: 13 additions & 0 deletions examples/scion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SCION Examples

This directory contains examples of using the SCION Internet architecture within the SEED-Emulator.

## Contributors
The following persons have contributed to the SCION emulation layers:
```
Lars-Christian Schulz (OVGU Magdeburg)
Thorben Krüger (OVGU Magdeburg)
Marten Gartner (OVGU Magdeburg)
Tony John (OVGU Magdeburg)
Robin Wehner (OVGU Magdeburg)
```
131 changes: 131 additions & 0 deletions examples/scion/S01-scion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# SCION Internet Architecture

SCION (Scalability, Control, and Isolation On Next-generation networks) is a new secure and reliable inter-domain routing protocol. SCION offers inter-domain path control with explicit trust by grouping ASes in Isolation Domains (ISDs) and embedding the cryptographically secured AS-level path into packet headers.

This example demonstrates how to create a small SCION Internet topology in the SEED emulator.

## Step 0: Install SCION PKI tool
We rely on an external tool called `scion-pki` to generate the cryptographic material necessary for SCION. You can install `scion-pki` in a number of ways:

### Install SCION Packages
[deb packages](https://docs.scionlab.org/content/install/pkg.html) are available for Debian and Ubuntu (x86, x86-64, arm32, and arm64).

Example installation on Ubuntu:
```bash
sudo apt-get install apt-transport-https ca-certificates
echo "deb [trusted=yes] https://packages.netsec.inf.ethz.ch/debian all main" | sudo tee /etc/apt/sources.list.d/scionlab.list
sudo apt-get update
sudo apt-get install scion-tools
```

### Compile from source
To compile from source you need an up-to-date version of the [Go programming language](https://go.dev/doc/install). The SCION source code is available on GitHub: https://github.com/scionproto/scion.
[Detailed build instructions](https://docs.scion.org/en/latest/build/setup.html) are available, but on Ubuntu systems it is usually enough to run the following commands.
```bash
git clone https://github.com/scionproto/scion.git
cd scion
go build -o bin ./scion-pki/cmd/scion-pki
```

Once you have installed a copy of `scion-pki` make sure to add it to the `PATH` environment variable before you continue.

## Step 1: Import emulator components for SCION

```python
from seedemu.compiler import Docker
from seedemu.core import Emulator
from seedemu.layers import ScionBase, ScionRouting, ScionIsd, Scion
from seedemu.layers.Scion import LinkType as ScLinkType
```

SCION support in the emulator relies on four emulation layers:
- The `ScionBase` layer extends the `Base` layer by adding Isolation Domains (ISDs). We will use the base layer to declare ISDs.
- The `ScionRouting` layer extends the `Routing` layer with support for SCION inter-AS routing. It installs and configures the SCION routing daemons on routers and control service hosts (see Step 3 below). Additionally, it installs the SCION host stack on all hosts.
- The `ScionIsd` layer manages the trust relationships between ASes. Each AS must be assigned to an ISD and given a role of either core or regular non-core AS. The `ScionIsd` layer invokes the `scion-pki` tool to generate the secret keys and certificates necessary for the SCION control plane.
- The `Scion` layer is the equivalent to the `Ebgp` layer for a BGP-based Internet. We use it to define links between ASes within and across ISDs.

Initialization is as usual:
```python
emu = Emulator()
base = ScionBase()
routing = ScionRouting()
scion_isd = ScionIsd()
scion = Scion()
```

## Step 2: Create isolation domains

```python
base.createIsolationDomain(1)
```

Each SCION AS is member of an isolation domain (ISD). ISDs manage the trust relationship between ASes. ASes in the same ISD have to trust each other to a higher degree than they would trust an AS from a foreign ISD. An ISD is identified by a globally unique numerical 16-bit ID. In this example we create a single ISD with identifier 1. In the emulator ISDs may optionally have a descriptive label as well.

## Step 3: Create autonomous systems

```python
as150 = base.createAutonomousSystem(150)
```

SCION ASes are created in the same way as BGP ASes. The `ScionBase` layer automatically returns SCION-enabled ASes. Within the emulator we use ASNs from the 32-bit BGP ASN namespace.

### Step 3.1: Add the AS to an ISD

```python
scion_isd.addIsdAs(1, 150, is_core=True)
```

We use the `ScionIsd` layer to assign AS 150 to the ISD we have created. By specifying `is_core=True` we make AS 150 a core AS of its ISD. Every ISD must have at least one core AS. Please note that it is currently not possible to assign an AS to multiple ISDs at the same time as the semantics of multi-ISD ASes have not been finalized yet in SCION.

For non-core ASes must additionally specify which core AS is signing the non-core AS's certificates with a call to `scion_isd.setCertIssuer()`.

### Step 3.2: Create the internal network and border routers

```python
as150.createNetwork('net0')
as150_router = as150.createRouter('br0')
as150_router.joinNetwork('net0').joinNetwork('ix100')
```

The `ScionRouting` layer upgrades all routers to SCION border routers, so we can add routers as usual. In this example, border router `br0` connects to three networks: (1) the internal network `net0`, (2) the internet exchange `ix100`, and (3) a cross-connect network to AS 153.

In addition to the border routers each SCION AS has at least one control service. The control service contains the beacon, certificate, and path servers necessary for SCION control plane operations. AS 150 as one control service called `cs1`.

```python
as150.createControlService('cs1').joinNetwork('net0')
```

## Step 4: Set up inter-AS routing

```python
scion.addIxLink(100, (1, 150), (1, 151), ScLinkType.Core)
scion.addIxLink(100, (1, 151), (1, 152), ScLinkType.Core)
scion.addIxLink(100, (1, 152), (1, 150), ScLinkType.Core)
scion.addXcLink((1, 150), (1, 153), ScLinkType.Transit)
```

Inter-AS routing in SCION is based on fixed "links" which are combined during the beaconing process to form end-to-end paths. SCION links are roughly equivalent to BGP peering sessions.

The `Scion` layer exposes two methods `addIxLink()` and `addXcLink()` for setting up SCION links over an IX and via direct cross-connect links, respectively. In both methods, we must specify the two endpoints of the link as pairs of ISD and ASN. The order of endpoints matters as SCION transit links are directional (for beaconing purposes, packets are still forwarded in both directions) from `a` to `b`. The reason we must name ASes by ASN and ISD is that only the pair of ISD and ASN uniquely identifies a SCION AS, i.e., a link from (1, 150) to (1, 151) is completely different from a hypothetical link between (2, 150) and (2, 151).

Besides the endpoints every SCION link has a type. Currently there are three types:
- `Core` links connect core ASes of the same or different ISDs. The core ASes of every ISD must all be reachable by one another via core links. The BGP analogy to core links is peering between Tier 1 ASes.
- `Transit` links connect core ASes to non-core ASes in the same ISD. They model Internet transit as sold from a provider AS to a customer AS.
- `Peering` links are used for any other type of peering between two ASes of the same or different ISDs.

In our example topology we have three core ASes with fully-meshed core-peering and an additional non-core AS 153 that obtains transit through AS 150.

## Step 5: Render and compile

```python
emu.addLayer(base)
emu.addLayer(routing)
emu.addLayer(scion_isd)
emu.addLayer(scion)

emu.render()

emu.compile(Docker(), './output')
```

Rendering and compiling the topology for Docker works as usual. Graphing the SCION links is supported as well.
69 changes: 69 additions & 0 deletions examples/scion/S01-scion/scion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python3

from seedemu.compiler import Docker
from seedemu.core import Emulator
from seedemu.layers import ScionBase, ScionRouting, ScionIsd, Scion
from seedemu.layers.Scion import LinkType as ScLinkType

# Initialize
emu = Emulator()
base = ScionBase()
routing = ScionRouting()
scion_isd = ScionIsd()
scion = Scion()

# SCION ISDs
base.createIsolationDomain(1)

# Internet Exchange
base.createInternetExchange(100)

# AS-150
as150 = base.createAutonomousSystem(150)
scion_isd.addIsdAs(1, 150, is_core=True)
as150.createNetwork('net0')
as150.createControlService('cs1').joinNetwork('net0')
as150_router = as150.createRouter('br0')
as150_router.joinNetwork('net0').joinNetwork('ix100')
as150_router.crossConnect(153, 'br0', '10.50.0.2/29')

# AS-151
as151 = base.createAutonomousSystem(151)
scion_isd.addIsdAs(1, 151, is_core=True)
as151.createNetwork('net0')
as151.createControlService('cs1').joinNetwork('net0')
as151.createRouter('br0').joinNetwork('net0').joinNetwork('ix100')

# AS-152
as152 = base.createAutonomousSystem(152)
scion_isd.addIsdAs(1, 152, is_core=True)
as152.createNetwork('net0')
as152.createControlService('cs1').joinNetwork('net0')
as152.createRouter('br0').joinNetwork('net0').joinNetwork('ix100')

# AS-153
as153 = base.createAutonomousSystem(153)
scion_isd.addIsdAs(1, 153, is_core=False)
scion_isd.setCertIssuer((1, 153), issuer=150)
as153.createNetwork('net0')
as153.createControlService('cs1').joinNetwork('net0')
as153_router = as153.createRouter('br0')
as153_router.joinNetwork('net0')
as153_router.crossConnect(150, 'br0', '10.50.0.3/29')

# Inter-AS routing
scion.addIxLink(100, (1, 150), (1, 151), ScLinkType.Core)
scion.addIxLink(100, (1, 151), (1, 152), ScLinkType.Core)
scion.addIxLink(100, (1, 152), (1, 150), ScLinkType.Core)
scion.addXcLink((1, 150), (1, 153), ScLinkType.Transit)

# Rendering
emu.addLayer(base)
emu.addLayer(routing)
emu.addLayer(scion_isd)
emu.addLayer(scion)

emu.render()

# Compilation
emu.compile(Docker(), './output')
Loading

0 comments on commit 9f3ac08

Please sign in to comment.