LocalSend is a free, open-source app that allows you to securely share files and messages with nearby devices over your local network without needing an internet connection. Basically, a platform neutral "airdrop".
LocalSend is a cross-platform app that enables secure communication between devices using a REST API and HTTPS encryption. Unlike other messaging apps that rely on external servers, LocalSend doesn't require an internet connection or third-party servers, making it a fast and reliable solution for local communication. The TLS/SSL certificate is generated on the fly on each device, ensuring maximum security. For more info, see the LocalSend protocol documentation.
This guide provides a step-by-step implementation of LocalSend in Qubes r4.2 as provided by @etaz in the following thread. While relatively easy to implement, this method does not enable LocalSend in Qubes to automatically discover other devices on the network. Manual discovery is simple if one knows the ip address of another device, so it's not a significant barrier to ease of use. An alternative implementation by @WillyJL allows discovery in both directions, but requires a more complicated setup.
LocalSend requires devices to be on the same subnet, so will not work if either device is tunneling traffic with a VPN. Use of disposable qubes is assumed below, but is not necessary.
localsend
qube (as named disposable)LocalSend is available as flatpak or snap packages, but not yet with extrepo
. This guide assumes flatpak integration in the template, but any installation method will do.
#in template-with-flatpak terminal$
export all_proxy=http://127.0.0.1:8082/
flatpak install flathub org.localsend.localsend_app
Use Qubes Tools to create the named disposable, localsend
. Disposability is optional, but should be named.
Application Menu (Q) -> Settings (Gear) -> Qubes Tools -> Create New Qube -> Named disposable
Name: localsend Label:
<COLOR>
template:<FLATPAK-DVM-TEMPLATE>
Network: sys-firewall Applications: + LocalSend + Open File Manager
Optional: Edit Qubes firewall to allow localsend
traffic to only local subnet IPs (eg, 192.168.1.0/24). Allow both TCP and UDP protocols.
For the following, we'll assume sys-net
is a disposable qube. If not, then skip the first part and create the script directly in sys-net
.
Edit a file, for example temp_localsend.sh
, to include the following script and copy the file from this qube, <FORUM-QUBE>
, to the disposable template of sys-net
.
#!/bin/sh
# script courtesy of @etaz on forum.qubes-os.org
if_lan=<your LAN network interface>
ip=$(ip -f inet addr show $if_lan | sed -En -e 's/.*inet ([0-9.]+).*/\1/p')
port=53317
case $1 in
start)
qvm-connect-tcp ::$port
nft add rule ip qubes custom-input ip daddr $ip tcp dport $port ct state new accept
;;
stop)
pkill -f "socat TCP-LISTEN:$port"
nft flush chain ip qubes custom-input
;;
*)
>&2 echo "usage: $0 start|stop"
exit 1
;;
esac
@etaz "You should adjust the line nft flush chain ip qubes custom-input
if you have other port forwarding rules you want to keep, when stopping this script."
The script will require root privileges. Create a file in the sys-net
disposable template and read/write the contents of the temporary file.
#in sys-net disposable template as root#
touch /usr/local/bin/localsend_forward.sh
cat /home/user/QubesIncoming/<FORUM-QUBE>/temp_localsend.sh >> /usr/local/bin/localsend_forward.sh
Finally, tailor the script to your specific LAN interface.
#in sys-net terminal$
ip addr show
This will display a numbered list with at least 3 entries. Ignore the lo
and vif+
entries. Your LAN interface will be something like eth*
, en*
, or wl*
, and be associated with an ip like 192.168.x.x, 172.16.x.x, or 10.x.x.x, listed after inet
. Replace <wl*>
below with your specific interface and edit the script.
#in sys-net disposable template as root#
sed -i 's/<your LAN network interface>/<wl*>/g' /usr/local/bin/localsend_forward.sh
#in dom0 terminal$
echo "qubes.ConnectTCP +53317 sys-net @default allow target=localsend" >> /etc/qubes/policy.d/30-user.policy
#in sys-net terminal$
sudo bash /usr/local/bin/localsend_forward.sh start
#create new starter object with following command
qvm-run sys-net 'xfce4-terminal -e "sudo bash /usr/local/bin/localsend_forward.sh"'
For automatic starts, make the script executable and modify /rw/config/rc.local
in the disposable template.
#in sys-net disposable template as root#
chmod +x /usr/local/bin/localsend_forward.sh
echo "sudo /usr/local/bin/localsend_forward.sh start" >> /rw/config/rc.local
Verify that /usr/local/bin/localsend_forward.sh
exists with if_lan
properly defined and restart sys-net
.
Running the script automatically can be unreliable (if sys-net
does not connect to the network before the script runs?). Manually stopping and starting the script after sys-net
has made a connection seems to work fine though.
Other devices on the subnet should discover your Qubes LocalSend instance, perhaps after a refresh, and identify it with a randomly generated two word name, a number #xxx
(the final octet in ipv4 of sys-net
), and as a Linux device. Sending to Qubes is straightforward.
With this setup, LocalSend in Qubes will not be able to discover other devices on the subnet. However, with an ip address you can manual send (arrow icon) or you can favorite a device (Send -> Heart icon -> Add -> IP Address) and then send by selecting Favorites and choosing the manually discovered device.