% ============================================================================ %
\nn{Introduction}
In this day and age, there has probably been nothing else considered as
inevitable and impactful on one's personal or professional life, media,
politics, culture or science as reliable Internet connection, allowing seemless
interaction and access to information.
Networking infrastructure powering the Internet has been the target of various
attacks almost since day one. While the early network interconnections had
been based on mutual trust and strong sharing spirit for advancement of humanity, with
increasing amount of participants from different backgrounds (essentially
democratization) and proliferating deeds of mischief, trust could no longer be
taken for granted.
Although trolling has always been an integral part of the Internet culture, it
had not taken long until criminals found their way into the online world with
the intention of taking advantage of lacking legislation and collecting easy
(though huge) economic profit. Furthermore, another popular activity has become
causing real harm to anybody on the way with the sense of lawlessness.

It is this willful damage in its many shapes and forms brought upon the
Internet service providers and users that our thesis deals with. What we have
commonly observed as being used in the wild in recent years may be called
attack 'professionalizing', by which we mean that the tools typically available
10 years ago cannot match to practically anything you can get ready in minutes
to cause real harm today. Since the networks compose the medium of
communication, it is essential they remained secured and protected, which in
fact poses a challenging task for us of coming up with new solutions to rapidly
evolving problem.

On the side of the user, unavailability of the service often means inability to
proceed with fulfilling their tasks. For the provider, an attack that cripples
the network or its resources means inability to provide the promised service.

We would like to take a look on some of the conventional methods and tools
which attackers resort to as well as methods and tools both users and network
operators may (and should) utilise to protect the network. The main objectives
of our thesis aim at researching key ways of DoS attack mitigations and
performing a DoS attack and a BGP blackhole reaction simulation.

Our thesis comprises two main parts - theoretical and practical. The
theoretical part discusses relevant context, different types of attack methods
and tools, mitigation attack methods and tools. The practical part describes a
simulated simple topology and an attack in lab conditions.
In the first two sections of the theoretical part, we were focused on attack
definitions and providing context. Section \ref{sec:attack-methods} attempts to
categorise attack methods based on several metrics and explain some of the
mentioned. The fourth section presents a list of some of the popular DoS tools
that are available.  Next on, the \autoref{sec:mitigation-methods} traces
various ways to mitigate attacks, both on the user and provider level and the
final section of the theoretical part, \autoref{sec:mitigation-tools}, marks
out some of the tools that can be used to mitigate an attack.
First of the practical part, \autoref{sec:infrastructure-set-up-description} gives an
overview of the tools used to construct the lab infrastructure and configure
the systems, as well as specifics of the configuration. It also focuses on
setting up the infrastructure and the tools and processes to achieve a
reproducible outcome. In \autoref{sec:mitigation-tools-set-up}, we set up
mitigation tools in preparation of an attack. In
\autoref{sec:attack-tools-set-up} we go through the process of preparing attack
tools. The final section \ref{sec:performing-an-attack} describes performing the attack
itself.


% ============================================================================ %
\part{Theoretical part}


\n{1}{Definition} \label{sec:definition}
While denial of service can be caused in a multitude of different ways and
impact any part of the stack, we are predominantly going to look at the ones
pertaining Internet networks. First, we shall define what a denial of service
(\it{DoS}) attack in fact \it{is} and we can achieve it by understanding what
it does.

A DoS attack is an action that harms a \it{service} in such a way that it can
no longer serve legitimate requests as a result of being occupied by bogus or
excessive requests from the attacker.

A DDoS is a DoS that is distributed among many participant devices (and
operators).

\begin{figure}[!hbt]
  \centering
\begin{tikzpicture}
  \draw (1,1)[color=red!60,thick,fill=red!15] circle (2.2cm);
  \draw (0.4,0.2pt) node[below left] {$DoS$};
  \draw (1,1)[dashed,fill=purple!25] circle (1.2cm);
  \draw (1,5pt) node[above] {$DDoS$};
\end{tikzpicture}
\caption{Illustration of relationship between DoS and DDoS attacks.}
\end{figure}

The devices participating are generally also victims in this, most of the
attacks are performed with open DNS resolvers, home routers left to rot by
vendors, misconfigured web services or IoT devices as involuntary
participants. All one has to do is open Shodan and look for specific ports open
(ports of protocols with good reflection ratio such as DNS, CLDAP, or SSDP),
start probing and then reap the easy harvest. A quick search for devices
running with port 123 (NTP) open is certain to return a mind-blowing number
\cite{ShodanNTPd}.

\n{1}{Context} \label{sec:context}
In the last decade only we have witnessed many large DoS/DDoS attacks, some of
them against critical infrastructure services like cloud hosting, DNS, git
hosting services or even CCTV cameras. All of the attacks weaponized poorly
managed endpoints, unpatched IoT devices or
malware-infected-hosts-turned-botnet-zombies. The intensity and frequency have
also been sharply increasing with the latest of attacks passing over the Tbps
threshold (Akamai mitigated a 1.44Tbps DDoS in 2020
\cite{akamai2020ddosretrospect}), with data from Cisco Annual Internet Report
showing that overall there was a \textbf{776\%} growth in attacks between 100
Gbps and 400 Gbps from 2018 to 2019, and with predictions for the total number
of DDoS attacks to double from 7.9 million in 2018 to 15.4 million by 2023
\cite{cisco2020report}. The question is: why?

The motifs will probably more often than not stay a mystery; however, a
proliferation of DDoS-for-hire websites \cite{Santanna2018BooterLG}, even on
\emph{clearnet}\footnotemark, points us to a plausible answer.

\footnotetext{the surface web; i.e.\ not even attempting to hide}

Somebody is making money selling abusive services that are being used for
putting competitors out of business or just plain extortion. According to
Akamai, extortion attacks have seen a widespread return, with a new wave
launching in mid-August 2020 \cite{akamai2021ddos}.

Akamai went on to note that DDoS attackers are expanding their reach across
geographies and industries, with the number of targeted entities now being 57\%
higher than the year before that.


\n{1}{Attack methods} \label{sec:attack-methods}
There are generally several different ways to categorise a method of
attack:
\begin{description}
  \item[By layers, in which the attacks are performed:]\
\begin{itemize}
\item Link layer
\item Internet layer
\item Transport layer
\item Application layer
\end{itemize}
  \end{description}

