---
title: 'Tutorial: Assign IPv6 Addresses to VPN Clients from a Group Pool'
canonical: https://openvpn.net/as-docs/tutorials/tutorial--assign-ipv6-from-group-pool/
product: Access Server Docs
description: This tutorial provides a step-by-step guide for assigning IPv6 addresses to VPN clients from a group pool and testing the setup to ensure functionality.
---

# Tutorial: Assign IPv6 Addresses to VPN Clients from a Group Pool

## Overview

Access Server primarily uses IPv4 for incoming VPN connections but also [supports IPv6 routing](https://openvpn.net/as-docs/ipv6-support.md) within the VPN tunnel. This tutorial will guide you through assigning IPv6 addresses to VPN clients using a group-specific address pool. You’ll configure IPv6 routing and assign a pool of IPv6 addresses to VPN clients within a specific group.

By the end of this tutorial, you'll have set up IPv6 routing for a group of VPN clients and tested the configuration by ensuring that clients can access external IPv6 resources.

> **Note**
>
> The IPv6 address `2001:db8` used in our examples is [reserved for documentation use](https://en.wikipedia.org/wiki/Reserved_IP_addresses#IPv6).
>
> Replace it with a valid IPv6 address for your network.

## Prerequisites

- An installed Access Server.
- An IPv6 interface and default IPv6 gateway configured on the Access Server host system.
- A VPN group and at least one user assigned to it. In this tutorial, we use a group named `group-test.`
- A valid IPv6 address pool to assign to your clients.

> **Important**
>
> This tutorial doesn't apply to Access Server deployments configured in a cluster. Per-group VPN client IP address assignment isn't available in cluster mode.

## Step 1: Enable IPv6 routing

1. Connect to the console and get root privileges.
2. Switch to the scripts directory:

   ```
   cd /usr/local/openvpn_as/scripts/
   ```
3. Turn on IPv6 routing:

   ```
   ./sacli --key "vpn.routing6.enable" --value "true" ConfigPut
   ```

## Step 2: Route all IPv6 traffic through the tunnel (full tunnel)

1. Turn on full tunneling to route all IPv6 traffic through the tunnel:

   ```
   ./sacli --key "vpn.client.routing6.reroute_gw" --value "true" ConfigPut
   ```

## Step 3: Create an IPv6 pool for the group

1. Create a pool of IPv6 addresses to assign to clients in your group. In this example, we use the group `group-test` and assign the subnet `2001:db8:b84b:5::/112`.

   ```
   ./sacli --user "group-test" --key "group_subnets6.0" --value "2001:db8:b84b:5::/112" UserPropPut
   ```

   - This subnet is a unique local IPv6 address range (similar to private IPv4 ranges) and is not routable over the internet.

## Step 4: Configure the IPv6 range

1. Specify the range of IPv6 addresses that can be assigned to users in the group. For example, use addresses from `2001:db8:b84b:5::8005` to `2001:db8:b84b:5::8009`:

   ```
   ./sacli --user "group-test" --key "group_range6.0" --value "2001:db8:b84b:5::8005-2001:db8:b84b:5::8009" UserPropPut
   ```

   - This assigns the IPv6 range `2001:db8:b84b:5::8005` to `2001:db8:b84b:5::8009` for VPN users in the `group-test` group. The `2001:db8::` block is reserved for documentation, so replace it with your actual network IPv6 range for real-world applications.

## Step 5: Save and apply the configuration

1. Save and apply the settings by restarting the server:

   ```
   ./sacli start
   ```

## Step 6: Test the setup

1. Connect a VPN client that belongs to the `group-test` group. (We recommend using OpenVPN Connect.)
   - The client app shows an IPv6 address assigned from the pool.
2. Run a ping test to a public IPv6 address:

   ```
   ping ipv6.google.com
   ```

   - Expected output:

     ```
     Reply from 2001:db8:4006:81f::200e: bytes=1500 time=30ms TTL=54
     ```
3. Verify the IPv6 traffic reaches the server by running `tcpdump` on the server:

   ```
   tcpdump -eni any host ipv6.google.com
   ```

   - Example output from the server while running `tcpdump`:

     ```
     root@openvpn-access-server:/usr/local/openvpn_as/scripts# tcpdump -eni any host ipv6.google.com
     tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
     listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes

     11:44:10.035937 In ethertype IPv6 (0x86dd), length 96: 2001:db8:b84b:5::8005 > 2607:f8b0:4006:81f::200e: ICMP6, echo request, seq 11, length 40
     11:44:10.035983 Out d6:77:ce:97:8c:7c ethertype IPv6 (0x86dd), length 96: 2604:a880:400:d0::189e:6005 > 2607:f8b0:4006:81f::200e: ICMP6, echo request, seq 11, length 40
     11:44:10.037937 In fe:00:00:00:01:01 ethertype IPv6 (0x86dd), length 96: 2607:f8b0:4006:81f::200e > 2001:db8:b84b:5::8005: ICMP6 echo reply, id 1, seq 11, length 40
     ```
   - The VPN client's IPv6 address is `2001:db8:b84b:5::8005`.
   - The public IPv6 address `2607:f8b0:4006:81f::200e` corresponds to Google's IPv6 server (`ipv6.google.com`).

### IPv6 configuration keys

Use the following configuration keys to work with IPv6 in Access Server.

| Configuration Key | Type | Description |
| --- | --- | --- |
| ``` vpn.routing6.enable ``` | bool | Enable IPv6 routing. |
| ``` vpn.server.nat6 ``` | bool | Enable IPv6 NAT. |
| ``` vpn.server.nat6.masquerade ``` | bool | Enable IPv6 masquerade. |
| ``` vpn.client.routing6.reroute_gw ``` | bool | Route all IPv6 traffic through the tunnel. |
| ``` vpn.server.daemon.vpn_network6 ``` | list of subnets | Default IPv6 VPN subnets to be subdivided among OpenVPN daemons: These are used by clients as VPN routing gateways and allocated to non-group clients. |
| ``` vpn.client.routing6.inter_client ``` | bool | Enable client-to-client IPv6 traffic. |
| ``` vpn.server.routing6.private_access ``` | string | Controls how to route private traffic: nat route none |
| ``` vpn.server.routing6.gateway_access ``` | bool (default=true) | If true, clients may access the server-side tun gateway IPv6 address. |
| ``` vpn.server.routing6.allow_private_nets_to_clients ``` | bool | If true, all IPv6 addresses in vpn.server.routing6.private\_network will be allowed to initiate client connections. |
| ``` vpn.server.routing6.private_network ``` | list of subnets | Access granted to private server-side subnets. |
| ``` vpn.server.routing6.incoming_network ``` | list of subnets | IPv6 addresses within this range may initiate connections with VPN clients. |
| ``` vpn.server.routing6.routed_subnets ``` | list of subnets | Subnets that should be routed rather than NATed (when NAT is enabled). |
| ``` vpn.server.group_pool6 ``` | list of subnets | Optional pool of VPN IPv6 addresses to be subdivided across groups that don't define group\_subnets6 or group\_range6. |
| ``` vpn.server.routing6.snat_source.N ``` | list of interface and IPv6 address mappings | This defines how to perform Source Network Address Translation (SNAT) for outgoing IPv6 packets. When NAT is enabled, SNAT ensures that VPN client traffic uses a specific IPv6 address or range for outgoing traffic. Specify a range of IPv6 addresses for SNAT on each outgoing network interface. The `N` suffix (e.g., `.0`, `.1`, `.2`, etc.) is required for the configuration to work. The command will not function properly if the `.N` suffix is omitted. |
| ``` vpn.server.custom_snat6_chain ``` | string | Define a custom ip6tables chain to handle all outgoing NAT. |

---

Prev: [Tutorial: Assign IPv6 IP Addresses to VPN Clients From A Global Pool](https://openvpn.net/as-docs/tutorials/tutorial--assign-ipv6-from-global-pool.md)
Next: [Authentication](https://openvpn.net/as-docs/tutorials/authentication.md)
Index: https://openvpn.net/as-docs/llms.txt
