In this lesson, we'll learn how to configure a firewall on Ubuntu machines.
Like the name suggests,
this helps us set up a line of defense against potential Attackers.
It lets us build a wall and block the network data that the server shouldn't process.
This wall can defend both against network data that's coming in.
But also for network data that's sent out.
When can a firewall save the day.
Here's an example,
an attacker might discover that they can create a special packet of
network data which can exploit the SSH daemon running on our machine.
If our SS SS H daemon receives that packet,
it might let the attacker break into our machine and do some damage.
But by setting up a packet filtering firewall, we can prevent this attack
because the packet filter could look at the network data that was received
and simply reject it
this way.
The malicious network packet doesn't even reach its target, the SSH daemon.
So the attack is prevented.
There are many types of firewalls.
For example, an application firewall can monitor individual apps
and decide if it should allow or deny network
traffic based on rules set up for each application,
something like this is implemented in the Windows operating system.
It makes sense to allow network data to flow through an app like Chrome.
But it also makes sense to block traffic for something like Windows calculator.
Linux
though includes a packet filtering firewall right out of the box.
As its name suggests,
it decides what to do with data based on the network packets themselves,
not applications.
Now, let's see how we can use a firewall in practice.
OK.
So we're here at our command prompt and we're
going to configure a firewall on our Ubuntu machine.
Now,
the easiest way to set up packet filtering rules on
Ubuntu is with the help of a tool called UFW.
The name is an abbreviation for uncomplicated firewall
by default UFW is disabled
and we can check its status with this command
and we can see that it's inactive.
Now, before we continue,
we must make sure to add at least one rule that allows SSH traffic.
Otherwise, when we enable UFW, we won't be able to log in through SSH anymore.
This happens because by default, when UFW is active,
it will block all incoming data.
This is called a whitelist approach,
which means that everything is disallowed except for
what we specifically allow on the whitelist.
So the wall of network defense is absolute in the beginning,
nothing gets through.
But by adding rules, we can allow what's useful for us.
In familiar terms, this is sometimes called punching holes in the firewall.
So let's create our first rule.
Now, the SSH daemon listens for incoming connections on port 22
to enable incoming network packets to port 22
we will type in this command.
This will allow connections on both the TCP protocol and the UDP protocol.
SS A chooses TCP.
So if we want to be more specific and pick one of the protocols,
we can specify it here by adding a front slash and the name of the protocol.
OK. Now we can enable UFW.
Now UFW shows a friendly reminder that we may disrupt SSH connections,
but we already took care of that. So we can type Y and press enter to continue.
Now let's check our firewall status again.
But this time we'll ask for more detailed output by adding the verbose parameter.
We can see that we have two rules,
one to allow incoming connections on port 22 on IPV four,
which is the first rule and another for allowing
IP D six connections on the same port.
Also, we can see the default policies for incoming data.
Everything is denied except for what we specifically allow in the rules below.
For data that is outgoing,
everything is permitted so that our server can send data wherever it needs to go
and routed packets are disallowed for now,
which will have to change when we learn how to
use port redirection in NAT later in our lesson.
NAT is an abbreviation for network address translation.
Now, our current firewall rule is rather generic.
We basically allow anyone to connect to port 22 of this machine
because we only specified the port number but nothing else.
However, in a real scenario, we would want to narrow down this access.
Now, here's an example,
we can take a look at active TCP connections
by typing SS dash TN.
As we can see,
we're connected to port 22 from the source IP address 10.0
0.0 0.192 which is our personal IP that we're connecting from.
So you can create a rule to only allow incoming traffic
to port 22 if it's coming from this exact IP address.
Now this keyword any is necessary here because when
we specify the IP address of the sender,
which is from UFW also wants to know the IP address of the receiver,
which is two by typing in any.
We say that this can come to any IP address of this machine.
Since a server can have multiple network cards and multiple IPs.
If we want to accept traffic only on a certain IP of this machine,
we just replace the word any with that actual IP address.
But now we have a problem with our rules
to better understand this.
We'll display the rules ordered according to the order in which they're processed
to do this. We add the word numbered to our UFW status command
our generic rule allowing traffic to port 22 from anywhere is still active.
So it doesn't matter that we added another rule stating that
traffic could be only accepted from the 10.0 0.0 0.192 IP address
rule number one from this list will allow connections to port 22.
Even if they come from different IP S
now to fix that we can remove this first rule using its index number.
Now, our generic rule allowing traffic to port 22 from anywhere is still active.
So it doesn't matter that we added another rule stating that
traffic should be accepted only from the 10.0 0.0 0.192 IP address
rule number one from this list will allow connections to port 22.
Even if they come from different IP S
to fix this, we can remove that first rule using its index number,
but we'll still have this last rule allowing access to port 22 from any IPv6 address.
Here's another way to remove a rule.
Instead of specifying its index number, we can specify the rule itself.
The command we used to add that rule was
pseudo UFW allow 22
right?
So the rule itself is allow 22
to delete it. We can type pseudo UFW delete followed by the rule specification.
In our case, it will complain that it can't find one of the two rules,
but that's just for the IPv4 1 that we deleted earlier.
It will find the IPv6 rule though and delete that one.
So now if we inspect our firewall again,
things are looking good.
We only allow incoming traffic to port 22 from our specific IP address.
So no other address will be able to connect.
Now instead of a fixed IP address, we can also specify a range.
For example, maybe we want to allow connections for any IP between 10.0 0.0 0.0
to 10.0 0.0 0.2 55.
Easy enough, we just have to specify the slash 24
cidr notation for this range.
And there we go.
Now let's explore a different scenario.
Say we want to allow all traffic from 10.0 0.0 0.0 slash 24 on any port.
Creating this rule is very simple. We just omit the port specification.
Now traffic from this IP will be allowed on all ports,
but let's go one step further.
What if we want to accept traffic from all IP S in this range except for one of them.
For example, maybe we want to disallow traffic coming from 10.0 0.0 0.37
for this purpose. Instead of an allow rule, we can add a deny rule.
However, there will be a problem here.
Lets take another look at the current rules
and lets remove the first two rules here to simplify the explanation of the problem.
As you can see here,
they've all moved up one level.
Ok.
And now we'll list our rules again.
And here's the problem,
traffic incoming from 10.0 0.0 0.37 will actually be allowed.
Now, why is that?
Because the firewall processes these rules from top to bottom from rule
one all the way down to the last one in this list.
So if traffic is coming in from an IP like 10.0 0.0 0.37 the following happens,
the firewall looks at the first rule and it sees that 10.0 0.0 0.37.
The sender's address is within the 10.0 0.0 0.0 range.
So it matches the rule and traffic is allowed and that's it.
It doesn't even get to the second deny
rule here because the first one already permitted,
the traffic go through
to correct this problem. We need to reorder and place the deny rule as the first one.
We can start out by deleting the deny rule.
But now how do we add it as the first rule?
If we use our old commands, this will be added at the end of the list again.
Well, we can use a different command.
Let's get some help with UFW dash dash help.
Now when assigning a number to a rule like this,
all the other rules below it are pushed down.
So if we insert something as number three, then what was number three becomes,
number 44 becomes 55 becomes six and so on.
Now, if we check our list again
there, it is
the deny rule is the first one and things will work as expected
this time, our firewall will see traffic incoming from 10.0 0.0 0.37.
It will find that it matches the deny rule and then deny it. So traffic will be blocked
and it won't process the rest of the rules in the list.
Now the second rule would theoretically allow traffic from 10.0 0.0 0.37
since it's within the range.
But by design, firewall rules are processed in order.
And the first thing that is a match is the first
thing that's executed no matter if it's an allow or deny operation
something we have to think about when designing our firewall logic.
Now let's continue.
As mentioned earlier, a server can have multiple network cards.
For example,
one can be used to process external traffic coming from or going to the internet
and another can process traffic from or to our internal office network
to apply a rule on only a certain network interface.
We need to find the name of that interface
and it looks like it's ENP 0 S3 in our case.
So let's test this out. First, let's ping one of Google's DNS servers 8.8 0.8 0.8.
And we'll use the dash C option to ping only four times
and then type out to specify this is for outgoing network packets.
Then to apply this to a specific network interface, we type on
followed by the name of the interface.
Finally, we fill out the rest of the rule to deny traffic outgoing to
8.8 0.8 0.8.
Now if we try our ping command again,
we'll see it doesn't work.
We get no response since we can't contact 8.8 0.8 0.8 as expected.
Now, here's another interesting thing
if we check our rules again,
notice the difference between outgoing rules and incoming ones,
namely the to and from fields.
When filtering incoming data
two refers to a destination on this machine,
namely on what IP of our machine that this is coming to
and from refers to the sender
the IP of the external machine that sent this to us.
But when we filter outgoing data, this is reversed.
Now, the first two column does not refer to an IP of our machine
but to an external IP of a different machine.
And from refers to an IP of our machine.
If this seems a bit complicated, just think about sending an email.
When you receive an email in the two field, people fill out your own email address.
But when you are sending an email, the two field refers to a different person,
an email address belonging to someone else,
same here as the receiver the two field refers to is this machine
as a sender, the two field refers to a different machine.
Now, let's recap.
We saw that some UFW commands can be quite simple.
We just specify a port and UFW fills in the blanks.
It figures out we want to apply this for TCP and UDP protocols
from any address to any address on any network interface and so on
in a nutshell.
If we skip some details in our UFW command,
it assumes we want everything in those spots,
no port specified, then it assumes it applies to all ports,
no IP specified, then it assumes it should apply the rule for all IPs.
However,
the more details we offer to UFW the more we can fine tune our firewall rules.
So let's build our most complex UFW command where
we specify all the details we learned about.
First,
let's see an IP address belonging to this machine as we'll use it in our command.
It will be 10.0 0.0 0.100. In this case,
now let's build our command
and then type in
to specify that this applies to incoming data
on
ENP
0 S3
to specify this applies to the E and P 0 S3 interface.
Then we continue with from
10.0 0.0
0.192
to specify the senders IP address,
then we'll add 2 10.0 0.0 0.100
to allow traffic on this IP of our machine.
And finally, we'll specify the port and protocol,
but we can't type in 80 slash TCP as we did for a previous command.
When we fine tune the Brum and two IP addresses in this world,
we need a different approach.
First,
we type the usual port 80 but then we follow
this with proto TCP to specify the TCP protocol.
And for a rule with outgoing traffic, we just change the in keyword to out.
But remember in this case, we apply a rule for our machine as a sender, not a receiver.
So we have to reverse the from and two specifications.
So our rule for outgoing traffic would be
will switch the IP addresses here.
Now,
we can see that the rules were added successfully.
So if you remember the syntax for these longer UFW commands,
you can basically build any rule you want,
even if you forget the syntax,
the manual for UFW offers plenty of example commands to serve as
a quick reminder or a guide for any purpose you might have.
Now let's move on to our next lesson.