Как настроить ядро ​​Linux не отправлять RST_ACK, чтобы я мог дать SYN_ACK в сыром сокете - PullRequest
4 голосов
/ 08 ноября 2011

Я хочу задать классический вопрос о программировании сырых сокетов и обработке TCP ядра Linux.Я провел исследование для некоторых тех же потоков, таких как вопрос программирования linux raw сокетов , Как правильно воспроизвести трехстороннее рукопожатие по протоколу TCP с raw сокетами? и TCP ACKподделка , но по-прежнему не может найти решение.

Я пытаюсь создать сервер, который не прослушивает ни один порт, но прослушивает пакеты SYN с удаленных хостов.После того, как сервер выполнит некоторые вычисления, он отправит обратно пакет SYN_ACK в соответствующий пакет SYN, чтобы я мог создать TCP-соединение вручную, не включая операции ядра.Я создал необработанный сокет и отправил через него SYN_ACK, но пакет не может пройти на удаленный хост.Когда я tcpdump на сервере (Ubuntu Server 10.04) и wireshark на клиенте (Windows 7), сервер возвращает RST_ACK вместо моего пакета SYN_ACK.После некоторых исследований я получил информацию о том, что мы не можем предотвратить обработку TCP ядром.

Есть ли еще какие-нибудь другие способы взломать или настроить ядро, чтобы оно не отвечало RST_ACK на эти пакеты?Я добавил брандмауэр в локальный ip сервера, чтобы сообщить ядру, что, возможно, за брандмауэром что-то есть, что ожидает пакет, но все равно не повезло

Ответы [ 2 ]

4 голосов
/ 20 декабря 2011

Вы пытались сбросить RST с помощью iptables?

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

должно выполнить эту работу за вас.

1 голос
/ 05 мая 2016

Я рекомендую использовать таблицы 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 (что будет иметь больше последствий).

Надеюсь, это поможет.

...