首页 文章

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

提问于
浏览
4

我想问一个关于原始套接字编程和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 回答

  • 4

    你试过drop RST using iptables?

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

    应该为你做的工作 .

  • 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找到套接字,如果没有,它将发送重置:

    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的行(但这会产生更多后果) .

    希望这可以帮助 .

相关问题