I mentioned about using Scapy to test my translation code in the last post. This post is going to reveal how I managed to find out if the translations that the code I wrote was providing were correct. Good thing is that they are correct. Some I have still to figure out but the other ones are working perfectly fine.
I’ll explain with the help of a simple example. Let’s consider TTL the thing to be tested. Patch for translation of ttl can be found here.
How did I carry out the testing?
I did the following:
- Got up from the bed.
- Tried to do some work that I’ve been stuck on for days.
- Failed again miserably at doing that work.
- Realized I’m not done with translation work yet so I launched Scapy and rest remains a mystery. Kidding. Read further.
What does a packet look like?
Also, with scapy, you can see the attributes of a packet as follows:
Now, let’s try using the magical iptables-translate to get the code for nftables for the match ttl. I’m using the same one that served as an example in the patch.
Now try to add up this rule into your chain. Results:
Now comes the job of Scapy. Since we have set up our chain to accept IP packets with ttl equal to 3, we forge a packet exactly like that.
Note that there are lot easier ways to send a packet with particular attributes but if you’re just beginning, nomenclature is not a bad idea. Now that we have our perfect packet made, let’s try to send the packet and observe changes in the chain.
About sr1() : The
sr1() function is used to send a packet or group of packets for receiving 1 response instead of continuing to listen for response.
Status of chain:
No change. That’s weird. Right? We forged a packet with the exact attributes as the rule expects.
Looking more closely at the packet attributes,
127.0.0.1 is so familiar!
OK, not so familiar.
Loopback interface. That’s what we’re working on if source and destination addresses are let set to their default values. And what’s loopback interface? A mirage. Packets going through this are not assembled or disassembled. So, the kernel never really receives any packet through this interface as it is fake. So, we need to make use of PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW. What this means is that we will now be using one layer above to build our packets.
This can be done by feeding the following to Scapy:
Scapy shows back decently about using PF_PACKET sockets.
Now, let’s try sending our testpkt again.
This time when we check our chain, we get the following:
We can see 1 packet of 20 bytes captured by our firewall.
Cool thing to do, already informed you that.
Make sure that if you’re checking nftables in general then add up counters so that you can see the packets coming/going. Using iptables-translate utility will always do that for you.
So, this is how I managed to test some translations, others were done differently, some are still left, I’ll post more about testing if something interesting comes my way.
Thanks for reading.