\begin{description}
  \item[By the nature of their distribution:]\
  \begin{description}
    \item[distributed] the effort is collectively advanced by a group of
      devices
      \begin{enumerate}
        \item deliberate
        \begin{enumerate}
          \item remotely coordinated devices (IRC C\&C) - so called \it{voluntary botnets}
          \item each operating their own computer, performing a premeditated operation
            in a synchronized manner
        \end{enumerate}
        \item involuntary - hijacked devices
      \end{enumerate}
    \item[not distributed] there is a single source of badness
  \end{description}
\end{description}

\begin{description}
  \item [By the kind of remoteness necessary to successfully execute the
    attack:]\
  \begin{description}
    \item[close-proximity] (physical engagement, i.e. sabotage) requires physical
      presence in/near e.g. a datacenter, networking equipment (cutting cables,
      playing a pyro)
    \item[local network access] such as over a WiFi access point or on LAN
    \item[remote] such as over the Internet
  \end{description}
\end{description}

\begin{description}
  \item[By specific features:]\
  \begin{itemize}
    \item IP fragmentation
    \item SYN flood - a rapid sequence of TCP protocol SYN messages
    \item volumetric DDoS attack
    \item amplification attack (also called 'reflection attack')
    \begin{itemize}
      \item memcached (up to 1:51200)
      \item DNS with a formula \cite{akamaidnsampl}
        \rov[DNSamplificationformula]{R = answer size / query size}
      \item SNMP (theoretically 1:650)
      \item NTP
    \end{itemize}
    \item exploits
    \begin{itemize}
      \item 0days
      \item simply running unpatched versions of software
    \end{itemize}
    \item physical network destruction/crippling
  \end{itemize}
\end{description}

\n{2}{IP fragmentation}
This is the type of attack whereby an attacker attempts to send a fragmented
payload (TCP, UDP or even ICMP) that the client is supposed to reassemble at
the destination, by doing of which their system resources (CPU and mainly
memory) would quickly get depleted, ultimately crashing the host.

It is usually necessary for IP datagrams (packets) to get fragmented in order
to be transmitted over the network. If a packet being sent is larger than the
maximum transmission unit (MTU) of the receiving side (e.g. a server), it has
to be fragmented to be transmitted completely.

ICMP and UDP fragmentation usually involves packets larger than the MTU, a
simple attempt to overwhelm the receiver that is unable to reassemble such
packets, ideally even accompanied by a buffer overflow that the attacker can
exploit further. Fragmenting TCP segments, on the other hand, targets the TCP
mechanism for reassembly. Reasonably recent Linux kernel implements protection
against this \cite{linuxretransmission}.
In either case, this is a network layer attack, since it targets the way the
Internet Protocol requires data to be transmitted and processed.

\n{2}{SYN flood} \label{synfloodattack}
To establish a TCP connection, a \emph{three way handshake} must be
performed.\\
That is the opening sequence of a TCP connection that any two machines -
let's call them TCP A and TCP B - perform, whereby TCP A wanting to talk
sends a \emph{segment} with a SYN control flag, TCP B (assuming also willing to
communicate) responds with a segment with SYN and ACK control flags set and
finally, TCP A answers with a final ACK \cite{rfc793tcp}.

Using \texttt{tcpdump} we can capture an outgoing SYN packet on interface
\texttt{enp0s31f6}.
\begin{verbatim}
# tcpdump -Q out -n -N -c 1 -v -i enp0s31f6 "tcp[tcpflags] == tcp-syn"
\end{verbatim}

A malicious actor is able to misuse the handshake mechanism by posing as a
legitimate \emph{client} (or rather many legitimate clients) and sending large
number of SYN segments to a \emph{server} willing to establish a connection
(\it{LISTEN} state). The server replies with a [SYN, ACK], which is a combined
acknowledgement of the client's request \it{and} a synchronization request of
its own.  The client responds back with an ACK and then the connection reaches
the \it{ESTABLISHED} state.

There is a state in which a handshake is in the process but connection has not
yet been ESTABLISHED. These connections are referred to as embryonic
(half-formed) sessions. That is precisely what happens when an attacker sends
many SYNs but stops there and leaves the connection hanging.

One particularly sly method aimed at causing as much network congestion near/at
the victim as possible is setting a private IP address (these are unroutable,
or rather, \it{should not be routed} over public Internet) or an address from
deallocated space as the source IP address. For the sake of the argument
suppose it is an address from deallocated space, what then ends up happening is
the server responds with a [SYN, ACK] and since no response comes from an address
that's not currently allocated to a customer (no response \it{can} come because
nobody is using it), TCP just assumes that the packets lost on the
way and attempts packet \it{retransmission} \cite{rfc6298}.
Obviously, this cannot yield a successful result so in the end the server just
added onto the already congesting network.

Current recommended practice as per RFC 3704 is to enable strict mode when
possible to prevent IP spoofing from DDoS attacks. If asymmetric routing or
other kind of complicated routing is used, then loose mode is recommended
\cite{rfc3704multihomed}.

That way the spoofed traffic never leaves the source network (responsibility of
the transit provider/ISP) and does not aggregate on a single host's interface.
For this to be a reality the adoption rate of the subject RFC recommendations
would need to see a proper increase.

As is true for anything, if countermeasures are set up improperly, legitimate
traffic could end up being blocked as a result.

