Tailscale and KDE Connect

I have been testing Tailscale in a POC scenario for about two weeks in a home environment (with hopes to POC it into a business environment if i find it successful).
I have a few devices connected and in one sample scenario, am running KDE Connect between a laptop and mobile phone. KDE Connect uses a dynamic set of ports in the range of 1714-1764.
I have setup an ACL to allow all hosts to speak over these ports. My rules are normally more restrictive, but in debugging have arrived at the below:

{ "Action": "accept", "Users": ["*"], "Ports": ["*:1714-1764"] },

I do not appear to see a successful connection just with this rule. The below is a tcpdump of traffic from the laptop received when refreshing KDE connect on the phone.

tcpdump: listening on tailscale0, link-type RAW (Raw IP), capture size 262144 bytes                  
09:25:17.850631 IP (tos 0x0, ttl 64, id 37889, offset 0, flags [+], proto UDP (17), length 1276)                                                                                                                                                                                                                             
    100.99.104.86.45022 > 100.114.126.6.1716: UDP, bad length 1751 > 1248                                                                                     
09:25:17.850667 IP (tos 0x0, ttl 64, id 37889, offset 1256, flags [none], proto UDP (17), length 523)                                                                                                                                                                                                                        
    100.99.104.86 > 100.114.126.6: ip-proto-17                                                                                                                
09:25:21.136517 IP (tos 0x0, ttl 64, id 38023, offset 0, flags [+], proto UDP (17), length 1276)                                                                                                                                                                                                                             
    100.99.104.86.38194 > 100.114.126.6.1716: UDP, bad length 1751 > 1248                                                                                     
09:25:21.136537 IP (tos 0x0, ttl 64, id 38023, offset 1256, flags [none], proto UDP (17), length 523)                                                                                                                                                                                                                        
    100.99.104.86 > 100.114.126.6: ip-proto-17

If i manually add an INPUT rule in iptables on the laptop with the following, traffic starts to flow correctly and a connection is successful on KDE Connet refresh.

sudo iptables -A INPUT -i tailscale0 -p udp -s 100.99.104.86 --match multiport --dport 1714:1764 -j ACCEPT

Not sure if i am missing something in the TS ACL or if i have hit a currently limitation with handling of the ACL and UDP maybe, but keen for any insight.

if any additional debugging is needed, happy to help.

It looks like the strange tcpdump messages just because you have fragmented UDP packets - an indication that KDE connect might be using dangerously large packet sizes, but otherwise not a serious issue. You’re seeing one short packet followed by a packet with a “wrong” ip-proto, which is simply a subsequent fragment. Put together (which happens after tcpdump sees them), they form a valid UDP packet. So this is confusing but probably not your problem. If you try reading the pcap with wireshark it might reassemble those for you.

If adding an iptables rule unblocks it, that seems to mean you have some other firewall on your machine which is blocking connections. The tailscale access control rules are additional restrictions on top of your kernel iptables settings; they do not automatically relax your iptables settings.

So, your iptables command is correct. If you’d like to rely only on tailscale’s ACLs, you could add a rule like: iptables -A INPUT -i tailscale0 -j ACCEPT, which allows any connection that was approved by tailscale.

More information on Linux firewall settings: How to secure an Ubuntu server using Tailscale and UFW - Tailscale

Hi @apenwar

Totally agree with your sentiments regarding the fragmented packets - i wasn’t too concerned with these initiially, putting these to KDE Connect.
I should of included some more info on my setup - apologies - definitely no additional firewall running, just iptables, on Arch Linux. I think you have answered my question though with:

The tailscale access control rules are additional restrictions on top of your kernel iptables settings; they do not automatically relax your iptables settings.

My default iptables INPUT is to DROP traffic, and if these are not “relaxed” would explain what i am seeing. I wasn’t really aware of how ACL rules were applying on the endpoints, so when i added the previous mentioned rule, explains why this worked. My rules have been quite specific in TS ACL (allow port X to this only to device A), but if i am understanding correctly, i will need to manage these on any endpoints anyway so outside am doubling up on my overall rule management.

As a follow up question, this has got me digging into the rule workings a little more and i’d like to understand how ACLs are applied. Based on my reading, as i understand direct connections via TS, there is no involvement from TS relays/servers once the connection between two devices is successfully established.
If i have a TS ACL rule that allows port 80 to one of the two devices, where is this filter applied? Looking at my iptables dump, i don’t see these specifics. Is some of this done by the TS local service on the host?

Thanks in advance.

Each tailscale node filters packets on the way in, before sending them along to the kernel. So if tailscale filters out a packet, you might see a tailscaled log message go by about why it was dropped, but you shouldn’t see it enter the kernel at all (eg. in wireshark or tcpdump). If it does go into the kernel, that’s where iptables also has the chance to filter it for other reasons.