netfilter - ipp.pt

14
1 Netfilter Lab handout 0. Introduction This work requires several changes to the configuration of the host used as server. In order to ensure the host safety during the working period, only connections to trusted networks or virtual machines hosted by trusted operating systems should be used. To allow restoring the firewall configuration after work, save a copy of actual iptables configuration: iptables-save > iptables.dump Since all the implemented changes will be temporary, it is possible to safely abort the work at any time by rebooting the involved machines or by issuing the command: iptables-restore < iptables.dump Register the names and the IP addresses of machines allocated to be used as server and clients. Only the server will have its configuration changed. Clients will only be used for testing proposes. Host Name IP Address Server Client1 Client2 Client3 Client4

Upload: others

Post on 10-Feb-2022

20 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Netfilter - ipp.pt

1

Netfilter

Lab handout

0. Introduction

This work requires several changes to the configuration of the host used as server. In order to ensure the

host safety during the working period, only connections to trusted networks or virtual machines hosted by

trusted operating systems should be used.

To allow restoring the firewall configuration after work, save a copy of actual iptables configuration:

iptables-save > iptables.dump

Since all the implemented changes will be temporary, it is possible to safely abort the work at any time by

rebooting the involved machines or by issuing the command:

iptables-restore < iptables.dump

Register the names and the IP addresses of machines allocated to be used as server and clients. Only the

server will have its configuration changed. Clients will only be used for testing proposes.

Host Name IP Address

Server

Client1

Client2

Client3

Client4

Page 2: Netfilter - ipp.pt

2

To allow different connection tests, the server host must provide HTTP and SSH services on the traditional

TCP ports (80 and 22).

Verify the availability of the provided HTTP and SSH services from each of the clients.

ping ip_server

wget http://ip_server/

ssh ip_server -l my_test_user

Register the obtained results on the following table.

Client ICMP HTTP SSH

Client1

Client2

Client3

Client4

1. Netfilter / iptables

Netfilter is a framework to implement packet filtering and address and port translations. It is commonly

integrated in the Linux kernel. The configuration of netfilter can be done from the command line using the

iptables utility. Any specific behavior can be implemented by defining chains of rules. Chains are located

into tables. In this work, only the filter table will be used.

Basic iptables operation:

iptables -L Lists all rules in chains

iptables -F Flushes (cleans) all chains

iptables -X Deletes all chains iptables -A chain rule Adds a new rule to a chain

iptables -D chain rule Deletes a rule

iptables -P chain DROP|ACCEPT Sets the policy (DROP/ACCEPT) for the chain

2. Simple Rule

On your server, clear the netfilter state.

iptables -F

iptables -X

Block all incoming traffic:

iptables -P INPUT DROP

Page 3: Netfilter - ipp.pt

3

Test the communication to your loopback interface.

ping -c 1 127.0.0.1

Create new rules in the INPUT chain to allow all traffic from the localhost.

iptables -A INPUT -s 127.0.0.0/8 -j ACCEPT

iptables -A INPUT -s ip_server -j ACCEPT

Verify that these new rules are now part of the INPUT chain.

iptables -L -v -n

Test again the communication to your loopback interface.

ping -c 1 127.0.0.1

Allow all the ICMP traffic, no matter its origin.

iptables -A INPUT -p icmp -j ACCEPT

Test the communication from each client to your server.

ping -c 1 ip_server

Allow clients 1 and 2 to access the SSH service in the server.

iptables -A INPUT -p tcp -m tcp -s ip_client1 --dport 22 -j ACCEPT

iptables -A INPUT -p tcp -m tcp -s ip_client2 --dport 22 -j ACCEPT

Allow clients 1 and 3 to access the HTTP service in the server.

iptables -A INPUT -p tcp -m tcp -s ip_client1 --dport 80 -j ACCEPT

iptables -A INPUT -p tcp -m tcp -s ip_client3 --dport 80 -j ACCEPT

Confirm the accessibility to the HTTP and SSH services in the server from each client. Register the results in

the following table.

Client ICMP HTTP SSH

Client1

Client2 Client3

Client4

This example applied a distinct rule for every combination of origin host and destination port. The use of

such rules to give access to p services from n hosts requires specifying a set of n x p rules.

Page 4: Netfilter - ipp.pt

4

3. Additional chains The total amount of rules may be reduced if it is possible to group a set of rules so they can be frequently

re-used. When two services (on different ports) should be available to a limited but identical list of IP

addresses, an additional chain can be used to enclose the IP address test. First, the packet is checked for

the destination port. If it matches, it is sent to the new chain, where a list of IP addresses is checked.

Delete all rules and all extra chains:

iptables -F ; iptables -X

Create new chain named admin_IP, that will be used to check the source IP address.

iptables -N admin_IP

iptables -L

Add rules to chain admin_IP to accept packets originated from the trusted IPs and reject all other traffic.

iptables -A admin_IP -s ip_client1 -j ACCEPT

iptables -A admin_IP -s ip_client2 -j ACCEPT

iptables -A admin_IP -s ip_client3 -j ACCEPT

// drop all packets that are not matched by previous rules

iptables -A admin_IP -j DROP

Add rules to the INPUT chain in order to implement the desired port filter. Packets directed to the accepted

destination ports will be redirected to the admin_IP chain.

iptables -A INPUT -p tcp -m tcp --dport 22 -j admin_IP

iptables -A INPUT -p tcp -m tcp --dport 80 -j admin_IP

Verify that the protection system is working as required. Register the obtained results in the following

table.

Client ICMP HTTP SSH

Client1 Client2

Client3

Client4

4. State Most processing of rules can be avoided with the use of state. Traffic related to previously established

connections can be summarily accepted in one of the first rules.

Page 5: Netfilter - ipp.pt

5

Delete all existent rules and chains.

iptables -F ; iptables -X

iptables -L -n

Allow all traffic incoming related to already established connections

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Allow incoming traffic on the default SSH port (22) and the default HTTP port (80).

iptables -A INPUT -p tcp --dport ssh -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT

iptables -L -n

Block all other incoming traffic:

iptables -P INPUT DROP

iptables -L -n -v

This setup blocks all traffic that has not been explicitly allowed. So, the traffic to the loopback interface is

also blocked. To allow the traffic to the loopback (lo) interface, insert a new rule in top of the chain.

iptables -I INPUT 2 -i lo -j ACCEPT

iptables -L -v -n

To further allow incoming traffic directed to other services, new rules can be created.

iptables -A INPUT -p tcp --dport xxxx -j ACCEPT

iptables -L -v -n

Verify that the protection system is working as required. Register the obtained results in the following

table.

Client ICMP HTTP SSH

Client1

Client2

Client3

Client4

5. Port knocking Port knocking is a stealth method to externally open ports that, by default, the firewall keeps closed. It

works by requiring connection attempts to a series of predefined closed ports. When the correct sequence

of port "knocks" (connection attempts) is received, the firewall opens certain port(s) to allow a connection.

The benefit is that, for a regular port scan, it may appear as the service of the port is just not available.

Page 6: Netfilter - ipp.pt

6

This exercise will show how to implement the port knocking mechanism with iptables.

The goal is to create a port knocking system only with iptables that will open up port 22 (SSH) when the

remote host “knocks” on ports 2222, 3333, 4444 within 30 seconds, without sending non-sequence traffic

in between.

Four different states will be defined to classify hosts trying to access.

• Initial state: This is the state that all IP addresses are in until they successfully send a packet to the

first knock target.

• Auth1 state: Addresses that have successfully knocked on the first knock target are flagged as

Auth1.

• Auth2 state: Addresses are flagged with this state if they have successfully knocked on the first and

second targets in sequence. The next packet from the same host determines whether the host will

be set back to the initial state or set to the Auth3 state.

• Auth3 state: Addresses that have been flagged as Auth3 have successfully knocked on all three

ports, in order, in the allotted amount of time. If an address flagged as Auth3 attempts to access

the service now (in window that is provided), the connection will be accepted. If any other traffic is

received, the address will be thrown back to the initial state.

States Auth1, Auth2 and Auth3 will be recorded by flags with the same name (AUTH1, AUTH2 and AUTH3).

The initial state will be signaled by unsetting all these three flags.

5.1. Chains framework Before starting to build the knocking system, flush the existing firewall rules to get a clean state.

iptables -F ; iptables -X

Required additional chains can be created using:

iptables -N KNOCKING

iptables -N GATE1

iptables -N GATE2

iptables -N GATE3

iptables -N PASSED

iptables -L -n

Eight different chains should be listed!

• KNOCKING: This chain will distribute traffic to other sub-chains according to current state.

• GATE1: Will be used to determine whether an address in the initial state should be flagged as

Auth1.

Page 7: Netfilter - ipp.pt

7

• GATE2: Will be used to determine whether an address in the Auth1 state should be processed to

Auth2 or reset to the initial state.

• GATE3: Will be used to determine whether an address in the Auth2 state should be flagged as

Auth3 to allow an SSH connection or reset to the Initial state.

• PASSED: This chain will be used to briefly open the port for the SSH daemon for clients that have

knocked successfully. Any traffic from clients in this chain that is not destined for the SSH daemon

is dropped and the state is reset to Initial.

