e359f383dab8973a353c83cec464fd7ec1cf42ab — jwijenbergh 2 months ago 2421aca
Markdown: Fix headings for static site
M API.md => API.md +26 -26
@@ 1,4 1,4 @@
# Introduction

This document describes version 3 of the API provided by eduVPN and 
Let's Connect! servers.

@@ 14,7 14,7 @@ servers with version >= 2.4.1.

The API design was finalized and is considered _stable_ from 2022-01-27.

# Standards
## Standards

We use a simple HTTP API protected by OAuth 2, following all recommendations 
of the [OAuth 2.1](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/) 

@@ 29,7 29,7 @@ of the changes from OAuth 2, it basically boils down:

All HTTP request MUST use HTTPS.

# Server Discovery
## Server Discovery

As there are many servers running eduVPN / Let's Connect! you need to know 
which server you need to connect to. This can be either hard-coded in the 

@@ 39,7 39,7 @@ can be implemented.
For eduVPN specific we implement "server discovery" as documented 

# Server Endpoint Discovery
## Server Endpoint Discovery

A "well-known" URL is provided to figure out the OAuth and API endpoint one
has to use. The document can be retrieved from `/.well-known/vpn-user-portal`, 

@@ 64,13 64,13 @@ this API.
This file MUST be freshly retrieved before all attempts to connect to a server 
to make sure any updates to this file are discovered.

## Endpoint Location
### Endpoint Location

When fetching this document, _redirects_, e.g. `301`, `302`, `303`, MUST be 
followed, but MUST NOT allow redirect to anything else than other `https://` 
URLs, e.g. redirects to `http://` MUST be rejected.

# Authorization Endpoint
## Authorization Endpoint

The `authorization_endpoint` is used to obtain an authorization code through an
"Authorization Request". All query parameters as defined by the OAuth 

@@ 97,7 97,7 @@ a location the application can intercept.
All error conditions, both during the authorization phase AND when talking 
to the API endpoint MUST be handled according to the OAuth specification(s).

# Token Endpoint
## Token Endpoint

The `token_endpoint` is used to exchange the authorization code, as obtained
through the `redirect_uri` as part of the authorization, for an access and 

@@ 107,7 107,7 @@ access token expires.
All error conditions, both during the authorization phase AND when talking 
to the API endpoint MUST be handled according to the OAuth specification(s).

# Using the API
## Using the API

Every API call below will include a cURL example, and an example response that 
can be expected.

@@ 123,16 123,16 @@ documented above. The following API calls are available:
- "Connect" to a VPN profile (`/connect`);
- "Disconnect" from a VPN profile (`/disconnect`)

# API Calls
## API Calls

## Info
### Info

This call will show the available VPN profiles for this instance. This will 
allow the application to show the user which profiles are available.

This `GET` call has no parameters.

### Request
#### Request

Request all available VPN profiles:

@@ 142,7 142,7 @@ $ curl \

### Response
#### Response

HTTP/1.1 200 OK

@@ 190,11 190,11 @@ omitted, or marked as unsupported in that VPN client. Currently `openvpn` and
`wireguard` values are supported. As an example: a WireGuard only client 
SHOULD NOT list VPN profiles that only support OpenVPN.

## Connect
### Connect

Get the profile configuration for the profile you want to connect to.

### Request
#### Request

Connect to the "Employees" profile (`employees`) and specify a WireGuard public 
key for when WireGuard will be used:

@@ 224,12 224,12 @@ header. To add it to the cURL example use e.g.
`-H "Accept: application/x-openvpn-profile"` to indicate your client only 
supports OpenVPN.

#### Profile ID
##### Profile ID

The value of `profile_id` MUST be of one of the identifiers for the profiles 
returned in the `/info` response.

#### Public Key
##### Public Key

When the WireGuard protocol is expected to be used, the `public_key` parameter 
MUST be set. The value of `public_key` MUST be a valid WireGuard public key. It 

@@ 250,7 250,7 @@ servers, generate one *per server*.
**NOTE**: a VPN client MAY opt to generate a new public / private key for 
every new call to `/connect` instead of storing it.

#### Prefer TCP
##### Prefer TCP

The `prefer_tcp` parameter is a hint for the VPN server, currently only for the 
OpenVPN protocol.

@@ 262,7 262,7 @@ The server MAY accept this and return an OpenVPN configuration with the TCP
The server MAY ignore the option, for example when the profile only supports
WireGuard, or the OpenVPN server configuration does not use TCP.

### Response
#### Response

If the profile is an OpenVPN profile you'll get the complete OpenVPN client
configuration with `Content-Type: application/x-openvpn-profile`, e.g.:

@@ 368,7 368,7 @@ PrivateKey = AJmdZTXhNRwMT1CEvXys2T9SNYnXUG2niJVT4biXaX0=

## Disconnect
### Disconnect

This call is to indicate to the server that the VPN session(s) belonging to 
this OAuth authorization can be terminated. This MUST ONLY be called when the 

@@ 398,7 398,7 @@ When talking about "System VPNs", i.e. VPN connections that are not controlled
by the user, but by the device administrator, or possibly explicitly configured
as a "System VPN" by the user, if available, these rules do not apply.

### Request
#### Request

$ curl -X POST \

@@ 408,14 408,14 @@ $ curl -X POST \

This `POST` call has no parameters.

### Response
#### Response

HTTP/1.1 204 No Content


## Error Responses
### Error Responses

Do **NOT** use the exact "Message" for string comparison in your application 
code, getting any of these (4xx) errors below indicates a problem in the 

@@ 450,7 450,7 @@ the user if so instructed by the support desk, and MAY be shown to the user in
full, however a generic "Server Error" could be considered as well, perhaps 
with a "Details..." button.

# VPN Protocol Selection
## VPN Protocol Selection

The VPN server decides which protocol will be used for the VPN connection. This
can be either OpenVPN or WireGuard. The client _is_ able to influence this 

@@ 518,7 518,7 @@ Accept: application/x-openvpn-profile, application/x-wireguard-profile
**NOTE**: if the `Accept` request header is missing, it is assumed that the 
VPN client supports both OpenVPN and WireGuard.

# Application Flow
## Application Flow

Below we describe how the application MUST interact with the API. It does NOT
include information on how to handle OAuth. The application MUST properly 

@@ 569,7 569,7 @@ application if not yet open. This allows the user to (manually)
disconnect/connect again restoring the VPN and possibly renewing the 
authorization when e.g. the authorization was revoked.

# Session Expiry
## Session Expiry

All VPN sessions have an expiry. The default (as set by the server) is 90 days. 
The server operator is able to change this. Some organizations set the session

@@ 618,7 618,7 @@ this order:
The OS notification shown to the user _MAY_ offer the "Renew Session" button 
inside the notification as well, if supported by the OS.

# History
## History

The changes made to the API documentation.

M ARCH.md => ARCH.md +1 -6
@@ 1,8 1,4 @@
title: Architecture
description: Description of Service Architecture
category: documentation
# Architecture

This is a very short overview of the server architecture for version 1.0 of 

@@ 70,4 66,3 @@ machine. When run on multiple machines, the portal and server API are installed
on 1 machine, and the server node on the other machine(s).


M BGP.md => BGP.md +1 -11
@@ 1,19 1,9 @@
title: BGP
description: Use BGP announcements
category: advanced
author: Jørn Åne (Uninett)


## Warning

This guide is provided as is.  The eduVPN project provides no support for BGP.

## Introduction

If your network allows it, the IP ranges used by your vpn-server-node can be obtained through BGP.  For this to work, you must know the following:

  * `neighbor` IP-address of your routers (this may differ from the default gateway)

M BRANDING.md => BRANDING.md +6 -4
@@ 1,19 1,21 @@
# Change branding

This document describes how to add the Let's Connect! or eduVPN branding to 
your server installation. By default a simple "plain" branding is used.

# Installation
## Installation

## Fedora / Enterprise Linux
### Fedora / Enterprise Linux

    $ sudo dnf -y install vpn-portal-artwork-LC
    $ sudo dnf -y install vpn-portal-artwork-eduVPN

## Debian / Ubuntu
### Debian / Ubuntu

    $ sudo apt -y install vpn-portal-artwork-lc
    $ sudo apt -y install vpn-portal-artwork-eduvpn

# Configuration
## Configuration

Now you can enable the `styleName` in `/etc/vpn-user-portal/config.php`. Set it 
to `LC` (or `eduVPN`).

@@ 1,3 1,5 @@
# Change Hostname

In case you want to change the hostname of your VPN server, you need to follow
these steps:

@@ 13,30 15,30 @@ Please adapt the hostname as appropriate.

This instruction is for a _single_ server deployment.

# Hostname
## Hostname

$ sudo hostnamectl set-hostname vpn.example.com

## DNS

Make sure the new hostname has an A (and AAAA) record to your VPN server IPs.

## TLS

When your DNS is correct you can use Let's Encrypt to obtain new certificates,
or manually obtain them from your CA and install them.

# Apache
## Apache

## Fedora / EL
### Fedora / EL

Rename `/etc/httpd/conf.d/vpn.example.org.conf` to 
`/etc/httpd/conf.d/vpn.example.com.conf`. Replace all occurrences of 
`vpn.example.org` with `vpn.example.com` in this file.

## Debian / Ubuntu
### Debian / Ubuntu

Disable the old site:

@@ 49,12 51,12 @@ $ sudo a2ensite vpn.example.com
Modify `/etc/apache2/sites-available/vpn.example.com.conf` and replace all 
occurrences of `vpn.example.org` with `vpn.example.com`.

# Server Configuration
## Server Configuration

Modify `/etc/vpn-user-portal/config.php` and look at all `hostName` entries and
change them to the new hostname.

# Apply
## Apply


M DATABASE.md => DATABASE.md +17 -17
@@ 1,4 1,4 @@
# Introduction
# Database

