Prelab 01
Table of contents
Prelab
In this prelab, we will get started with setting things up to spin up a virtual network using Docker, and accessing the machines on it.
Login to the server
If you will be using our class server, then login using ssh. If you have set things up correctly, you should be able to just use ssh netsec.
Test access to Docker
To make sure the server has been appropriately configured, please try to run the docker hello world instance. To do so, use:
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which
sent it to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
If you do not see the message above, then please contact me as soon as possible so I can take a look.
Get the lab
For this lab, we will be working in the directory 00_Prelab01 of the netsec-labs repository. You should be working in your own private repository that you have synced with the class public repository.
Generating your .env file
Before we spin up our containers, there are some configuration variables that we need to generate. To do so, please run the gen_env_file.sh script from the prelab repository directory as follows:
$ ./gen_env_file.sh
If run correctly, three files will appear:
.env(hidden file - usels -alto see it) contains yourUIDandGIDvariables.connect_hostA.sha utility script to connect tohostA.connect_hostB.sha utility script to connect tohostB.
Spin up the containers
Now you are ready to spin up the containers for this prelab. First, make sure that you are in the 00_Prelab01 directory of your repository. Then spin up the containers using:
$ docker compose up -d
...
[+] Running 3/3
✔ Network local-net Created 0.1s
✔ Container hostB Started 0.1s
✔ Container hostA Started 0.1s
Alternatively, you can also use dcupd as an alias to docker compose up -d. If you see the output, your environment is fully setup and are running. If you run into any issues, then please contact me as soon as possible.
The fist time you run the environment, it needs to download the virtual machine images, so it might take a while. After that, it should be faster, unless occasionally when I patch the image.
Check your images
First, check on your environment using:
$ docker compose ls
NAME STATUS CONFIG FILES
prelab01 running(2) <remove for privacy>
If things look good, check on your running containers as follows:
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS
hostA netsos/rhit-netsec:latest "bash -c ' groupadd …" hostA About a minute ago Up About a minute
hostB netsos/rhit-netsec:latest "bash -c ' groupadd …" hostB About a minute ago Up About a minute
If all looks good, move on to the next step.
You can also check the logs of those containers using docker compose logs or dcl. Finally, you can watch the logs update using docker compose logs -f or dcl -f. This will take over your terminal input to watch for any changes in the logs. To exit the logs watch, you can use C-c (i.e., control-c) to go back to your terminal input.
Access the containers
Next, let’s ssh into one of the containers to make sure things are okay. In your 00_Prelab01 directory, use the following:
$ ./connect_hostA.sh
This will drop you into a shell on the hostA container. You will login in as the user netsec, but you have password-less sudo privileges on the container. Try the same on hostB to make sure that it is up as well.
Shared volumes
In this 00_Prelab01 directory, you will notice that there is a volumes/ directory. Once you spin up your containers, this directory will mounted by your containers, i.e., it will be shared between your host machine and the containers. Any changes the containers make to the directory will impact the volumes/ directory under 00_Prelab01/.
Test this out. On your host server (i.e., on the class server), add a dummy file to the volumes/ directory.
$ echo "Hello World" > volumes/test.txt
Then, access any one of the containers and try to read the file:
$ cat /volumes/test.txt
Hello World
Note that in the containers, that directory appears under /volumes.
You will mostly use the volumes/ directory to compile your code and push it onto the containers for testing. You will also be using it to collect network packet data from your running containers.
Test networking
Now on to the most relevant parts of this. Let’s make sure that our network is working correctly.
Checking on hostA
Login to the hostA container as we have showed above. Then from there, check your network interfaces and network configuration:
(hostA) $ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host proto kernel_lo
valid_lft forever preferred_lft forever
2: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether de:3c:06:f0:77:b4 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.10.0.4/24 brd 10.10.0.255 scope global eth0
valid_lft forever preferred_lft forever
You can see that the container has two interfaces:
lo: This is the loopback interface. By default, it’s IP address is127.0.0.1.eth0: This is the virtual Network Interface Card (NIC) connected to your subnetwork. Notice its IP address, it is10.10.0.4.
Your IP address might be different from mine depending on your container configuration. That is totally ok. Replace all values with the corresponding ones obtained from the command or from peeking into the Docker compose file.
Reaching hostB
From hostA, try to ping hostB to make sure that the route it setup. To do so, use:
(hostA) $ ping -c1 hostB
PING hostB (10.10.0.5) 56(84) bytes of data.
64 bytes from hostB.local-net (10.10.0.5): icmp_seq=1 ttl=64 time=0.127 ms
--- hostB ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.127/0.127/0.127/0.000 ms
Note that you can also reach hostB using its IP address as follows:
(hostA) $ ping -c1 10.10.0.5
Bidirectional communication
Next, let’s make sure we can communicate both ways between A and B. You will need to flex your tmux muscles here. Launch a tmux session in the prelab directory, then split it into two panes (horizontally or vertically, depending on your preference). Then in one pane, login to hostA, while on the other pane, login hostB. We will make hostA our server while hostB will be our client.
On hostA, use:
(hostA) $ nc -l 1234
This will start a netcat TCP server running on port 1234.
One hostB, connect to that server as follows:
(hostB) $ nc hostA 1234
Now, anything you type on hostB will show on the screen under hostA. To close the connection on hostB, simply hit C-c (recall, this means ctrl and c). This will close on both ends.
Talking to the outside world
Finally, let’s make sure that you can reach the outside world (we’re not always going to have that option open, but it is for now). Let’s see how your route to 1.1.1.1 looks like. To do so, on either container, do the following:
(hostA) $ traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
1 10.11.1.1 (10.11.1.1) 0.048 ms 0.017 ms 0.012 ms
2 137.112.104.3 (137.112.104.3) 0.398 ms 0.458 ms 0.467 ms
3 137.112.9.156 (137.112.9.156) 0.118 ms 0.103 ms 0.104 ms
4 * * *
5 199.8.48.102 (199.8.48.102) 2.026 ms 2.049 ms 2.014 ms
6 ae-0.2022.rtr.ll.indiana.gigapop.net (199.8.220.1) 1.976 ms 2.757 ms 2.772 ms
7 206.53.139.34 (206.53.139.34) 2.963 ms 2.568 ms 2.902 ms
8 one.one.one.one (1.1.1.1) 3.487 ms 3.501 ms 3.378 ms
Take down your containers
Once you are done, shut down your containers using:
$ docker compose down
Alternatively, you can also use the dcdn shortcut. After a while, the containers should be down and the network will be removed.
Please note that the containers are ephemeral; anything you install or change in the container will be lost after shutting it down. If you need files to persist beyond the lifetime of a container, then write them to /volumes/.
If you are not actively working on this class, please do take down your docker environments, to make room for other students in the class.