如何设置linux内核不发送RST_ACK,这样我就可以在raw socket中给出SYN_ACK

时间:2011-11-08 08:33:36

标签: linux sockets tcp kernel

我想问一个关于原始套接字编程和linux内核TCP处理的经典问题。我已经完成了对linux raw socket programming questionHow to reproduce TCP protocol 3-way handshake with raw sockets correctly?TCP ACK spoofing等相同线程的研究,但仍无法得到解决方案。

我尝试制作一个不听任何端口的服务器,但是从远程主机嗅探SYN数据包。在服务器进行一些计算之后,它会将SYN_ACK数据包发送回相应的SYN数据包,这样我就可以手动创建TCP连接,而不包括内核的操作。我已创建原始套接字并在其上发送SYN_ACK,但数据包无法通过远程主机。当我在服务器(Ubuntu Server 10.04)上tcpdump和客户端(Windows 7)上的wireshark时,服务器返回RST_ACK而不是我的SYN_ACK数据包。在做了一些研究之后,我得到的信息是我们不能抢占内核的TCP处理。

还有其他方法可以破解或设置内核不响应RST_ACK到这些数据包吗? 我已经为服务器的本地ip添加了一个防火墙,告诉内核可能在防火墙后面有什么东西正在等待数据包,但仍然没有运气

2 个答案:

答案 0 :(得分:4)

您是否尝试drop RST using iptables?

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP

应该为你做好工作。

答案 1 :(得分:1)

我建议使用ip表,但是既然你也在讨论如何破解内核,这里有一个解释你如何做到这一点(我使用内核4.1.20作为参考):

当收到数据包(sk_buff)时,IP协议处理程序会将其发送到注册的网络协议:

static int ip_local_deliver_finish(struct sock *sk, struct sk_buff *skb)
{
        ...
        ipprot = rcu_dereference(inet_protos[protocol]);
        if (ipprot) {
           ...
           ret = ipprot->handler(skb);

假设协议是TCP,则处理程序是tcp_v4_rcv:

static const struct net_protocol tcp_protocol = {
    .early_demux    =   tcp_v4_early_demux,
    .handler    =  tcp_v4_rcv,
    .err_handler    =   tcp_v4_err,
    .no_policy  =   1,
    .netns_ok   =   1,
    .icmp_strict_tag_validation = 1,
};

所以调用tcp_v4_cv。它将尝试为收到的skb找到套接字,如果没有,它将发送reset:

int tcp_v4_rcv(struct sk_buff *skb)
{
    sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
    if (!sk)
        goto no_tcp_socket;

no_tcp_socket:
    if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
        goto discard_it;

    tcp_v4_send_reset(NULL, skb);
    ...

有许多不同的方法可以解决这个问题。您可以转到xfrm4_policy_check函数并修改/更改AF_INET的策略。或者您可以简单地注释掉调用xfrm4_policy_check的行,这样代码将始终转到discard_it,或者您可以注释掉调用tcp_v4_send_reset的行(但这会产生更多后果)。

希望这有帮助。