Câu hỏi Thư viện lỗ TCP (NAT Traversal) hay gì đó?


Tôi muốn làm TCP Hole Punching (NAT Traversal) trong C #. Nó có thể được thực hiện với một máy chủ hẹn gặp nếu cần thiết. tôi đã tìm thấy http://sharpstunt.codeplex.com/ nhưng không thể làm được điều này. Lý tưởng nhất tôi cần một số phương pháp mà tôi cung cấp cho một số cổng (int) như là tham số sau khi một cuộc gọi đến phương pháp này có sẵn ("Port Forwarded") tại NAT. Nó cũng sẽ OK nếu phương thức chỉ trả về một số số cổng mà sau đó có sẵn tại NAT. Có ai đã làm điều này trong C #? Bạn có thể cho tôi các ví dụ làm việc cho sharpstunt hoặc cái gì khác?


32
2018-03-14 19:39


gốc


Hmm ... tại sao trường hợp đặc biệt này lại cần thiết? nếu nó chỉ là về kết nối, hãy cài đặt bất kỳ Proxy nào và kết hợp nó trong Webclient. cũng nên giải quyết nó. - cRichter
Proxy rất chậm và không an toàn.


Các câu trả lời:


Trong mỗi kịch bản mạng, lỗ đục lỗ TCP hoạt động theo cách tương tự với lỗ đục lỗ UDP. Ví dụ, nếu hai đồng nghiệp A và B đứng đằng sau các NAT khác nhau, thì gói SYN đầu tiên của mỗi peer được gửi tới một peer khác sẽ mở ra một lỗ kết hợp với địa chỉ public của nó trong NAT tương ứng của nó. Nếu gói SYN đầu tiên của A đến B đạt tới NAT của B trước khi gói SYN đầu tiên của B đến A đạt tới NAT của B, NAT của B coi gói SYN của A không được yêu cầu và loại bỏ nó. Tuy nhiên, sau đó gói SYN đầu tiên của B có thể di chuyển qua NAT của A thành công vì NAT của A nhận ra địa chỉ công khai của B làm đích đến của phiên đi mà A đã bắt đầu.

Vì vậy, có. Có thể TCP được kết nối. Tôi không hiểu tại sao mọi người lại nghĩ khác.

Ngoài ra, bạn có thể không tạo kiểu bahaviour này theo cách thủ công không? Nó không cần phải phụ thuộc vào bất kỳ giao thức cụ thể miễn là các bước là như nhau để thu thập tất cả các thông tin cần thiết.

Nói chung, lỗ đục lỗ TCP (3.2.1) tiến hành như sau:

Khách hàng: A, B Máy chủ: S

• A sử dụng kết nối của nó với S để yêu cầu S kết nối với B. • S trả lời A bằng địa chỉ riêng và công khai của B, đồng thời gửi địa chỉ của A đến B.

• A và B không đồng bộ tạo kết nối đi tại- tempts (gửi gói SYN) đến công khai của nhau và địa chỉ riêng, từ cùng một cổng mà họ đã sử dụng để đăng ký với S. Đồng thời, họ lắng nghe Kết nối TCP đến cố gắng trên TCP cục bộ của họ cổng.

• A và B chờ phản ứng SYN-ACK cho ra ngoài đi các gói SYN hoặc yêu cầu kết nối đến (Gói SYN). Nếu kết nối không thành công, đồng đẳng có thể thử lại nó lên đến một khoảng thời gian chờ tối đa.

• Một khi quá trình bắt tay ba chiều đã hoàn thành, các đồng nghiệp xác thực lẫn nhau. Nếu authentica- tion không thành công, các đồng nghiệp đóng kết nối đó và đợi đến một kết nối khác được xác thực thành công. Các Kết nối được xác thực thành công đầu tiên sẽ được sử dụng để chuyển dữ liệu TCP.

(Tôi biết điều này không có nhiều câu trả lời nhưng không đủ chỗ để nhận xét).


17
2018-06-04 19:52



