[HOME] [DOWNLOAD] [DOCS] [NEWS] [SUPPORT] [TIPS] [ISSUES] [CONTRIBUTE] [DONATE]

User > Tor > VPN > Internet doesn't work in Whonix 16

In Whonix 15, with OpenVPN 2.4, it was easy to Tor > VPN > Internet, but since Whonix 16 (based on Debian Bullseye) has OpenVPN 2.5, iproute isn’t available and lots of other changes, and as such Tor > VPN > Internet is not working as per documentation.

I am making the changes in Whonix Workstation as per the docs.

The issues:

1) In the openvpn config file iproute ( iproute /usr/bin/ip_unpriv ) no longer works in openvpn 2.5 and as such it throws off

Options error: Unrecognized option or missing or extra parameter(s) in /etc/openvpn/openvpn.conf:26: iproute (2.5.1)
Use --help for more information.

when trying to connect. If iproute is commented out then

ERROR: Cannot ioctl TUNSETIFF tun: Operation not permitted (errno=1)

even if dev tun0 is present in the config file.

2) If OpenVPN is compiled with --enable-iproute2, then error

RTNETLINK answers: File exists
ERROR: Linux route add command failed: external program exited with error status: 2

3) If Whonix workstation Firewall is modified as per the docs i.e.

WORKSTATION_FIREWALL=1
TUNNEL_FIREWALL_ENABLE=true

then there is no internet connectivity in the workstation, even after reboot.

I have verified the signatures and both the Gateway and Workstation VM are ok (uncorrupted).

System Specs:
Windows 7 (Host)
Virtualbox VM ( Virtualbox Version 6.1.34)

Debian dropped --enable-iproute2 as suggested by upstream. Source:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=976070

For potential approach to research / fix this, see:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=976070#10

Maybe helpful search term:

openvpn unprivileged Netlink

The abstract thing to be found out is:

How to run OpenVPN unprivileged using netlink?

Hi @Patrick

The discussions on the iproute issue in these two threads:

https://phabricator.vyos.net/T3805

The workaround suggested was

Remove user & group directives from /etc/openvpn/openvpn.conf and to add Ambient Capabilities and User=tunnel and Group=tunnel to a separate .service file (which, in our case, would be /lib/systemd/system/openvpn@openvpn.service.d/50_unpriv.conf).

So, I modified the 50_unpriv.conf file as follows

[Unit]
ConditionPathExists=!/run/qubes/this-is-templatevm

[Service]

User=tunnel
Group=tunnel
SecureBits=keep-caps
ExecStartPre=/usr/bin/sudo --non-interactive /usr/sbin/openvpn --rmtun --dev tun0
ExecStartPre=/usr/bin/sudo --non-interactive /usr/sbin/openvpn --mktun --dev tun0 --dev-type tun --user tunnel --group tunnel
AmbientCapabilities=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE

ExecStopPost=/usr/bin/sudo --non-interactive /usr/sbin/openvpn --rmtun --dev tun0

I did a **sudo systemctl daemon-reload** and ran the debug process steps including sudo -u tunnel openvpn /etc/openvpn/openvpn.conf. But this didn’t work and gave the following error:

	2022-06-20 07:38:04 us=410798 net_iface_mtu_set: mtu 1500 for tun0
	2022-06-20 07:38:04 us=410867 sitnl_send: rtnl: generic error (-1): Operation not permitted
	2022-06-20 07:38:04 us=410936 Linux can't set mtu (1500) on tun0
	2022-06-20 07:38:04 us=410985 Exiting due to fatal error

The solution that worked for me:

I gave the Ambient Capability directly to the Openvpn executable with user=tunnel privileges, and nothing in the systemd service:

sudo /sbin/capsh --keep=1 --user='tunnel' --inh='cap_ipc_lock,cap_net_admin,cap_net_bind_service,cap_net_raw,cap_setgid,cap_setuid,cap_sys_chroot,cap_dac_override,cap_audit_write' --addamb='cap_ipc_lock,cap_net_admin,cap_net_bind_service,cap_net_raw,cap_setgid,cap_setuid,cap_sys_chroot,cap_dac_override,cap_audit_write' -- -c 'openvpn /etc/openvpn/openvpn.conf'

Refer: How do I use capsh: I am trying to run an unprivileged ping, with minimal capabilities - Unix & Linux Stack Exchange

I also checked out Openvpn process for capabilities related to user=tunnel

user@host:~$ sudo grep Cap /proc/23712/status
	CapInh:	00000000200474c2
	CapPrm:	00000000200474c2
	CapEff:	00000000200474c2
	CapBnd:	000001ffffffffff
	CapAmb:	00000000200474c2
user@host:~$ sudo capsh --decode=00000000200474c2
0x00000000200474c2=cap_dac_override,cap_setgid,cap_setuid,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_sys_chroot,cap_audit_write

This works! But I don’t want to use this route as this might not be the best way to go about it.I now have a binary that can be executed by any user, which I don’t really like.

Why wasn’t systemd able to set the Ambient Capabilities in case of user=tunnel whereas capsh was able to? How to make this work with systemd? Is this an issue of SELinux?

My working config file for OpenVPN: (without iproute and User directive)

client
dev tun0
proto tcp

remote X.X.X.X 443

server-poll-timeout 20

remote-random
resolv-retry infinite
nobind

# The following setting is only needed for old OpenVPN clients compatibility. New clients
# automatically negotiate the optimal cipher.
cipher AES-256-CBC

auth SHA512
verb 4

setenv CLIENT_CERT 0
persist-key
persist-tun

reneg-sec 0

remote-cert-tls server
auth-user-pass /etc/openvpn/auth.txt
pull

script-security 2
up "/etc/openvpn/update-resolv-conf script_type=up dev=tun0"
down "/etc/openvpn/update-resolv-conf script_type=down dev=tun0"

<ca>
-----BEGIN CERTIFICATE-----

---------------------------
-----END CERTIFICATE-----
</ca>

key-direction 1
<tls-auth>
# 2048 bit OpenVPN static key
-----BEGIN OpenVPN Static key V1-----
-----------------------------------
-----END OpenVPN Static key V1-----
</tls-auth>
1 Like

That’s excellent progress!

Using systemd and its capabilities seems the right approach.

Could you please consider to Improve the Documentation / Edit the Whonix ™ Wiki?

Which binary? The sudo /sbin/capsh command? Well, it still requires sudo. So not worsening the security model.

I appreciate the --non-interactive as this makes potential issues in the future easier to debug.

I don’t think systemd units should ever use sudo. ExecStartPre / ExecStartPost can if desired run as root while ExecStart does not and runs as a limited user.

  • That is systemd config under [Service]:
    • PermissionsStartOnly=true

  • An alternative to this is:
    • ExecStartPre=+

    • ExecStartPost=+

[Imprint] [Privacy Policy] [Cookie Policy] [Terms of Use] [E-Sign Consent] [DMCA] [Contributors] [Investors] [Priority Support] [Professional Support]