I want to test how the netfilter/ip6tables firewall handles some IPv6-related stuff like tiny/overlapped fragments, type 0 routing headers, excessive HPH options etc. For this I wanted to use Scapy to craft my own packets, but apparently Scapy using raw sockets means bypassing iptables. Is there another way of achieving my goal and how would I go about it? Some library I could use to make my own packets, which iptables can act on?
Run your packet injection program from a VM, and inspect the network connected to that VM.
Scapy is useful for such odd tasks. Sometimes what you want to do is just as easily done by writing small programs using the normal C APIs (including raw sockets in some cases, or TCP connections with odd options set). In many cases, a trivial TCP or UDP client in any high level language such as Python will do.
Related
For learning purposes I'm implementing TCP (for now just RFC 793) but I have no
idea how to test it. Most TUN/TAP stuff on the internet are out of date (e.g.
Linux API calls no longer work) and just doesn't explain enough. In addition, I
feel like a creating a device and forwarding packages etc. are not the best way
for learning purposes. For example, I'd rather only override socket(),
listen(), connect(), accept(), send(), recv() etc. in a program rather
than forwarding all ethernet traffic to a device/program that does the
bookeeping for the whole system rather than for a single program.
I'm wondering if this is possible. If not, I'd like to know the simplest way to
test a TCP implementation on Linux.
Because I'm following RFC 793, it'd be great if I could have an IP (Internet
Protocol as mentioned in the RFC) API in my application. Is this possible or do
I have to mess with TUN/TAP stuff?
Thanks..
If we talk about research I strongly recommend you read Engineering with Logic: Rigorous Test-Oracle Specification and
Validation for TCP/IP and the Sockets API
It contains section about testing TCP/IP implementation:
"EXPERIMENTAL VALIDATION: TESTING INFRASTRUCTURE"
You could try setting up two peers, one using a RAW socket and the other a TCP socket.
If they can communicate and packets are really delivered/recovered the same way TCP does, you know that your custom implementation is successful.
C sockets
C RAW sockets
C TCP implementation
All you need is to intercept all tcp packets with bits (syn, ack, fin, etc.) your application has sent and to see if it works properly:
It could simply be done with wireshark or other sniffer. When testing you will see all tcp packets with bits you've sent.
In order you want to see linux system calls which your application are calling, you can use GDB or any other debugger.
I'm trying to write a TCP transparent proxy to run on Linux.
I want to, upon receipt of an incoming connection, initiate a corresponding outgoing connection, but only accept (SYN|ACK) the incoming connection if the outgoing connection is successful.
TCP_DEFERRED_ACCEPT doesn't do what I want -- it always sends a SYN|ACK.
The question is: how do I accept TCP connections, but defer the SYN|ACK, with the Linux sockets API?
You can do that with Linux, but not via the socket API. You would use the NFQUEUE target which allows you to redirect some packets to userspace and decide their fate from within your program.
Obiously, you'd still have to parse the packet in userspace, but searching for a few TCP flags should not be that hard and not require a complete TCP stack. And this way Linux still does the whole network job.
In your case, it would seem possible that you both use NFQUEUE and classical sockets API. The first will give you early decisions, the latter TCP stream data access. Although I never tried it.
See https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/ for instance.
I am searching for a TCP traffic generator. The problem is that I do not simply want to send TCP traffic as it can be done with e.g. Iperf. I want to be able to configure the flags and other header fields and I want to react on incoming packets e.g. a TCP SYN.
So for example I want to send a TCP FIN packet if a TCP SYN arrives.
I prefer Linux tools but it would be also ok if the tool only runs under other OS.
I have looked into hping3, it looks promising. But I would like to look into other tools before choosing it.
SendIP can generate TCP packets, with options to manipulate SYN/FIN bits as well as other fields.
This sort of question really belongs on Server Fault.
Assuming that you have determined that for a given niche case, neither TCP or UDP are ideal, how would you go about writing your own IP based protocol?
For example, if you're developing on Linux, where would you look in the kernel to "hook" your protocol in?
Where would you start?
You can do this through a kernel module. I would start by reading how arp works for example. That is a simpler protocol since userspace doesn't send packets out with it directly.
The entry point for creating a new network protocol is dev_add_pack, and the code for arp can be found here.
If your protocol can be implemented directly on top of IP, then it can also be implemented wrapped in UDP packets - and the latter has the advantage that it'll pass through existing NAT devices and firewalls that would simply drop your custom protocol.
Read up on UNIX sockets and networking. It's not so much 'hooking' into the kernel, as it is opening a socket and sending your binary data over that.
I was wondering if there is any way to tune (on a linux system), the MTU for a given socket. (To make IP layer fragmenting into chunks smaller that the actual device MTU).
When I say for a given socket, I don't mean programatically in the code of the application owning the socket but rather externally, for example via a sysfs entry.
If there is currently no way do that, do you have any ideas about where to hook/patch in linux kernel to implement such a possibility ?
Thanks.
EDIT: why the hell do I want to do that ?
I'm doing some Layer3-in-Layer4 (eg: tunneling IP and above through TCP tunnel) tunneling. Unlike VPN-like solutions, I'm not using a virtual interface to achieve that. I'm capturing packets using iptables, dropping them for their normal way and writing them to the tunnel socket.
Think about the case of a big file transfer, all packets are filled up to MTU size. When I tunnel them, I add some overhead, leading in every original packet to produce two tunneled packets, it's under-optimal.
If the socket is created such that DF set on outgoing packets you might have some luck in spoofing (injecting) an ICMP fragmentation needed message back at yourself until you end up with the desired MTU. Rather ugly, but depending on how desperate you are it might be appropriate.
You could for example generate these packets with iptables rules, so the matching and sending is simple and external to your application. It looks like the REJECT target for iptables doesn't have a reject-with of fragmentation needed though, it probably wouldn't be too tricky to add one.
The other approach, if it's only TCP packets you care about is you might have some luck with the socket option TCP_MAXSEG or the TCPMSS target if that's appropriate to your problem.
For UDP or raw you're free to send() packets as small as you fancy!
Update:
Based on the "why would I want to do that?" answer, it seems like fragmenting packets if DF isn't set or raising ICMP "fragmentation needed" and dropping would actually be the correct solution.
It's what a more "normal" router would do and provided firewalls don't eat the ICMP packet then it will behave sanely in all scenarios, whereas retrospectively changing things is a recipe for odd behaviour.
The iptables clamp mss is quite a good fix for TCP over this "VPN" though, especially as you're already making extensive use of iptables it seems.
MTU is a property of a link, not socket. They belong to different layers of the stack. That said TCP performs Path MTU discovery during the three-way handshake and tries very hard to avoid fragmentation. You'll have hard time making TCP send fragments. With UDP the easiest is to force some smallish MTU on an interface with ifconfig(8) and then send packets larger then that value.