Điều này sẽ không hoạt động với Enterprise NAT (NAT đối xứng). Tại sao A và B gửi tới địa chỉ riêng? Chúng không thể được định tuyến qua Internet. Những gì bạn mô tả là STUNT - tobias
Tôi chỉ mô tả quá trình đục lỗ. STUNT là một bộ công cụ thực sự để hỗ trợ trong quá trình đục lỗ. Điểm chính của câu trả lời của tôi là cho thấy rằng việc đục lỗ TCP thực sự là có thể bởi vì ai đó đã đề cập đến nó. Tôi biết rằng có những tình huống trong đó nó sẽ không hoạt động nhưng đó không phải là câu hỏi. (Về lý do tại sao đề cập đến địa chỉ riêng. Tôi không biết. Tôi đã sao chép phần lớn dữ liệu từ các nguồn khác). - SilverX
Wikipedia cho STUN trong "Hạn chế": Vì địa chỉ IP của máy chủ STUN khác với địa chỉ của điểm cuối, trong trường hợp NAT đối xứng, ánh xạ NAT sẽ khác với máy chủ STUN so với điểm cuối. TURN cung cấp kết quả tốt hơn với NAT đối xứng. - SilverX


Có vẻ như bạn có thể nhận được TCP và UDP lẫn lộn. TCP là giao thức định hướng kết nối, dễ hiểu bởi tường lửa và bộ định tuyến và yêu cầu một người khởi xướng (máy khách) và một người nghe (máy chủ). Nếu cả máy khách và máy chủ đều nằm sau tường lửa hoặc NAT, bạn không thể đục lỗ thông qua mà không cần cả hai kết nối với một số máy chủ proxy (không được tường lửa). Vấn đề với điều này là sau đó proxy sẽ chịu trách nhiệm chuyển tiếp tất cả lưu lượng truy cập của họ.

Từ câu hỏi của bạn, có vẻ như bạn quan tâm nhiều hơn đến việc đục lỗ UDP, khai thác chất béo mà UDP là không trạng thái và không được định hướng kết nối. Do đó, hầu hết tường lửa theo dõi trạng thái sẽ thực hiện "phỏng đoán tốt nhất" về luồng dữ liệu UDP và giả sử rằng lưu lượng truy cập để lại trên một cổng nhất định sẽ nhận được trả lời trên cùng một cổng và tự động định tuyến lại chúng. Nếu sử dụng một số phương tiện ngoài kênh (như máy chủ TCP đơn giản chuyển địa chỉ và không dữ liệu), cả hai đồng nghiệp có thể truyền dữ liệu cho nhau trên cùng một cổng, tường lửa / bộ định tuyến NAT tương ứng sẽ mở lỗ cho phép lưu lượng truy cập trong.

Đối với làm thế nào để làm điều đó, tất cả phụ thuộc vào cách bạn sẽ nhận được địa chỉ IP của các đồng nghiệp với nhau. Một khi bạn đã có nó, chỉ cần bắt đầu truyền các gói UDP trên một cổng đã đồng ý và chờ trả lời.


2
2017-07-08 18:09



Tôi có thể làm lỗ UDP Hole được gọi là STUN khá dễ dàng. NHƯNG bạn có thể làm lỗ TCP Hole, nó chỉ phức tạp hơn và được gọi là STUNT (cuối cùng là TCP). sharpstunt.codeplex.com tuyên bố có thể làm điều đó nhưng tôi không thể làm cho nó hoạt động. Ngoài ra còn có một số libs JAVA làm điều đó ... - TobiHeidi
+1> Nếu cả máy khách và máy chủ đều nằm sau tường lửa hoặc NAT, bạn không thể đục lỗ thông qua mà không cần cả hai máy chủ và máy chủ proxy kết nối - Valmond
Hãy nhớ rằng STUN không hoạt động với tất cả các loại NAT. ICE định nghĩa TURN là dự phòng. - tobias
Cú đấm lỗ TCP là có thể, nhưng nó yêu cầu máy chủ khởi tạo kết nối (nhưng máy chủ không cần thiết sau khi liên kết được thiết lập - ít nhất đó là cách tôi hiểu nó) https://en.wikipedia.org/wiki/TCP_hole_punching - Markaos


