Mullvad - create AppVM and disposable template. Tidy up

This commit is contained in:
unman 2024-02-14 00:36:39 +00:00
parent 20f04eb4ee
commit 96794f34c8
No known key found for this signature in database
GPG Key ID: FDD1B8244731B36C
14 changed files with 31 additions and 233 deletions

View File

@ -1,75 +1,53 @@
Name: 3isec-qubes-mullvad-vpn
Version: 2.01
Release: 1%{?dist}
Summary: Set up a Mullvad wireguard proxy in Qubes
Summary: Set up a Mullvad qube and disposable template
License: GPLv3+
SOURCE0: mullvad
%description
This package sets up a VPN gateway, named MullvadVPN
It follows the method detailed in the Mullvad docs,
https://mullvad.net/en/help/qubes-os-4-and-mullvad-vpn/
This package creates a template, loaded with the MullvadVPN GUI and Mullvad Browser.
An AppVM named mullvad, and a disposable template, mullvad-dvm, are
created from that template.
This package is for use with wireguard.
If you use openvpn, install the 3isec-qubes-openvpn package.
The template, template-mullvad, is based on the debian-12-minimal template.
If the debian-12-minimal template is not present, it will be downloaded
and installed - this may take some time depending on your net connection.
The package creates a qube called MullvadVPN based on the debian-11-minimal
template. If the debian-11-minimal template is not present, it will
be downloaded and installed - this may take some time depending on your
net connection.
Both the AppVM and the disposable template have the Mullvad GUI to
set up a VPN, and the Mullvad browser. You can run the Mullvad Browser
independently of the VPN.
There are changes to the firewall rules on MullvadVPN to ensure
blocking of outbound connections.
Only traffic to the Mullvad gateway is allowed.
If you remove this package, the salt files will be removed, but the qubes will not.
You can manually remove them if you wish.
After installing the package, copy your Mullvad configuration file or
zip file to MullvadVPN.
A menu item for "Setup Mullvad VPN" will be created on the main Qubes Menu.
Run this to set up the VPN.
When finished, restart MullvadVPN.
You can, of course, use template-mullvad to create other qubes for
separate VPN connections, or a qube where you will just use the Mullvad browser.
To use the VPN, set MullvadVPN as the netvm for your qubes(s).
All traffic will go through the VPN.
The VPN will fail closed if the connection drops.
No traffic will go through clear.
If you remove the package, the salt files will be removed.
**The MullvadVPN gateway will also be removed.**
To do this ALL qubes will be checked to see if they use MullvadVPN.
If they do, their netvm will be set to `none`.
You can, of course, use template-mullvad to create other VPN gateways.
Remember that each qube that creates a VPN will count toward the maximum of 6 clients.
Log out and close the VPN when you have finished with it: if you do not,
you will be prompted to log out other clients from the GUI.
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/srv/salt
mkdir -p %{buildroot}/usr/bin
mkdir -p %{buildroot}/usr/share/applications
cp -rv %{SOURCE0}/ %{buildroot}/srv/salt
cp -rv %{SOURCE0}/qubes-setup-MullvadVPN.desktop %{buildroot}/usr/share/applications
cp -rv %{SOURCE0}/setup_MullvadVPN.sh %{buildroot}/usr/bin/setup_MullvadVPN.sh
%files
%defattr(-,root,root,-)
/srv/salt/mullvad/*
/usr/share/applications/qubes-setup-MullvadVPN.desktop
/usr/bin/setup_MullvadVPN.sh
%post
if [ $1 -eq 1 ]; then
qubesctl state.apply mullvad.clone
qubesctl --skip-dom0 --targets=template-mullvad state.apply mullvad.repo
qubesctl --skip-dom0 --targets=template-mullvad state.apply mullvad.browser
qubesctl state.apply mullvad.create
qubesctl --skip-dom0 --targets=MullvadVPN state.apply mullvad.configure
qubesctl state.apply mullvad.create_disposable
fi
%postun
if [ $1 -eq 0 ]; then
for i in `qvm-ls -O NAME,NETVM | awk '/ MullvadVPN/{ print $1 }'`;do qvm-prefs $i netvm none; done
qvm-kill MullvadVPN
qvm-remove --force MullvadVPN template-mullvad
fi
%changelog

View File

@ -1,17 +0,0 @@
/etc/skel/Downloads/mullvad_browser-linux-x86_64-13.0.9.tar.xz:
file.managed:
- source:
- salt://mullvad/mullvad-browser-linux-x86_64-13.0.9.tar.xz
- user: root
- group: root
- makedirs: True
mullvad-browser-linux-x86_64-13.0.9.tar.xz:
module.run:
- name: archive.tar
- tarfile: /etc/skel/Downloads/mullvad_browser-linux-x86_64-13.0.9.tar.xz
- options: -x -f
- runas: root
- dest: /etc/skel

View File

@ -3,22 +3,21 @@ include:
qvm-present-id:
qvm.present:
- name: MullvadVPN
- name: mullvad
- class: AppVM
- template: template-mullvad
- label: green
qvm-prefs-id:
qvm.prefs:
- name: MullvadVPN
- name: mullvad
- memory: 400
- maxmem: 800
- vcpus: 2
- provides-network: true
qvm-features-id:
qvm.features:
- name: MullvadVPN
- name: mullvad
- disable:
- service.cups
- service.cups-browsed

View File

@ -1,32 +1,33 @@
include:
- mullvad.clone
- mullvad.create
create_mullvad:
create_mullvad_dvm:
qvm.present:
- name: Mullvad
- name: mullvad-dvm
- class: AppVM
- template: template-mullvad
- label: green
mullvad-prefs:
mullvad-prefs_dvm:
qvm.prefs:
- name: Mullvad
- name: mullvad-dvm
- memory: 400
- maxmem: 800
- vcpus: 2
- template_for_dispvms: True
mullvad-features:
mullvad-features_dvm:
qvm.features:
- name: Mullvad
- name: mullvad-dvm
- disable:
- service.cups
- service.cups-browsed
- service.tinyproxy
- set:
- menu-items: "start-mullvad-browser.desktop mullvad-vpn.desktop debian-xterm.desktop"
- menu-items: "mullvad-vpn.desktop start-mullvad-browser.desktop debian-xterm.desktop"
- appmenus-dispvm: True
'qvm-appmenus --update Mullvad':
'qvm-appmenus --update mullvad-dvm':
cmd.run:
- runas: user

View File

@ -1,11 +0,0 @@
virtualif=`ip -o -4 addr show eth0|awk '{ print $4}'`
vpndns1=10.8.0.1
vpndns2=10.14.0.1
iptables -F OUTPUT
iptables -I FORWARD -o eth0 -j DROP
iptables -I FORWARD -i eth0 -j DROP
iptables -F PR-QBS -t nat
iptables -A PR-QBS -t nat -d $virtualif -p udp --dport 53 -j DNAT --to $vpndns1
iptables -A PR-QBS -t nat -d $virtualif -p tcp --dport 53 -j DNAT --to $vpndns1
iptables -A PR-QBS -t nat -d $virtualif -p udp --dport 53 -j DNAT --to $vpndns2
iptables -A PR-QBS -t nat -d $virtualif -p tcp --dport 53 -j DNAT --to $vpndns2

View File

@ -1,26 +0,0 @@
#!/bin/bash
# Block forwarding of connections through upstream network device
# (in case the vpn tunnel breaks):
iptables -I FORWARD -o eth0 -j DROP
iptables -I FORWARD -i eth0 -j DROP
ip6tables -I FORWARD -o eth0 -j DROP
ip6tables -I FORWARD -i eth0 -j DROP
# Accept traffic to VPN
iptables -P OUTPUT DROP
iptables -F OUTPUT
iptables -I OUTPUT -o lo -j ACCEPT
# Add the `qvpn` group to system, if it doesn't already exist
if ! grep -q "^qvpn:" /etc/group ; then
groupadd -rf qvpn
sync
fi
sleep 2s
# Block non-VPN traffic to clearnet
iptables -I OUTPUT -o eth0 -j DROP
# Allow traffic from the `qvpn` group to the uplink interface (eth0);
# Our VPN client will run with group `qvpn`.
iptables -I OUTPUT -p all -o eth0 -m owner --gid-owner qvpn -j ACCEPT
iptables -I OUTPUT -o eth0 -p udp --dport 53 -j ACCEPT

View File

@ -1,5 +0,0 @@
#!/usr/sbin/nft -f
define vpndns1 = 10.64.0.1
flush chain nat PR-QBS
insert rule nat PR-QBS tcp dport 53 dnat to $vpndns1
insert rule nat PR-QBS udp dport 53 dnat to $vpndns1

View File

@ -1,2 +0,0 @@
#!/bin/sh
nft -f /rw/config/network-hooks.d/flush

View File

@ -1,38 +0,0 @@
#!/usr/bin/bash
if [ "`id -u`" -ne 0 ]; then
exec sudo "$0"
exit 99
fi
target_file='/rw/config/wireguard.conf'
cd /rw/config/vpn
zenity --question --text="Do you have a zip file from Mullvad?" --ok-label="Yes" --cancel-label="No"
if [ $? = 0 ] ; then
client_file=`zenity --file-selection`
if [ $(mimetype -b $client_file) == "application/zip" ]; then
unzip -j -d /rw/config/vpn "$client_file"
else
zenity --error --text="That doesn't look like a zip file"
exit
fi
fi
zenity --question --text="Have you copied the wireguard config file to /rw/config/vpn/ ?" --ok-label="Yes" --cancel-label="No"
if [ $? = 0 ] ; then
zenity --question --text="Please select the wireguard configuration file you want to use" --ok-label="OK" --cancel-label="No"
if [ $? = 0 ] ; then
client_file=`zenity --file-selection`
if grep -q '^PrivateKey' "$client_file" ; then
if [ "$client_file" != "$target_file" ]; then
cp $client_file $target_file
fi
zenity --info --text="Restart this qube. The VPN service will start automatically."
else
zenity --error --text="That doesn't look like a client config file"
exit
fi
else
zenity --error --text="You need a config file\nCheck with Mullvad VPN"
exit
fi
else
exit
fi

View File

@ -1,50 +0,0 @@
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :
#
#
#
{% if grains['nodename'] != 'dom0' %}
{% if salt['pillar.get']('update_proxy:caching') %}
{% if grains['os_family']|lower == 'debian' %}
{% if grains['nodename']|lower != 'host' %}
{% for repo in salt['file.find']('/etc/apt/sources.list.d/', name='*list') %}
{{ repo }}_baseurl:
file.replace:
- name: {{ repo }}
- pattern: 'https://'
- repl: 'http://HTTPS///'
- flags: [ 'IGNORECASE', 'MULTILINE' ]
- backup: False
{% endfor %}
/etc/apt/sources.list:
file.replace:
- name: /etc/apt/sources.list
- pattern: 'https:'
- repl: 'http://HTTPS/'
- flags: [ 'IGNORECASE', 'MULTILINE' ]
- backup: False
{% endif %}
{% endif %}
{% endif %}
mullvad_installed:
pkg.installed:
- refresh: True
- pkgs:
- qubes-core-agent-networking
- qubes-core-agent-passwordless-root
- iproute2
- libdbus-glib2.0-cil
- libnotify-bin
- mate-notification-daemon
- resolvconf
- unzip
- wireguard
- wireguard-tools
- zenity
{% endif %}

View File

@ -1,5 +0,0 @@
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :
base:
'*':
- mullvad.install

View File

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Application
Exec=setup_MullvadVPN.sh
Path=/usr/bin
Icon=qubes-manager
Terminal=false
Name=Setup Mullvad VPN
GenericName=Setup Mullvad VPN
StartupNotify=false
Categories=Settings;X-XFCE-SettingsDialog

View File

@ -41,6 +41,7 @@ requirements_installed:
- iproute2
- libnotify-bin
- lsb-release
- xz-utils
echo "deb [signed-by=/usr/share/keyrings/mullvad-keyring.asc arch=$( dpkg --print-architecture )] https://repository.mullvad.net/deb/stable $(lsb_release -cs) main" > /etc/apt/sources.list.d/mullvad.list :
cmd.run

View File

@ -1,17 +0,0 @@
#!/usr/bin/bash
qvm-run MullvadVPN /home/user/install.sh
if ! (qvm-firewall MullvadVPN|tail -n1 |grep -q '.*drop.*-.*-'.*-);then
qvm-firewall MullvadVPN add --before 0 drop && qvm-firewall MullvadVPN del --rule-no 1
fi
endpoint=$(qvm-run -p MullvadVPN 'awk "/Endpoint/{print \$3}" /rw/config/wireguard.conf')
IFS=":" read -r server_ip server_port PORT <<< $endpoint
if ! (qvm-firewall MullvadVPN |grep -q 'accept.*-.*tcp.*53'); then
qvm-firewall MullvadVPN add --before 0 proto=tcp dstports=53 accept
fi
if ! (qvm-firewall MullvadVPN |grep -q 'accept.*-.*udp.*53'); then
qvm-firewall MullvadVPN add --before 0 proto=udp dstports=53 accept
fi
if ! (qvm-firewall MullvadVPN |grep -q "$server_ip");then
qvm-firewall MullvadVPN add --before 0 dsthost=$server_ip proto=udp dstports=$server_port accept
fi