Source nat in netfilter prerouting hooks - linux-kernel

We are developing our own kernel module that does advanced source nat in netfilter prerouting hook. After upgrading from Linux kernel 2.6.32 (Ubuntu 10.04) to 2.6.35 (Ubuntu 10.04 lucid-back-ports) it seems that SNATted packets are simply dropped inside the Linux kernel.
I know that SNAT was never advised to be done in Prerouting hooks for general usage (Netfilter mailing list), but there are still some reasons why we would prefer to do source natting before the actual routing decision is made.
Has anyone experience of developing kernel modules that do SNAT in netfilter prerouting hook for 2.6.35+ linux kernel? What exactly should be changed in linux-kernel/netfilter-kernel-module code so that SNATted packets would not be dropped? Maybe SNAT in prerouting is simply a bad idea for 2.6.35+ Linux kernel and we should better use nf_marks for routing decision and do the SNAT in postrouting?
I am using Ubunut 10.04 with back-ported Linux kernel (2.6.35) on X86_64.

Start with finding exact line which drops the packet.

Have you re-calculated all checksums after updating the source IP? Keep in mind that you will also need to update TCP/UDP checksums as they are based on the src/dst IP address.

Related

Setting up two-machine kernel debugging over network

I'd like to check the option to debug my kernel driver installed over remote physical machine (since I don't have firewire cables). Reading the relevant documentation, I haven't seen any limitation about remote physical debugging medium, so I deduced both firewire cables and ip over wireless network should work.
I thought that lldb remote connection using kdp-remote <machine-ip> would do the trick, but I don't get any response.
From remote VM however, it succeed even though the VM can be located on remote physical machine.
My boot-args configuration are keepsyms=1 debug=0x144 -v
We figured out the problem in the comments (item 2 below), but for posterity, here's a list of things to check if xnu kernel debugging isn't working:
The target machine must have a physical ethernet port which is connected via PCIe or Thunderbolt, or you must use a direct firewire connection (optionally via Thunderbolt). USB to ethernet adapters will not work on the target end. The client machine is less fussy, you can use wifi or USB-ethernet there.
The protocol uses UDP, not TCP. Have you got a firewall running on your lldb machine which might be blocking UDP packets? (You could try sending udp packets from target to client with the nc (netcat) tool while the machine is not crashed.)
Is the ARP entry correct on the client machine? arp <target ip> should yield the target interface's MAC address.
The crashed Mac will NOT respond to pings, only to KDP packets via UDP. So not getting pings back doesn't mean anything.
As far as I'm aware the machine won't request a new DHCP lease when it crashes, so that shouldn't be the problem, but you can always try setting a static IP address just to be sure.
Did you reboot after setting the boot-args? They only take effect on a fresh boot.
If SIP is active, you can only set nvram variables from the recovery environment from OS X/macOS 10.11 onwards. You can run nvram boot-args to verify that the settings stuck.
My personal recommendation is to use FireWire for kernel debugging if possible, it seems to be the fastest and most reliable in my experience.

has the linux kernel support sctp protocol in container of LXC/docker yet?