The VPN server supports other databases than just the default 
[SQLite](https://sqlite.org/). For SQLite, no configuration is needed, it works 

@@ 21,12 21,12 @@ MariaDB/MySQL.
**NOTE (4)**: we assume you used `deploy_${DIST}_controller.sh` and 
`deploy_${DIST}_node.sh` to install the VPN service.

# Configuration
## Configuration

You can configure the database in `/etc/vpn-user-portal/config.php`, replace 
the `host`, `dbname` with the values obtained from your database administrator. 

## PostgreSQL
### PostgreSQL

Make sure you have the `php-pgsql` package installed, on Debian use `apt` 
instead of `dfn`:

@@ 46,7 46,7 @@ In `/etc/vpn-user-portal/config.php`:
Replace `host`, `dbname`, `user` and `password` with the values you obtained 
from your database administrator.

## MariaDB/MySQL
### MariaDB/MySQL

Make sure you have the `php-mysqlnd` package installed:

@@ 67,7 67,7 @@ In `/etc/vpn-user-portal/config.php`:
Replace `host`, `dbname`, `dbUser` and `dbPass` with the values you obtained 
from your database administrator.

## Database Info
### Database Info

You can show the current status of your database, this will tell you whether 
the configuration was done properly, i.e. we are able to connect to the 

@@ 80,7 80,7 @@ Required Schema Version: 2022010202
Status                 : **OK**

## Database Initialization
### Database Initialization

If you need to initialize the database:

@@ 92,7 92,7 @@ You can override your database configuration with `--dsn`, `--user`, `--pass`
options in case you need different credentials to perform a database 

## Database Migration
### Database Migration

Updates to the VPN software MAY require database migrations. This will be 
indicated in the release notes of newer versions.

@@ 110,7 110,7 @@ migration.
If a migration is needed, but not performed the VPN portal will give a clear 
error message.

## Manual Initialization / Migration
### Manual Initialization / Migration

If you really want to perform every step manually, you need to look in 
`/usr/share/vpn-user-portal/schema` for the SQL schema files. The latest 

@@ 126,26 126,26 @@ CREATE TABLE version (current_version TEXT NOT NULL);
INSERT INTO version VALUES('2021123001');

# Database Server Installation
## Database Server Installation

As mentioned above, this is only for testing!

## PostgreSQL Installation
### PostgreSQL Installation

### Fedora
#### Fedora

$ sudo dnf -y install postgresql-server 
$ sudo postgresql-setup --initdb

### Debian
#### Debian

$ sudo apt -y install postgresql 

## PostgreSQL Configuration
### PostgreSQL Configuration

First we'll allow password authentication. Modify 
`/var/lib/pgsql/data/pg_hba.conf`. On Debian this is 

@@ 219,7 219,7 @@ vpn=>

All good!

# MariaDB Installation
## MariaDB Installation

Follow the instructions below to configure your MariaDB server:

@@ 232,7 232,7 @@ $ sudo mysql_secure_installation
You can leave most things at their defaults, but set a `root` password when 
asked, you will need it below.

## MariaDB Configuration
### MariaDB Configuration

Now you need to create a database and a user with a password.

@@ 243,7 243,7 @@ $ mysql -u root -p
Provide the `root` password, and run the following commands. Replace the name 
of the database and user if you want. Make sure you choose your own password.

### Local Access
#### Local Access

If you install the MariaDB on the same system as your VPN service, run the 
following commands:

@@ 262,7 262,7 @@ account:
$ mysql vpn -u vpn -p

### Remote Access
#### Remote Access

If you install the MariaDB on a different system from your VPN service, as you
SHOULD, run the following commands:

@@ 1,3 1,5 @@
# Deploy Debian

For simple one server deployments and tests, we have a deploy script available 
you can run on a fresh Debian 11 or Ubuntu 22.04 installation. It will 
configure all components and will be ready for use after running!

M FIREWALL.md => FIREWALL.md +11 -11
@@ 1,4 1,4 @@
# Introduction
# Firewall

A very simple static firewall based on `iptables` is installed when running the 
deploy scripts. It allows connections to the VPN, SSH, HTTP and HTTPS ports. In 

@@ 70,7 70,7 @@ addresses in the IPv4 firewall, and the IPv6 style addresses in the IPv6
firewall. In addition, the ICMP type is different, i.e. `icmp` for IPv4 and 
`ipv6-icmp` for IPv6, see the `iptables` and `ip6tables` for examples.

# Improving the Defaults
## Improving the Defaults

The default firewall works well, but can be improved upon by updating it to 
match your deployment.

@@ 97,7 97,7 @@ This allows only SSH connections coming from `` and
``. This will also prevent VPN clients from accessing the SSH 

# Opening Additional VPN Ports
## Opening Additional VPN Ports

By default, one port, both for TCP and UDP are open for OpenVPN 

@@ 114,7 114,7 @@ You can easily add more by using "ranges", e.g.
-A INPUT -p tcp -m state --state NEW -m tcp --dport 1194:1197 -j ACCEPT

# NAT to Multiple Public IP Addresses
## NAT to Multiple Public IP Addresses

When using NAT with many clients, it makes sense to "share" the traffic over
multiple public IP addresses.

@@ 141,7 141,7 @@ specified `--to-source` range will be used, specified IPs included.
**NOTE**: for IPv6 the situation is similar, except you'd use the IPv6 range(s) 
and address(es).

# NAT to Different Public IP Addresses per Profile
## NAT to Different Public IP Addresses per Profile

When using [Multiple Profiles](MULTI_PROFILE.md), you may want to NAT to 
different public IP addresses. You could for example use:

@@ 159,7 159,7 @@ IP addresses.
**NOTE**: for IPv6 the situation is similar, except you'd use the IPv6 range(s) 
and address(es).

# Allow Client to Client Traffic
## Allow Client to Client Traffic

By default, client-to-client traffic is not allowed:

@@ 192,7 192,7 @@ the Internet, and the second only allows connectivity between the clients.
-A FORWARD -i wg0 -s -d -i wg0 -o wg0 -j ACCEPT

# Reject Forwarding Traffic
## Reject Forwarding Traffic

Sometimes you want to prevent VPN clients from reaching certain network, or 
allow them to reach only certain networks. For example in the "split tunnel" 

@@ 214,7 214,7 @@ your VPN clients, you can use the following:

**NOTE**: for IPv6 the situation is similar.

# Reject IPv6 Client Traffic
## Reject IPv6 Client Traffic

As the VPN server is "dual stack" throughout, it is not possible to "disable" 
IPv6. However, one can easily modify the firewall to prevent all IPv6 traffic

@@ 230,7 230,7 @@ This will cause all IPv6 to be rejected. The VPN becomes thus effectively
IPv4 only. You can of course also use it to reject IPv4 traffic to create an
IPv6-only VPN.

# Public IP Addresses for VPN Clients
## Public IP Addresses for VPN Clients

If you want to use [Public Addresses](PUBLIC_ADDR.md) for the VPN clients, this 
has some implications for the firewall:

@@ 241,12 241,12 @@ has some implications for the firewall:
**NOTE**: it is possible to use NAT for IPv4 and public IP addresses for IPv6,
actually this is recommended over using IPv6 NAT!

## Disabling NAT
### Disabling NAT

By removing all `POSTROUTING` rules from the "NAT" table takes care of 
disabling NAT.

## Allowing Incoming Traffic
### Allowing Incoming Traffic

The default `FORWARD` rules used are:

M FROM_2_TO_3.md => FROM_2_TO_3.md +2 -0
@@ 1,3 1,5 @@
# From v2 to v3 server

This document will help you migrate your existing server from eduVPN / Let's 
Connect! 2.x to 3.x.

@@ 1,4 1,4 @@
# Introduction
# Guest Access

This document describes how to enable "Guest Access". This is a feature 
provided to the eduVPN community. It is NOT available for Let's Connect!.

@@ 13,7 13,7 @@ Netherlands by SURF can access the VPN server in Germany hosted by DFN.
this purpose. It MUST NOT be used for any other purpose like providing 
access to restricted resources on the network!

# Eligibility / Requirements
## Eligibility / Requirements

Only NRENs are able to register a server for "Guest Access". 

@@ 29,7 29,7 @@ Currently we do NOT recommend registering your VPN server in eduGAIN!
In order to enable "Guest Access" on your server you MUST have 
`vpn-user-portal` >= 3.1. In older versions it will NOT work.

# Configuration
## Configuration

The "Guest Access" functionality MUST be manually enabled.

@@ 64,7 64,7 @@ list the new "User IDs". Have your admins look on their "Account" page in the
portal so you can add them. For more information on admin accounts you can 
look [here](https://github.com/eduvpn/documentation/blob/v3/PORTAL_ADMIN.md).

# Public Key
## Public Key

We need to register your OAuth public key in our "discovery" file 
to allow all participating servers to fetch it and allow users from

@@ 80,7 80,7 @@ k7.pub.ozEaVoU0p1HezQ41.HmV1WLVuRDoPiYoa2pP0qxP1YpWdKr5AoMdV_ZWl4i4

Make note of this public key as you need it for your server's registration.

# Registration
## Registration

Please contact 
[eduvpn-support@lists.geant.org](mailto:eduvpn-support@lists.geant.org) and 

@@ 113,7 113,7 @@ provide use with the following information:

Use "_Add [${FQDN}] to Secure Internet eduVPN_" as "Subject" of the mail.
## Template
### Template

Subject: `Add [vpn.example.org] to Secure Internet eduVPN`

@@ 137,12 137,12 @@ Public Key: k7.pub.ozEaVoU0p1HezQ41.HmV1WLVuRDoPiYoa2pP0qxP1YpWdKr5AoMdV_ZWl4i4

Do **NOT** forget to attach the signed copy of the policy document!

# Usage
## Usage

Once deployed, it may be interesting to figure out whether your service is used
and by whom.

## Guest Users
### Guest Users

To show how many guest users there are, you can use the including tooling, 

@@ 172,7 172,7 @@ $ sudo sqlite3 \
    "SELECT DATE(connected_at) AS date, COUNT(DISTINCT user_id) as unique_guest_user_count FROM connection_log WHERE user_id LIKE '%@%' GROUP BY date ORDER BY connected_at"

## Local Users
### Local Users

When "Guest Access" is enabled, and you also have local users, you can also 
figure out who they are, depending on your server's configuration. For example,

M HA.md => HA.md +4 -4
@@ 1,4 1,4 @@
# Introduction
# High Availability (HA)

The easiest way to install the VPN service is using the `deploy_${DIST}.sh` 
script. This will install the service on a single machine. This work really 

@@ 22,7 22,7 @@ Of course, everything has trade-offs. If you are not careful, your service
could easily become _less_ available, than simply running everything on a 
Raspberry Pi in your office closet 😊

# Terminology
## Terminology

The software conceptually consists of two components that can be "split" and 
which can then run on different (virtual) systems.

@@ 54,7 54,7 @@ WireGuard, reporting to the Portal and handling the VPN connections themselves.

# Handling More VPN Connections (Multi Node)
## Handling More VPN Connections (Multi Node)

If you are not so worried about _availability_, but just want to be able to 
handle more VPN connections than can be offered by a single system, e.g. you 

@@ 102,7 102,7 @@ the VPN client would simply pick another node and connect to that one.
which Node to connect to, this means if one of the nodes goes down, the client
talks again to the Portal to obtain a new configuration file.

# Making the Portal Redundant (HA Portal)
## Making the Portal Redundant (HA Portal)

If you _are_ worried about _availability_, you may want to duplicate the Portal 
as well. Obviously, this only makes sense if you have more than one node, 

M HA_PORTAL.md => HA_PORTAL.md +10 -10
@@ 1,4 1,4 @@
# Introduction
# HA Portal

Setting up a redundant portal is one part of making the VPN service 
"High Available". The other is running multiple VPN nodes. A complete 

@@ 16,7 16,7 @@ few steps:

We'll walk you through all steps in the rest of this document.

# Installation
## Installation

You can configure the "Controller / Portal" on multiple systems, using the 
`deploy_${DIST}_controller.sh`, and your node(s) using 

@@ 31,12 31,12 @@ The machines themselves SHOULD have the names `p1.vpn.example.org`,
You perform all configuration on one of the "Controllers / Portal", and then 
simple copy the configuration / data to the other(s).

# Database
## Database

In order to configure the database, perform that from one of the portals you 
just set up and follow the instructions [here](DATABASE.md).

# Memcached
## Memcached

On all of your "Controller / Portal" machines:

@@ 45,12 45,12 @@ $ sudo apt -y install memcached php-memcached
$ sudo systemctl restart php$(/usr/sbin/phpquery -V)-fpm

## Configuration
### Configuration

By default Memcached only listens on `localhost`. For our purpose however each
installation of the portal should be able to reach all Memcached servers. 

### Debian / Ubuntu
#### Debian / Ubuntu

Modify `/etc/memcached.conf` and change the `-l` line from `-l` to

@@ 64,7 64,7 @@ $ sudo systemctl restart memcached
**NOTE**: you MUST make sure you use your firewall to prevent systems on the 
Internet from reaching your Memcached service!

### Fedora 
#### Fedora 

Modify `/etc/sysconfig/memcached` and change the `OPTIONS` line from 
`OPTIONS="-l,::1"` to `OPTIONS=""` to listen on all interfaces.

@@ 95,7 95,7 @@ Memcache again:
$ sudo systemctl restart memcached

### Portal
#### Portal

Modify the session configuration in `/etc/vpn-user-portal/config.php`:

@@ 113,7 113,7 @@ Modify the session configuration in `/etc/vpn-user-portal/config.php`:
first, and on `p2.vpn.example.org`, the server `p2.vpn.example.org` SHOULD come

# Synchronize Configuration
## Synchronize Configuration

Some files need to be copied from one of the portals to the other(s), e.g. VPN 
CA, OAuth key, OpenVPN/WireGuard key material and HTTPS certificate.

@@ 138,7 138,7 @@ If you are using
`/etc/letsencrypt` folder to your other portals. Make sure you do this at least
every 90 days (the expiry of Let's Encrypt certificates)!

# keepalived
## keepalived

Install `keepalived`:

M IPV6.md => IPV6.md +2 -2
@@ 1,7 1,7 @@

# IPv6


The VPN server software supports both IPv4 and IPv6. We've reached a point 
in the "evolution" of the Internet that IPv4 NAT is unavoidable, but for IPv6
there is no excuse to not issue proper public IPv6 addresses to the VPN 

M LDAP.md => LDAP.md +13 -11
@@ 1,3 1,5 @@

This document describes how to configure LDAP. We assume you used the 
`deploy_${DIST}.sh` script to deploy the software.

@@ 6,9 8,9 @@ The LDAP integration can be used both for _authentication_ and _authorization_.
This document talks about _authentication_. See [ACL](ACL.md) for more on 

# Important Notes
## Important Notes

## 3.0.2
### 3.0.2

There was an issue in `vpn-user-portal` before 3.0.2 where, when 
`userIdAttribute` was set, but not available in the LDAP result set, the user 

@@ 31,7 33,7 @@ In case you were depending on this unintended behavior, your VPN server
installation may fail to allow users to authenticate with version 3.0.2, even 
though it worked with previous versions.

# Introduction
## Introduction

It is a good idea to try with `ldapsearch` if you are not absolutely sure what
to configure. Once `ldapsearch` works, it becomes easier to configure the LDAP

@@ 58,7 60,7 @@ administrator, you need _at least_:
* The attribute to use for user authentication;
* Whether or not this attribute is part of the user's DN.

## FreeIPA
### FreeIPA

For simple [FreeIPA](https://www.freeipa.org/page/Main_Page) setups these are
sufficient. Here the `uid` we want to use for users to authenticate is part of 

@@ 75,7 77,7 @@ $ ldapsearch \
After providing the user's password, you should see all the LDAP attributes 
associated with that user account, e.g. `memberOf`, `mail`, `uid`.

## Active Directory
### Active Directory

If you are using 
[Active Directory](https://en.wikipedia.org/wiki/Active_Directory), it is 

@@ 105,7 107,7 @@ $ ldapsearch \

## Search First
### Search First

If you want to use an attribute that is NOT part of the DN, you first need to 
perform a search for the user's DN, based on the attribute + value you 

@@ 140,7 142,7 @@ $ ldapsearch \
If this works, we can use this information as explained below in the 
configuration examples.

# Configuration
## Configuration

You can configure the portal to use LDAP. This is configured in the file 

@@ 239,7 241,7 @@ or not results are returned.

This should be all to configure your LDAP!


In order to use LDAPS, you can use the LDAPS scheme in the `baseUri`
configuration option, e.g.:

@@ 264,7 266,7 @@ You can copy/paste the CA certificate from the certificates shown.
**NOTE**: make sure you validate this CA out of band! You MUST be sure this 
is the actual CA!

## Fedora / EL
### Fedora / EL

If you use a self signed certificate for your LDAP server perform these steps. 
If your certificate is signed by a trusted CA you do not need to do this, it

@@ 286,7 288,7 @@ You **MUST** restart `php-fpm` to pick up the changes:
$ sudo systemctl restart php-fpm

## Debian / Ubuntu
### Debian / Ubuntu

If you use a self signed certificate for your LDAP server perform these steps. 
If your certificate is signed by a trusted CA you do not need to do this, it

@@ 308,7 310,7 @@ You **MUST** restart `php-fpm` to pick up the changes:
$ sudo systemctl restart php$(/usr/sbin/phpquery -V)-fpm

# Troubleshooting
## Troubleshooting

You can use `ldapsearch` to figure out what would be the required values for
the various configuration options and test them independently of the VPN 

@@ 1,25 1,27 @@
# Mod auth mellon

Below we assume you use `vpn.example`, but modify this domain to your own 
domain name!

This document describes how to use/configure 

# Installation
## Installation

## Fedora / Enterprise Linux
### Fedora / Enterprise Linux

First install `mod_auth_mellon`:

    $ sudo dnf -y install mod_auth_mellon

## Debian  / Ubuntu
### Debian  / Ubuntu

    $ sudo apt -y install libapache2-mod-auth-mellon

In the examples below you will not use `/etc/httpd` but `/etc/apache2` as the
base path, and for `systemctl` you use `apache2` instead of `httpd`.

# Configuration
## Configuration

Generate an SP signing key:

@@ 75,7 77,7 @@ If you also want to use authorization based on an attribute, e.g.
`eduPersonEntitlement` or `eduPersonAffiliation` you can set the 
`permissionAttributeList` as well.

## Examples
### Examples

Using `uid`:

@@ 115,9 117,9 @@ This will _serialize_ the XML node to a string using the IdP and SP entity ID
together with the eduPersonTargetedId _value_. If you are using the "Name ID", 
very much not recommended, you can set `userIdAttribute` to `MELLON_NAME_ID`.

# Apache
## Apache

## Fedora / Enterprise Linux
### Fedora / Enterprise Linux

    <VirtualHost *:443>

@@ 167,7 169,7 @@ very much not recommended, you can set `userIdAttribute` to `MELLON_NAME_ID`.


## Debian / Ubuntu
### Debian / Ubuntu

    <VirtualHost *:443>

@@ 1,28 1,28 @@
# Introduction
# Mod Auth OpenIDC

This module configures the Apache web server to operate as an OpenID Connect 
Relying Party (RP) towards an OpenID Connect Provider (OP) using 

# Installation
## Installation

## Fedora
### Fedora

$ sudo dnf install mod_auth_openidc
$ sudo systemctl restart httpd

## Debian / Ubuntu
### Debian / Ubuntu

$ sudo apt install libapache2-mod-auth-openidc
$ sudo systemctl restart apache2

# Configuration
## Configuration

## OpenID Connect
### OpenID Connect

The below instructions will show you what to do at the _minimum_ to get your
RP working.

@@ 43,7 43,7 @@ $ pwgen -s 64 -n 1

Once you have/know all values configure the "VirtualHost" as mentioned below.

## Virtual Host
### Virtual Host

Modify your Apache "Virtual Host" by changing 
`/etc/apache2/sites-available/vpn.example.org.conf` (Debian / Ubuntu) or 

@@ 101,7 101,7 @@ On Debian / Ubuntu:
$ sudo systemctl restart apache2
## VPN Portal
### VPN Portal

Modify `/etc/vpn-user-portal/config.php` and set:

M MOD_MD.md => MOD_MD.md +1 -1
@@ 1,4 1,4 @@
### mod_md
# Apache mod_md

**NOTE**: I am experimenting with this since 2021-08-08!

M MULTI_NODE.md => MULTI_NODE.md +1 -1
@@ 1,4 1,4 @@
# Introduction
# Multi Node

Setting up multiple VPN nodes is one part of making the VPN service 
"High Available". The other is setting up a redundant portal. A complete 

@@ 1,4 1,4 @@
# Introduction
# Multi Profile

It is possible to add additional "profiles" to a VPN service. This is useful 
when you for example have two categories of users using the same VPN server,

@@ 16,7 16,7 @@ Below, we will end up with two profiles:
You may also need to take a look at the [SELinux](SELINUX.md) instructions when
running on Fedora.

# Configuration
## Configuration

The configuration file `/etc/vpn-user-portal/config.php` needs to be 
modified, you can remove the `default` profile that was there if you didn't

@@ 55,7 55,7 @@ more flexibility to move to a setup with multiple machines in the future.
**NOTE**: if you add/modify UDP and TCP ports you may also need to update the 

## Apply Changes
### Apply Changes

To apply the configuration changes:

@@ 1,4 1,4 @@
# Introduction
# Multi Profile Node

As shown in the [Multi Profile](MULTI_PROFILE.md) and 
[Multi Node](MULTI_NODE.md) documentation it is possible to define multiple 

M PHP_SAML_SP.md => PHP_SAML_SP.md +1 -7
@@ 1,10 1,4 @@
title: PHP-SAML-SP
description: SAML Authentication using php-saml-sp
category: authentication

## Introduction
# PHP Saml SP

Very simple, secure SAML SP written in PHP.

@@ 1,3 1,5 @@
# Portal admin

Certain users can be "promoted" to admin in the VPN portal. This can be done in
two ways, based on either

@@ 1,3 1,5 @@
# Port sharing

This document describes how to configure your VPN server in such a way as to
make it most likely people can connect to it. This is done by making it 
possible to connect to the VPN service using both `udp/443` and `tcp/443`. A 

M RADIUS.md => RADIUS.md +3 -1
@@ 1,3 1,5 @@
# Radius

This document describes how to configure RADIUS for deployed systems. We assume 
you used the `deploy_${DIST}.sh` script to deploy the software. Below we assume 
you use `vpn.example`, but modify this domain to your own domain name!

@@ 25,7 27,7 @@ for instructions on how to configure LDAP.
**NOTE**: RADIUS authentication is no longer supported on PHP 8.x so it will
only work on Debian 11 as of this moment and not on Fedora or Ubuntu.

# Configuration
## Configuration

First install the PHP module for RADIUS:

M README.md => README.md +11 -11
@@ 1,4 1,4 @@
# Introduction
# About

This is the eduVPN/Let's Connect! documentation repository. This repository 
targets administrators and developers. It contains information on how to deploy 

@@ 17,7 17,7 @@ try to find the contact information of your organization
contact us at 

# Supported Versions
## Supported Versions

| Version                                              | Release Date | OS Support                                                   |  EOL*      |
| ---------------------------------------------------- | ------------ | ------------------------------------------------------------ | ---------- |

@@ 32,7 32,7 @@ running that version anymore, whichever comes first.
We **only** support the particular release on operating systems that are still 
supported by their vendor!

# Features
## Features

This is an (incomplete) list of features of the VPN software:

@@ 63,12 63,12 @@ This is an (incomplete) list of features of the VPN software:
- Support multiple deployment scenarios [simultaneously](MULTI_PROFILE.md);
- [SELinux](SELINUX.md) fully enabled (on Fedora);

# Client Support
## Client Support

See [Client Compatibility](CLIENT_COMPAT.md) for more information about the 
supported VPN clients.

# Deployment
## Deployment

**NOTE**: if you plan to install and run a eduVPN/Let's Connect! server please 
subscribe to the mailing list 

@@ 76,7 76,7 @@ subscribe to the mailing list
for announcements of updates and discussion about running 
eduVPN/Let's Connect!.

# IRC Contact
## IRC Contact

You can also join IRC for _technical_ questions/discussions/feedback on 
[Libera.Chat](https://libera.chat/), channel `#eduvpn`. Please stick around for 

@@ 85,7 85,7 @@ a while to wait for a response!
You can also easily use the [Web Chat](https://web.libera.chat/#eduvpn) if you 
can't be bothered to setup an IRC client. See you there!

## Instruction Videos
### Instruction Videos

**NOTE**: these videos are for eduVPN / Let's Connect 2.x and still need to
be updated for 3.x:

@@ 93,7 93,7 @@ be updated for 3.x:
- [Basic eduVPN/Let's Connect! Server Installation](https://www.youtube.com/watch?v=yBItHovq4AU)
- [Integrate your Active Directory via LDAP with eduVPN/Let's Connect!](https://www.youtube.com/watch?v=qwf0RZ8YK9A)

## Supported Operating Systems
### Supported Operating Systems

- [Debian](DEPLOY_DEBIAN.md) 11 (`x86_64`) 
- [Ubuntu](DEPLOY_DEBIAN.md) 22.04 (`x86_64`) 

@@ 110,12 110,12 @@ rebooted before you install the software!
**NOTE**: if you want to deploy on multiple machines for load balancing, please 
follow [these](HA.md) instructions!

# Development
## Development

If you want to set up your own server development environment see 

# License 
## License 

This work (this documentation repository) is licensed under a Creative Commons 
Attribution-ShareAlike 4.0 International License.

@@ 125,7 125,7 @@ See [LICENSE](LICENSE).
The VPN server software is licensed under the 

# Security Contact
## Security Contact

If you find a security problem in the code, the deployed service(s) and want to
report it responsibly, contact [fkooman@tuxed.net](mailto:fkooman@tuxed.net). 

M SBOM.md => SBOM.md +1 -1
@@ 1,4 1,4 @@
# Introduction

This page lists ALL software, including dependencies, of the _production_ 
releases of eduVPN / Let's Connect! It does _not_ include installation or 

@@ 1,3 1,5 @@
# Script connection hook

This page documents how to launch a (custom) script when a VPN client connects, 
and/or disconnects. This can for example be used to verify if a user still 
exists in the LDAP server, or trigger firewall modifications in a remote 

M SELINUX.md => SELINUX.md +3 -1
@@ 1,9 1,11 @@
# SELinux

If you used the `deploy_${DIST}.sh` script on CentOS, Red Hat Enterprise Linux 
or Fedora, your VPN server has SELinux fully enabled and configured. If you 
make changes to the configuration, you MAY need to update the SELinux 

# OpenVPN 
## OpenVPN 

By default, OpenVPN is not allowed to listen on any other ports than `udp/1194` 
and `tcp/1194`.

@@ 1,16 1,7 @@
title: Avoid Organization Selection
description: Avoid Browser Organization Selection in Identity Federations
category: dev

# Skipping the SAML WAYF


## Introduction

Most "Secure Internet" servers use SAML to authenticate users and have a WAYF 
(Where Are You From) in the browser to redirect users to the 
IdP of the organization chosen by the user for the actual authentication. 

@@ 1,8 1,10 @@
# Shibboleth SP

This document describes installing Shibboleth on Debian 11.

# Installation
## Installation

## Debian 11
### Debian 11

$ sudo apt install libapache2-mod-shib

@@ 10,7 12,7 @@ $ sudo shib-keygen -n sp-encrypt
$ sudo shib-keygen -n sp-signing

# Configuration
## Configuration

Modify `/etc/shibboleth/shibboleth2.xml`:

@@ 46,7 48,7 @@ $ sudo systemctl restart shibd
Next: register your SP in your identity federation, or in your IdP. The
metadata URL is typically `https://vpn.example.org/Shibboleth.sso/Metadata`.

### Apache
#### Apache

In `/etc/apache2/sites-available/vpn.example.org.conf` add the following:

@@ 100,7 102,7 @@ $ sudo systemctl restart apache2
make sure they are correctly enabled/set in 

### Portal
#### Portal

In order to configure the VPN portal, modify `/etc/vpn-user-portal/config.php`
and set the `authModule` and `ShibAuthModule` options:

@@ 1,14 1,5 @@
title: Traceable NAT
description: Make NAT users tracable using a static iptables configuration
category: advanced
author: Jørn Åne de Jong (Uninett)

# Traceable NAT

## Introduction

When using NAT, it is hard to identify the user behind an action, because every uses has the same outgoing IP address.
A solution to this could be Netflow, but that requires Netflow to be installed on every eduVPN host, which can be a hassle.

@@ 116,7 107,7 @@ You will see a lot of lines such as
Port ranges are shown at the end of the line. Scroll with the arrow keys or PgUp/PgDown and find the line that matches your source port number.
You have now found the internal IPv4 address that was involved in the incident.  This internal IP address (on the left) can be matched to a user through the eduVPN portal (webinterface).

# Example Script
## Example Script


@@ 1,22 1,22 @@
# Introduction
# WireGuard

As WireGuard is new in 3.x, this document will try to dive into some more 
detail regarding how it works.

# Configuration
## Configuration

WireGuard in eduVPN / Let's Connect! has a lot less toggles than OpenVPN so 
should be easier to configure. See the "WireGuard" 
[section](PROFILE_CONFIG.md#wireguard) for more information. There is also the
"global" option to set the WireGuard port. By default this is `51820`.

# Comparison with OpenVPN
## Comparison with OpenVPN

There are a number of differences between OpenVPN and WireGuard. Most of them 
are summed up in 
[this](https://www.tuxed.net/fkooman/blog/taming_wireguard.html) blog post.

# What to Use?
## What to Use?

It is possible to configure profiles to support both OpenVPN and WireGuard 
simultaneously. We recommend to use WireGuard whenever possible, and only