LocalSend

On second thought it won’t work with not named disposables (dispX qubes) but you can try to use it with named disposable.

There are a Mac and an android phone on the same network and they see each other and can exchange files with LocalSend

I tried, but the result is the same

Is 192.168.1.226 the IP address of your network interface connected to your LAN in sys-net?
Do you have your Qubes OS PC connected to the same LAN (to the same router) as your Mac and android?
Do you have the same 192.168.1.x subnet IP addresses in your Mac/android?

Try to test the port forwarding like this:
Configure the policy in dom0 to allow qubes.ConnectTCP connection from sys-net to your test qube with LocalSend:

qubes.ConnectTCP +53317 sys-net @default allow target=test-localsend-qube

Start test-localsend-qube and close LocalSend if it’s running.
Open the terminal in test-localsend-qube and run these commands:

mkdir /tmp/webtest
python3 -m http.server -d /tmp/webtest 53317

Now try to open this link in the Mac/android browser:
http://192.168.1.226:53317
Change the 192.168.1.226 to the IP of your Qubes OS PC.
If you see the page loading then the port forwarding works.

yes,

yes, on the router I set each machine, Qubes, Mac and android, each with its static address, just to be able to get LocalSend setup favorites connected to a specific IP address. The static IP address of Qubes machine is 192.168.1.226. This is confirmed also on Qubes by the “connecting information” item right clicking on the network icon.

Dom0 policy was already set up this way:

qubes.connectTCP +53317 sys-net @default allow target=localsend

since your last recommendation and the commands in localsend VM gave the following reply:

Serving HTTP on 0.0.0.0 port 53317 (http://0.0.0.0:53317/) ...

why HTTP on 0.0.0.0?
Obviously localsend VM is connected to firewall

Anyway, neither android nor Mac are able to load anything, they reply this page is not working.

Did you run the script in sys-net?
What’s the output of these commands in sys-net?

ss -tulnp | grep 53317
sudo nft list chain ip qubes custom-input

It means that it’s accepting incoming connections to any of its interfaces IPv4 addresses.

It was already running , but I stopped and restarted it

tcp   LISTEN 0      5                               0.0.0.0:53317      0.0.0.0:*          

table ip qubes {
	chain custom-input {
		ip daddr 192.168.1.226 tcp dport 53317 ct state new accept
	}
}

Many thanks @apparatus for your very precise help.

Try to run these commands in sys-net:

curl http://192.168.1.226:53317
curl http://127.0.0.1:53317
~$ curl http://192.168.1.226:53317
curl: (52) Empty reply from server

~$ curl http://127.0.0.1:53317
curl: (52) Empty reply from server

What if you run this command in localsend qube?

curl http://127.0.0.1:53317
~$ curl http://127.0.0.1:53317
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
</ul>
<hr>
</body>
</html>

Ok, I found the error:

The connectTCP should be ConnectTCP: qubes.connectTCP +53317 sys-net @default allow target=localsend`
Did you not see the denied qubes.ConnectTCP notification?

Huge improvement thanks. I remember I even noted that the C in the front of connect seemed a little bigger, but then decided it was a small display error. :roll_eyes:

I did see that as well and I even mentioned above in this thread, but I did not connect it to C size.

Now both Mac and android can see Qubes LocalSend, but Qubes LocalSend cannot see them. If I ping Mac and android IP from localsend terminal I get a reply with no problems. So I do not know what to think.

This matter is really very complicated, but after various years I cannot find a working way to transfer files among different machines.

Good news,

I found that even if localsend Qubes cannot see either Mac or android, it can send and receive files at high speed.

On the LocalSend GUI I can add Mac and android as favorite using their IP address and then send files to them and it works as supposed.

I do not understand why I cannot see them, but I can send files to them. But the most important thing is done and with time this sort of things improves.

Many thanks again to @apparatus and @etaz for the precious help, without which this result would be impossible.

The discovery is using broadcast so it won’t work behind a NAT (sys-net is basically a router).

I figured out how to make LocalSend member discovery work in both directions (other devices can see Qubes, Qubes can see other devices). I have made a blog post explaining the process of figuring it out, and with a guide on how to set it up. Note that is does not hand hold you, it requires some basic knowledge of scripting and terminal usage.

You can find it here on my website: WillyJL ─ LocalSend through 2 layers of NAT

Not sure if it would be welcome as a community guide on this forum too, I’m new here. Didn’t even know of this post prior to figuring LocalSend out on my own :smiley:

2 Likes

The problem is that masquerade can only be used in postrouting chains of type nat, but the UDP multicasts from LocalSend never show in nat postrouting chains. I could trace them just fine in filter output, nat output and filter postrouting chains, but never in a nat postrouting chain.

Maybe it’s discarded and not going further because of this:

IP multicast address range Description Routable
224.0.0.0 to 224.0.0.255 Local subnetwork[3] No

Local subnetwork
Addresses in the range of 224.0.0.0 to 224.0.0.255 are individually assigned by IANA and designated for multicasting on the local subnetwork only. For example, the Routing Information Protocol (RIPv2) uses 224.0.0.9, Open Shortest Path First (OSPF) uses 224.0.0.5 and 224.0.0.6, and Multicast DNS uses 224.0.0.251. Routers must not forward these messages outside the subnet from which they originate.

Multicast address - Wikipedia

Maybe it’ll work if you change the destination IP from 224.0.0.167 to e.g. 224.1.0.167 in the sys-firewall and then back to 224.0.0.167 in sys-net.
Or maybe use multicast relay:

And it’s even weirder because the default Qubes OS setup includes a masquerade at the end of postrouting chain, so anything that leaves through the outbound network interface should be SNATted (Source NAT), but these multicast packets simply ignore it.

Not everything is masqueraded:

	chain postrouting {
		type nat hook postrouting priority srcnat; policy accept;
		oifgroup 2 accept
		oif "lo" accept
		masquerade
	}

The vif+ and lo interfaces are not masqueraded.

1 Like

Very good observations @apparatus, thanks!

Indeed, I had noticed that there are extra rules in postrouting but was just adding a conclusion statement that I thought “if it were leaving the interface it shouldve been masqueraded, since it wouldn’t match the previous 2 rules”. However, you solved the dilemma! Simply put multicast packets in that range should not be routed, and in fact they are not processed for NAT. Good to know!
Atleast the fake SNAT using a NetworkManager hook works :smiley:

But I will try to see if changing the IP as you suggests allows SNAT with masquerade, might just be able to reset back to the correct destination address when it gets picked up in nat postrouting chain
Update: I gave it my best and could not figure that one out. I even tried changing to something outrageous like ip daddr set 1.1.1.1 just to make sure it gets no special multicast treatment, but nope. I think it’s some caveat of how dup works in prerouting, and at this point I don’t care enough to figure that one out. Using a dispatcher script works, and Qubes uses something similar too for knowing external IP in QubesDB, so it’s not all that outlandish either I think.

would be awesome if this thread could be turned into a guide.

i’ve looked into other options such as pairdrop, snapdrop, sharik, simplex, toxchat and afaik they do not employ e2ee policies over LAN. This where localsend shines imo

I just implemented LocalSend for myself following this thread and wrote my notes up as a community guide.

2 Likes