日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux raw限制端口访出,使用Linux raw socket时需要注意的一些问题

發(fā)布時(shí)間:2023/12/9 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux raw限制端口访出,使用Linux raw socket时需要注意的一些问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文的copyleft歸gfree.wind@gmail.com所有,使用GPL發(fā)布,可以自由拷貝,轉(zhuǎn)載。但轉(zhuǎn)載請(qǐng)保持文檔的完整性,注明原作者及原鏈接,嚴(yán)禁用于任何商業(yè)用途。

作者:gfree.wind@gmail.com

博客:linuxfocus.blog.chinaunix.net

一般情況下,我們使用raw socket都是用于發(fā)送icmp包或者自己定義的包。最近我想用raw socket

自己去創(chuàng)建TCP的包,并完成3次握手。

在這個(gè)過程中,發(fā)現(xiàn)了幾個(gè)問題:

1. 發(fā)現(xiàn)收不到對(duì)端返回的ACK,但是通過tcpdump卻可以看到。這個(gè)通過修改創(chuàng)建socket的API參數(shù)得以糾正。

原來創(chuàng)建socket使用如下參數(shù)s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)。因?yàn)閘inux的raw socket不會(huì)把

不會(huì)把UDP和TCP的分組傳遞給任何原始套接口。——見《UNIX網(wǎng)絡(luò)編程》28.3.

所以為了讀到ACK包,我們創(chuàng)建的raw socket需要建立在數(shù)據(jù)鏈路層上。

s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP))

這樣該socket就可以讀取到所有的數(shù)據(jù)包。當(dāng)然這樣的數(shù)據(jù)包無疑是非常龐大的,那么我們可以

使用bind和connect來過濾數(shù)據(jù)包。bind可以指定本地的IP和端口,connect可以指定對(duì)端的IP和端口。

2. 在修改完創(chuàng)建socket的API,我發(fā)現(xiàn)還有一個(gè)問題,到現(xiàn)在依然沒有找到合適的解決方法。

通過鏈路層的raw socket,我們可以收到對(duì)端的ACK。但是因?yàn)閘inux內(nèi)核也會(huì)處理TCP的握手過程,

所以,當(dāng)它收到ACK的時(shí)候,會(huì)認(rèn)為這是一個(gè)非法包,會(huì)直接發(fā)送一個(gè)RST給對(duì)端。這樣我們拿到了這個(gè)ACK,

也沒有實(shí)際的用處了——因?yàn)檫@個(gè)連接已經(jīng)被RST了。

我想,內(nèi)核之所以會(huì)直接發(fā)送RST,也許是因?yàn)槲覀儎?chuàng)建的是raw socket,但是發(fā)送的確是TCP包,

當(dāng)對(duì)端返回ACK時(shí),內(nèi)核根本不認(rèn)為我們已經(jīng)打開了這個(gè)TCP端口,所以會(huì)直接RST掉這個(gè)連接。

那么問題就在于,我們?nèi)绾胃嬖V內(nèi)核,我們打開了TCP的這個(gè)端口。

我想過一個(gè)方法,除了一個(gè)raw socket,再創(chuàng)建一個(gè)真正的TCP socket。但是細(xì)想起來,這條路應(yīng)該行不通。

在網(wǎng)上搜了半天,總算找到一個(gè)比較詳細(xì)的解釋了。原因給我猜想的相差不遠(yuǎn),當(dāng)我們使用raw

socket來發(fā)送sync包時(shí),內(nèi)核的TCP協(xié)議棧并不知道你發(fā)送了sync包,所以當(dāng)對(duì)端返回SYNC/ACK時(shí),內(nèi)核首先要處理這個(gè)包,發(fā)現(xiàn)它是一

個(gè)SYNC/ACK,然而協(xié)議棧卻不知道前面的sync,所以就認(rèn)為這個(gè)包是非法的,于是就會(huì)發(fā)送RST來中止連接。

原文如下:

This is one of the most frequently asked question by someone who is

experimenting with raw sockets and TCP/IP. It is known that the

'IP_HDRINCL' socket option allows you to include the IP header along

with the data. Since TCP encapsulates the IP header, we can also build

a TCP packet and send it over a network. But the problem is, a TCP

connection can never be established this way. The scenario is as

follows:

A TCP connection is always made by a three-way handshake.

So, initially you send a 'SYN' packet to the remote machine. If it is

actively listening on the port, you get a 'SYN/ACK' packet. So far so

good. But before you can respond, your machine sends an 'ACK/RST'

packet and connection attempt is ended. For the connection to be

complete, instead of the 'RST' packet, your machine should be sending

an 'ACK' to the remote machine.

The difference lies where the

connection is exactly made. Although the programs are communicating

after the connection is complete, the TCP connection is never between

two programs but rather between the TCP stacks of the two machines.

Here 'stack' means a layer of programs that communicates between each

other. TCP stack stands for the protocol driver or the actual network

transport protocol. Now lets look at exactly what happens when you send

a 'SYN' packet...

Since you are using raw sockets ('SOCK_RAW') and

not TCP/Stream sockets ('SOCK_STREAM') the TCP stack has no information

about what you are doing at program level. And since the 'IP_HDRINCL'

allows you to build any type of IP packet and send it along with the

data, you can build a 'SYN' packet and send it to the TCP server

program which is actively listening. But the point is that the 'SYN'

packet is being sent from your program and not the stack. In other

words the TCP stack of your machine has no idea how of sending the

'SYN' packet.

On the other side the 'SYN' packet is received by the

stack at the remote machine and not exactly by the program. As with the

case of the arrival of any 'SYN' packet, the stack at the remote

machine responds with a 'SYN/ACK' packet. This packet is now received

by the TCP stack of your machine. In other words, the incoming TCP

packet ('SYN/ACK') will be processed by the stack. Since it has no

information of the previous sent 'SYN' packet, it responds with a 'RST'

packet, as in the case of any improper or unacceptable packet for a

connection.

So the difference between sending and receiving a TCP

packet using raw sockets is, the former is not processed while the

latter is processed by the TCP stack of your machine.

該解釋來自于,

感謝Mr Andreas Masur 和Mr Mathew Joy. Thanks Mr Andreas Masur and Mr Mathew Joy.

作者:gfree.wind@gmail.com

總結(jié)

以上是生活随笔為你收集整理的linux raw限制端口访出,使用Linux raw socket时需要注意的一些问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。