Chion82 / kcptun-raw

Kcptun with raw socket and fake TCP headers.
GNU General Public License v3.0
416 stars 101 forks source link

SYN flag #19

Open zhorakuz opened 6 years ago

zhorakuz commented 6 years ago

Hi. Can you add to kcptun-raw option - only SYN flag a tcp header ? All data must is transmitted only with SYN flag. Without 3 way handshake

Chion82 commented 6 years ago

What is the problem with 3 way handshake enabled? Here is a simple program where you can test the connectivity with fixed TCP flags: https://gist.github.com/Chion82/699ae432a27507242ea788df324f4e47

zhorakuz commented 6 years ago

Firewall block all packets with ACK flags. Only packets SYN flag are allowed. Can you modify you great tool ? Is this possible ?

Chion82 commented 6 years ago

It is totally possible and actually relayRawSocket, by which kcptun-raw is inspired, is doing what you want by sending TCP packets with only SYN flags.

However:

zhorakuz commented 6 years ago

I tried to run it relayRawSocket on Ubuntu 16.04. But it does not work on Ubuntu 16.04. (client not send any packets to server) Your program kcptun-raw runs well for me on Ubuntu 16.04 . But your program uses other flags - client to server -> SYN
server to client <- SYN+ACK
client to server -> ACK
server to client <- PSH+ACK
client to server -> PSH+ACK
And my corporate firewall drop this packets - (tested on you tools and Hping3)

client  to server  ->  SYN                    ok
server to client   <-  SYN+ACK           ok
client  to server  ->  ACK                    drop(flag RST)
server to client   <-  PSH+ACK           drop(flag RST)
client  to server  ->  PSH+ACK           drop(flag RST)

It would be very cool if you teach your program to work only on the SYN flag. Yes, I understand that some firewalls are struggling with syn flood. But not mine

Chion82 commented 6 years ago

I've added the SYN-only feature to syn-only branch with additional --syn-only option. Make some tests and see if it works.

zhorakuz commented 6 years ago

I tested with this option 1. The client sends these flags to the server SYN PSH+ACK 2. the server does not respond any packets see image server Ubuntu 16.04x64 1 client Ubuntu 16.04x64 3 client wireshark 2 I tried to change different ports, but nothing helps. Have you tested this option yourself? Does it work for you?

Chion82 commented 6 years ago

@zhorakuz you should enable --syn-only BOTH on client and server side

zhorakuz commented 6 years ago

Yes. See image

Chion82 commented 6 years ago

The client should have printed Use SYN-only mode on the screen but I don't see any. Did you do a fresh build by make clean ?

zhorakuz commented 6 years ago

The client should have printed Use SYN-only mode on the screen but I don't see any. yes

Did you do a fresh build by make clean ? How to do it? ./autogen.sh ./configure make clean make ?

Chion82 commented 6 years ago

@zhorakuz Just rm -rf the entire directory and git clone && git checkout to make sure you have the latest syn-only branch. I don't wanna repeat git basics anymore here. If you look into the commit you'll see the --syn-only option really exists and it actually works on my local environment.

zhorakuz commented 6 years ago

Ok. Now client printed Use SYN-only mode and send to server SYN packets. But The server does not respond any packets to client. Test please in you machine this option

Chion82 commented 6 years ago

The server does not respond any packets to client.

Your server DOES respond once it receives packets from the client. Please use tcpdump on the server to verify that for yourself. Possible causes of connection failure would be either:

I have already tested this feature dozens of times on my virtual machines with bridged network and it works as expected.

zhorakuz commented 6 years ago

Now I checked the connection through the local network. Working. Connection through the internet network. Not working. 111 Can the logic of work between the client and the server be broken? See the screenshot. Server 192.168.10.106 Client 192.168.10.101 The client sends the SYN to the server. The server resets the connection, although SYN+ACK must respond. I think this is the problem

Chion82 commented 6 years ago

The server resets the connection, although SYN+ACK must respond.

Nope. That's why iptables rules are required, where we tell the kernel to ignore our user-space TCP stacks and not to send RSTs.

From kcptun-raw README:

on server: iptables -A INPUT -p tcp --dport SERVER_PORT -j DROP on client: iptables -A INPUT -p tcp -s SERVER_IP --sport LISTEN_PORT -j DROP

By adding these iptables rules no more RST happens.

Another possible cause might be the MTU problem. But this doesn't explain why your client received exactly nothing, even not receiving the initial negotiating packets which are relatively small sized.

client to server -> SYN ok server to client <- SYN+ACK ok client to server -> ACK drop(flag RST) server to client <- PSH+ACK drop(flag RST) client to server -> PSH+ACK drop(flag RST)

It looks like the problem is not caused by firewall dropping ACKs, but you haven't configure iptables on both server and client side properly.

zhorakuz commented 6 years ago

I checked and with customized rules iptables and without customized rules iptables. The result is one. Through the local network works. Through the Internet does not work. If you can test through the Internet - tell me. I have another question - I can modify in this code iph-> saddr = inet_addr (packetinfo-> source_ip); // Spoof the source ip addres An castom ip address? For example 8.8.8.8. If I can, how?

Chion82 commented 6 years ago

Please use tcpdump ON THE SERVER to see if the packets are sent out while using wireshark on the client. Then we can make a diagnosis to see what happens.

I can modify in this code iph-> saddr = inet_addr (packetinfo-> source_ip); // Spoof the source ip addres An castom ip address? For example 8.8.8.8.

Yes you can. Modifying src/common.c: int update_src_addr() does the trick. Just change the code to: remote_addr.sin_addr.s_addr = inet_addr("8.8.8.8");

zhorakuz commented 6 years ago

After i change remote_addr.sin_addr.s_addr = inet_addr("8.8.8.8"); I see source my ip on tcpdumd and wireshark. Not 8.8.8.8

Chion82 commented 6 years ago

update_src_addr() is for automatically probing an appropriate source address using an external destination IP address, but not actually change the source address to a fixed one. If you are willing to exactly use a specified source address such as 8.8.8.8, modify src/tran_packet.c: int send_packet() and change the code to:

iph->saddr = inet_addr("8.8.8.8");    //Spoof the source ip address

Do you see packets trying to send out from the server, by using tcpdump on the server?

zhorakuz commented 6 years ago

ip is changed and i see TCP: [Bad CheckSum]

Chion82 commented 6 years ago

Oh you should also update:

psh.source_address = inet_addr("8.8.8.8");
zhorakuz commented 6 years ago

Now checksum ok. But server not send packets to client)