5.2. Input chain The knocking mechanism will be used only to control the creation of new external connections to the SSH

service. All traffic belonging to any already established connection will be immediately accepted as usual:

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Connections from the local machine will also be accepted:

iptables -A INPUT -i lo -j ACCEPT

Services that should remain externally and publicly accessible, like a Web server, can be configured now.

Allow all traffic directed to a Web server running on the default port 80:

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

All traffic that was not handled in the above rules is directed to the KNOCKING chain to implement the

actual knocking logic:

iptables -A INPUT -j KNOCKING

Verify that the server keeps its services available as usually.

5.3. Knocking Chain All incoming traffic not yet accepted will redirect into the chain called KNOCKING, presented on next

figure. In this chain, the packet will be directed to a specific test chain, depending on the sender state.

Packets from hosts in the Initial state will be handled by the GATE1 chain where they will be tested for the

first knocking target.

Packets from hosts in the Auth1 state will be directed to the GATE2 chain to test the second knocking

target.

Packets from hosts in the Auth2 state will be directed to the GATE3 chain to test the third knocking target.

Packets from hosts in the Auth3 state will be directed to the PASSED chain where the access to the port 22

can be accepted.

Page 8: Netfilter - ipp.pt

8

The general KNOCKING chain will pass traffic from clients that have successfully completed all the knocks

directly into the PASSED chain. This gate will be open only for the first packet from the successful client and

only for a 30 second window. After that, the rule will no longer match successfully.

iptables -A KNOCKING -m recent --rcheck --seconds 30 --name AUTH3 -j PASSED

While being in the AUTH2 state, traffic will be processed by the GATE3 chain. A 10 second time limit is

imposed before the previous knock expires.

iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH2 -j GATE3

While being in the Auth1 state, traffic will be processed by the GATE2 chain. A 10 second time limit is

imposed before the previous knock expires.

iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH1 -j GATE2

This will require clients to complete each next stage of the knocking within 10 seconds, and then connect

to the SSH daemon in another 30 seconds

All traffic that has not matched so far is sent back to GATE1, as usual. This will catch any attempt for the

first knock:

Page 9: Netfilter - ipp.pt

9

iptables -A KNOCKING -j GATE1

Verify that the server keeps its services available as usually.

5.4. GATE1 Chain

The KNOCKING chain will call this gate only if none of AUTH1, AUTH2 or AUTH3 flags is set.

When a client connects, this gate will see if it is sending a packet to our first knocking target. If it is, the

client will be flagged in state Auth1 and the connection is dropped.

iptables -A GATE1 -p tcp --dport 2222 -m recent --name AUTH1 --set \

-j LOG --log-prefix "Enter Auth1 "

This rule will match when the protocol being used is TCP and when the port it is trying to access is "2222",

the first knock target. If it matches, the recent module (called with -m recent) flags the requesting IP

address with the name AUTH1 (with the "--name AUTH1 –set" rule). This is the flag used to register the

successfully first knock. A logging target is added to allow further analysis of the gate behavior. The packet

is dropped after the flag is set, so that the client does not know if anything happened.

If it not a valid first knock, the connection is simply dropped.

iptables -A GATE1 -j DROP

Every kind of traffic in the KNOCKING sub-chains should be dropped (except the traffic for the SSH daemon

from successful knock clients), regardless of whether it matched the correct port. This is necessary for the

port knocking implementation to be valid. Persons attempting to connect should receive no feedback as to

what stage of the process they are in or even if such a mechanism is in place.

Confirm the produced implementation of the chains INPUT, KNOCKING and GATE1.

Page 10: Netfilter - ipp.pt

10

iptables -L -n

Test the implemented gate by issuing TCP requests to port 2222.

nping -tcp-connect -p 2222 ip_server

Observe the produced output in the system log.

dmesg -w

5.5. GATE2 Chain The second gate is configured in much the same way as the first. It is slightly more complex though.

The KNOCKING chain will call this second gate chain only if the AUTH1 flag is already set. This chain will

clear the AUTH1 flag and will set the AUTH2 flag if the port 3333 is being addressed.

The recent module will be used again, this time just to clear the named flag:

iptables -A GATE2 -m recent --name AUTH1 --remove

This is a processing rule, so it does not include any decisions or jumps. Execution continues in the second

rule.

Now the origin address is in a clean state with no flags set. At this point, the connection attempt is tested

for a correct match with next port target:

iptables -A GATE2 -p tcp --dport 3333 -m recent --name AUTH2 --set -j DROP

Page 11: Netfilter - ipp.pt

11

This is handled in much the same way as the first gate. If the correct port was knocked on, the AUTH2 flag