\n{2}{Amplified Reflection Attack}
The name suggests this type of attack is based on two concepts: amplification and
reflection. The amplification part pertains the fact that certain protocols
answer even a relatively small query with a sizable response.
The reflection part is usually taking advantage of session-less protocols.
One such protocol is UDP with session-less meaning that hosts are not required
to first establish a \it{session} to communicate, a response is simply sent
back to the address that the packet arrives from (source address).
Except for the fact that if a malicious player is not interested in
communication but only wants to cause harm, a packet's source address does not
necessarily have to, in fact \it{cannot} (from an attacker's point of view)
correspond to the source address of their machine.

Since overwriting fields of the packet header (where the information important
to routing reside) is trivial and there's nothing easier than supplying a UDP
request with (either a bogus but more commonly) a victim IP address as the
source address instead of our own that's present there by default.
The response is then returned \it{back} - not to the actual sender, but simply
according to the source address.\\
Since UDP has no concept of a \it{connection} or any verification mechanism,
the response arrives at the door of the victim that has never asked for it - in
the worst case an unsolicited pile of them.

This is why the three-way handshake is used with TCP, which was developed later
than UDP, as it reduces the possibility of false connections.

The goal of the attacker is then clear: get the largest possible response and
have it delivered to the victim (in good faith of the server even).

Spoofing the source address is done with the purpose of evading detection as a
blocking or rate-limiting mechanism at the destination would likely identify any
above-threshold-number requests coming from a single IP and ban them, thus
decreasing the impact of the attack when the intent was to achieve congestion
at the designated destination - the victim.

A perfect example for how bad this can get is unpatched or misconfigured
\texttt{memcached} software, that is very commonly being used as e.g. a database
caching system and has an option to listen on UDP port.
Cloudflare say they have witnessed amplification factors up to 51200 times
\cite{cfmemcached}.

As has already been mentioned in ~\ref{synfloodattack}, this entire suite of issues
could be if not entirely prevented then largely mitigated if the very sound
recommendations of RFC 3704 gained greater adoption among ISPs.

Until then, brace yourselves for the next assault.


\n{2}{Slowloris} \label{slowloris}
The principle of this attack is to first open as many connections as
possible, aiming to fill the capacity of the server, and then keep them
open for as long as possible by sending periodic keep-alive packets.\\
This attack works at the application layer but the principle can easily be
reapplied elsewhere.

\n{2}{BGP hijacking}
BGP is an inter-Autonomous System routing protocol, whose primary function is
to exchange network reachability information with other BGP systems.
Furthermore, this network reachability information "includes information on the
list of Autonomous Systems (ASes) that reachability information traverses.
This information is sufficient for constructing a graph of AS connectivity for
this reachability, from which routing loops may be pruned and, at the AS level,
some policy decisions may be enforced. This information is sufficient for
constructing a graph of AS connectivity for this reachability, from which
routing loops may be pruned and, at the AS level, some policy decisions may be
enforced." \cite{rfc4271bgp4}.

BGP hijacking, in some places spoken of as prefix hijacking, route hijacking or
IP hijacking is a result of a intentional or unintentional misbehavior in
which a malicious or misconfigured BGP router originates a route to an IP
prefix it does not own and Zhang et al. find it is becoming an increasingly
serious security problem in the Internet \cite{Zhang2007PracticalDA}.

\n{2}{Low-rate DoS on BGP}
As shown by Zhang et al. in their "Low-Rate TCP-Targeted DoS Attack Disrupts
Internet Routing" paper, BGP itself is prone to a variation of slowloris due to
the fact that it runs over TCP for reliability. Importantly, this is a
low-bandwidth attack and a more difficult one to detect because of that.
Beyond the attack's ability to further slow down the already slow BGP
convergence process during route changes, it can cause a BGP session reset. For
the BGP session to be reset, the induced congestion by attack traffic needs to
last sufficiently long to cause the BGP Hold Timer to expire \cite{Zhang2007LowRateTD}.
On top of all that, this attack is especially hideous in that it can be launched
remotely from end hosts without access to routers or the ability to send
traffic directly to them.


\n{1}{Attack tools} \label{sec:attack-tools}
Believe it or not there actually exists a DDoS attack tools topic on
GitHub
\url{https://github.com/topics/ddos-attack-tools?o=desc\&s=stars}.

\n{2}{HOIC}
LOIC successor HTTP flooding High Orbit Ion Cannon, affectionately
referred to as 'HOIC' is a \emph{free software}\footnotemark tool which enables
one to stress-test the robustness of their infrastructure by applying
enormous pressure on the designated target in form of high number of requests.
It operates with HTTP and users are able to send 'GET' or 'POST' requests to as
many as 256 sites simultaneously.
While it is relatively easily defeated by a WAF (see \ref{waf}), the
possibility to target many sites at once makes it possible for users to
coordinate the attack, consequently making detection and mitigation efforts
more difficult.

\footnotetext{free as both in freedom and free beer}

\n{2}{slowloris.py}
\texttt{slowloris.py} is a python script available
from~\url{github.com/gkbrk/slowloris} that is able to perform a slowloris
attack. It seeks to extinguish file descriptors needed for opening new
connections on the server and then keeping the connections for as long as it can.\\
Legitimate requests cannot be served as a result, since there is no way for the
server to facilitate them until resources bound by bogus requests are freed,
i.e. the attack ceases to be.

\n{2}{Metasploit Framework}
Metasploit is a penetration testing framework with an open source community
version and a commercial version (Metasploit Unleashed) available. It enables
security researchers to automate workflows of probing vulnerable services or
devices via use of so called modules - smaller programs with definable inputs
that perform prefined actions. Modules are often community-contributed and one
can even write a module ourselves.a The SYN-flooding funtionality has been
implemented - \texttt{aux/synflood} an auxiliary module. Auxiliary modules do
not execute payloads and perform arbitrary actions that may not be related to
exploitation, such as scanning, fuzzing and denial of service attacks
\cite{metasploit}.

\n{2}{Web browser}
Depending on our point of view (more fittingly, our scaling
capabilities), sometimes all that is needed to cause a denial of
service is tons of people behind a web browser.\\
Numerous requests quickly overload a small server, eventually causing it
respond so slowly that the impact is indistinguishable from a DoS attack.

That is because in principle \it{a DoS attack} is practically the same
thing as discussed above, the only difference is the malicious intent,
imperceivable to a machine.


\n{1}{Mitigation methods} \label{sec:mitigation-methods}
Drastic times require drastic measures and since a DDoS attacks coming
at us practically every other month classify as
\it{drastic} quite easily, we're forced to act accordingly
\cite{akamai2021ddos}.

Still, it is more reasonable to prepare than to improvise, therefore the
following write-up mentions of commonly used mitigation methods at different
levels, from a hobbyist server to an e-commerce service to an ISP. The list is
inconclusive and of course if reading this at a later date, always cross-check
with the current best practices at the time.

\n{2}{Blackhole routing (black-holing, null routing)}
Black-holing is a technique that instructs routers that traffic for a specific
prefix is to be routed to the null interface, i.e. be dropped and is used to
cut attack traffic before it reaches the destination AS.\\
Assuming the router is properly configured to direct RFC 1918 destined traffic
to a null interface, traffic destined to the attacked network gets dropped,
making the attacked network unreachable to the attacker and everyone else.
Matter of factly, we actually conclude the DoS for the attacker
ourselves.\cite{rfc1918}\cite{rfc3882}

In case of a DDoS, the traffic is likely to come from all over the world
\cite{akamai2020ddosretrospect}.
The idea here is to announce to our upstream (ingress provider) that supports RTBH
(remotely-triggered black hole) signalling (critical) that we do not need any
traffic for the victim IP anymore. They would then propagate the announcement
further and in no time we'd stop seeing malicious traffic coming to a victim IP
in our network.
In fact, we would not see any traffic coming to the victim anymore, because we
just broadcast a message that we do not wish to receive traffic for it.
For the entire time we're announcing it, the victim host stays unreachable.

We should make sure to announce the smallest possible prefix to minimise the
collateral damage. Generally, a /21 or /22 prefix is assigned to an AS (the
average prefix per AS being 22.7866 as of 11 May 2021 \cite{prefixavgsize})
announcing a black hole for such a large space would likely cause more damage
than the attack itself.

To reduce BGP overhead, prefixes are usually announced aggregated, with the
exception of "a~situation", such as when we wish to only stop receiving traffic
for one IP address. Smallest possible accepted prefix size tends to be /24
(which is still a lot) with average prefix size updated being 23.11
\cite{prefixavgupdatedsize}, however, some upstream providers might even
support a /32 in case of emergency, effectively dropping traffic only for the
victim.

When an attack hits, all we have to do is:
\begin{enumerate}
  \item deaggregate prefixes
  \item withdraw hit prefixes.
\end{enumerate}

In case our upstream provider did not support RTBH and we could not lose them
(e.g. the only one around), we could still make use of Team Cymru's new
BGP-based solution that distributes routes to participating networks using only
vetted information about current and ongoing unwanted traffic - the \b{Unwanted
Traffic Removal Service} (UTRS). It is a free community service, currently only
available to operators who have an existing ASN assigned and publicly announce
one or more netblocks with their own originating ASN into the public Internet
BGP routing tables.

If only there was a way to just shut down the bad traffic but keep the good one
flowing\footnotemark!

\footnotetext{other than scrubbing}

Behold, this is what \it{selective black-holing} actually is. Some upstream
providers define multiple different blackhole communities each followed by a
predefined action on the upstream. One is able to announce to these communities
as needed.
Assume we would announce to a community that would in response announce the
blackhole to Internet exchanges in, say, North America and Asia and but allow
traffic coming from Europe, would be a perfect example of selective
black-holing.
This causes two things to happen. First, our customer's IP is still reachable
from our local area (e.g. Europe) and since our fictitious customer mostly
serves European customers that's fine. Second, outside of the prefedined radius
(Europe in this exercise) any traffic destined for our network (of which the
victim IP is a part of) is immediately dropped at the remote IXPs, long before
it ever comes anywhere near our geographical area, let alone our network.

I believe this approach is superior to indiscriminate black-holing and, given
it is reasonably automated and quick to respond, in combination with other
mitigation methods it can provide a viable protection for the network.

\n{2}{Sinkholing}
Moving on, this method works by diverting only malicious traffic away from its
target, usually using a predefined list of IP addresses known to be part of
malicious activities to identify DDoS traffic. False positives can occur more
rarely and collateral damage is lesser than with black-holing but since botnet
IPs can be also used by legitimate users this is still prone to false
positives.
Additionally, sinkholing as such is ineffective against IP
spoofing, which is a common feature in network layer attacks.

\n{2}{Scrubbing}
An improvement on arbitrary full-blown sinkholing, during the scrubbing process
all ingress traffic is routed through a security service, which can be
performed in-house or can even be outsourced. Malicious network
packets are identified based on their header content, size, type, point of
origin, etc. using heuristics or just simple rules. The challenge is to perform
scrubbing at an inline rate without impacting legitimate users.

If outsourced, the scrubber service has the bandwidth capacity (either
on-demand or permanently) to take the hit that we do not have. There are at
least two ways to go about this - the BGP and the DNS way, we will cover the
BGP one. Once an attack is identified, we stop announcing the prefix that is
currently being hit, contact our scrubbing provider (usually
automatically/programatically) to start announcing the subject prefix,
receiving all its traffic (including the attack traffic), the scrubbing service
does the cleaning and sends us back the clean traffic \cite{akamaiddosdefence}.

When performing the scrubbing in-house, we have to clean the traffic on our own
appliance that has to have sufficient bandwidth (usually on par with upstream).

A poor man's scrubber:
\begin{itemize}
\item utilizing hardware accelerated ACLs on switches,
\item switches can do simple filtering at \it{inline rate} (ASICs)
\item this can be effective when attack protocol is easily distinguishable from
  real traffic
\item hit by NTP/DNS/SNMP/SSDP amplification attack
\end{itemize}

We should be performing network analysis and once higher rates of packets with
source ports of protocols known to be misused for DoS/DDoS start arriving to
our network (such as 123 or 53), we start signalling to our upstream
providers, since they can probably handle it better than us and have as much
interest in doing so as us (or should).

Volumetric attacks sending traffic in smaller packet sizes will, however,
still result in higher CPU utilization, especially on non-dedicated networking
equipment.

One thing we should do no matter whether we are currently suffering an attack
(and scrubbing it ourselves) is to rule out and drop and never receive traffic
appearing to come from \it{our own network}, since such traffic could not exist
naturally and is obviously spoofed.

Team Cymru has got now a long tradition of maintaining bogons lists called the
\textbf{Bogon Reference}. Bogon prefixes are routes that should never appear in the
Internet routing table. A packet with an address from a bogon range should
not be routed over the public Internet. These ranges are commonly found as the
source addresses in DoS/DDoS attacks.\\
Bogons are netblocks that have not been allocated to a regional Internet
registry (RIR) by the Internet Assigned Numbers Authority (IANA) and Martian packets
(private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598
\cite{rfc1918}, \cite{rfc5735}, \cite{rfc6598}).

To get help with bogon ingress and egress filtering, we should set up automated
obtaining of updated and curated bogon lists via HTTP, BGP, RIRs and DNS from
Team Cymru \cite{teamcymru}.

In case we have our own ASN, are connected directly at an IXP, have no
RTBH support upstream and basically have no other choice, we just need
to find out who is sending the malicious traffic and, if possible, drop the
session and receive traffic from other peers.


\n{2}{IP masking} \label{ipmasking}
This is technique is widely used (e.g. CloudFlare flagship service), relying
solely on not divulging sensitive information - in this case server IP - to
attackers and the capacity of the \it{fronting} service to withstand the attack
due to having access to more badwidth than the attacker can produce. All traffic
- including potentially harmful traffic - flows through what is basically a giant
proxy. However, before declaring it a net win for us, it is important to
acknowledge that it also comes with heavy privacy implications, as now some
other service performs TLS termination in our behalf and \textbf{sees
everything} (that was encrypted only \emph{in transit} and is not additionally
encrypted) that \emph{anyone} sends us, before finally forwarding it back.

\n{2}{WAF} \label{waf}
WAF - \it{Web Application Firewall} - is an appliance used to protect
(as name suggests) web applications. In this day and age, this is
especially necessary and enables system administrators to craft protection
logic in one place and shield potentially vulnerable applications. This method
works on the application layer of the OSI model and is commonly deployed
as part of a web proxy or a module of a web proxy, which means network layer
attacks cannot be handled in this way. While not negligible, as always,
it is crucial to not have any assumptions and know exactly what
\it{layer} of protection using of WAF brings.

Generally or at least as per CBP (current best practices), applications are not
deployed with ports exposed directly to the Internet. A sane approach of having
access to resources \it{proxied} yields multiple possibilities in terms of
authentication/authorization and protection scenarios and also several ways to
more effectively use resources available. For one, where any web content
\it{caching} is required, it is easily achieved with a \it{caching} proxy
server. It commonly also enables specifying custom access policies.

There are also hosted (cloud) WAF offerings, however, they come with exactly
the same privacy implications as IP masking solutions (see \ref{ipmasking}).

\n{2}{Rate-limiting}
As a general precaution, it is sane to limit number of connections a client is
able to make in a predefined amount of time (based on the requirements of the
service). The same applies to a limit on how many connections a client can have
open simultaneously, which can even prevent Slowloris (see \ref{slowloris}).
Rate-limiting is usually set either on a proxy or a WAF, but some form of
rate-limiting can even be built into an app.

A well known rate-limiting pluggable solution that can be used with SSHd, HTTP
or multitude of other endpoints is \texttt{Fail2Ban}.


\n{2}{Decreased-TIME\_WAIT connection closing} \label{decreased-timewait}
This can help withstand a situation when conntrack table fills up and
the server refuses to accept any new connections. There is absolutely no
reason to keep connections in the conntrack table long after they become
inactive. The Linux kernel's NetFilter actually has a scrubbing mechanism, that
is supposed to be getting the conntrack table rid of the timed-out entries.
Except practice shows they can linger for much longer than necessary.

When dealing with massive amounts of traffic it is very reasonable not only to
increase the size of the conntrack table (memory trade-off), which is the
generally recommended solution, but also to decrease the TIME\_WAIT timeout to
force-evict connections that have stopped sending data.
It is also an easy way to mitigate slowloris (see \ref{slowloris}).
More on the workings of conntrack in \ref{netfilter}

Nginx is a widely used proxy. It uses two FDs (file descriptors) for each
connection. The limit of max open FDs can indeed be increased easily,
howerever, we might still just be delaying the inevitable (FD exhaustion)
and inefficiently wasting precious compute resources needed when an attack
comes. If Nginx is unable to allocate FDs necessary to track a connection, the
connection attempt will fail. By resetting connections that timed out we
prevent such a situation from occurring easily. In Nginx this is set with a
single line: \texttt{reset\_timedout\_connection on;}


\n{1}{Mitigation tools} \label{sec:mitigation-tools}
No tools are going to remedy for a bad design decision and that applies
equally to physical and Internet engineering.

\n{2}{Firewall}
No matter the specific implementation, it is presumably safe to say that
any firewall is better than no firewall.

There are two main types of firewalls:
\begin{itemize}
\item software,
\item appliance (hardware-accelerated).
\end{itemize}

A software firewall is just another program running on the operating
system, apart from the fact that it is typically running with system-level
privileges. It can be run on a general-purpose computer. In fact most of the
consumer-grade operating systems nowadays incorporate or by default enable a
firewall solution.

In contrast, an appliance firewall is a dedicated piece of hardware
purpose-build specifically for the sole role of behaving as a firewall and
is typically running a custom and very minimal operating system and no
userspace programs. Usually the system does not have a userspace, since it is
vendored to run as an appliance.

\n{3}{Software firewall}
Solutions available as software firewalls are typically specific to a given
operating system.

Usually, there exist several tools that enable communication with the core
implementing the logic, commonly by a way of embedding deeply in the networking
stack of the OS or utilizing kernel APIs. In Linux distributions, the Linux
kernel is the one that sees all. Each packet arriving at the network interface
is inspected by the kernel and a decision is made regarding it.

Historically, \texttt{ipset} and later \texttt{iptables} used to be the de-facto
standard, however, a more recent successor emerged quite some time ago
and is replacing (in modern distributions has replaced, although
backward compatibility has been preserved) the former two - the
\texttt{nftables} tool.

\n{3}{Netfilter} \label{netfilter}
The Linux kernel subsystem named \texttt{Netfilter} is part of the Internet
protocol stack of the kernel and is responsible for packet manipulation and
filtering \cite{Boye2012NetfilterCT}. The packet filtering and classification
rules framework frontend tools \texttt{iptables} as well as the newer
\texttt{nftables} can be interacted with via a shell utility and since they
also expose APIs of their own, it is common that they have graphical frontends
as additional convenience as well, most notably \texttt{firewalld}, which can
be used in conjunction with both of them.

Although newer versions of the Linux kernel support both \texttt{iptables} and
\texttt{nftables} just the same, only one of them can be used at a time. This
can be arbitrarily changed at runtime, a reboot is not necessary since they are
userspace tools) and interact with the kernel using \it{loadable kernel
modules}.

Part of the \texttt{Netfilter} framework responsible for connection tracking is
fittingly named Conntrack. Connection, or a \it{flow} is a tuple defined by a
unique combination of source address, destination address, source port,
destination port a and the transport protocol used.
Conntrack keeps track of the flows in a special fixed-size
(tunable\footnotemark) in-kernel
hash table structure with a fixed upper limit.

\footnotetext{via \texttt{net.netfilter.nf\_conntrack\_buckets}}

On Linux devices functioning as router devices (especially when you add NAT to
the mix) a common issue is the depletion of space in the conntrack table. Once
the maximum number of connection is reached, Linux simply logs an error message
\texttt{nf\_conntrack: table full, dropping packet} to the kernel log and
"all further new connection requests are dropped until the table is below the
maximum limit again." \cite{Westphal2017CT}. That, as Westphal further notes,
is indeed very unfortunate, especially in DoS scenarios.

Unless the router also functions as a NAT, this can be remedied in two ways:
decreasing the timeout until an established connection is closed and decreasing
the timeout until an inactive connection in the TIME\_WAIT state is evicted from
the conntrack table. By default, the TIME\_WAIT timeout is several hours long
and leaves the router vulnerable to packet floods or Slowloris.

Netfilter is here to help again with conntrack treating entries that have not
(yet) seen two-way communication specially – they can be evicted early if
the connection tracking table is full. In case insertion of a new entry fails
because the table is full, "...the kernel searches the next 8 adjacent buckets
of the hash slot where the new connection was supposed to be inserted at for an
entry that has not seen a reply. If one is found, it is discarded and the new
connection entry is allocated."\cite{Westphal2017CT}. Randomised source address
in TCP SYN floods becomes a non-issue because now most entries can be
early-evicted because the TCP connection tracker sets the "assured" flag only
once the three-way handshake has completed.

In case of UDP, the assured flag is set once a packet arrives after the
connection has already seen at least one packet in the reply direction, that is
the request/response traffic does not have the assured bit set and can
therefore be early-dropped at any time.


\n{2}{FastNetMon DDoS Mitigation toolkit}
Originally created by Pavel Odintsov, this program can serve as a helper on top
of analysis and metric collection tools, evaluate data and trigger configurable
mitigation reactions \cite{fastnetmonorig}, \cite{fastnetmonfork},
\cite{fastnetmonng}.

FastNetMon can run on most popular architectures an several different
general-purpose and specialised platforms such as Linux distributions, VyOS,
FreeBSD or Mikrotik devices. Most of the program is written in C++ but it uses
many C libraries for additional functionality and also Perl install scripts. It
has got a command line client and an API and analysis server. Its detection
engine is able to identify many types of flood attacks, fragmentation and
amplification attacks. The metrics can be exported into an InfluxDB engine for
visualization. It is capable of interacting directly with BGP-enabled equipment
and even supports Flow Spec.


% ============================================================================ %
\part{Practical part}
\n{1}{Infrastructure Set-Up Description} \label{sec:infrastructure-set-up-description}
The testing was performed in a virtual lab comprised of five virtual machines
(VMs) running on a KVM-enabled Fedora 34. Since the expectation was to
frequently tweak various system settings of the guests (VMs) as part of the
verification process, we decided to take the \emph{infrastructure as code}
approach. Every piece of infrastructure - down to the details of how many
virtual CPUs are allocated to a host, what is the disk size and the filesystem,
etc. - is declared as code, can be versioned and used to provision resources.

The industry standard tool \texttt{Terraform} was chosen due to a broad support
of infrastructure and providers, great documentation, large user base and the
tool being open source.

For bootstrapping, \texttt{cloud-init} has been used mainly because of the fact
that it can integrate with terraform quite smoothly, works on many Linux
distributions and allows us to pre-setup things like copy over SSH pubkeys so
that a secure connection can be established right after first boot, set VM
hostname, locale, timezone, add users/groups, install packages, run commands
and even create arbitrary files, such as program configurations.

The disk sizes of the VMs were determined by the size of their base image.
The VM naming convention is specified as follows: a prefix \texttt{r\_} for
routers and \texttt{h\_} for other hosts, in our case the attacker, victim and
defender machines.

\n{2}{VM specifications}
\tab{VM specifications}{tab:vmspecifications}{0.75}{ |c||rrrrc| }{
  \hline
  \bf{VM name} & \bf{vCPU(s)} & \bf{RAM} & \bf{disk space} & \bf{net ifaces} &
  \bf{operating system} \\
  \hline\hline
  r\_upstream & 1 & 768MB & 4.3GB & {outer,DMZ} & Fedora 33 \\
  \hline
  r\_edge& 1 & 768MB & 4.3GB & {DMZ,inner} & Fedora 33 \\
  \hline
  h\_victim & 1 & 768MB & 11GB & {inner} & CentOS 8 \\
  \hline
  h\_attacker & 1 & 1GB & 5.37GB & {outer} & Fedora 34 \\
  \hline
  h\_defender & 1 & 1GB & 5.37GB & {DMZ} & Fedora 34 \\
  \hline
}
The inner (our edge) and the upstream (our transit provider) routers are
each part of different \it{AS}. They are directly connected and communicate
using BGP. The outer router and the inner router are BGP peers.

We assume our upstream provider supports RTBH signalling.
In this scenario the attacker is directly connected to our UPSTREAM router,
and while in reality there would probably be a greater distance between us and
them, this is fine for our simulation purposes, since malicious traffic will be
cut before it reaches us.

If our upstream provider did not support RTBH signalling, in case we were
attacked we could still use a scrubbing service but it is preferred that such a
provider is picked that has the RTBH capabilities.

The cunning plan is to watch for traffic anomalies, when the attack comes
detect it as soon as possible, trigger a reaction (announce a black hole), wait
for some time, withdraw the black hole if the attack is gone and reintroduce it
if it is still going on. Automatically, of course.

\begin{figure}[!hbt]
  \centering
  \begin{tikzpicture}
    \fill[even odd rule,gray!30] circle (2.3) circle (2.2);
      \arcarrow{2}{2.25}{2.5}{165}{200}{5}{red!50,
        draw = red!50!black, very thick}{attack}
      \arcarrow{2}{2.25}{2.5}{210}{260}{5}{blue!50,
        draw = blue!50!black, very thick}{detection}
      \arcarrow{2}{2.25}{2.5}{270}{320}{5}{green!50,
        draw = green!50!black, very thick}{blackhole}
      \arcarrow{2}{2.25}{2.5}{330}{460}{5}{blue!50,
        draw = blue!50!black, very thick}{wait {\&} withdraw blackhole}
      \arcarrow{2}{2.25}{2.5}{470}{515}{5}{blue!50,
        draw = blue!50!black, very thick}{analysis}
  \end{tikzpicture}
  \caption{The Cunning Plan} \label{fig:cunning-plan}
\end{figure}

Initially, two approaches for setting up infrastructure were considered.
While both proposed to use KVM and \texttt{Terraform} with \texttt{libvirt}
provider \cite{libvirt-tf-provider}, the first one planned to continue
configuring the VMs with \texttt{cloud-init}, which is compatible with any
GNU/Linux distribution. The finishing touches would be done using
\texttt{ansible}. The second one, on the other hand, considered a newer
technology - Fedora CoreOS, which uses a different paradigm where hosts are
only customised on initial boot via \texttt{ignition} (although he
configuration format used is called \it{Butane}, which uses YAML and is then
transpiled to Ignition's JSON) and ran as configured, by default without a
separate install disk. This provides the much needed system immutability during
runtime but also makes it more difficult to configure. Configuration changes
\it{can} be done during runtime, however, the CoreOS provisioning philosophy
teaches that there is no need to deploy once and endlessly configure (by hand
or e.g. with \texttt{ansible}) when boot times are short (Ignition runs before
the userspace begins to boot) and the system is as minimal as possible
(container-like).

\begin{description}
  \item[approach 0:]\
  \begin{itemize}
    \item KVM
    \item \texttt{terraform} with \texttt{libvirt} provider
    \item \texttt{cloud-init}
    \item \texttt{ansible}
  \end{itemize}
\end{description}

\begin{description}
  \item[approach 1:]\
  \begin{itemize}
    \item KVM
    \item \texttt{terraform}
    \item \texttt{ignition}
    \item Fedora CoreOS
  \end{itemize}
\end{description}

We decided to go with the approach 0 as we felt it was more appropriate for our
use case, which involves relatively lot of configuration.

\begin{description}
  \item[VMs required:]\
  \begin{itemize}
    \item victim
    \item router - inner
    \item router - edge
    \item attacker
    \item defence machine
  \end{itemize}
\end{description}
See tab.~\ref{tab:vmspecifications} for details.

To reiterate, simulating multiple physical devices performing different roles
(routing, attacking, playing victim) in our attack-defence/mitigation scenario
has been achieved by creating a test-lab virtual infrastructure.\\
The tried-and-true way, state-of-the-art Linux kernel-native virtualization
solution has been chosen to tackle the hypervisor task - the KVM technology.

Testing has been performed on our personal laptop - Dell Latitude 5480
machine equipped with a ULV dual-core Intel i5 Core 6300U processor with
\texttt{mitigations=off}, 24GB (8+16) of RAM and a 512GB SATA SSD (TLC).

The host operating system from the perspective of VMs was \texttt{Fedora\ 34}.
Both \texttt{updates} and \texttt{updates-testing} repositories have been
enabled, which allowed us to use latest (at the time) stable Linux kernel
Fedora had to offer directly without too much of a hassle, as of the time of
writing in version \texttt{5.11.20}.

File system in use on the host was Btrfs on top of LVM (LUKS+LVM to be
precise) and a Btrfs subvolume has been created specifically for the
libvirt storage pool for better logical isolation (subvolumes are omited during
snapshotting etc.; that way the lab does not end up in system snapshots. Since
all of the system images for our VMs have been downloaded in a QCOW2 format,
the CoW (Copy-on-Write) feature of Btrfs has been turned off for the subject
subvolume, just as recommended in the Brfs Sysadmin Guide \cite{linuxbtrfs}
for improved storage performance (and decreased flash wear).

Notably, the system has also been using the \texttt{nftables} backend of
\texttt{firewalld}, for which, luckily, \texttt{libvirt} was already
prepared and played nice together.

The whole infrastructure code resides in a git repository available at
\url{https://git.dotya.ml/mirre-bt/tf-libvirt}.

\n{2}{Terraform and Cloud-Init}
Thanks to the \texttt{libvirt} provider for Terraform, VMs could easily be
brought up and torn down. Terraform works by tracking state of the resources
that together create the infrastructure, which can be described in numerous ways.
Every resource that is absent needs to be created. Terraform uses a
\emph{plan} of the infrastructure as it wants to \emph{apply} changes to the
current \emph{state}. Every VM or a network, every backing storage is a
resource that is managed for us, which is very convenient especially for
testing.

The initial boot configuration has been performed by Cloud-Init
\cite{cloudinit}. It enabled us to configure users with SSH public keys to
secure further connections, install packages and create arbitrary files.
Scenario-role-specific configuration was made really easy thanks to this tool.

\n{2}{Ansible}
What has not been prepared by either Terraform or Cloud-Init was left to
Ansible. It was used to deploy configurations of GoBGPd and FastNetMon, as well
as to install and enable services.

\n{1}{Mitigation tools set-up} \label{sec:mitigation-tools-set-up}
\n{2}{FastNetMon}
An open-source DDOS mitigation toolkit named \texttt{fastnetmon} was
picked to serve as an attack detection tool. It supports analysing traffic from
multiple different exporter types, including Netflow (v5 and v9), sFlow and port
mirrors.
We tried the installer from projects website, however, the
installation did not appear to succeed. Therefore, we decided to build it from
sources. That is when we uncovered some curious information.

The project's master branch on GitHub, where it is hosted, appears to have been
modified on 22 June 2016 \cite{fnm-wayback} \cite{fastnetmonorig}. Since we
knew about some propagation activities \cite{fnm-freebsd-wayback} and we found
the repo as "updated" on 17 Feb 2021 (that is what GitHub shows when e.g. a
description is updated) \cite{fnm-search-wayback} at the same time as we saw
the last commit pushed with a 2016 date, we went digging over the project's
forks to find out what happened to the project. They perfectly preserve it,
from a point in time when the "fork" (essentially a clone) was created, up
until the latest updates that have either been integrated from upstream or
changed by the owner of the fork. While some forks have been abandoned a long
time ago, several more showed the same tree with the exact same commits,
referring to a common history.  Furthermore, the one thing giving away what
apparently happened (not why) with almost certainty is the Pull Requests tab.
It showed some 164 Closed PRs, some of them \it{merged} as late as 23 Dec 2020
\cite{fnm-pulls-wayback}. That is, the history \it{has} indeed been overwritten
and we have no information as to why, but that was also a reason why we chose
to use one of the latest updated forks \cite{fnm-fork-wayback} \cite{fastnetmonfork}
as a base for our work \cite{fastnetmonng} instead of the original upstream.
The claim that the history has been overwritten is also supported by an earlier
grab (snapshot) of the project by the Internet Archive's awesome \emph{Wayback
Machine} \cite{fnm-early-wayback}, the rest have been triggered by us to help
support the arguments in case anything changed.

Ad setup itself, several changes had to be made to the project to make it even
compile on recent hosts (Fedora 33/34, Arch Linux). A Drone CI build job has
been set up to help make sure nothing breaks with our changes. Fastnetmon needs
quite a lot of dependencies for its full functionality and the way to go about
it in the project was using custom versions of the third party libraries to
link against, all downloaded using the Perl install script mentioned earlier.
While that might seem like a sound idea, we feel in the long run it is always
better to use a reasonably recent distribution with sizable repositories and
active community that, combined, are able to provide for most developer needs.
The only major overhaul that had to be done was patching the
\texttt{CMakeLists.txt} file to instruct CMake/Make to use system locations to
look for headers and (dynamic) libraries (\texttt{.so} files) instead of
download location from the install script. Further, to accomodate using newer
version of \texttt{nDPI} (Open Source Deep Packet Inspection Software Toolkit)
that aids FastNetMon with traffic sorting (if enabled), an interface and
\texttt{fast\_dpi.h} header had to be updated. The history of all changes can be
found in the repository at \url{https://git.dotya.ml/wanderer/fastnetmon-ng}.

For building and deployment to the defender host, an Ansible role has been
created. It makes sure that FastNetMon is built correctly, installed and its
\texttt{systemd} service is \it{enabled} (at boot time) and started.

\n{2}{GoBGPd}
We attempted to peer the two router VMs, however, we were not able to pin down
the proper configuration that would allow us to define a community tied to a
black-holing action.

\n{2}{Netflow}
FastNetMon supports collecting Netflow metrics, therefore the edge router has
been configured to listen on the upstream interface and to send traffic
information to this FastNetMon's collector. The ansible role
\url{github.com/juju4/ansible-fprobe} has been edited and used to deploy
the configuration to the edge router.

\n{1}{Attack tools set-up} \label{sec:attack-tools-set-up}
When considering the way to simulate an attack locally, we weren't
primarily looking for a tool, which would enable a decentralised (the
first "D" of DDOS) attack, instead the objective was mainly to congest
the weakest link, which would happen to live inside our network (that's
why we're concerned in the first place).

\n{2}{slowlorispy}
With this python script there are a couple of flags to tweak the intended
behaviour. Flag \texttt{-p} sets the port we want to target,
\texttt{--sleeptime} allows us to rate-limit the tool so that we open as many
connections as possible without getting banned. The \texttt{-s} flag specifies
the number of sockets we want to open.

\n{2}{iperf3}
This tool works in server-client mode. To receive traffic, it \texttt{runs in
server mode} and listens on port 5201 by default, although both the traffic
direction and port and multitude of other parameters can be configured.
To listen on the victim server, we simply ran \texttt{iperf3 -s -P 8} to
receive 8 parallel streams.
Then on the client - the attacker - we entered \texttt{iperf3 -c \{server
ip\} -P 8} to send 8 parallel streams to the victim. This filled the available
link bandwidth but, unfortunately, we haven not observed FastNetMon ban action
even though the threshold has been crossed.


\n{1}{Performing an attack} \label{sec:performing-an-attack}
As mentioned previously, the attack was planned to be performed in the
controlled environment of a virtual lab with practically no natural traffic
occuring, that would generally be present on a reasonably large ISP network and
thus with essentially no load on the network equipment/virtual devices.
However, it should not have had any major impact on the results of the subject
attack and our chosen way to mitigate.

As is the case when using e.g. a selective blackhole technique, the suspect
traffic first has to be identified as highly abnormal/malicious, either by
analysing network metrics over a period of time as collected by sFlow or
Netflow protocols, or by direct packet capture and inspection aided by tools
such as nDPI.
The analysis and detection mechanism in our scenario is left to FastNetMon and
so is the reaction (mitigation) logic.

With the first attack we performed, we basically attempted to naively overflow
the conntrack table of our server host.
We were not able to extinguish connections on the server using
\texttt{slowloris.py}, presumably because the inactive connections were quickly
being closed. While the number of used sockets steadily grew, after about 5000
this tool was not able to open any new connections and the server worked fine.
The key was to set the
\texttt{net.netfilter.nf\_conntrack\_tcp\_timeout\_time\_wait} parameter to a lower
value, such as 10 or 5 and the
\texttt{net.netfilter.nf\_conntrack\_tcp\_timeout\_established} parameter to
somewhere between 300 and 1200 (we chose 600). Both values are seconds and they
are set either in the global \emph{sysctl} file (\texttt{/etc/sysctl.conf} or
they can be placed in an arbitrary complementary file inside the sysctl include
directory at \texttt{/etc/sysctl.d/}. The \emph{TIME\_WAIT} timeout value
affects for how long the connections in the TIME\_WAIT (see
\ref{decreased-timewait}) TCP state are kept before they are completely cleared
and stop consuming resources. The ESTABLISHED timeout merely sets for
how long the \emph{established} connections are kept in the ESTABLISHED state
before processing them further.

As per running FastNetMon attack traffic detection, we have experienced
unexpected issues in the form of FastNetMon incorrectly reporting 0pps for
both outbound and inbound traffic. We were not able to uncover the root cause
of the issue, which might very well even be attributed to a configuration error.
Due to this and the fact that we could not establish BGP peering in our virtual
lab, neither the other attack nor the mitigation could be properly performed.


% ============================================================================ %
\nn{Conclusion}
Recent past has seen an immense increase in the number of DoS attacks of all
kinds. A large part of these attacks flood service resources and ultimately end
up blocking or delaying responses for legitimate user requests. As we touched
on in the beginning, the motivations for these attacks can range all from a
business model with extortion plans to hacktivism to simply somebody choosing a
wrong place to have fun.

The goal of our work was to describe some of the popular types of DoS attacks,
including DDoS, casually used attack methods, techniques and tools most popular
and most widely used among attackers to annoy Internet users, harm businesses
and worry Internet service providers with small to medium capacities. We have
dived a little into the workings of several potential attack vectors, but have
not stayed there.

Further in the theoretical part, we also outlined various mitigation methods
readily available to network operators and end users alike, along with their
scope and reach. Several pros and cons of black-holing, selective black-holing,
scrubbing and rate-limiting were considered in section
\ref{sec:mitigation-methods} - Mitigation methods. Next, we looked at some of
the concrete tools that aid mitigating DoS attacks.

In the practical part, we set out to build a virtual lab using tools like
Libvirt, Terraform, Cloud-Init and Ansible on top of KVM in an automated
manner by applying the \emph{infrastructure as code} principles. The virtual
lab was running on a Fedora 34 host, each virtual machine has been provisioned
using Terraform, pre-configured using Cloud-Init and further configured with
Ansible after the initial configuration has finished.
We explored setting up both the mitigation tools used to protect Internet
networks and tools used by adversaries.

Finally, we have attempted to perform several attacks in our controlled
virtual environment, which has been described in the practical part of this
work. The attempts were partially successful in that our proposed mitigation
methods showed that a certain kind of attack \emph{can} easily be mitigated and
the unhappy consequences averted.\\
Sadly, in the next part of attack simulation we have arrived at unexpected
results, where we were not able to fully simulate the black hole propagation
among ASes due to configuration inconsistencies, presumably on multiple levels.

This, as well as improving and potentially reworking the virtual lab stays as a
challenge for us for the future, and I believe performing these attack
simulations could aid us in better understanding the threats and preparing for
what we \emph{surely are} going to face.


% ============================================================================ %