I'm using docker to set up an application in container which will use sctp for communication. The network connection is fine, i can ping each other, but I run the sctp-test from lksctp_tools and met problem below:
[root#a2c771287273]#sctp_test -H 0 -P 250 -l
local:addr=0.0.0.0, port=250, family=2
seed = 1417166664
Starting tests...
socket(SOCK_SEQPACKET, IPPROTO_SCTP)
*** socket: failed to create socket: Address family not supported by protocol ***
i did a little google and found out reason from post in lxc mailing list that it's because the kernel doesn't support sctp protocol in linux container. for details, please refer to post below:
https://www.mail-archive.com/lxc-users#lists.sourceforge.net/msg03826.html
But it was two years ago, I'm wondering if it's supported by kernel now. the version of kernel i'm using is 2.6.32-431.29.2.el6.x86_64, do i need to use other kernel? or anyone of you met same problem as me and happen to have some workaround here?
Thanks in advance.

Set up port forwarding for SSLSplit (Supports ipfw fwd only) on OSX Mavericks

I am trying to set up SSLSplit on OSX Mavericks according to this tutorial.
I got it working on a Ubuntu Machine, so I know SSLSplit works just fine and the issue is only with packets not being forwarded to the port on which SSLSplit is listening on Mavericks. On the SSLSplit homepage it says :
SSLsplit currently supports the following operating systems and NAT engines:
Mac OS X: ipfw fwd
so I try to set up port forwarding using the following two commands, but I read somewhere that ipfw has been dropped in OSX 10.9 Mavericks.
sudo sysctl -w net.inet.ip.forwarding=1
sudo ipfw add fwd 127.0.0.1,8080 tcp from 192.168.2.2 to any 443 in via bridge100
I even tried this in OSX 10.8.5, the commands don't give any error on either operating systems but traffic is not being forwarded.
I also tried the pfctl approach as mentioned here. But with this method, I don't think SSLSplit is too happy, since I think the packet loops around, I get too many files open error and SSLSplit crashes. Can SSLSplit work with pfctl? Does it really care how traffic is forwarded to the port on which it is listening? Or does the error occur because of some misconfiguration on my part?
Has someone been able to use SSLSplit on OSX Mavericks? Can you guide me with the port forwarding part? It would be better if you could explain the entire process.
I am not using tools such as mitmproxy since I have to decrypt the SSL Layer over non-HTTP Traffic.
Can SSLSplit work with pfctl? Does it really care how traffic is forwarded to the port on which it is listening? Or does the error occur because of some misconfiguration on my part?
When receiving a connection on a socket, SSLsplit needs to determine where the connection was originally destined to, before it got intercepted and redirected by ipfw, pf or some other NAT mechanism. Each NAT mechanism requires that SSLsplit uses a different way of figuring out what the original destination address was. When using pf rdr, that mechanism is the DIOCNATLOOK ioctl interface. For ipfw fwd, that mechanism is a standard getsockname() call. If you call getsockname() on a connected socket redirected by pf rdr, you will receive the local socket endpoint which is the IP address and port that sslsplit is listening on, therefore creating and endless packet loop. If you do that on a ipfw fwd divert socket, you get the original destination.
Has someone been able to use SSLSplit on OSX Mavericks? Can you guide me with the port forwarding part?
Unfortunately, there is currently no way to make SSLsplit support pf on Mac OS X since Apple does not seem to install the required header files required to use the DIOCNATLOOK ioctl interface, and the headers shipping with the source distribution differ from the OpenBSD/FreeBSD counterparts in that the ioctl interface has slightly changed and was made private. It would be possible to add support for that Apple modified private ioctl interface to SSLsplit, but nobody has written the code to do that so far.
SSLsplit is quite usable in SNI configurations though, where the destination address is taken from the SNI hostname the client asks for, but that of course only works with clients supporting SNI. Also working are configurations with static destinations.
There is also pf divert-to which would be compatible with ipfw fwd, but that feature of pf is not available on Mac OS X pf so far.
Also see this bug tracker issue: https://github.com/droe/sslsplit/issues/15
Update: SSLsplit git master now includes experimental support for pf on Mac OS X 10.7, 10.8 and 10.9 which will be part of the upcoming 0.4.8 release.

IPsec in Linux kernel - how to figure out what's going on

I'm writing an IPsec implementation for a microcontroller and I want to test it using a standard Linux box running Debian Lenny. Both devices should secure the communication between them using IPsec ESP in tunnel mode. The keys are setup manually using setkey. There's no (or at least should be no) user space program involved in processing an IPsec packet. Now I want to see how my created packets are processed by the Linux kernel. To see the raw packets I capture them using tcpdump and analyze them using wireshark.
What's the best way to obtain debug information about IPsec processing?
How can I figure out whether the packet is accepted by the kernel?
How can I view the reason for a packet to be dropped?
You can instrument the XFRM (or perhaps ipv4/esp.c) kernel code to print out debug messages at the right spots.
For example, in net/ipv4/esp.c there exists a function esp_input() which has some error cases, but you'll see most the interesting stuff is in the xfrm/*.c code.
That said, I didn't have a problem interoperating a custom IPSec with Linux. Following the 43xx specs and verifying the packets came out correctly via wireshark seemed to do well. If you're having issues and don't want to instrument the kernel then you can setup iptables rules and count the number of (various type of) packets at each point.
Finally, be sure you've actually added a security policy (SP) as well as a security association (SA) and setup firewall rules properly.

iptables and libpcap

i have rule set up to drop udp/tcp packets with matching strings. however, my program which captures packet using libpcap, is still able to see this packet.
Why is this/, what should be the iptable rules to drop packets before it is seen by libpcap?
Is there anyway,perhaps other than iptables rules, to drop this packet before it is seen by libpcap/tcpdump?
Yes, libpcap sees all the packets..
They are being captured before being processed by the netfilter.
Did you try to change the priority of the netfilter hook you use? if you try hooking with the highest priority for incoming packets, it will get the packet before the packet socket kernel code, which is the way libpcap uses to capture packets.
* I assume you are using linux *
EDIT:
Libpcap uses different ways to capture packets - according to the OS. on linux it uses packet socket which is implemented in kernel code using the netfilter framework.
Theres no way for libpcap to see the packets before netfilter, netfilter is a kernel module, and processes all packets before they hit user mode, it can even see the packets before the kernel sees it.
Could you explain further explain ?
Its possible that libpcap is also setting hooks on netfilter that overwrite the one in iptables. The real issue is that looking and what hooks are set on netfilter is far from trivial, and can only be done in kernel mode. Investigate how libpcap gets the packets.

Resources