Virtual Private Network (VPN) Examples in NeST¶
This directory contains examples to demonstrate how to use Virtual Private Network (VPN) in NeST
.
IMPORTANT
Before running the examples, you will need to install OpenVPN and Easy-RSA. You can do this by running the following command in your terminal:
sudo apt install openvpn easy-rsa
1. vpn-point-to-point-3.py¶
This program emulates point to point networks that connect two hosts h1
and h2
via two routers r1
and r2
. Five ping packets are sent from h1
to h2
once using Using the VPN endpoint address and once using Using the public address, and the success/failure of these packets is reported. It is similar to point-to-point-3.py
available in examples/basic-examples
, the only difference is that we use connect_vpn
API to create VPN tunnel between nodes.
1# SPDX-License-Identifier: GPL-2.0-only
2# Copyright (c) 2019-2023 NITK Surathkal
3
4########################
5# SHOULD BE RUN AS ROOT
6########################
7from nest.topology import *
8from nest.topology.network import Network
9from nest.topology.address_helper import AddressHelper
10from nest.topology.vpn import connect_vpn
11
12# This program emulates point to point networks that connect two hosts `h1`
13# and `h2` via two routers `r1` and `r2`. Five ping packets are sent from `h1`
14# to `h2` once using Using the VPN endpoint address and once using Using the public address,
15# and the success/failure of these packets is reported. It is similar to
16# `ah-point-to-point-3.py` available in `examples/address-helpers`, the only
17# difference is that we use `connect_vpn` API to create VPN tunnel between nodes.
18
19##############################################################################
20# Network Topology #
21# #
22# 5mbit, 5ms --> 5mbit, 5ms --> 5mbit, 5ms --> #
23# h1 -------------------- r1 -------------------- r2 -------------------- h2 #
24# <-- 10mbit, 100ms <-- 10mbit, 100ms <-- 10mbit, 100ms #
25# #
26##############################################################################
27
28# Create two hosts `h1` and `h2`, and two routers `r1` and `r2`
29h1 = Node("h1")
30h2 = Node("h2")
31r1 = Router("r1")
32r2 = Router("r2")
33
34# Set the IPv4 address for the networks.
35# Note: this example has three networks: one on the left of `r1`, second
36# between the two routers, and third on the right of `r2`.
37n1 = Network("192.168.1.0/24") # network on the left of `r1`
38n2 = Network("192.168.2.0/24") # network between two routers
39n3 = Network("192.168.3.0/24") # network on the right of `r2`
40
41# Connect `h1` to `r1`, `r1` to `r2`, and then `r2` to `h2`
42# `eth1` and `eth2` are the interfaces at `h1` and `h2`, respectively.
43# `etr1a` is the first interface at `r1` which connects it with `h1`
44# `etr1b` is the second interface at `r1` which connects it with `r2`
45# `etr2a` is the first interface at `r2` which connects it with `r1`
46# `etr2b` is the second interface at `r2` which connects it with `h2`
47(eth1, etr1a) = connect(h1, r1, network=n1)
48(etr1b, etr2a) = connect(r1, r2, network=n2)
49(etr2b, eth2) = connect(r2, h2, network=n3)
50
51# Assign IPv4 addresses to all the interfaces in the network.
52AddressHelper.assign_addresses()
53
54# Set the link attributes: `h1` --> `r1` --> `r2` --> `h2`
55eth1.set_attributes("5mbit", "5ms") # from `h1` to `r1`
56etr1b.set_attributes("5mbit", "5ms") # from `r1` to `r2`
57etr2b.set_attributes("5mbit", "5ms") # from `r2` to `h2`
58
59# Set the link attributes: `h2` --> `r2` --> `r1` --> `h1`
60eth2.set_attributes("10mbit", "100ms") # from `h2` to `r2`
61etr2a.set_attributes("10mbit", "100ms") # from `r2` to `r1`
62etr1a.set_attributes("10mbit", "100ms") # from `r1` to `h1`
63
64# Set default routes in `h1` and `h2`. Additionally, set default routes in
65# `r1` and `r2` so that the packets that cannot be forwarded based on the
66# entries in their routing table are sent via a default interface.
67h1.add_route("DEFAULT", eth1)
68h2.add_route("DEFAULT", eth2)
69r1.add_route("DEFAULT", etr1b)
70r2.add_route("DEFAULT", etr2a)
71
72# Set up the VPN network with a private IPv4 address range.
73# Make sure the chosen address range is not overlapping with any existing subnets on the network.
74vpn_network = Network("10.200.0.0/24")
75
76# For this address range the IP block 10.200.0.[0-3] is reserved for the OpenVPN server itself.
77# The IP block 10.200.0.[4-7] is assigned to the first client, and subsequent clients are allocated
78# consecutive IP addresses like 10.200.0.[8-11], [12-15], [16-19], and so on.
79
80# Connect the VPN server and multiple clients using the `connect_vpn` API.
81# By default, OpenVPN will work with Layer 3 and create a UDP tunnel using it's default port 1194.
82# The `network` parameter specifies the network to allocate VPN endpoint addresses from.
83# In this example, `vpn_network`, which is "10.200.0.0/24", is used for VPN endpoint addressing.
84
85# Node `h1` acts as the VPN server and is assigned the IP address 10.200.0.1.
86# When a client (e.g., `h2`) initiates a connection to the server on the designated port,
87# it is allocated the VPN endpoint IP address 10.200.0.6 after the initial TLS handshake.
88
89# Now, we establish the VPN connection between `h1` (VPN server) and `h2` (VPN client)
90# using the `connect_vpn` API.
91# The `connect_vpn` API returns the tunnel endpoints for `h1` (h1tun) and `h2` (h2tun).
92(h1tun, h2tun) = connect_vpn(h1, h2, network=vpn_network)
93
94# Once the VPN is established, we have created a secure alternate path between the nodes.
95# This path is addressed using the tunnel endpoints which belongs to same private network.
96# We have the flexibility to control which network traffic passes between the nodes over the VPN,
97# and which traffic should go independently, not using the VPN.
98
99# Using the VPN endpoint address to access `h2` from `h1`.
100h1.ping(h2tun.address)
101
102# Using the public address to access `h2` from `h1`.
103# This traffic will not be sent through the VPN.
104h1.ping(eth2.address)