cn » projects »

Project 6 - DNS Amplification


In this assignment you will explore a class of Denial of Service (DoS) attacks known as amplification attacks. Although there are several protocols susceptible to amplification, for this project we will be using DNS amplification. After seeing the effects of the amplification attack on a target web server, you'll program an appliance to protect the web server from the attack.


Although the attack script we are providing cannot be used exactly as-is to attack a real server, the necessary principles are there. Therefore this project comes with two important caveats:
1) We are counting on you to be responsible and use the provided code ONLY to learn about DNS, amplification attacks and DoS, and protecting against these attacks, and NOT to use the code or the knowledge you gain to do anything malicious to others.
2) DO NOT DISTRIBUTE this code to others, so they cannot use it for any malicious purposes either.


Before we begin, let's take a look at the topology we'll be using for this project:

     svr (
  firewall (s1)
  switch (s2)
  /   |   \
 |    |    |
h1   h2    dns (

The host named svr will run the web server that we'll be attacking, and dns will run the innocent DNS server that we'll take advantage of to amplify our attack. The hosts h1 and h2 are ordinary client / end hosts that we can use to retrieve web pages from the svr or launch our DoS attack.  The switch s2 is an ordinary learning switch, but s1 is different. 

s1 is configured as a blacklist firewall with no rules, meaning all traffic is allowed through. It also has hooks in it to send DNS traffic to the controller where the function you write will inspect the traffic and either allow the DNS packets to pass through, or block them. The default behavior we've provided you to start with is to simply let all traffic through.  This firewall differs from the one in Project 2, in that you will define blocking behavior as a function, not as a list of rules read from a configuration file.

The two switches are connected to each other by a high-bandwidth link. The two servers (svr and dns) are connected by moderate-bandwidth links, and the hosts (h1 and h2) are connected by low-bandwidth links. In this project we observe how a host with limited bandwidth can use an amplification attack to saturate much larger network links.

Files and directory descriptions:

  • - script that runs a DNS amplification attack
  • - the topology for the mininet network
  • - shell script to launch the topology ( and start the DNS server and web server inside the mininet environment
  • - shell script to start pyretic
  • - contains a function that gets called on every DNS packet that the firewall (s1) sees; this is the only file you need to turn in, and should be the only one you modify
  • - the firewall (s1) policy: calls the function on on every DNS packet, and simply forwards all non-DNS traffic
  • - a standard learning switch policy, which is used for the regular switch (s2)
  • - the main file for the Pyretic controller
  • bind/ - this directory contains configuration files for the bind9 DNS server
  • http/ - this directory contains the web server and a web page that can be retrieved from the server
  • impacket/ - this directory contains the impacket library, which is used by the attack script
  • ryu-update/ - this directory contains the files needed to install the DNS parser into your Ryu configuration - already configured in the class VM
  • - this file is used to submit your file across the Internet to the auotgrader server.


If you have changed the number of cores in the course VM from one to anything else, please change this back. There are known issues with running with anything other than one core, but it's not known why it happens.  This project MUST be run on a single core VM.

First, update your git repository to get the Project 6 code:

git commit -a -m "Saving work"
git pull --rebase

For this project, we will be using a new automatic submission system provided by Udacity.  It relies on a Git submodule (think of it like a nested repository containing an external dependency) that needs to be initialized. Next, we need to initialize this submodule:

git submodule init
git submodule update

Provided you are using the course VM provided at the start of the class, this is all that's required by you to get started! In the highly unlikely event that you have been using your own development environment for this course, please post privately on Piazza for instructions on configuring this project's dependencies.  We highly discourage this practice, especially for this project.  It's far easier for all parties involved to use the course VM!


Once you have completed the configuration section, we can start the network and launch our attack. We created scripts to help launch the mininet topology and pyretic:

  1. In one terminal, ./ to start the mininet topology (
  2. In another terminal window, ./ to start pyretic

    Note: In the course of running things, you may see some messages in the pyretic output that say "ERROR PUSHING MESSAGE". It is safe to ignore this message, it does not affect the correctness of the project.

    These scripts should start the DNS server and web server inside the mininet environment automatically. Let's test those and make sure they're working.

  3. mininet> h1 dig @ (If that doesn't work, you can try running dig locally on the DNS server to see if it's a problem with the DNS server or with connectivity between the hosts. dns dig @localhost

  4. mininet> h2 ping -c 10 svr to confirm connectivity and see what the latency to the web server is. Make a note of the RTT times you see here.
  5. mininet> h2 wget to make sure the web server is working. Make a note of how long it took to download the file. It should be somewhere around 4 seconds.

    Now that you've seen the latency (RTT time) and throughput (time to wget the web page) to the web server in normal conditions, let's launch the attack and see how the web server fairs when it's being DoSed. The attack script we've provided issues a query for the domain but spoofs the web server's IP as the source address in the IP header, so the DNS server's replies will be sent to the web server instead of back to the attacking host. It takes two parameters. The first parameter is the address of the DNS server that will be used for the attack, and the second is the target of the attack (the web server, svr, in this case).

  6. mininet> h1 python ./ & Note the & on the end runs it in the background so we can keep working in Mininet while the attack continues.

    Now that the attack is going, let's see how the web server performs.

  7. mininet> h2 ping -c 10 svr Note that the RTT latency is now much larger than before. (It's possible you may even see some packet loss.)

  8. mininet> h2 wget This should now take much longer than it took originally.

    Now that you've seen what the attack does, it's time to modify the firewall (s1) to block it. For starters, let's just block all DNS traffic.  Before we modify the files, we need to clean up the simulation.  To do this, select your pyretic terminal and use CTRL+c to kill the process.  At the Mininet CLI, type exit to terminate the CLI, and then type sudo mn -c at the prompt to terminate the simulated topology and hosts.  You should issue these commands in your terminals whenever you intend to edit, and then restart the simulation with the two helper scripts in step 1. 

  9. has a function that will be called every time s1 receives a DNS packet. Modify it to change it's policy from allowing all DNS packets to blocking DNS responses. You can add your code to the function provided there, and you can also add any global variables you need. Some starter code is provided to parse the DNS packets for you, so you can use the variables the parser extracted from the packet for you. To allow a packet through, simply return it from the function; to block a packet, return None

    Note: Be careful with print statements in this function. The function is called on every single DNS packet that the switch sees, which is a lot when the attack is underway. Since output statements are also relatively slow to execute (compared to other lines of code), print statements that are executing on every single function call can potentially overload the controller itself, turning the DoS attack against the web server into a DoS on pyretic (even if your policy correctly drops the attack traffic). Conditional output may be okay, if the condition is infrequent enough. It also may be okay to use some print statements for debugging, if you like to debug that way, so long as you take them back out before testing to see if your policy actually works under attack conditions.  In general, once your submission is complete, you should remove all print statements before making your final submissions.

  10. Now start up mininet and test your policy. Run steps 1-8 again (you can skip step 3, running dig). If your policy works, you should now see comparable performance both before and during the attack. 

  11. There's just one problem now. Run mininet> svr dig @  Uh-oh! The web server can't issue legitimate DNS requests anymore! (You can also stop the attack and try this; it should still fail even when there is no attack.)

  12. We'd like to allow matched pairs of queries and their responses, while blocking any gratuitous responses (that is, responses to queries that we haven't seen). Modify to monitor DNS queries that pass through the firewall (and allow them to pass, of course), then to check any DNS responses against previously seen queries and allow them if they match an earlier query, but block them otherwise. DNS queries contain a transaction ID field with a randomly-assigned number. DNS responses also have a transaction ID that matches the transaction ID of the queries they are responding to. This is normally used to match responses to their queries, in the event that a host issues multiple queries in a short time, and you can also use it for matching responses to queries.

  13. Now test your new policy! Start mininet and pyretic and make sure the server can make DNS queries to the DNS server (step 11). Then run steps 1-8 again (you can skip step 3) to make sure it is still effective at blocking the attack.

What to turn in

This project takes advantage of a remote Udacity Autograder.  When you are finished, you can submit your file for grading with the command python The autograder will ask for a username and password, you should use your GT username and password (the same credentials used to log into T-Square).  You will also be asked after the first submission if you would like to Save the jwt?.  This is referring to your credentials, so entering y here will prevent you from having to enter your credentials on subsequent submissions.

The autograder is unit test based, and will return to you text based feedback indicating which tests have failed.  You can submit as many times as you like.  Your last submission will be the one counted for your final grade.

You MUST still submit your code to T-Square.  We will use this as an official backup in case there is a discrepancy with what the autograder has recorded and your expectations.

To recap, the desired workflow for turn-in looks like this:

  1. Implement and run your project as described in the project instructions 1 through 13.
  2. Once satisfied that your project is complete, submit it for autograding.
  3. If necessary, make changes to your code to account for the failed unit tests, re-running the autograder as necessary.
  4. When complete, submit the file that you used for your final autograder submission to T-Square.

What you can and cannot share

You CANNOT share the code you write for, or the output from the autograder.  You CAN share the output of the commands you run during the Instructions section of the project on piazza for the purposes of comparing results or troubleshooting.


  • Your VM should have ONLY ONE CPU configured. If you changed it, you will likely encounter timing issues.
  • In the unlikely event you are using your own VM, be sure to contact the instructors privately on Piazza for help configuring your VM properly.  For this project especially, it is highly discouraged to use your own environment.
  • This project is known to have some hardware dependency issues.  If for some reason the project is inconsistent with expectations or you run into errors, please try to isolate the VM as much as possible while working on this project (i.e. close background processes, close any other programs running in the host OS, etc.).  Please do not wait until the last minute to start this project, only to find your environment has an issue.  If you run into issues, please post on Piazza so the instructors and other students can help.  Feel free to make these posts public, as long as you aren't posting anything you are not permitted to share.
  • In the event you have issues reproducing the expected results on your system, you are still required to complete the project.  To mitigate this, we have provided an autograder that you can submit your project to for grading as many times as you wish before the deadline.  You can use the feedback provided to continue working on the project.  Note that your last submission will before the deadline is the one that will count for your final grade for the project.

Grading Rubric

2 ptsCorrect Submissionfor turning in, and significant effort has been made towards completing the assignment.  If your solution naively allows all traffic, a maximum of 1 point for the next rubric item will be awarded, resulting in a maximum of 3 points.
4 ptsFirewall Implementationfor allowing the web server to make DNS queries and receive the legitimate responses to those queries.  For full credit, the firewall should be well formed, for example it should allow only a single response to a legitimate query, multiple outstanding queries should be supported, etc.
4 ptsBlocking the Attackfor successfully blocking DNS amplification attacks against the web server.