Chúng tôi cùng nhau đặt một thư viện IceLink mà không P2P streaming bằng cách sử dụng ICE / STUN / TURN với đầy đủ NAT traversal. Cú đấm lỗ dựa trên STUN hoạt động cho phần lớn các bộ định tuyến để thiết lập kết nối trực tiếp giữa các máy ngang hàng và cho các bộ định tuyến "xấu" trên mạng, kết nối quay trở lại một rơle dựa trên TURN.


2
2017-12-04 23:06



Có vẻ đó là một thư viện thương mại (chỉ cần nói) - Valmond


Câu hỏi là khá cũ nhưng đối với bất cứ ai tìm kiếm một giải pháp, bạn nên nhìn vào Dự án Open.NAT nó thực sự dễ sử dụng và làm việc với cả UPNP và PMP NAT!

Giả sử bạn muốn chuyển tiếp cổng ngoài 1700 đến cổng địa phương 1600, tất cả những gì bạn phải làm là:

var discoverer = new NatDiscoverer();
var device = await discoverer.DiscoverDeviceAsync();
await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700, "The mapping name"));

Bạn cũng có thể liệt kê tất cả các ánh xạ hiện có, do đó bạn có thể xác thực rằng cổng của bạn chưa được sử dụng.

var sb = new StringBuilder();
var ip = await device.GetExternalIPAsync();

sb.AppendFormat("\nAdded mapping: {0}:1700 -> 127.0.0.1:1600\n", ip);
sb.AppendFormat("\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+");
sb.AppendFormat("\n| PROT | PUBLIC (Reacheable)           | PRIVATE (Your computer)        | Descriptopn                        |                         |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
sb.AppendFormat("\n|      | IP Address           | Port   | IP Address            | Port   |                                    | Expires                 |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
foreach (var mapping in await device.GetAllMappingsAsync())
{
    sb.AppendFormat("\n|  {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|",
        ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime());
}
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
Console.WriteLine(sb.ToString());

Ngoài ra còn có một bài đăng blog về NAT Traversal trên MSDN: https://blogs.msdn.microsoft.com/ncl/2009/07/27/end-to-end-connectivity-with-nat-traversal/


2
2018-05-18 18:28



làm việc liên tục cho tôi ... - beppe9000
Có một chút khó khăn để làm cho nó hoạt động hoàn hảo và với một số phần cứng mạng, nó có thể không hoạt động chút nào. - JPelletier
Chỉ cần rõ ràng, UPnP không phải là điều tương tự như lỗ hổng tường lửa. Cả hai đều là dạng NAT traversal, tuy nhiên UPnP chỉ là một cách tạo cổng chuyển tiếp cổng trong NAT, trong khi lỗ đục lỗ có thể kết nối hai đồng nghiệp mà không xác định rõ ràng các mục này. - stenlan


http://sipsorcery.codeplex.com có một máy chủ làm việc stun.

SipSorcery.core -> SipSorcery.Net -> Stun


1
2018-04-26 11:00



tôi rất thích có STUNT không STUN nhưng cảm ơn nó có thể là một điểm khởi đầu - TobiHeidi
Tôi nghĩ rằng nó có cả hai. stunt chỉ là stun qua TCP, phải không? - jgauffin
stunt là stun nhưng với TCP thay vì UDP. Bạn không thể thay thế UDP bằng TCP và nó hoạt động giống như ma thuật. Unipunatly SipSorcery.core -> SipSorcery.Net -> Stun KHÔNG cung cấp STUNT ... - TobiHeidi
Không có cú đấm lỗ TCP, đó là cú đấm lỗ UDP. - Pavel Radzivilovsky


Tôi không quen với chủ đề của bạn, nhưng tôi tình cờ biết một P2PVPN mã nguồn mở, sử dụng một lib để làm NAT. Bạn có thể kiểm tra tại đây (www.SocialVPN.org).

Chúc may mắn.


0
2018-04-23 08:02