## File: README.md

# Get Peace of Mind  with [Easy Privacy](https://safing.io/)

Portmaster is a free and open-source application firewall that does the heavy lifting for you.
Restore privacy and take back control over all your computer's network activity.

With great defaults your privacy improves without any effort. And if you want to configure and control everything down to the last detail - Portmaster has you covered too. Developed in the EU 🇪🇺, Austria.

__[Download for Free](https://safing.io/download/)__

__[About Us](https://safing.io/about/)__



_seen on:_  

[](https://www.heise.de/tests/Datenschutz-Firewall-Portmaster-im-Test-9611687.html)
&nbsp;&nbsp;&nbsp;
[](https://www.ghacks.net/2022/11/08/portmaster-1-0-released-open-source-application-firewall/)
&nbsp;&nbsp;&nbsp;
[](https://www.youtube.com/watch?v=E8cTRhGtmcM)
&nbsp;&nbsp;&nbsp;
[](https://lifehacker.com/the-lesser-known-apps-everyone-should-install-on-a-new-1850223434)

## [Features](https://safing.io/features/)

1. Monitor All Network Activity
2. Full Control: Block Anything
3. Automatically Block Trackers & Malware
4. Set Global & Per‑App Settings
5. Secure DNS (Doh/DoT)
6. Record and Search Network Activity ([$](https://safing.io/pricing/))
7. Per-App Bandwidth Usage ([$](https://safing.io/pricing/))
8. [SPN, our Next-Gen Privacy Network](https://safing.io/spn/) ([$$](https://safing.io/pricing/))

# Technical Introduction

Portmaster is a privacy suite for your Windows and Linux desktop.

### Base Technology

- Portmaster integrates into network stack using nfqueue on Linux and a kernel driver (WFP) on Windows.
- Packets are intercepted at the raw packet level - every packet is seen and can be stopped.
- Ownership of connections is found using eBPF and `/proc` on Linux and a kernel driver and the IP Helper API (`iphlpapi.dll`) on Windows.
- Most settings can be defined per app, which can be matched in different ways.
- Support for special processes with weird or concealed paths/actors:
  - Snap, AppImage and Script support on Linux
  - Windows Store apps and svchost.exe system services support on Windows
- Everything is 100% local on your device. (except the SPN, naturally)
  - Updates are fully signed and downloaded automatically.
  - Intelligence data (block lists, geoip) is downloaded and applied automatically.
- The Portmaster Core Service runs as a system service, the UI elements (App, Notifier) run in user context.
- The main UI still uses electron as a wrapper :/ - but this will change in the future. You can also open the UI in the browser

### Feature: Secure DNS

- Portmaster intercepts "astray" DNS queries and reroutes them to itself for seamless integration.
- DNS queries are resolved by the default or configured DoT/DoH resolvers.
- Full support for split horizon and horizon validation to defend against rebinding attacks.

### Feature: Privacy Filter

- Define allowed network scopes: Localhost, LAN, Internet, P2P, Inbound.
- Easy rules based on Internet entities: Domain, IP, Country and more.
- Filter Lists block common malware, ad, tracker domains etc.

### Feature: Network History ($)

- Record connections and their details in a local database and search all of it later
- Auto-delete old history or delete on demand

### Feature: Bandwidth Visibility ($)

- Monitor bandwidth usage per connection and app

### Feature: SPN - Safing Privacy Network ($$)

- A Privacy Network aimed at use cases "between" VPN and Tor.
- Uses onion encryption over multiple hops just like Tor.
- Routes are chosen to cover most distance within the network to increase privacy.
- Exits are chosen near the destination server. This automatically geo-unblocks in many cases.
- Exclude apps and domains/entities from using SPN.
- Change routing algorithm and focus per app.
- Nodes are hosted by Safing (company behind Portmaster) and the community.
- Speeds are pretty decent (>100MBit/s).
- Further Reading: [SPN Whitepaper](https://safing.io/files/whitepaper/Gate17.pdf)

## Documentation

All details and guides in the dedicated [wiki](https://wiki.safing.io/)

- [Getting Started](https://wiki.safing.io/en/Portmaster/App)
- Install
  - [on Windows](https://wiki.safing.io/en/Portmaster/Install/Windows)
  - [on Linux](https://wiki.safing.io/en/Portmaster/Install/Linux)
- [Contribute](https://wiki.safing.io/en/Contribute)
- [VPN Compatibility](https://wiki.safing.io/en/Portmaster/App/Compatibility#vpn-compatibly)
- [Software Compatibility](https://wiki.safing.io/en/Portmaster/App/Compatibility)
- [Architecture](https://wiki.safing.io/en/Portmaster/Architecture)
- [Settings Handbook](https://docs.safing.io/portmaster/settings)
- [Portmaster Developer API](https://docs.safing.io/portmaster/api)

# Build Portmaster Yourself (WIP)

1. [Install Earthly CLI](https://earthly.dev/get-earthly)
2. [Install Docker Engine](https://docs.docker.com/engine/install/)
3. Run `earthly +release`
4. Find artifacts in `./dist`

---

## File: base/database/query/README.md

# Query

## Control Flow

- Grouping with `(` and `)`
- Chaining with `and` and `or`
  - _NO_ mixing! Be explicit and use grouping.
- Negation with `not`
  - in front of expression for group: `not (...)`
  - inside expression for clause: `name not matches "^King "`

## Selectors

Supported by all feeders:
- root level field: `field`
- sub level field: `field.sub`
- array/slice/map access: `map.0`
- array/slice/map length: `map.#`

Please note that some feeders may have other special characters. It is advised to only use alphanumeric characters for keys.

## Operators

| Name                    | Textual            | Req. Type | Internal Type | Compared with             |
|-------------------------|--------------------|-----------|---------------|---------------------------|
| Equals                  | `==`               | int       | int64         | `==`                      |
| GreaterThan             | `>`                | int       | int64         | `>`                       |
| GreaterThanOrEqual      | `>=`               | int       | int64         | `>=`                      |
| LessThan                | `<`                | int       | int64         | `<`                       |
| LessThanOrEqual         | `<=`               | int       | int64         | `<=`                      |
| FloatEquals             | `f==`              | float     | float64       | `==`                      |
| FloatGreaterThan        | `f>`               | float     | float64       | `>`                       |
| FloatGreaterThanOrEqual | `f>=`              | float     | float64       | `>=`                      |
| FloatLessThan           | `f<`               | float     | float64       | `<`                       |
| FloatLessThanOrEqual    | `f<=`              | float     | float64       | `<=`                      |
| SameAs                  | `sameas`, `s==`    | string    | string        | `==`                      |
| Contains                | `contains`, `co`   | string    | string        | `strings.Contains()`      |
| StartsWith              | `startswith`, `sw` | string    | string        | `strings.HasPrefix()`     |
| EndsWith                | `endswith`, `ew`   | string    | string        | `strings.HasSuffix()`     |
| In                      | `in`               | string    | string        | for loop with `==`        |
| Matches                 | `matches`, `re`    | string    | string        | `regexp.Regexp.Matches()` |
| Is                      | `is`               | bool*     | bool          | `==`                      |
| Exists                  | `exists`, `ex`     | any       | n/a           | n/a                       |

\*accepts strings: 1, t, T, true, True, TRUE, 0, f, F, false, False, FALSE

## Escaping

If you need to use a control character within a value (ie. not for controlling), escape it with `\`.
It is recommended to wrap a word into parenthesis instead of escaping control characters, when possible.

| Location | Characters to be escaped |
|---|---|
| Within parenthesis (`"`) | `"`, `\` |
| Everywhere else | `(`, `)`, `"`, `\`, `\t`, `\r`, `\n`, ` ` (space) |

---

## File: base/metrics/testdata/README.md

# Testing metrics

You can spin up a test setup for pushing and viewing metrics with `docker-compose up`.
Then use the flag `--push-metrics http://127.0.0.1:8428/api/v1/import/prometheus` to push metrics.

---

## File: base/utils/renameio/README.md

This is a fork of the github.com/google/renameio Go package at commit 353f8196982447d8b12c64f69530e657331e3dbc.

The inital commit of this package will carry the original package contents.  
The Original License is the Apache License in Version 2.0 and the copyright of the forked package is held by Google Inc.  
Any changes are recorded in the git history, which is part of this project.

---

The `renameio` Go package provides a way to atomically create or replace a file or
symbolic link.

## Atomicity vs durability

`renameio` concerns itself *only* with atomicity, i.e. making sure applications
never see unexpected file content (a half-written file, or a 0-byte file).

As a practical example, consider https://manpages.debian.org/: if there is a
power outage while the site is updating, we are okay with losing the manpages
which were being rendered at the time of the power outage. They will be added in
a later run of the software. We are not okay with having a manpage replaced by a
0-byte file under any circumstances, though.

## Advantages of this package

There are other packages for atomically replacing files, and sometimes ad-hoc
implementations can be found in programs.

A naive approach to the problem is to create a temporary file followed by a call
to `os.Rename()`. However, there are a number of subtleties which make the
correct sequence of operations hard to identify:

* The temporary file should be removed when an error occurs, but a remove must
  not be attempted if the rename succeeded, as a new file might have been
  created with the same name. This renders a throwaway `defer
  os.Remove(t.Name())` insufficient; state must be kept.

* The temporary file must be created on the same file system (same mount point)
  for the rename to work, but the TMPDIR environment variable should still be
  respected, e.g. to direct temporary files into a separate directory outside of
  the webserver’s document root but on the same file system.

* On POSIX operating systems, the
  [`fsync`](https://manpages.debian.org/stretch/manpages-dev/fsync.2) system
  call must be used to ensure that the `os.Rename()` call will not result in a
  0-length file.

This package attempts to get all of these details right, provides an intuitive,
yet flexible API and caters to use-cases where high performance is required.

## Disclaimer

This is not an official Google product (experimental or otherwise), it
is just code that happens to be owned by Google.

This project is not affiliated with the Go project.

---

## File: base/README.md

> **Check out our main project at [safing/portmaster](https://github.com/safing/portmaster)**

# Portbase

Portbase helps you quickly take off with your project. It gives you all the basic needs you would have for a service (_not_ tool!).
Here is what is included:

- `log`: really fast and beautiful logging
- `modules`: a multi stage, dependency aware boot process for your software, also manages tasks
- `config`: simple, live updating and extremely fast configuration storage
- `info`: easily tag your builds with versions, commit hashes, and so on
- `formats`: some handy data encoding libs
- `rng`: a feedable CSPRNG for great randomness
- `database`: intelligent and syncable database with hooks and easy integration with structs, uses buckets with different backends
- `api`: a websocket interface to the database, can be extended with custom http handlers

Before you continue, a word about this project. It was created to hold the base code for both Portmaster and Gate17. This is also what it will be developed for. If you have a great idea on how to improve portbase, please, by all means, raise an issue and tell us about it, but please also don't be surprised or offended if we ask you to create your own fork to do what you need. Portbase isn't for everyone, it's quite specific to our needs, but we decided to make it easily available to others.

Portbase is actively maintained, please raise issues.

## log

The main goal of this logging package is to be as fast as possible. Logs are sent to a channel only with minimal processing beforehand, so that the service can continue with the important work and write the logs later.

Second, is beauty, both in form what information is provided and how.

You can use flags to change the log level on a source file basis.

## modules <small>requires `log`</small>

packages may register themselves as modules, to take part in the multi stage boot and coordinated shutdown.

Registering only requires a name/key and the `prep()`, `start()` and `stop()` functions.

This is how modules are booted:

- `init()` available: ~~flags~~, ~~config~~, ~~logging~~, ~~dependencies~~
  - register flags (with the stdlib `flag` library)
  - register module
- `module.prep()` available: flags, ~~config~~, ~~logging~~, ~~dependencies~~
  - react to flags
  - register config variables
  - if an error occurs, return it
  - return ErrCleanExit for a clean, successful exit. (eg. you only printed a version)
- `module.start()` available: flags, config, logging, dependencies
  - start tasks and workers
  - do not log errors while starting, but return them
- `module.stop()` available: flags, config, logging, dependencies
  - stop all work (ie. goroutines)
  - do not log errors while stopping, but return them

You can start tasks and workers from your module that are then integrated into the module system and will allow for insights and better control of them in the future.

## config <small>requires `log`</small>

The config package stores the configuration in json strings. This may sound a bit weird, but it's very practical.

There are three layers of configuration - in order of priority: user configuration, default configuration and the fallback values supplied when registering a config variable.

When using config variables, you get a function that checks if your config variable is still up to date every time. If it did not change, it's _extremely_ fast. But if it, it will fetch the current value, which takes a short while, but does not happen often.

    // This is how you would get a string config variable function.
    myVar := GetAsString("my_config_var", "default")
    // You then use myVar() directly every time, except when you must guarantee the same value between two calls
    if myVar() != "default" {
      log.Infof("my_config_var is set to %s", myVar())
    }
    // no error handling needed! :)

WARNING: While these config variable functions are _extremely_ fast, they are _NOT_ thread/goroutine safe! (Use the `Concurrent` wrapper for that!)

## info

Info provides a easy way to store your version and build information within the binary. If you use the `build` script to build the program, it will automatically set build information so that you can easily find out when and from which commit a binary was built.

The `build` script extracts information from the host and the git repo and then calls `go build` with some additional arguments.

## formats/varint

This is just a convenience wrapper around `encoding/binary`, because we use varints a lot.

## formats/dsd <small>requires `formats/varint`</small>

DSD stands for dynamically structured data. In short, this a generic packer that reacts to the supplied data type.

- structs are usually json encoded
- []bytes and strings stay the same

This makes it easier / more efficient to store different data types in a k/v data storage.

## rng <small>requires `log`, `config`</small>

This package provides a CSPRNG based on the [Fortuna](https://en.wikipedia.org/wiki/Fortuna_(PRNG)) CSPRNG, devised by Bruce Schneier and Niels Ferguson. Implemented by Jochen Voss, published [on Github](https://github.com/seehuhn/fortuna).

Only the Generator is used from the `fortuna` package. The feeding system implemented here is configurable and is focused with efficiency in mind.

While you can feed the RNG yourself, it has two feeders by default:
- It starts with a seed from `crypto/rand` and periodically reseeds from there
- A really simple tickfeeder which extracts entropy from the internal go scheduler using goroutines and is meant to be used under load.

## database <small>requires `log`</small>
_introduction to be written_

## api <small>requires `log`, `database`, `config`</small>
_introduction to be written_

## The main program

If you build everything with modules, your main program should be similar to this - just use an empty import for the modules you need:

    import (
      "os"
      "os/signal"
      "syscall"

      "github.com/safing/portmaster/base/info"
      "github.com/safing/portmaster/base/log"
      "github.com/safing/portmaster/base/modules"

      // include packages here
      _ "path/to/my/custom/module"
    )

    func main() {

    	// Set Info
    	info.Set("MySoftware", "1.0.0")

    	// Start
    	err := modules.Start()
    	if err != nil {
    		if err == modules.ErrCleanExit {
    			os.Exit(0)
    		} else {
    			os.Exit(1)
    		}
    	}

    	// Shutdown
    	// catch interrupt for clean shutdown
    	signalCh := make(chan os.Signal)
    	signal.Notify(
    		signalCh,
    		os.Interrupt,
    		syscall.SIGHUP,
    		syscall.SIGINT,
    		syscall.SIGTERM,
    		syscall.SIGQUIT,
    	)
    	select {
    	case <-signalCh:
    		log.Warning("main: program was interrupted")
    		modules.Shutdown()
    	case <-modules.ShuttingDown():
    	}

    }

---

## File: desktop/tauri/src-tauri/README.md

# Update Tauri guide

Check latest versions of tauri packages and update them accordingly (https://crates.io/)  
Cargo.toml:  
```toml
[build-dependencies]
tauri-build = { version = "2.0.0-beta.19", features = [] } # Update to latest

[dependencies]
# Tauri
tauri = { version = "2.0.0-beta.24", features = ["tray-icon", "image-png", "config-json5", "devtools"] } # Update to latest
tauri-plugin-shell = "2.0.0-beta"
tauri-plugin-dialog = "2.0.0-beta"
tauri-plugin-clipboard-manager = "2.0.0-beta"
tauri-plugin-os = "2.0.0-beta"
tauri-plugin-single-instance = "2.0.0-beta"
tauri-plugin-cli = "2.0.0-beta"
tauri-plugin-notification = "2.0.0-beta"
tauri-plugin-log = "2.0.0-beta"
tauri-plugin-window-state = "2.0.0-beta"

tauri-cli = "2.0.0-beta.21" # Update to latest
```

Run:
```sh
cargo update
```

> Make sure to update the npm tauri plugin dependencies to have the same version as the rust plugins. (desktop/angular)

## Update WIX installer template

> If the migration functionality is not needed anymore remove the template, this will cause tauri to use its default template and not call the migration script.

1. Get the latest [main.wxs](https://github.com/tauri-apps/tauri/blob/dev/tooling/bundler/src/bundle/windows/templates/main.wxs) template from the repository.
2. Replace the contents of `templates/wix/main_original.wxs` with the repository version. (The file is kept only for reference)
3. Replace the contents of `templates/wix/main.wsx` and add the fallowing lines at the end of the file, inside the `Product` tag. 
```xml
    
    <CustomActionRef Id='MigrationPropertySet' />
    <CustomActionRef Id='Migration' />
    
    
    
```

---

## File: desktop/angular/projects/safing/ui/README.md

# Ui

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.

## Code scaffolding

Run `ng generate component component-name --project ui` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ui`.
> Note: Don't forget to add `--project ui` or else it will be added to the default project in your `angular.json` file. 

## Build

Run `ng build ui` to build the project. The build artifacts will be stored in the `dist/` directory.

## Publishing

After building your library with `ng build ui`, go to the dist folder `cd dist/ui` and run `npm publish`.

## Running unit tests

Run `ng test ui` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

---

## File: desktop/angular/projects/safing/portmaster-api/README.md

# PortmasterApi

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.0.0.

## Code scaffolding

Run `ng generate component component-name --project portmaster-api` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project portmaster-api`.
> Note: Don't forget to add `--project portmaster-api` or else it will be added to the default project in your `angular.json` file. 

## Build

Run `ng build portmaster-api` to build the project. The build artifacts will be stored in the `dist/` directory.

## Publishing

After building your library with `ng build portmaster-api`, go to the dist folder `cd dist/portmaster-api` and run `npm publish`.

## Running unit tests

Run `ng test portmaster-api` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

---

## File: desktop/angular/README.md

# Portmaster

Welcome to the new Portmaster User-Interface. It's based on Angular and is built, unit and e2e tested using `@angular/cli`.

## Running locally

This section explains how to prepare your Ubuntu machine to build and test the new Portmaster User-Interface. It's recommended to use
a virtual machine but running it on bare metal will work as well. You can use the new Portmaster UI as well as the old one in parallel so
you can simply switch back when something is still missing or buggy.

1. **Prepare your tooling**

There's a simple dockerized way to build and test the new UI. Just make sure to have docker installed:

```bash
sudo apt update
sudo apt install -y docker.io git
sudo systemctl enable --now docker
sudo gpasswd -a $USER docker
```

2. **Portmaster installation**

Next, make sure to install the Portmaster using the official .deb installer from [here](https://updates.safing.io/latest/linux_amd64/packages/portmaster-installer.deb). See the [Wiki](https://github.com/safing/portmaster/wiki/Linux) for more information.

Once the Portmaster is installed we need to add two new configuration flags. Execute the following:

```bash
echo 'PORTMASTER_ARGS="--experimental-nfqueue --devmode"' | sudo tee /etc/default/portmaster
sudo systemctl daemon-reload
sudo systemctl restart portmaster
```

3. **Build and run the new UI**

Now, clone this repository and execute the `docker.sh` script:

```bash
# Clone the repository
git clone https://github.com/safing/portmaster-ui

# Enter the repo and checkout the correct branch
cd portmaster-ui
git checkout feature/new-ui

# Enter the directory and run docker.sh
cd modules/portmaster
sudo bash ./docker.sh
```

Finally open your browser and point it to http://localhost:8080.

## Hacking Quick Start

Although everything should work in the docker container as well, for the best development experience it's recommended to install `@angular/cli` locally.

It's highly recommended to:
- Use [VSCode](https://code.visualstudio.com/) (or it's oss or server-side variant) with
  - the official [Angular Language Service](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template) extension
  - the [Tailwind CSS Extension Pack](https://marketplace.visualstudio.com/items?itemName=andrewmcodes.tailwindcss-extension-pack) extension
  - the [formate: CSS/LESS/SCSS formatter](https://github.com/mblander/formate) extension

### Folder Structure

From the project root (the folder containing this [README.md](./)) there are only two folders with the following content and structure:

- **`src/`** contains the actual application sources:
  - **`app/`** contains the actual application sources (components, services, uni tests ...)
    - **`layout/`** contains components that form the overall application layout. For example the navigation bar and the side dash are located there.
    - **`pages/`** contains the different pages of the application. A page is something that is associated with a dedicated application route and is rendered at the applications main content.
    - **`services/`** contains shared services (like PortAPI and friends)
    - **`shared/`** contains shared components that are likely used accross other components or pages.
    - **`widgets/`** contains widgets and their settings components for the application side dash.
    - **`debug/`** contains a debug sidebar component
  - **`assets/`** contains static assets that must be shipped seperately.
  - **`environments/`** contains build and production related environment settings (those are handled by `@angular/cli` automatically, see [angular.json](angular.json))
- **`e2e/`** contains end-to-end testing sources.


### Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

In development mode (that is, you don't pass `--prod`) the UI expects portmaster running at `ws://127.0.0.1:817/api/database/v1`. See [environment](./src/app/environments/environment.ts).

### Code scaffolding

Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.

### Build

Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.

### Running unit tests

Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).

### Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).

### Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).