is set, indicating that the requesting address passed the second test. The packet is again dropped, giving

the client no indication of their progress.

Traffic that does not fit in this rule is not a valid second knock, but it can be a valid first knock. So, it will be

sent to GATE1 in order to provide its evaluation.

iptables -A GATE2 -j GATE1

To allow further debugging of the knocking system, some logging rules can be added to this chain.

iptables -I GATE2 3 -j LOG --log-prefix "State Auth0 "

iptables -I GATE2 1 -j LOG --log-prefix "Gate 2 "

Confirm the produced implementation of the chain GATE2. Test the implemented gates by issuing TCP

requests to ports 2222 and 3333 and analyzing the output in the system log.

5.6. GATE3 Chain The second gate can be used as an example to implement the third gate.

First, the AUTH2 flag that have been given to the requesting address is cleared.

iptables -A GATE3 -m recent --name AUTH2 --remove

Next, the third knock target is tested. If it matches, the AUTH3 flag is set, which indicates that the client

successfully completed all required knocks. As usual, the packet if dropped afterwards.

iptables -A GATE3 -p tcp --dport 4444 -m recent --name AUTH3 --set -j DROP

Page 12: Netfilter - ipp.pt

12

The traffic that did not match the third knock target is sent back to the first gate to see if it should count as

a successful first knock to restart the sequence:

iptables -A GATE3 -j GATE1

At this point, clients who've completed the correct knocking sequence should be flagged with AUTH3,

which will allow opening the service for them in the PASSED chain.

To allow further debugging of the knocking system, some logging rules can be added to this chain.

iptables -I GATE3 3 -j LOG --log-prefix "State Auth0 "

iptables -I GATE3 1 -j LOG --log-prefix "Gate 3 "

Confirm the produced implementation of the chains INPUT, KNOCKING, GATE1 and GATE2. Test the

implemented gates by issuing TCP requests to ports 2222 and 3333 and analyzing the system log.

5.7. PASSED Chain This chain is executed if a correct knocking sequence was previously detected. Here, the requested service

and the requester identification can be tested.

First, the usual flag reset is performed:

iptables -A PASSED -m recent --name AUTH3 --remove

Next, SSH connections from the users who have made it into the knocking chain are accepted:

iptables -A PASSED -p tcp --dport 22 -j ACCEPT

All other traffic that does not match the allowed services is sent back to the first chain to see if it matches

the first port knock target:

iptables -A PASSED -j GATE1

To allow further debugging of the knocking system, some logging rules can be added to this chain.

iptables -I PASSED 3 -j LOG --log-prefix "State Auth0 "

iptables -I PASSED 1 -j LOG --log-prefix "Passed chain "

At this point, all knocking chains are ready. It's time to test it out.

5.8. Test the Port Knocking There are several utilities that can be used to generate the TCP packets required to knock this service. The

following command sequence can be used to establish an SSH session.

nping --quiet -tcp-connect -p 2222 -c 1 ip_server

nping --quiet -tcp-connect -p 3333 -c 1 ip_server

Page 13: Netfilter - ipp.pt

13

nping --quiet -tcp-connect -p 4444 -c 1 ip_server

ssh -l my_test_user ip_server

For an UDP port knocking configuration the hping3 command could be used:

hping3 ip_server --udp -c 1 -p 2222

hping3 ip_server --udp -c 1 -p 3333

hping3 ip_server --udp -c 1 -p 4444

ssh -l my_test_user ip_server

To verify that the protection system is working as required, try access the SSH service after several

knocking sequences. Register the obtained results in the following table.

Port Knocking Sequence SSH

2222, 3333, 4444

2222, 3333

2222, 4444, 3333 1111, 2222, 3333, 4444

2222, 3333, 4444, 5555

Store the whole netfilter database in a file named ingre-lab13.ipt

iptables-save > ingre-lab13.ipt

Send this file together with the lab work report to your Lab teacher by eMail. Use a Subject header with the

format:

INGRE:2020:LAB13:StudentNumber

6. More information An alternative to the proposed iptables implementation is to use the knockd daemon, which is a dedicated

and highly configurable port-knock server. The configuration file that it uses is considerably simpler and

more readable than the equivalent for iptables. This can be a significant advantage for large and traditional

configurations.

More information about netfilter and iptables can be found at www.netfilter.org

Versions Versão 0.1, jml, Setembro 2017

Versão 0.2, jml, 24 Novembro 2017

Versão 0.9, jml, 24 Novembro 2017

Versão 1.0, crc, jml, 12 Dezembro 2018

Versão 1.1, jml, 6 Janeiro 2021

Page 14: Netfilter - ipp.pt

14