mirror of
https://github.com/QubesOS/qubes-doc.git
synced 2024-12-29 01:06:24 -05:00
197 lines
8.6 KiB
Markdown
197 lines
8.6 KiB
Markdown
|
---
|
||
|
layout: doc
|
||
|
title: HTTP Filtering Proxy
|
||
|
permalink: /doc/config/http-filtering-proxy/
|
||
|
---
|
||
|
|
||
|
How to run an HTTP filtering proxy in a FirwallVM
|
||
|
=================================================
|
||
|
|
||
|
Introduction
|
||
|
------------
|
||
|
|
||
|
By default Qubes uses a special firewall VM that sits between the
|
||
|
networking VM and each AppVM. This VM controls the traffic for AppVMs
|
||
|
and can be used to restrict what AppVMs can send or receive. The
|
||
|
traffic rules can be setup using filtering rules GUI in Qubes VM
|
||
|
manager. The manager translates user-defined setup into iptables rules
|
||
|
for the kernel of firewall VM.
|
||
|
|
||
|
The primary goal of the filtering rule setup in firewall VM is to
|
||
|
allow for the user to protect either from own mistakes (like accessing
|
||
|
an arbitrary website from a browser running in a banking VM) or from
|
||
|
mistakes of websites (like a banking website that loads JS code from a
|
||
|
social network operator when the user logs in into the bank).
|
||
|
|
||
|
As the rules in the firewall are IP-based, it has drawbacks. First the
|
||
|
rules cannot be used if one has to use a HTTP proxy to connect for
|
||
|
websites (a common setup on corporate networks). Second the Qubes
|
||
|
resolves DNS names from the firewall rules when the AppVM loads. This
|
||
|
prevents websites that use DNS-based load balancers from working
|
||
|
unless the user reloads the firewall rules (which re-resolve the DNS
|
||
|
names) whenever the balancer transfer her session to another IP. Third
|
||
|
the initial setup of the rules is complicated as the firewall drops
|
||
|
the connection silently. As a workaround on can use browser's network
|
||
|
console to see what is blocked, but this is time-consuming and one can
|
||
|
trivially miss some important cases like including in the firewall
|
||
|
white list sites for OCSP SSL certificate verification.
|
||
|
|
||
|
These drawbacks can be mitigated if one replaces iptable-based rules
|
||
|
with a filtering HTTP proxy. The following describes how to setup
|
||
|
tinyproxy-based proxy in the firewall VM to archive such filtering.
|
||
|
|
||
|
|
||
|
Warning
|
||
|
-------
|
||
|
|
||
|
Running a HTTP proxy in your firewall VM increases the attack surface
|
||
|
against that VM from a compromised AppVM. tinyproxy has a relatively
|
||
|
simple code and a reasonable track record to allow to certain level of
|
||
|
trust. But one cannot exclude bugs especially in the case of a hostile
|
||
|
proxy clients as this is less tested scenario. So it is not advisable
|
||
|
to use the proxy in a shared firewall VM against untrusted AppVM to
|
||
|
black-list some unwanted connection like advertisement sites.
|
||
|
|
||
|
Less problematic setup is to white-list possible connections for
|
||
|
several trusted and semi-trusted AppVMs within one firewall VM. Still
|
||
|
for maximum safety one should consider running a separated firewall VM
|
||
|
per each important AppVMs and run the proxy there.
|
||
|
|
||
|
As a counterweight to this warning it is important to point out that
|
||
|
HTTP proxy decreases attack surface against AppVM. For example, with a
|
||
|
proxy the AppVM does not need DNS connections so a bug in the kernel
|
||
|
or in the browser in that area would not affect the AppVM. Also
|
||
|
browsers typically avoid many latest and greatest HTTP features when
|
||
|
connection through proxies minimizing exposure of new and unproven
|
||
|
networking code.
|
||
|
|
||
|
|
||
|
Setup
|
||
|
-----
|
||
|
|
||
|
1. Copy this [archive] with the proxy control script, default
|
||
|
tinyproxy config and a sample firewall filtering file into the
|
||
|
firewall VM and unpack it in `/rw/config` folder there as root:
|
||
|
|
||
|
cd /rw/config
|
||
|
sudo tar xzf .../proxy.tar.xz
|
||
|
|
||
|
2. If necessary adjust `/rw/config/tinyproxy/config` according to the
|
||
|
man page for `tinyproxy.conf`. The included config file refuses the
|
||
|
connection unless the host is white-listed in the filtering file, so
|
||
|
this can be altered if one wants rather to black-list connection. One
|
||
|
may also specify upstream proxies there. The file is a template file
|
||
|
and the control script will replace `{name}` constructs in the file with
|
||
|
actual parameters. In general lines with `{}` should be preserved as is.
|
||
|
|
||
|
3. For each AppVM that one wants to run through the proxy create an
|
||
|
the corresponding filtering file in the `/rw/config/tinyproxy`
|
||
|
directory. With the default config the filtering file should contain
|
||
|
regular expressions to match white-listed hosts with one regular
|
||
|
expression per line, see the man page for tinyproxy.conf for details.
|
||
|
The file should be named:
|
||
|
|
||
|
name.ip-address-of-app-vm
|
||
|
|
||
|
The name part before the dot can be arbitrary. For convenience one can
|
||
|
use AppVm name here, but this is not required. It is important to get
|
||
|
ip address part right as this is what the control script uses to
|
||
|
determine for which AppVM to apply the proxy rules. One can check the
|
||
|
IP address of AppVM in Qubes VM manager in the VM settings dialog, see
|
||
|
the Networking session under the Basic tab.
|
||
|
|
||
|
The attached archive includes `tinyproxy/social.10.137.2.13` file with a
|
||
|
rules for a AppVM allowing connection to google, facebook, linkedin,
|
||
|
livejournal, youtube and few other other sites. One can use it as an
|
||
|
example after changing the the IP address accordingly.
|
||
|
|
||
|
When editing the rules remember to include `$` at the end of the host
|
||
|
name and to prefix each dot in the host name with the backslash. This
|
||
|
way the pattern matches the whole host and not just some prefix and
|
||
|
the dot is not interpreted as an instruction to match an arbitrary
|
||
|
character according to regular expression syntax.
|
||
|
|
||
|
4. Check that `proxyctl.py` script can properly recognize the rule
|
||
|
files. For that run:
|
||
|
|
||
|
sudo /rw/config/tinyproxy/proxyctl.py show
|
||
|
|
||
|
For each rule file it should print the name, ip address, network
|
||
|
interface of the running AppVM if AppVM runs and the id of the
|
||
|
tinyproxy process that proxies that AppVM. The first time each pid
|
||
|
should be `--`.
|
||
|
|
||
|
5. Now run some AppVM with proxy and then run:
|
||
|
|
||
|
sudo /rw/config/tinyproxy/proxyctl.py update
|
||
|
|
||
|
The update command starts proxy processes and adjusts the iptable
|
||
|
rules to allow for proxy traffic for each running AppVM from the
|
||
|
filtering files list. For each stopped AppVM the proxy is killed.
|
||
|
|
||
|
Check that proxy is started so the `pid` field of the show command is a
|
||
|
number:
|
||
|
|
||
|
sudo /rw/config/tinyproxy/proxyctl.py show
|
||
|
|
||
|
6. Run the browser in the started AppVM and configure it to use the
|
||
|
proxy on the port 8100 running at the IP address of the firewall VM
|
||
|
gateway interface. In Qubes VM manager the address is given after the
|
||
|
Gateway label in the Setting dialog for the firewall VM.
|
||
|
|
||
|
In Firefox go to the Preferences dialog, select Advanced->Network,
|
||
|
click Settings for the Connection section. In the Connection Settings
|
||
|
dialog select Manual proxy configuration. For HTTP Proxy field use the
|
||
|
IP address of the firewall gateway interface. Enter 8100 as the port
|
||
|
and the select the checkbox "Use this proxy server for all protocols".
|
||
|
|
||
|
Go to some site. The browser should either load it if it was
|
||
|
white-listed in the filtering file or show a page generated by
|
||
|
tinyproxy that the page was filtered out.
|
||
|
|
||
|
In the firewall VM see `/run/tinyproxy/name/log` file. For each filtered
|
||
|
out website it contains an entry and one can adjust the filtering file
|
||
|
to include the corresponding host. After changing the file run either:
|
||
|
|
||
|
sudo /rw/config/tinyproxy/proxyctl.py restart name
|
||
|
|
||
|
to restart proxy with the updated rules file only for the given VM or
|
||
|
|
||
|
sudo /rw/config/tinyproxy/proxyctl.py kill-all-and-restart
|
||
|
|
||
|
to restart all proxy processes.
|
||
|
|
||
|
7. To make sure that the proxy is started automatically when the AppVM
|
||
|
starts change `/rw/config/qubes_firewall_user_script` to include the
|
||
|
following line:
|
||
|
|
||
|
/rw/config/tinyproxy/proxyctl.py update
|
||
|
|
||
|
If the file does not exist, create it so it looks like this:
|
||
|
|
||
|
#!/usr/bin/bash
|
||
|
/rw/config/tinyproxy/proxyctl.py update
|
||
|
|
||
|
Make sure that the script is owned by root and executable:
|
||
|
|
||
|
sudo chown root:root /rw/config/qubes_firewall_user_script
|
||
|
sudo chmod 755 /rw/config/qubes_firewall_user_script
|
||
|
|
||
|
8. In Qubes VM manager adjust Firewall rules for each AppVM with a
|
||
|
proxy. In a typical case when only HTTP proxy should be used for
|
||
|
outside connections, simply select "Deny network access except...," make
|
||
|
sure that the address list is empty and then unselect "Allow ICMP," "DNS"
|
||
|
and "Update proxy" checkboxes.
|
||
|
|
||
|
There is no need to add any special entries for the proxy in the GUI
|
||
|
as `proxyctl.py` adds rules for the proxy traffic itself.
|
||
|
|
||
|
--------------------------------------------------------------------------------
|
||
|
|
||
|
This guide was initially written by Igor Bukanov in a [message] to the
|
||
|
`qubes-devel` [mailing list].
|
||
|
|
||
|
[archive]: https://groups.google.com/group/qubes-devel/attach/39c95d63fccca12b/proxy.tar.gz?part=0.1
|
||
|
[message]: https://groups.google.com/d/msg/qubes-devel/UlK8P27UtD4/K6HM_GNdyTkJ
|
||
|
[mailing list]: /mailing-lists/
|