Systemd-native service to forward network connections between qubes

qrexec-connect is a systemd-native service for client qubes to forward TCP and Unix socket connections to service qubes. It’s like a systemd socket-activated qrexec-client-vm or qvm-connect-tcp.

The documented method to permanently bind TCP ports between a client qube and service qube requires the user to duplicate systemd unit file content and manage a new systemd service for each connection.

I wanted a single, systemd-native service to forward multiple TCP and Unix socket connections from a client qube to service qubes. qrexec-connect reduces new service configuration to a single socket unit file on the client qube:

# /home/user/.config/systemd/user/qrexec-connect-http.socket
[Socket]
# IP address and port on the client qube:
ListenStream=127.0.0.1:8000
# Arguments you would normally use with qrexec-client-vm:
FileDescriptorName=web-server qubes.ConnectTCP+8000

[Install]
WantedBy=sockets.target

Test without installing or writing any unit files:

user@client:~$ systemd-socket-activate --listen=127.0.0.1:8000 --fdname="web-server qubes.ConnectTCP+8000" ./qrexec-connect

The systemd journal shows both the sockets it listens on and the addresses that qrexec-connect forwards to RPCs:

user@client:~$ journalctl --follow
Mar 04 00:15:01 client systemd[684]: Listening on qrexec-connect-gpg-agent-ssh.socket.
Mar 04 00:15:01 client systemd[684]: Listening on qrexec-connect-httpd.socket.
Mar 04 00:15:01 client systemd[684]: Listening on qrexec-connect-httpd-ipv6.socket.
Mar 04 00:15:01 client systemd[684]: Listening on qrexec-connect-container.socket.
Mar 04 00:15:05 client systemd[684]: Starting qrexec-connect.service - systemd-native qrexec-client-vm service...
Mar 04 00:15:05 client qrexec-connect[10412]: /run/user/1000/gnupg/S.gpg-agent.ssh (service qubes.GPGAgentSSH)
Mar 04 00:15:05 client qrexec-connect[10412]: 127.0.0.1:8000 (service qubes.ConnectTCP+8000)
Mar 04 00:15:05 client qrexec-connect[10412]: @container (service qubes.ConnectContainer)
Mar 04 00:15:05 client qrexec-connect[10412]: [::1]:8000 (service qubes.ConnectTCP+8000)
Mar 04 00:15:05 client systemd[684]: Started qrexec-connect.service - systemd-native qrexec-client-vm service.

Use systemctl to show the sockets each unit starts:

user@client:~$ systemctl --user list-sockets
LISTEN                                   UNIT                                  ACTIVATES                   
/run/user/1000/gnupg/S.gpg-agent.ssh     qrexec-connect-gpg-agent-ssh.socket   qrexec-connect.service
127.0.0.1:8000                           qrexec-connect-httpd.socket           qrexec-connect.service
@container                               qrexec-connect-container.socket       qrexec-connect.service
[::1]:8000                               qrexec-connect-httpd-ipv6.socket      qrexec-connect.service
...

Are there other tools or methods that provide similar functionality?

Does the name collide with any existing or future official Qubes tools?

I wrote this for my use cases. Maybe it fits others’ use cases? Feedback welcome!

Looks interesting to me. I’ve had a couple of ideas that I wanted to play with but needed to figure out how to do this kind of ServiceVM<->AppVM coms to make them work. I’m definitely going to play with this to see what it can do.

1 Like