-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TCP knocks not being received over mobile Internet #23
Comments
Most likely, your device that receives knocks is incorrectly configured. Check the interface that is listening. If this works on the local network, then you are listening on the local interface. You need to listen to another interface that looks "outside". Or both, if you want it to work both on the local network and outside. App is fine. The proposed improvements will break the application - the resulting packet sequences will be incorrect. |
The device that receives the knocks is not misconfigured. I'm verifying the activity by monitoring the incoming interface with tcpdump, and as stated, when I use another application to initiate a TCP connection from the phone to the device via the carrier's network I can see them. I don't see how adding a delay before closing the initiated connection could possibly cause out-of-order packets, since it would still be closed before starting the next connection in the sequence. For more safety it could wait delay / 2 before closing the connection, then delay / 2 before advancing to the next packet in the sequence. |
Just check it with another port knocking app. For example, this one. As for the delay... connect() and delay will send more than one SYN packet. Let's say we need to send packets to ports 222, 333, 444 in this order. If we add a delay after connect(), the resulting sequence will look like "222, 222, 222, 333, 333, 333, 444, 444" instead of "222, 333, 444". |
I hadn't considered the duplicated SYN issue, although that will depend on how long the delay is. If you want to be really pedantic the kernel could technically queue up multiple SYNs for transmission before the shutdown() and close() syscalls get processed. Additionally, if the server explicitly sends an ICMP reject OR accepts the knock connection, then there won't be multiple SYNs. As far as I can tell, the immediate FIN/RST packets being generated are causing the initial SYN to be discarded by my carrier's network before it makes it through to my server. Now I'm thinking about it, there is also another case where an immediate close might cause the packet to be lost - if you're on-link with the target and don't have its MAC address cached, or any of the routers along the path need to do an ARP lookup before they can forward the packet (and they're keeping track of the TCP state in that buffer). So I still think adding a delay before doing the shutdown/close (with a predefined upper limit to avoid SYN retransmissions... I wonder if we can get the retransmit delay from the kernel). For my use case a "wait for connect to complete/fail" tickbox in the profile settings would do it, I might try getting it compiling and prototype either/both to verify it works. |
The TCP part is a bit clunky, but there's no better way to do it. Android is very strict. I recommend using UDP or ICMP.
You are first and only one who reports this.
As far as I remember, there was a delay there at one time. And quite a few reports about duplicate packets that break the sequence.
Feel free to try. Oh, and btw keep in mind that the recipient is not required to respond to the packet. |
I strongly doubt this statement because there are no FIN/RST packets. What other packets could be mentioned if there is no connection? Wireshark logs confirm that nothing besides SYN is being sent. |
You're right about that. I was jumping to conclusions as it explained (in my mind) how the packets arrived fine over Wi-Fi but not via the carrier's network. I got it building and confirmed that adding a usleep(10000); call between connect() and shutdown() generates TCP traffic at the receivers end when knocking from my carrier's network, while the unmodified code has no traffic. I've uploaded a dump of the first few packets received tcp.pcap, it looks to me like they're operating some kind of transparent TCP proxy, especially as the SYN keeps getting retransmitted for a while even though the phone closed the socket after only 10ms, so sending just a SYN packet via my carrier is probably impossible. I'll continue looking to implement an option to wait for the connection to actively complete/fail, since that should still work for my application. |
As a side note, I'm using TCP specifically because I can ensure each packet is acknowledged before proceeding to the next one. When I initially set it up with UDP I had issues with the packets not arriving in order without a long wait, especially when using a flakey wireless connection (#18 suggests I'm not the only one who has this problem). |
Adding a delay after connect() does only one thing - it increases the number of retransmitted SYN packets. Strictly speaking, it results in an incorrectly generated sequence. If increasing the number of sent packets somehow helps, it may indicate an unstable connection and packet loss.
The recipient is not obligated to respond to packets. Neither confirming nor denying. In most cases, the received packets are simply discarded. This is normal and expected behavior. |
In any case, I am planning a major refactoring of the application. It's not happening today or tomorrow... Maybe I'll start working on it in a month or so, something like that. I will keep your issue in mind. If increasing the number of sent packets really does help in some way, I will consider how to incorporate this feature into the application without breaking anything for other users. Just to clarify, are you absolutely certain, 100% sure, that packet retransmission actually helps in your case? |
Its not the retransmission that is helping in this case, but allowing the connection to complete. As far as I've been able to figure out, my carrier operates a transparent TCP proxy between my phone and the target system. If I initiate a connection and then immediately close the socket my phone doesn't get to complete the handshake with the proxy, so the proxy never attempts to initiate a connection with the target system and it never sees anything. If I allow the handshake to complete, THEN the TCP proxy in the carrier's network starts its own connection attempt to the target system, and "helpfully" continues doing so even after my phone has terminated its connection to the proxy, and the server has replied with an ICMP error (port unreachable). Adding So, I'm inclined to think either adding a "TCP connect mode" checkbox to the "Advanced" screen, or adding "TCP SYN" and "TCP connect" as different port types makes more sense than the delay. As well as my iptables/ipset-based port knocking, this would work with a port knocking server written using plain TCP sockets rather than packet sniffing (which would be reliable against packet loss, since TCP would guarantee a complete exchange before moving on). I was going to add a PR with something like the above, but if you're intending to do major refactoring anyway I'll leave it with you. Here are the changes I've made to my build to get it working:
|
I'm trying to set this up to knock on a sequence of TCP ports, it works fine if I send to a host over the LAN, but when I switch to my carrier's connection none of the packets come through. I see packets on the correct ports if I attempt to connect using a Telnet client from my phone, so my ISP isn't blocking those ports.
I had a quick look at the source and can see it initiates a TCP connection, then immediately shuts it down, so my only thought is maybe the immediate shut-down after the connection causes my carrier's network to drop the connection before the server sees the SYN. From several Linux PCs I've been knocking using a shell script that attempts to initiate a connection with nc (which fails, as the target explicitly rejects the connection), this is to ensure the ports are knocked in sequence and there is no out-of-order issues from the Linux PCs.
So my ideas for improvements:
The text was updated successfully, but these errors were encountered: