## File: README.md

[English](README.md) | [简体中文](README-zh.md) | [繁體中文](README-zh-Hant.md) | [Русский](README-ru.md)

# IPsec VPN Server on Docker

[](https://github.com/hwdsl2/docker-ipsec-vpn-server/actions/workflows/main-alpine.yml) [](https://github.com/hwdsl2/docker-ipsec-vpn-server/stargazers) [](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server/) [](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server/)

Docker image to run an IPsec VPN server, with IPsec/L2TP, Cisco IPsec and IKEv2.

Based on Alpine 3.23 or Debian 12 with [Libreswan](https://libreswan.org) (IPsec VPN software) and [xl2tpd](https://github.com/xelerance/xl2tpd) (L2TP daemon).

An IPsec VPN encrypts your network traffic, so that nobody between you and the VPN server can eavesdrop on your data as it travels via the Internet. This is especially useful when using unsecured networks, e.g. at coffee shops, airports or hotel rooms.

**Features:**

- Automatically generates VPN credentials and IKEv2 configuration on first start
- Supports IKEv2 with strong and fast ciphers (e.g. AES-GCM)
- Generates VPN profiles to auto-configure iOS, macOS and Android devices
- Supports Windows, macOS, iOS, Android, Chrome OS and Linux as VPN clients
- Includes a helper script to manage IKEv2 users and certificates
- Automatically built and published via [GitHub Actions](https://github.com/hwdsl2/docker-ipsec-vpn-server/actions)
- Persistent data via a Docker volume
- Multi-arch: `linux/amd64`, `linux/arm64`, `linux/arm/v7`

**Also available:**

- VPN: [IPsec without Docker](https://github.com/hwdsl2/setup-ipsec-vpn), [WireGuard](https://github.com/hwdsl2/docker-wireguard), [OpenVPN](https://github.com/hwdsl2/docker-openvpn), [Headscale](https://github.com/hwdsl2/docker-headscale)
- AI: [Self-Hosted AI Stack](https://github.com/hwdsl2/self-hosted-ai-stack) for local LLMs, chat, RAG, voice and AI tools
- :books: **Books:** [The Self-Hosted AI Builder’s Guide](https://books2read.com/aiguide?store=amazon), [Privacy Tools in the Age of AI](docs/vpn-book.md)

## Quick start

Use this command to set up an IPsec VPN server on Docker:

```bash
docker run \
    --name ipsec-vpn-server \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

Your VPN login details will be randomly generated. See [Retrieve VPN login details](#retrieve-vpn-login-details).

Alternatively, you may [set up IPsec VPN without Docker](https://github.com/hwdsl2/setup-ipsec-vpn). To learn more about how to use this image, read the sections below.

## Community

- 📬 [Subscribe for project updates](https://selfhostedstack.beehiiv.com/subscribe?utm_campaign=vpn) (1–2 emails/month) — get free VPN and AI deployment guides (PDF)
- 💬 Join the [r/selfhostedstack](https://www.reddit.com/r/selfhostedstack/) community for discussions
- ⭐ Star the repository if you find it useful — it helps others discover it

## Requirements

- A Linux server with a public IP address or DNS name
- Docker installed
- VPN ports open in your firewall (UDP 500 and 4500)
- You may also use [Podman](https://docs.podman.io) to run this image, after creating an alias for `docker`

**Note:** Advanced users can use this image on macOS with [Docker for Mac](https://docs.docker.com/desktop/setup/install/mac-install/). Before using IPsec/L2TP mode, you may need to restart the container once with `docker restart ipsec-vpn-server`. This image does not support Docker for Windows.

## Download

Get the trusted build from the [Docker Hub registry](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server/):

```bash
docker pull hwdsl2/ipsec-vpn-server
```

Alternatively, you may download from [Quay.io](https://quay.io/repository/hwdsl2/ipsec-vpn-server):

```bash
docker pull quay.io/hwdsl2/ipsec-vpn-server
docker image tag quay.io/hwdsl2/ipsec-vpn-server hwdsl2/ipsec-vpn-server
```

Supported platforms: `linux/amd64`, `linux/arm64` and `linux/arm/v7`.

Advanced users can [build from source code](docs/advanced-usage.md#build-from-source-code) on GitHub.

### Image comparison

Two pre-built images are available. The default Alpine-based image is only ~19 MB.

|                   | Alpine-based             | Debian-based                   |
| ----------------- | ------------------------ | ------------------------------ |
| Image name        | hwdsl2/ipsec-vpn-server  | hwdsl2/ipsec-vpn-server:debian |
| Compressed size   | ~ 19 MB                  | ~ 62 MB                        |
| Base image        | Alpine Linux 3.23        | Debian Linux 12                |
| Platforms         | amd64, arm64, arm/v7     | amd64, arm64, arm/v7           |
| Libreswan version | 5.3.2                    | 5.3.2                          |
| IPsec/L2TP        | ✅                       | ✅                              |
| Cisco IPsec       | ✅                       | ✅                              |
| IKEv2             | ✅                       | ✅                              |

**Note:** To use the Debian-based image, replace every `hwdsl2/ipsec-vpn-server` with `hwdsl2/ipsec-vpn-server:debian` in this README. These images are not currently compatible with Synology NAS systems.



I want to use the older Libreswan version 4.


It is generally recommended to use the latest [Libreswan](https://libreswan.org/) version 5, which is the default version in this project. However, if you want to use the older Libreswan version 4, you can build the Docker image from source code:

```bash
git clone https://github.com/hwdsl2/docker-ipsec-vpn-server
cd docker-ipsec-vpn-server
# Specify Libreswan version 4
sed -i 's/SWAN_VER=5\..*/SWAN_VER=4.15/' Dockerfile Dockerfile.debian
# To build Alpine-based image
docker build -t hwdsl2/ipsec-vpn-server .
# To build Debian-based image
docker build -f Dockerfile.debian -t hwdsl2/ipsec-vpn-server:debian .
```


## How to use this image

### Environment variables

**Note:** All the variables to this image are optional, which means you don't have to type in any variable, and you can have an IPsec VPN server out of the box! To do that, create an empty `env` file using `touch vpn.env`, and skip to the next section.

This Docker image uses the following variables, that can be declared in an `env` file (see [example](vpn.env.example)):

```
VPN_IPSEC_PSK=your_ipsec_pre_shared_key
VPN_USER=your_vpn_username
VPN_PASSWORD=your_vpn_password
```

This will create a user account for VPN login, which can be used by your multiple devices[\*](#important-notes). The IPsec PSK (pre-shared key) is specified by the `VPN_IPSEC_PSK` environment variable. The VPN username is defined in `VPN_USER`, and VPN password is specified by `VPN_PASSWORD`.

Additional VPN users are supported, and can be optionally declared in your `env` file like this. Usernames and passwords must be separated by spaces, and usernames cannot contain duplicates. All VPN users will share the same IPsec PSK.

```
VPN_ADDL_USERS=additional_username_1 additional_username_2
VPN_ADDL_PASSWORDS=additional_password_1 additional_password_2
```

The variables above are only for IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes. For IKEv2, see [Configure and use IKEv2 VPN](#configure-and-use-ikev2-vpn).

**Note:** In your `env` file, DO NOT put `""` or `''` around values, or add space around `=`. DO NOT use these special characters within values: `\ " '`. A secure IPsec PSK should consist of at least 20 random characters.

**Note:** If you modify the `env` file after the Docker container is already created, you must remove and re-create the container for the changes to take effect. Refer to [Update Docker image](#update-docker-image).

### Additional environment variables

Advanced users can optionally specify a DNS name, client name and/or custom DNS servers.



Learn how to specify a DNS name, client name and/or custom DNS servers.


Advanced users can optionally specify a DNS name for the IKEv2 server address. The DNS name must be a fully qualified domain name (FQDN). Example:

```
VPN_DNS_NAME=vpn.example.com
```

You may specify a name for the first IKEv2 client. Use one word only, no special characters except `-` and `_`. The default is `vpnclient` if not specified.

```
VPN_CLIENT_NAME=your_client_name
```

By default, clients are set to use [Google Public DNS](https://developers.google.com/speed/public-dns/) when the VPN is active. You may specify custom DNS server(s) for all VPN modes. Example:

```
VPN_DNS_SRV1=1.1.1.1
VPN_DNS_SRV2=1.0.0.1
```

For more details and a list of some popular public DNS providers, see [Use alternative DNS servers](docs/advanced-usage.md).

By default, no password is required when importing IKEv2 client configuration. You can choose to protect client config files using a random password.

```
VPN_PROTECT_CONFIG=yes
```

**Note:** The variables above have no effect for IKEv2 mode, if IKEv2 is already set up in the Docker container. In this case, you may remove IKEv2 and set it up again using custom options. Refer to [Configure and use IKEv2 VPN](#configure-and-use-ikev2-vpn).


### Start the IPsec VPN server

Create a new Docker container from this image (replace `./vpn.env` with your own `env` file):

```bash
docker run \
    --name ipsec-vpn-server \
    --env-file ./vpn.env \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

In this command, we use the `-v` option of `docker run` to create a new [Docker volume](https://docs.docker.com/storage/volumes/) named `ikev2-vpn-data`, and mount it into `/etc/ipsec.d` in the container. IKEv2 related data such as certificates and keys will persist in the volume, and later when you need to re-create the Docker container, just specify the same volume again.

It is recommended to enable IKEv2 when using this image. However, if you prefer not to enable IKEv2 and use only the IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes to connect to the VPN, remove the first `-v` option from the `docker run` command above.

**Note:** Advanced users can also [run without privileged mode](docs/advanced-usage.md#run-without-privileged-mode).

### Retrieve VPN login details

If you did not specify an `env` file in the `docker run` command above, `VPN_USER` will default to `vpnuser` and both `VPN_IPSEC_PSK` and `VPN_PASSWORD` will be randomly generated. To retrieve them, view the container logs:

```bash
docker logs ipsec-vpn-server
```

Search for these lines in the output:

```
Connect to your new VPN with these details:

Server IP: your_vpn_server_ip
IPsec PSK: your_ipsec_pre_shared_key
Username: your_vpn_username
Password: your_vpn_password
```

The output will also include details for IKEv2 mode, if enabled.

(Optional) Backup the generated VPN login details (if any) to the current directory:

```bash
docker cp ipsec-vpn-server:/etc/ipsec.d/vpn-gen.env ./
```

## Using docker-compose

```bash
cp vpn.env.example vpn.env
# Edit vpn.env if needed, then:
docker compose up -d
docker logs ipsec-vpn-server
```

Example `docker-compose.yml` (already included):

```yaml
volumes:
  ikev2-vpn-data:

services:
  vpn:
    image: hwdsl2/ipsec-vpn-server
    restart: always
    env_file:
      - ./vpn.env
    ports:
      - "500:500/udp"
      - "4500:4500/udp"
    privileged: true
    hostname: ipsec-vpn-server
    container_name: ipsec-vpn-server
    volumes:
      - ikev2-vpn-data:/etc/ipsec.d
      - /lib/modules:/lib/modules:ro
```

## Next steps

*Read this in other languages: [English](README.md#next-steps), [简体中文](README-zh.md#下一步), [繁體中文](README-zh-Hant.md#下一步), [Русский](README-ru.md#следующие-шаги).*

Get your computer or device to use the VPN. Please refer to:

**[Configure and use IKEv2 VPN (recommended)](#configure-and-use-ikev2-vpn)**

**[Configure IPsec/L2TP VPN Clients](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients.md)**

**[Configure IPsec/XAuth ("Cisco IPsec") VPN Clients](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-xauth.md)**

**Read [:book: VPN book](docs/vpn-book.md) to access [extra content](https://ko-fi.com/post/Support-this-project-and-get-access-to-supporter-o-O5O7FVF8J).**

Enjoy your very own VPN! :sparkles::tada::rocket::sparkles:

## Important notes

**Windows users**: For IPsec/L2TP mode, a [one-time registry change](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients.md#windows-error-809) is required if the VPN server or client is behind NAT (e.g. home router).

The same VPN account can be used by your multiple devices. However, due to an IPsec/L2TP limitation, if you wish to connect multiple devices from behind the same NAT (e.g. home router), you must use [IKEv2](#configure-and-use-ikev2-vpn) or [IPsec/XAuth](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-xauth.md) mode.

If you wish to add, edit or remove VPN user accounts, first update your `env` file, then you must remove and re-create the Docker container using instructions from the [next section](#update-docker-image). Advanced users can [bind mount](docs/advanced-usage.md#bind-mount-the-env-file) the `env` file.

For servers with an external firewall (e.g. [EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)/[GCE](https://cloud.google.com/vpc/docs/firewalls)), open UDP ports 500 and 4500 for the VPN. Aliyun users, see [#433](https://github.com/hwdsl2/setup-ipsec-vpn/issues/433).

Clients are set to use [Google Public DNS](https://developers.google.com/speed/public-dns/) when the VPN is active. If another DNS provider is preferred, read [this section](docs/advanced-usage.md#use-alternative-dns-servers).

## Update Docker image

To update the Docker image and container, first [download](#download) the latest version:

```bash
docker pull hwdsl2/ipsec-vpn-server
```

If the Docker image is already up to date, you should see:

```
Status: Image is up to date for hwdsl2/ipsec-vpn-server:latest
```

Otherwise, it will download the latest version. To update your Docker container, first note your [VPN login details](#retrieve-vpn-login-details). Then remove the Docker container with `docker rm -f ipsec-vpn-server`. Finally, re-create it using instructions from [How to use this image](#how-to-use-this-image).

## Configure and use IKEv2 VPN

IKEv2 mode has improvements over IPsec/L2TP and IPsec/XAuth ("Cisco IPsec"), and does not require an IPsec PSK, username or password. Read more [here](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/ikev2-howto.md).

First, check container logs to view details for IKEv2:

```bash
docker logs ipsec-vpn-server
```

**Note:** If you cannot find IKEv2 details, IKEv2 may not be enabled in the container. Try updating the Docker image and container using instructions from the [Update Docker image](#update-docker-image) section.

During IKEv2 setup, an IKEv2 client (with default name `vpnclient`) is created, with its configuration exported to `/etc/ipsec.d` **inside the container**. To copy config file(s) to the Docker host:

```bash
# Check contents of /etc/ipsec.d in the container
docker exec -it ipsec-vpn-server ls -l /etc/ipsec.d
# Example: Copy a client config file from the container
# to the current directory on the Docker host
docker cp ipsec-vpn-server:/etc/ipsec.d/vpnclient.p12 ./
```

**Next steps:** [Configure your devices](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/ikev2-howto.md) to use the IKEv2 VPN.



Learn how to manage IKEv2 clients.


You can manage IKEv2 clients using the helper script. See examples below. To customize client options, run the script without arguments.

```bash
# Add a new client (using default options)
docker exec -it ipsec-vpn-server ikev2.sh --addclient [client name]
# Export configuration for an existing client
docker exec -it ipsec-vpn-server ikev2.sh --exportclient [client name]
# List existing clients
docker exec -it ipsec-vpn-server ikev2.sh --listclients
# Show usage
docker exec -it ipsec-vpn-server ikev2.sh -h
```

**Note:** If you encounter error "executable file not found", replace `ikev2.sh` above with `/opt/src/ikev2.sh`.



Learn how to change the IKEv2 server address.


In certain circumstances, you may need to change the IKEv2 server address. For example, to switch to use a DNS name, or after server IP changes. To change the IKEv2 server address, first [open a bash shell inside the container](docs/advanced-usage.md#bash-shell-inside-container), then [follow these instructions](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/ikev2-howto.md#change-ikev2-server-address). Note that the container logs will not show the new IKEv2 server address until you restart the Docker container.



Remove IKEv2 and set it up again using custom options.


In certain circumstances, you may need to remove IKEv2 and set it up again using custom options.

**Warning:** All IKEv2 configuration including certificates and keys will be **permanently deleted**. This **cannot be undone**!

**Option 1:** Remove IKEv2 and set it up again using the helper script.

Note that this will override variables you specified in the `env` file, such as `VPN_DNS_NAME` and `VPN_CLIENT_NAME`, and the container logs will no longer show up-to-date information for IKEv2.

```bash
# Remove IKEv2 and delete all IKEv2 configuration
docker exec -it ipsec-vpn-server ikev2.sh --removeikev2
# Set up IKEv2 again using custom options
docker exec -it ipsec-vpn-server ikev2.sh
```

**Option 2:** Remove `ikev2-vpn-data` and re-create the container.

1. Write down all your [VPN login details](#retrieve-vpn-login-details).
1. Remove the Docker container: `docker rm -f ipsec-vpn-server`.
1. Remove the `ikev2-vpn-data` volume: `docker volume rm ikev2-vpn-data`.
1. Update your `env` file and add custom IKEv2 options such as `VPN_DNS_NAME` and `VPN_CLIENT_NAME`, then re-create the container. Refer to [How to use this image](#how-to-use-this-image).


## Advanced usage

See [Advanced usage](docs/advanced-usage.md).

- [Use alternative DNS servers](docs/advanced-usage.md#use-alternative-dns-servers)
- [Run without privileged mode](docs/advanced-usage.md#run-without-privileged-mode)
- [Select VPN modes](docs/advanced-usage.md#select-vpn-modes)
- [Enable IKEv2 perfect forward secrecy](docs/advanced-usage.md#enable-ikev2-perfect-forward-secrecy)
- [Access other containers on the Docker host](docs/advanced-usage.md#access-other-containers-on-the-docker-host)
- [Specify VPN server's public IP](docs/advanced-usage.md#specify-vpn-servers-public-ip)
- [Assign static IPs to VPN clients](docs/advanced-usage.md#assign-static-ips-to-vpn-clients)
- [Customize VPN subnets](docs/advanced-usage.md#customize-vpn-subnets)
- [IPv6 support](docs/advanced-usage.md#ipv6-support)
- [Split tunneling](docs/advanced-usage.md#split-tunneling)
- [About host network mode](docs/advanced-usage.md#about-host-network-mode)
- [Enable Libreswan logs](docs/advanced-usage.md#enable-libreswan-logs)
- [Check server status](docs/advanced-usage.md#check-server-status)
- [Build from source code](docs/advanced-usage.md#build-from-source-code)
- [Bash shell inside container](docs/advanced-usage.md#bash-shell-inside-container)
- [Bind mount the env file](docs/advanced-usage.md#bind-mount-the-env-file)
- [Deploy Google BBR congestion control](docs/advanced-usage.md#deploy-google-bbr-congestion-control)

## Technical details

There are two services running: `Libreswan (pluto)` for the IPsec VPN, and `xl2tpd` for L2TP support.

The default IPsec configuration supports:

* IPsec/L2TP with PSK
* IKEv1 with PSK and XAuth ("Cisco IPsec")
* IKEv2

Ports required: `500/udp` and `4500/udp` (IPsec)

## License

**Note:** The software components inside the pre-built image (such as Libreswan and xl2tpd) are under the respective licenses chosen by their respective copyright holders. As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within.

Copyright (C) 2016-2026 [Lin Song](https://github.com/hwdsl2) [](https://www.linkedin.com/in/linsongui)   
Based on [the work of Thomas Sarlandie](https://github.com/sarfata/voodooprivacy) (Copyright 2012)

[](http://creativecommons.org/licenses/by-sa/3.0/)   
This work is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/)   
Attribution required: please include my name in any derivative and let me know how you have improved it!

---

## File: docs/advanced-usage.md

[English](advanced-usage.md) | [中文](advanced-usage-zh.md)

# Advanced Usage

- [Use alternative DNS servers](#use-alternative-dns-servers)
- [Run without privileged mode](#run-without-privileged-mode)
- [Select VPN modes](#select-vpn-modes)
- [Enable IKEv2 perfect forward secrecy](#enable-ikev2-perfect-forward-secrecy)
- [Access other containers on the Docker host](#access-other-containers-on-the-docker-host)
- [Specify VPN server's public IP](#specify-vpn-servers-public-ip)
- [Assign static IPs to VPN clients](#assign-static-ips-to-vpn-clients)
- [Customize VPN subnets](#customize-vpn-subnets)
- [IPv6 support](#ipv6-support)
- [Split tunneling](#split-tunneling)
- [About host network mode](#about-host-network-mode)
- [Enable Libreswan logs](#enable-libreswan-logs)
- [Check server status](#check-server-status)
- [Build from source code](#build-from-source-code)
- [Bash shell inside container](#bash-shell-inside-container)
- [Bind mount the env file](#bind-mount-the-env-file)
- [Deploy Google BBR congestion control](#deploy-google-bbr-congestion-control)

## Use alternative DNS servers

By default, clients are set to use [Google Public DNS](https://developers.google.com/speed/public-dns/) when the VPN is active. If another DNS provider is preferred, define `VPN_DNS_SRV1` and optionally `VPN_DNS_SRV2` in your `env` file, then follow [instructions](../README.md#update-docker-image) to re-create the Docker container. Example:

```
VPN_DNS_SRV1=1.1.1.1
VPN_DNS_SRV2=1.0.0.1
```

Use `VPN_DNS_SRV1` to specify the primary DNS server, and `VPN_DNS_SRV2` to specify the secondary DNS server (optional).

Note that if IKEv2 is already set up in the Docker container, you will also need to edit `/etc/ipsec.d/ikev2.conf` inside the Docker container and replace `8.8.8.8` and `8.8.4.4` with your alternative DNS server(s), then restart the Docker container.

Below is a list of some popular public DNS providers for your reference.

| Provider | Primary DNS | Secondary DNS | Notes |
| -------- | ----------- | ------------- | ----- |
| [Google Public DNS](https://developers.google.com/speed/public-dns) | 8.8.8.8 | 8.8.4.4 | Default in this project |
| [Cloudflare](https://1.1.1.1/dns/) | 1.1.1.1 | 1.0.0.1 | See also: [Cloudflare for families](https://1.1.1.1/family/) |
| [Quad9](https://www.quad9.net) | 9.9.9.9 | 149.112.112.112 | Blocks malicious domains |
| [OpenDNS](https://www.opendns.com/home-internet-security/) | 208.67.222.222 | 208.67.220.220 | Blocks phishing domains, configurable. |
| [CleanBrowsing](https://cleanbrowsing.org/filters/) | 185.228.168.9 | 185.228.169.9 | [Domain filters](https://cleanbrowsing.org/filters/) available |
| [NextDNS](https://nextdns.io/?from=bg25bwmp) | Varies | Varies | Ad blocking, free tier available. [Learn more](https://nextdns.io/?from=bg25bwmp). |
| [Control D](https://controld.com/free-dns) | Varies | Varies | Ad blocking, configurable. [Learn more](https://controld.com/free-dns). |

## Run without privileged mode

Advanced users can create a Docker container from this image without using [privileged mode](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) (replace `./vpn.env` in the command below with your own `env` file).

**Note:** If your Docker host runs CentOS Stream, Oracle Linux 8+, Rocky Linux or AlmaLinux, it is recommended to use [privileged mode](../README.md#start-the-ipsec-vpn-server). If you want to run without privileged mode, you **must** run `modprobe ip_tables ip6_tables` before creating the Docker container and also on boot.

```
docker run \
    --name ipsec-vpn-server \
    --env-file ./vpn.env \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --cap-add=NET_ADMIN \
    --device=/dev/ppp \
    --sysctl net.ipv4.ip_forward=1 \
    --sysctl net.ipv4.conf.all.accept_redirects=0 \
    --sysctl net.ipv4.conf.all.send_redirects=0 \
    --sysctl net.ipv4.conf.all.rp_filter=0 \
    --sysctl net.ipv4.conf.default.accept_redirects=0 \
    --sysctl net.ipv4.conf.default.send_redirects=0 \
    --sysctl net.ipv4.conf.default.rp_filter=0 \
    --sysctl net.ipv6.conf.all.forwarding=1 \
    hwdsl2/ipsec-vpn-server
```

When running without privileged mode, the container is unable to change `sysctl` settings. This could affect certain features of this image. A known issue is that the [Android/Linux MTU/MSS fix](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients.md#androidlinux-mtumss-issues) also requires adding `--sysctl net.ipv4.ip_no_pmtu_disc=1` to the `docker run` command. If you encounter any issues, try re-creating the container using [privileged mode](../README.md#start-the-ipsec-vpn-server).

After creating the Docker container, see [Retrieve VPN login details](../README.md#retrieve-vpn-login-details).

Similarly, if using [Docker compose](https://docs.docker.com/compose/), you may replace `privileged: true` in [docker-compose.yml](../docker-compose.yml) with:

```
  cap_add:
    - NET_ADMIN
  devices:
    - "/dev/ppp:/dev/ppp"
  sysctls:
    - net.ipv4.ip_forward=1
    - net.ipv4.conf.all.accept_redirects=0
    - net.ipv4.conf.all.send_redirects=0
    - net.ipv4.conf.all.rp_filter=0
    - net.ipv4.conf.default.accept_redirects=0
    - net.ipv4.conf.default.send_redirects=0
    - net.ipv4.conf.default.rp_filter=0
    - net.ipv6.conf.all.forwarding=1
```

For more information, see [compose file reference](https://docs.docker.com/compose/compose-file/).

## Select VPN modes

Using this Docker image, the IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes are enabled by default. In addition, IKEv2 mode will be enabled if the `-v ikev2-vpn-data:/etc/ipsec.d` option [is specified](../README.md#start-the-ipsec-vpn-server) in the `docker run` command when creating the Docker container.

Advanced users can selectively disable VPN modes by setting the following variable(s) in the `env` file, then re-create the Docker container.

Disable IPsec/L2TP mode: `VPN_DISABLE_IPSEC_L2TP=yes`   
Disable IPsec/XAuth ("Cisco IPsec") mode: `VPN_DISABLE_IPSEC_XAUTH=yes`   
Disable both IPsec/L2TP and IPsec/XAuth modes: `VPN_IKEV2_ONLY=yes`

## Enable IKEv2 perfect forward secrecy

By default, IKEv2 Child SAs derive keying material from the existing IKE SA without a new Diffie-Hellman exchange (`pfs=no`). Enabling perfect forward secrecy (PFS) causes each Child SA rekey to perform a fresh DH exchange, so that a future compromise of the server's private key cannot decrypt previously recorded sessions.

**Note:** The IKE SA already proposes ECP-256 as its first preference (`aes_gcm_c_256-hmac_sha2_256-ecp_256`), and all modern clients negotiate it, so session keys are already independent of the server's long-term private key for those clients. Enabling PFS for Child SAs is an incremental hardening step, not a critical gap.

**Client compatibility:** All modern clients support PFS. However, macOS and iOS clients require re-export and re-import of the `.mobileconfig` profile with `EnablePFS` set to `1` (see below). Windows clients require a connection update. RouterOS users must change `pfs-group=none` to `pfs-group=ecp256` in their IKEv2 profile. Android and Linux strongSwan clients require no changes. Windows 7 IKEv2 clients do not support ECP PFS groups and will fail to connect if PFS is enabled on the server.

To enable PFS, first open a [Bash shell inside the container](#bash-shell-inside-container), then run:

```bash
sed -i 's/pfs=no/pfs=yes/' /etc/ipsec.d/ikev2.conf
```

When finished, `exit` the container and restart it:

```
docker restart ipsec-vpn-server
```

After enabling PFS, the following client configurations must be updated:

- **macOS / iOS:** Re-export the client `.mobileconfig` by running `docker exec -it ipsec-vpn-server ikev2.sh --exportclient <name>` and copying it to your Docker host, then edit the exported file to enable PFS:
  ```bash
  sed -i '/EnablePFS/{n;s/0/1/;}' <name>.mobileconfig
  ```
  Re-import the updated file on your device.
- **Windows:** In an elevated PowerShell window, run `Set-VpnConnection -Name "Your VPN Name" -PfsGroup ECP256` (replace with your actual VPN connection name), then reconnect the VPN.
- **RouterOS (MikroTik):** In the IKEv2 peer profile, change `pfs-group=none` to `pfs-group=ecp256`.

Android and Linux strongSwan clients require no changes; PFS is auto-negotiated.

To revert to the default (PFS disabled), repeat the steps above but replace `pfs=yes` with `pfs=no` in the `sed` command.

## Access other containers on the Docker host

After connecting to the VPN, VPN clients can generally access services running in other containers on the same Docker host, without additional configuration.

For example, if the IPsec VPN server container has IP `172.17.0.2`, and an Nginx container with IP `172.17.0.3` is running on the same Docker host, VPN clients can use IP `172.17.0.3` to access services on the Nginx container. To find out which IP is assigned to a container, run `docker inspect <container name>`.

## Specify VPN server's public IP

On Docker hosts with multiple public IP addresses, advanced users can specify a public IP for the VPN server using variable `VPN_PUBLIC_IP` in the `env` file, then re-create the Docker container. For example, if the Docker host has IPs `192.0.2.1` and `192.0.2.2`, and you want the VPN server to use `192.0.2.2`:

```
VPN_PUBLIC_IP=192.0.2.2
```

Note that this variable has no effect for IKEv2 mode, if IKEv2 is already set up in the Docker container. In this case, you may remove IKEv2 and set it up again using custom options. Refer to [Configure and use IKEv2 VPN](../README.md#configure-and-use-ikev2-vpn).

Additional configuration may be required if you want VPN clients to use the specified public IP as their "outgoing IP" when the VPN connection is active, and the specified IP is NOT the main IP (or default route) on the Docker host. In this case, you can try adding an IPTables `SNAT` rule on the Docker host. To persist after reboot, you may add the command to `/etc/rc.local`.

Continuing with the example above, if the Docker container has internal IP `172.17.0.2` (check using `docker inspect ipsec-vpn-server`), Docker's network interface name is `docker0` (check using `iptables -nvL -t nat`), and you want the "outgoing IP" to be `192.0.2.2`:

```
iptables -t nat -I POSTROUTING -s 172.17.0.2 ! -o docker0 -j SNAT --to 192.0.2.2
```

To check the "outgoing IP" for a connected VPN client, you may open a browser on the client and [look up the IP address on Google](https://www.google.com/search?q=my+ip).

## Assign static IPs to VPN clients

When connecting using IPsec/L2TP mode, the VPN server (Docker container) has internal IP `192.168.42.1` within the VPN subnet `192.168.42.0/24`. Clients are assigned internal IPs from `192.168.42.10` to `192.168.42.250`. To check which IP is assigned to a client, view the connection status on the VPN client.

When connecting using IPsec/XAuth ("Cisco IPsec") or IKEv2 mode, the VPN server (Docker container) does NOT have an internal IP within the VPN subnet `192.168.43.0/24`. Clients are assigned internal IPs from `192.168.43.10` to `192.168.43.250`.

Advanced users may optionally assign static IPs to VPN clients. For **IKEv2 mode**, first open a [Bash shell inside the container](#bash-shell-inside-container), then follow the steps in section "IKEv2 mode: Assign static IPs to VPN clients" of [Internal VPN IPs and traffic](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/advanced-usage.md#internal-vpn-ips-and-traffic). Note that you should skip steps 2, 3 and 5, and restart the Docker container when finished. This is because changes to `/etc/ipsec.conf` may be overwritten on container restart.

Instructions below **ONLY** apply to IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes.

To assign static IPs, declare the `VPN_ADDL_IP_ADDRS` variable in your `env` file, then re-create the Docker container. Example:

```
VPN_ADDL_USERS=user1 user2 user3 user4 user5
VPN_ADDL_PASSWORDS=pass1 pass2 pass3 pass4 pass5
VPN_ADDL_IP_ADDRS=* * 192.168.42.2 192.168.43.2
```

In this example, we assign static IP `192.168.42.2` for `user3` for IPsec/L2TP mode, and assign static IP `192.168.43.2` for `user4` for IPsec/XAuth ("Cisco IPsec") mode. Internal IPs for `user1`, `user2` and `user5` will be auto-assigned. The internal IP for `user3` for IPsec/XAuth mode and the internal IP for `user4` for IPsec/L2TP mode will also be auto-assigned. You may use `*` to specify auto-assigned IPs, or put those user(s) at the end of the list.

Static IPs that you specify for IPsec/L2TP mode must be within the range from `192.168.42.2` to `192.168.42.9`. Static IPs that you specify for IPsec/XAuth ("Cisco IPsec") mode must be within the range from `192.168.43.2` to `192.168.43.9`.

If you need to assign more static IPs, you must shrink the pool of auto-assigned IP addresses. Example:

```
VPN_L2TP_POOL=192.168.42.100-192.168.42.250
VPN_XAUTH_POOL=192.168.43.100-192.168.43.250
```

This will allow you to assign static IPs within the range from `192.168.42.2` to `192.168.42.99` for IPsec/L2TP mode, and within the range from `192.168.43.2` to `192.168.43.99` for IPsec/XAuth ("Cisco IPsec") mode.

Note that if you specify `VPN_XAUTH_POOL` in the `env` file, and IKEv2 is already set up in the Docker container, you **must** manually edit `/etc/ipsec.d/ikev2.conf` inside the container and replace `rightaddresspool=192.168.43.10-192.168.43.250` with the **same value** as `VPN_XAUTH_POOL`, before re-creating the Docker container. Otherwise, IKEv2 may stop working.

**Note:** In your `env` file, DO NOT put `""` or `''` around values, or add space around `=`. DO NOT use these special characters within values: `\ " '`.

## Customize VPN subnets

By default, IPsec/L2TP VPN clients will use internal VPN subnet `192.168.42.0/24`, while IPsec/XAuth ("Cisco IPsec") and IKEv2 VPN clients will use internal VPN subnet `192.168.43.0/24`. For more details, read the previous section.

For most use cases, it is NOT necessary and NOT recommended to customize these subnets. If your use case requires it, however, you may specify custom subnet(s) in your `env` file, then you must re-create the Docker container.

```
# Example: Specify custom VPN subnet for IPsec/L2TP mode
# Note: All three variables must be specified.
VPN_L2TP_NET=10.1.0.0/16
VPN_L2TP_LOCAL=10.1.0.1
VPN_L2TP_POOL=10.1.0.10-10.1.254.254
```

```
# Example: Specify custom VPN subnet for IPsec/XAuth and IKEv2 modes
# Note: Both variables must be specified.
VPN_XAUTH_NET=10.2.0.0/16
VPN_XAUTH_POOL=10.2.0.10-10.2.254.254
```

**Note:** In your `env` file, DO NOT put `""` or `''` around values, or add space around `=`.

In the examples above, `VPN_L2TP_LOCAL` is the VPN server's internal IP for IPsec/L2TP mode. `VPN_L2TP_POOL` and `VPN_XAUTH_POOL` are the pools of auto-assigned IP addresses for VPN clients.

Note that if you specify `VPN_XAUTH_POOL` in the `env` file, and IKEv2 is already set up in the Docker container, you **must** manually edit `/etc/ipsec.d/ikev2.conf` inside the container and replace `rightaddresspool=192.168.43.10-192.168.43.250` with the **same value** as `VPN_XAUTH_POOL`, before re-creating the Docker container. Otherwise, IKEv2 may stop working.

## IPv6 support

If the Docker host has a public (global unicast) IPv6 address and the requirements below are met, IPv6 support for IKEv2 clients is automatically enabled when the container starts. No manual configuration is needed.

**Note:** IPv6 works without additional configuration when using the strongSwan VPN client on Android. For Windows and macOS clients, follow the platform-specific steps below. iOS clients do not currently support routing IPv6 traffic through the IKEv2 VPN; you may instead use [OpenVPN](https://github.com/hwdsl2/openvpn-install) or [WireGuard](https://github.com/hwdsl2/wireguard-install).



Windows: Route IPv6 traffic through the VPN


If you used the `ikev2_config_import.cmd` script to import IKEv2 configuration, you can answer **y** when prompted to automatically add IPv6 routes. Otherwise, run the following commands once in a PowerShell window to route IPv6 traffic through the VPN. Replace `IKEv2 VPN X.X.X.X` with the actual name of your VPN connection. When finished, reconnect to the IKEv2 VPN.

```powershell
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix ::/1
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix 8000::/1
```



macOS: Route IPv6 traffic through the VPN


After connecting to the IKEv2 VPN, run the following command in Terminal to route IPv6 traffic through the VPN. This command must be run each time you connect. The route is automatically removed when you disconnect from the VPN. The interface is usually `ipsec0`; if you have multiple VPN connections active it may be `ipsec1`, etc. Run `ifconfig | grep ipsec` to confirm.

```
sudo route -n add -inet6 default -interface ipsec0
```


When IPv6 is enabled, IKEv2 VPN clients receive both an IPv4 address from the `192.168.43.0/24` pool and an IPv6 address from the `fddd:500:500:500::/64` pool. The container masquerades IPv6 traffic from VPN clients through the host's IPv6 address, giving clients full IPv6 internet access through the tunnel.

**Requirements:**
- The Docker host must have a routable global unicast IPv6 address (starting with `2` or `3`). Link-local (`fe80::/10`) addresses are not sufficient.
- IPv6 must be enabled for the Docker container. See [Enable IPv6 support in Docker](https://docs.docker.com/engine/daemon/ipv6/).
- Libreswan 5.0 or newer (the Docker image includes 5.x by default).
- IPv6 is only supported for **IKEv2 mode**. IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes do not support IPv6.

To enable IPv6 for the Docker container, first enable IPv6 in the Docker daemon by adding the following to `/etc/docker/daemon.json` on the Docker host, then restart Docker:

```json
{
  "ipv6": true,
  "fixed-cidr-v6": "fddd:1::/64"
}
```

After that, re-create the Docker container. The `run.sh` script will detect the container's public IPv6 address and automatically configure IPv6 support.

To verify that IPv6 is working, connect to the VPN using IKEv2 and check your IPv6 address, e.g. using [test-ipv6.com](https://test-ipv6.com).

**Note for existing containers:** If IKEv2 is already set up in your container (i.e. `ikev2.conf` already exists in the `ikev2-vpn-data` volume), IPv6 will **not** be automatically added to the existing IKEv2 configuration when the container restarts or is recreated. To enable full IPv6 support for IKEv2, you must remove IKEv2 and set it up again. Refer to "remove IKEv2" in [Configure and use IKEv2 VPN](../README.md#configure-and-use-ikev2-vpn).

You may optionally customize the IPv6 pool subnet by setting `VPN_IP6_NET` in your `env` file before re-creating the container:

```
# Example: Specify custom IPv6 pool subnet for IKEv2 mode
# Must be a /64 subnet in the ULA range
VPN_IP6_NET=fddd:1234:5678:9012::/64
```

## Split tunneling

With split tunneling, VPN clients will only send traffic for a specific destination subnet through the VPN tunnel. Other traffic will NOT go through the VPN tunnel. This allows you to gain secure access to a network through your VPN, without routing all your client's traffic through the VPN. Split tunneling has some limitations, and is not supported by all VPN clients.

Advanced users can optionally enable split tunneling for IKEv2 mode. Add the variable `VPN_SPLIT_IKEV2` to your `env` file, then re-create the Docker container. For example, if the destination subnet is `10.123.123.0/24`:

```
VPN_SPLIT_IKEV2=10.123.123.0/24
```

Note that this variable has no effect if IKEv2 is already set up in the Docker container. In this case, you have two options:

**Option 1:** First start a [Bash shell inside the container](#bash-shell-inside-container), then edit `/etc/ipsec.d/ikev2.conf` and replace `leftsubnet=0.0.0.0/0` with your desired subnet. When finished, `exit` the container and run `docker restart ipsec-vpn-server`.

**Option 2:** Remove both the Docker container and the `ikev2-vpn-data` volume, then re-create the Docker container. All VPN configuration will be **permanently deleted**. Refer to "remove IKEv2" in [Configure and use IKEv2 VPN](../README.md#configure-and-use-ikev2-vpn).

Alternatively, Windows users can enable split tunneling by manually adding routes. For more details, see [Split tunneling](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/advanced-usage.md#split-tunneling).

## About host network mode

Advanced users can run this image in [host network mode](https://docs.docker.com/network/host/), by adding `--network=host` to the `docker run` command.

Host network mode is NOT recommended for this image, unless your use case requires it. In this mode, the container's network stack is not isolated from the Docker host, and VPN clients may be able to access ports or services on the Docker host using its internal VPN IP `192.168.42.1` after connecting using IPsec/L2TP mode. Note that you will need to manually clean up the changes to IPTables rules and sysctl settings by [run.sh](../run.sh) or reboot the server when you no longer use this image.

Some Docker host OS, such as Debian 10, cannot run this image in host network mode due to the use of nftables.

## Enable Libreswan logs

To keep the Docker image small, Libreswan (IPsec) logs are not enabled by default. If you need to enable it for troubleshooting purposes, first start a Bash session in the running container:

```
docker exec -it ipsec-vpn-server env TERM=xterm bash -l
```

Then run the following commands:

```
# For Alpine-based image
apk add --no-cache rsyslog
rsyslogd
rc-service ipsec stop; rc-service -D ipsec start >/dev/null 2>&1
sed -i '\|pluto\.pid|a rm -f /var/run/rsyslogd.pid; rsyslogd' /opt/src/run.sh
exit
# For Debian-based image
apt-get update && apt-get -y install rsyslog
rsyslogd
service ipsec restart
sed -i '\|pluto\.pid|a rm -f /var/run/rsyslogd.pid; rsyslogd' /opt/src/run.sh
exit
```

**Note:** The error `rsyslogd: imklog: cannot open kernel log` is normal if you use this Docker image without privileged mode.

When finished, you may check Libreswan logs with:

```
docker exec -it ipsec-vpn-server grep pluto /var/log/auth.log
```

To check xl2tpd logs, run `docker logs ipsec-vpn-server`.

## Check server status

Check the status of the IPsec VPN server:

```
docker exec -it ipsec-vpn-server ipsec status
```

Show currently established VPN connections:

```
docker exec -it ipsec-vpn-server ipsec trafficstatus
```

## Build from source code

Advanced users can download and compile the source code from GitHub:

```
git clone https://github.com/hwdsl2/docker-ipsec-vpn-server
cd docker-ipsec-vpn-server
# To build Alpine-based image
docker build -t hwdsl2/ipsec-vpn-server .
# To build Debian-based image
docker build -f Dockerfile.debian -t hwdsl2/ipsec-vpn-server:debian .
```

Or use this if not modifying the source code:

```
# To build Alpine-based image
docker build -t hwdsl2/ipsec-vpn-server github.com/hwdsl2/docker-ipsec-vpn-server
# To build Debian-based image
docker build -f Dockerfile.debian -t hwdsl2/ipsec-vpn-server:debian \
  github.com/hwdsl2/docker-ipsec-vpn-server
```

## Bash shell inside container

To start a Bash session in the running container:

```
docker exec -it ipsec-vpn-server env TERM=xterm bash -l
```

(Optional) Install the `nano` editor:

```
# For Alpine-based image
apk add --no-cache nano
# For Debian-based image
apt-get update && apt-get -y install nano
```

Then run your commands inside the container. When finished, exit the container and restart if needed:

```
exit
docker restart ipsec-vpn-server
```

## Bind mount the env file

As an alternative to the `--env-file` option, advanced users can bind mount the `env` file. The advantage of this method is that after updating the `env` file, you can restart the Docker container to take effect instead of re-creating it. To use this method, you must first edit your `env` file and use single quotes `''` to enclose the values of all variables. Then (re-)create the Docker container (replace the first `vpn.env` with your own `env` file):

```
docker run \
    --name ipsec-vpn-server \
    --restart=always \
    -v "$(pwd)/vpn.env:/opt/src/env/vpn.env:ro" \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

## Deploy Google BBR congestion control

After the VPN server is set up, the performance can be improved by deploying the Google BBR congestion control algorithm on your Docker host.

This is usually done by modifying the configuration file `/etc/sysctl.conf`. However, some Linux distributions may additionally require updates to the Linux kernel.

For detailed deployment methods, please refer to [this document](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/bbr.md). When finished, restart the Docker container:

```
docker restart ipsec-vpn-server
```

## License

**Note:** The software components inside the pre-built image (such as Libreswan and xl2tpd) are under the respective licenses chosen by their respective copyright holders. As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within.

Copyright (C) 2016-2026 [Lin Song](https://github.com/hwdsl2) [](https://www.linkedin.com/in/linsongui)

[](http://creativecommons.org/licenses/by-sa/3.0/)   
This work is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/)   
Attribution required: please include my name in any derivative and let me know how you have improved it!

---

## File: docs/advanced-usage-zh.md

[English](advanced-usage.md) | [中文](advanced-usage-zh.md)

# 高级用法

- [使用其他的 DNS 服务器](#使用其他的-dns-服务器)
- [不启用 privileged 模式运行](#不启用-privileged-模式运行)
- [选择 VPN 模式](#选择-vpn-模式)
- [启用 IKEv2 前向保密](#启用-ikev2-前向保密)
- [访问 Docker 主机上的其它容器](#访问-docker-主机上的其它容器)
- [指定 VPN 服务器的公有 IP](#指定-vpn-服务器的公有-ip)
- [为 VPN 客户端指定静态 IP](#为-vpn-客户端指定静态-ip)
- [自定义 VPN 子网](#自定义-vpn-子网)
- [IPv6 支持](#ipv6-支持)
- [VPN 分流](#vpn-分流)
- [关于 host network 模式](#关于-host-network-模式)
- [启用 Libreswan 日志](#启用-libreswan-日志)
- [查看服务器状态](#查看服务器状态)
- [从源代码构建](#从源代码构建)
- [在容器中运行 Bash shell](#在容器中运行-bash-shell)
- [绑定挂载 env 文件](#绑定挂载-env-文件)
- [部署 Google BBR 拥塞控制](#部署-google-bbr-拥塞控制)

## 使用其他的 DNS 服务器

在 VPN 已连接时，客户端默认配置为使用 [Google Public DNS](https://developers.google.com/speed/public-dns/)。如果偏好其它的域名解析服务，你可以在 `env` 文件中定义 `VPN_DNS_SRV1` 和 `VPN_DNS_SRV2`（可选），然后按照[说明](../README-zh.md#更新-docker-镜像)重新创建 Docker 容器。示例如下：

```
VPN_DNS_SRV1=1.1.1.1
VPN_DNS_SRV2=1.0.0.1
```

使用 `VPN_DNS_SRV1` 指定主 DNS 服务器，使用 `VPN_DNS_SRV2` 指定辅助 DNS 服务器（可选）。

请注意，如果 Docker 容器中已经配置了 IKEv2，你还需要编辑 Docker 容器内的 `/etc/ipsec.d/ikev2.conf` 并将 `8.8.8.8` 和 `8.8.4.4` 替换为你的其他的 DNS 服务器，然后重新启动 Docker 容器。

以下是一些流行的公共 DNS 提供商的列表，供你参考。

| 提供商 | 主 DNS | 辅助 DNS | 注释 |
| ----- | ------ | ------- | ---- |
| [Google Public DNS](https://developers.google.com/speed/public-dns) | 8.8.8.8 | 8.8.4.4 | 本项目默认 |
| [Cloudflare](https://1.1.1.1/dns/) | 1.1.1.1 | 1.0.0.1 | 另见：[Cloudflare for families](https://1.1.1.1/family/) |
| [Quad9](https://www.quad9.net) | 9.9.9.9 | 149.112.112.112 | 阻止恶意域 |
| [OpenDNS](https://www.opendns.com/home-internet-security/) | 208.67.222.222 | 208.67.220.220 | 阻止网络钓鱼域，可配置。 |
| [CleanBrowsing](https://cleanbrowsing.org/filters/) | 185.228.168.9 | 185.228.169.9 | [域过滤器](https://cleanbrowsing.org/filters/)可用 |
| [NextDNS](https://nextdns.io/?from=bg25bwmp) | 按需选择 | 按需选择 | 广告拦截，免费套餐可用。[了解更多](https://nextdns.io/?from=bg25bwmp)。 |
| [Control D](https://controld.com/free-dns) | 按需选择 | 按需选择 | 广告拦截，可配置。[了解更多](https://controld.com/free-dns)。 |

## 不启用 privileged 模式运行

高级用户可以在不启用 [privileged 模式](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)的情况下使用本镜像创建一个 Docker 容器（将以下命令中的 `./vpn.env` 替换为你自己的 `env` 文件）。

**注：** 如果你的 Docker 主机运行 CentOS Stream, Oracle Linux 8+, Rocky Linux 或者 AlmaLinux，推荐使用 [privileged 模式](../README-zh.md#运行-ipsec-vpn-服务器)。如果你想要不启用 privileged 模式运行，则 **必须** 在创建 Docker 容器之前以及系统启动时运行 `modprobe ip_tables ip6_tables`。

```
docker run \
    --name ipsec-vpn-server \
    --env-file ./vpn.env \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --cap-add=NET_ADMIN \
    --device=/dev/ppp \
    --sysctl net.ipv4.ip_forward=1 \
    --sysctl net.ipv4.conf.all.accept_redirects=0 \
    --sysctl net.ipv4.conf.all.send_redirects=0 \
    --sysctl net.ipv4.conf.all.rp_filter=0 \
    --sysctl net.ipv4.conf.default.accept_redirects=0 \
    --sysctl net.ipv4.conf.default.send_redirects=0 \
    --sysctl net.ipv4.conf.default.rp_filter=0 \
    --sysctl net.ipv6.conf.all.forwarding=1 \
    hwdsl2/ipsec-vpn-server
```

在不启用 privileged 模式运行时，容器不能更改 `sysctl` 设置。这可能会影响本镜像的某些功能。一个已知问题是 [Android/Linux MTU/MSS fix](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-zh.md#androidlinux-mtumss-问题) 需要另外在 `docker run` 命令添加 `--sysctl net.ipv4.ip_no_pmtu_disc=1` 才有效。如果你遇到任何问题，可以尝试换用 [privileged 模式](../README-zh.md#运行-ipsec-vpn-服务器)重新创建容器。

在创建 Docker 容器之后，请转到[获取 VPN 登录信息](../README-zh.md#获取-vpn-登录信息)。

类似地，如果你使用 [Docker compose](https://docs.docker.com/compose/)，可以将 [docker-compose.yml](../docker-compose.yml) 中的 `privileged: true` 替换为：

```
  cap_add:
    - NET_ADMIN
  devices:
    - "/dev/ppp:/dev/ppp"
  sysctls:
    - net.ipv4.ip_forward=1
    - net.ipv4.conf.all.accept_redirects=0
    - net.ipv4.conf.all.send_redirects=0
    - net.ipv4.conf.all.rp_filter=0
    - net.ipv4.conf.default.accept_redirects=0
    - net.ipv4.conf.default.send_redirects=0
    - net.ipv4.conf.default.rp_filter=0
    - net.ipv6.conf.all.forwarding=1
```

更多信息请参见 [compose file reference](https://docs.docker.com/compose/compose-file/)。

## 选择 VPN 模式

在使用此 Docker 镜像时，默认启用 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式。此外，如果在创建 Docker 容器时在 `docker run` 命令中[指定](../README-zh.md#运行-ipsec-vpn-服务器)了 `-v ikev2-vpn-data:/etc/ipsec.d` 选项，则会启用 IKEv2 模式。

高级用户可以有选择性地禁用 VPN 模式，通过在 `env` 文件中设置以下变量并重新创建 Docker 容器来实现。

禁用 IPsec/L2TP 模式：`VPN_DISABLE_IPSEC_L2TP=yes`   
禁用 IPsec/XAuth ("Cisco IPsec") 模式：`VPN_DISABLE_IPSEC_XAUTH=yes`   
禁用 IPsec/L2TP 和 IPsec/XAuth 模式：`VPN_IKEV2_ONLY=yes`

## 启用 IKEv2 前向保密

默认情况下，IKEv2 子安全关联（Child SA）从现有 IKE SA 派生密钥材料，不进行新的 Diffie-Hellman 交换（`pfs=no`）。启用前向保密（PFS）后，每次子 SA 重新生成密钥时都会执行新的 DH 交换，从而确保即使服务器私钥在将来遭到泄露，攻击者也无法解密之前录制的会话。

**注：** IKE SA 已将 ECP-256（`aes_gcm_c_256-hmac_sha2_256-ecp_256`）作为首选提案，所有现代客户端均会协商使用，因此这些客户端的会话密钥已与长期密钥材料独立。为子 SA 启用 PFS 是一项渐进式安全加固措施，而非关键漏洞修复。

**客户端兼容性：** 所有现代客户端均支持 PFS。但是，macOS 和 iOS 客户端需要重新导出并导入已将 `EnablePFS` 设为 `1` 的 `.mobileconfig` 配置文件（详见下文）。Windows 客户端需要更新连接配置。RouterOS 用户需将 IKEv2 配置文件中的 `pfs-group=none` 改为 `pfs-group=ecp256`。Android 和 Linux strongSwan 客户端无需更改。Windows 7 IKEv2 客户端不支持 ECP PFS 组，若服务器启用 PFS，将无法连接。

要启用 PFS，请先[在容器内打开 Bash shell](#在容器中运行-bash-shell)，然后运行：

```bash
sed -i 's/pfs=no/pfs=yes/' /etc/ipsec.d/ikev2.conf
```

完成后，`exit` 容器并重启：

```
docker restart ipsec-vpn-server
```

启用 PFS 后，需要更新以下客户端配置：

- **macOS / iOS：** 运行 `docker exec -it ipsec-vpn-server ikev2.sh --exportclient <名称>` 重新导出客户端 `.mobileconfig` 文件并复制到 Docker 主机，然后编辑导出的文件以启用 PFS：
  ```bash
  sed -i '/EnablePFS/{n;s/0/1/;}' <名称>.mobileconfig
  ```
  在设备上重新导入更新后的文件。
- **Windows：** 在提升权限的 PowerShell 窗口中运行 `Set-VpnConnection -Name "你的VPN名称" -PfsGroup ECP256`（替换为实际的 VPN 连接名称），然后重新连接 VPN。
- **RouterOS (MikroTik)：** 在 IKEv2 对等配置文件中，将 `pfs-group=none` 改为 `pfs-group=ecp256`。

Android 和 Linux strongSwan 客户端无需更改，PFS 会自动协商。

要恢复默认设置（禁用 PFS），请重复上述步骤，但在 `sed` 命令中将 `pfs=yes` 替换为 `pfs=no`。

## 访问 Docker 主机上的其它容器

连接到 VPN 后，VPN 客户端通常可以访问在同一 Docker 主机上其他容器中运行的服务，而无需进行其他配置。

例如，如果 IPsec VPN 服务器容器的 IP 为 `172.17.0.2`，并且一个 IP 为 `172.17.0.3` 的 Nginx 容器在同一 Docker 主机上运行，则 VPN 客户端可以使用 IP `172.17.0.3` 来访问 Nginx 容器上的服务。要找出分配给容器的 IP ，可以运行 `docker inspect <container name>`。

## 指定 VPN 服务器的公有 IP

在具有多个公有 IP 地址的 Docker 主机上，高级用户可以使用 `env` 文件中的变量 `VPN_PUBLIC_IP` 为 VPN 服务器指定一个公有 IP，然后重新创建 Docker 容器。例如，如果 Docker 主机的 IP 为 `192.0.2.1` 和 `192.0.2.2`，并且你想要 VPN 服务器使用 `192.0.2.2`：

```
VPN_PUBLIC_IP=192.0.2.2
```

请注意，如果在 Docker 容器中已经配置了 IKEv2，则此变量对 IKEv2 模式无效。在这种情况下，你可以移除 IKEv2 并使用自定义选项重新配置它。参见[配置并使用 IKEv2 VPN](../README-zh.md#配置并使用-ikev2-vpn)。

如果你想要 VPN 客户端在 VPN 连接处于活动状态时使用指定的公有 IP 作为其 "出站 IP"，并且指定的 IP **不是** Docker 主机上的主 IP（或默认路由），则可能需要额外的配置。在这种情况下，你可以尝试在 Docker 主机上添加一个 IPTables `SNAT` 规则。如果要在重启后继续有效，你可以将命令添加到 `/etc/rc.local`。

继续上面的例子，如果 Docker 容器具有内部 IP `172.17.0.2`（使用 `docker inspect ipsec-vpn-server` 查看），Docker 的网络接口名称为 `docker0`（使用 `iptables -nvL -t nat` 查看)，并且你希望 "出站 IP" 为 `192.0.2.2`：

```
iptables -t nat -I POSTROUTING -s 172.17.0.2 ! -o docker0 -j SNAT --to 192.0.2.2
```

要检查一个已连接的 VPN 客户端的 "出站 IP"，你可以在该客户端上打开浏览器并到[这里](https://www.ipchicken.com)检测 IP 地址。

## 为 VPN 客户端指定静态 IP

在使用 IPsec/L2TP 模式连接时，VPN 服务器（Docker 容器）在虚拟网络 `192.168.42.0/24` 内具有内网 IP `192.168.42.1`。为客户端分配的内网 IP 在这个范围内：`192.168.42.10` 到 `192.168.42.250`。要找到为特定的客户端分配的 IP，可以查看该 VPN 客户端上的连接状态。

在使用 IPsec/XAuth ("Cisco IPsec") 或 IKEv2 模式连接时，VPN 服务器（Docker 容器）在虚拟网络 `192.168.43.0/24` 内 **没有** 内网 IP。为客户端分配的内网 IP 在这个范围内：`192.168.43.10` 到 `192.168.43.250`。

高级用户可以将静态 IP 分配给 VPN 客户端。这是可选的。对于 **IKEv2 模式**，首先[在容器中运行 Bash shell](#在容器中运行-bash-shell)，然后按照[VPN 内网 IP 和流量](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/advanced-usage-zh.md#vpn-内网-ip-和流量)中的 "IKEv2 模式：为 VPN 客户端分配静态 IP" 小节中的步骤操作。请注意，你需要跳过第 2, 3 和 5 步，并且在完成后重启 Docker 容器。这是因为对 `/etc/ipsec.conf` 的修改可能会在重启容器时被覆盖。

以下说明 **仅适用于** IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式。

要分配静态 IP，在你的 `env` 文件中定义 `VPN_ADDL_IP_ADDRS` 变量，然后重新创建 Docker 容器。例如：

```
VPN_ADDL_USERS=user1 user2 user3 user4 user5
VPN_ADDL_PASSWORDS=pass1 pass2 pass3 pass4 pass5
VPN_ADDL_IP_ADDRS=* * 192.168.42.2 192.168.43.2
```

在此示例中，我们为 IPsec/L2TP 模式的 `user3` 分配静态 IP `192.168.42.2`，并为 IPsec/XAuth ("Cisco IPsec") 模式的 `user4` 分配静态 IP `192.168.43.2`。`user1`, `user2` 和 `user5` 的内网 IP 将被自动分配。`user3` 在 IPsec/XAuth 模式下的内网 IP 和 `user4` 在 IPsec/L2TP 模式下的内网 IP 也将被自动分配。你可以使用 `*` 来指定自动分配的 IP，或者将这些用户放在列表的末尾。

你为 IPsec/L2TP 模式指定的静态 IP 必须在 `192.168.42.2` 到 `192.168.42.9` 范围内。你为 IPsec/XAuth ("Cisco IPsec") 模式指定的静态 IP 必须在 `192.168.43.2` 到 `192.168.43.9` 范围内。

如果你需要分配更多静态 IP，则必须缩小自动分配的 IP 地址池。示例如下：

```
VPN_L2TP_POOL=192.168.42.100-192.168.42.250
VPN_XAUTH_POOL=192.168.43.100-192.168.43.250
```

这将允许你为 IPsec/L2TP 模式在 `192.168.42.2` 到 `192.168.42.99` 范围内分配静态 IP，并且为 IPsec/XAuth ("Cisco IPsec") 模式在 `192.168.43.2` 到 `192.168.43.99` 范围内分配静态 IP。

请注意，如果你在 `env` 文件中指定了 `VPN_XAUTH_POOL`，并且在 Docker 容器中已经配置了 IKEv2，你 **必须** 在重新创建 Docker 容器之前手动编辑容器内的 `/etc/ipsec.d/ikev2.conf` 并将 `rightaddresspool=192.168.43.10-192.168.43.250` 替换为与 `VPN_XAUTH_POOL` **相同的值**。否则 IKEv2 可能会停止工作。

**注：** 在你的 `env` 文件中，**不要**为变量值添加 `""` 或者 `''`，或在 `=` 两边添加空格。**不要**在值中使用这些字符： `\ " '`。

## 自定义 VPN 子网

默认情况下，IPsec/L2TP VPN 客户端将使用内部 VPN 子网 `192.168.42.0/24`，而 IPsec/XAuth ("Cisco IPsec") 和 IKEv2 VPN 客户端将使用内部 VPN 子网 `192.168.43.0/24`。有关更多详细信息，请阅读上一节。

对于大多数用例，没有必要也 **不建议** 自定义这些子网。但是，如果你的用例需要它，你可以在 `env` 文件中指定自定义子网，然后你必须重新创建 Docker 容器。

```
# 示例：为 IPsec/L2TP 模式指定自定义 VPN 子网
# 注：必须指定所有三个变量。
VPN_L2TP_NET=10.1.0.0/16
VPN_L2TP_LOCAL=10.1.0.1
VPN_L2TP_POOL=10.1.0.10-10.1.254.254
```

```
# 示例：为 IPsec/XAuth 和 IKEv2 模式指定自定义 VPN 子网
# 注：必须指定以下两个变量。
VPN_XAUTH_NET=10.2.0.0/16
VPN_XAUTH_POOL=10.2.0.10-10.2.254.254
```

**注：** 在你的 `env` 文件中，**不要**为变量值添加 `""` 或者 `''`，或在 `=` 两边添加空格。

在上面的例子中，`VPN_L2TP_LOCAL` 是在 IPsec/L2TP 模式下的 VPN 服务器的内网 IP。`VPN_L2TP_POOL` 和 `VPN_XAUTH_POOL` 是为 VPN 客户端自动分配的 IP 地址池。

请注意，如果你在 `env` 文件中指定了 `VPN_XAUTH_POOL`，并且在 Docker 容器中已经配置了 IKEv2，你 **必须** 在重新创建 Docker 容器之前手动编辑容器内的 `/etc/ipsec.d/ikev2.conf` 并将 `rightaddresspool=192.168.43.10-192.168.43.250` 替换为与 `VPN_XAUTH_POOL` **相同的值**。否则 IKEv2 可能会停止工作。

## IPv6 支持

如果 Docker 宿主机拥有公共（全局单播）IPv6 地址并且满足以下要求，IKEv2 客户端的 IPv6 支持将在容器启动时自动启用，无需手动配置。

**注：** 在 Android 上使用 strongSwan VPN 客户端时，IPv6 无需额外配置即可正常工作。对于 Windows 和 macOS 客户端，请按照以下平台特定步骤进行配置。iOS 客户端目前不支持通过 IKEv2 VPN 路由 IPv6 流量；你可以改用 [OpenVPN](https://github.com/hwdsl2/openvpn-install/blob/master/README-zh.md) 或 [WireGuard](https://github.com/hwdsl2/wireguard-install/blob/master/README-zh.md)。



Windows：通过 VPN 路由 IPv6 流量


如果你使用了 `ikev2_config_import.cmd` 脚本导入 IKEv2 配置，可以在提示时输入 **y** 以自动添加 IPv6 路由。否则，你需要在 PowerShell 窗口中运行以下命令一次，以通过 VPN 路由 IPv6 流量。将 `IKEv2 VPN X.X.X.X` 替换为你的 VPN 连接的实际名称。完成后，重新连接到 IKEv2 VPN。

```powershell
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix ::/1
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix 8000::/1
```



macOS：通过 VPN 路由 IPv6 流量


连接到 IKEv2 VPN 后，需要在终端中运行以下命令以通过 VPN 路由 IPv6 流量。每次连接后都需要运行此命令。断开 VPN 时，该路由将自动删除。接口通常为 `ipsec0`；如果同时有多个 VPN 连接处于活动状态，可能为 `ipsec1` 等，运行 `ifconfig | grep ipsec` 确认。

```
sudo route -n add -inet6 default -interface ipsec0
```


启用 IPv6 后，IKEv2 VPN 客户端将同时获得来自 `192.168.43.0/24` 地址池的 IPv4 地址和来自 `fddd:500:500:500::/64` 地址池的 IPv6 地址。容器会将来自 VPN 客户端的 IPv6 流量通过宿主机的 IPv6 地址进行伪装（NAT），使 VPN 客户端通过隧道获得完整的 IPv6 互联网访问。

**要求：**
- Docker 宿主机必须拥有可路由的全局单播 IPv6 地址（以 `2` 或 `3` 开头）。链路本地地址 (`fe80::/10`) 不满足要求。
- 必须为 Docker 容器启用 IPv6。参见[在 Docker 中启用 IPv6 支持](https://docs.docker.com/engine/daemon/ipv6/)。
- Libreswan 5.0 或更新版本（Docker 镜像默认包含 5.x）。
- IPv6 仅支持 **IKEv2 模式**。IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式不支持 IPv6。

要为 Docker 容器启用 IPv6，首先在 Docker 宿主机上将以下内容添加到 `/etc/docker/daemon.json`，然后重启 Docker：

```json
{
  "ipv6": true,
  "fixed-cidr-v6": "fddd:1::/64"
}
```

然后重新创建容器。`run.sh` 脚本将检测容器的公共 IPv6 地址并自动配置 IPv6 支持。

要验证 IPv6 是否正常工作，请使用 IKEv2 连接到 VPN，然后检查你的 IPv6 地址，例如使用 [test-ipv6.com](https://test-ipv6.com)。

**现有容器注意事项：** 如果你的容器中已经配置了 IKEv2（即 `ikev2-vpn-data` 卷中已存在 `ikev2.conf`），在容器重启或重新创建时 IPv6 **不会**自动添加到现有的 IKEv2 配置中。要为 IKEv2 启用完整的 IPv6 支持，必须移除 IKEv2 并重新配置。参见[配置并使用 IKEv2 VPN](../README-zh.md#配置并使用-ikev2-vpn) 中的"移除 IKEv2"部分。

你也可以在 `env` 文件中设置 `VPN_IP6_NET`，在重新创建容器之前自定义 IPv6 地址池子网：

```
# 示例：为 IKEv2 模式指定自定义 IPv6 地址池子网
# 必须是 ULA 范围内的 /64 子网
VPN_IP6_NET=fddd:1234:5678:9012::/64
```

## VPN 分流

在启用 VPN 分流 (split tunneling) 时，VPN 客户端将仅通过 VPN 隧道发送特定目标子网的流量。其他流量 **不会** 通过 VPN 隧道。这允许你通过 VPN 安全访问指定的网络，而无需通过 VPN 发送所有客户端的流量。VPN 分流有一些局限性，而且并非所有的 VPN 客户端都支持。

高级用户可以为 IKEv2 模式启用 VPN 分流。这是可选的。将变量 `VPN_SPLIT_IKEV2` 添加到你的 `env` 文件，然后重新创建 Docker 容器。例如，如果目标子网是 `10.123.123.0/24`：

```
VPN_SPLIT_IKEV2=10.123.123.0/24
```

请注意，如果在 Docker 容器中已经配置了 IKEv2，则此变量无效。在这种情况下，有两个选项：

**选项 1：** 首先[在容器中运行 Bash shell](#在容器中运行-bash-shell)，然后编辑 `/etc/ipsec.d/ikev2.conf` 并将 `leftsubnet=0.0.0.0/0` 替换为你想要的子网。在完成后，退出容器并运行 `docker restart ipsec-vpn-server`。

**选项 2：** 删除 Docker 容器以及 `ikev2-vpn-data` 卷，然后重新创建容器。这将**永久删除**所有的 VPN 配置。参见[配置并使用 IKEv2 VPN](../README-zh.md#配置并使用-ikev2-vpn) 中的"移除 IKEv2"部分。

另外，Windows 用户也可以通过手动添加路由的方式启用 VPN 分流。有关详细信息，请参阅 [VPN 分流](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/advanced-usage-zh.md#vpn-分流)。

## 关于 host network 模式

高级用户可以使用 [host network 模式](https://docs.docker.com/network/host/)运行本镜像，通过为 `docker run` 命令添加 `--network=host` 参数来实现。

在非必要的情况下，**不推荐**使用 host network 模式运行本镜像。在该模式下，容器的网络栈未与 Docker 主机隔离，从而在使用 IPsec/L2TP 模式连接之后，VPN 客户端可以使用 Docker 主机的 VPN 内网 IP `192.168.42.1` 访问主机上的端口或服务。请注意，当你不再使用本镜像时，你需要手动清理 [run.sh](../run.sh) 所更改的 IPTables 规则和 sysctl 设置，或者重启服务器。

某些 Docker 主机操作系统，比如 Debian 10，不能使用 host network 模式运行本镜像，因为它们使用 nftables。

## 启用 Libreswan 日志

为了保持较小的 Docker 镜像，Libreswan (IPsec) 日志默认未开启。如果你需要启用它以进行故障排除，首先在正在运行的 Docker 容器中开始一个 Bash 会话：

```
docker exec -it ipsec-vpn-server env TERM=xterm bash -l
```

然后运行以下命令：

```
# For Alpine-based image
apk add --no-cache rsyslog
rsyslogd
rc-service ipsec stop; rc-service -D ipsec start >/dev/null 2>&1
sed -i '\|pluto\.pid|a rm -f /var/run/rsyslogd.pid; rsyslogd' /opt/src/run.sh
exit
# For Debian-based image
apt-get update && apt-get -y install rsyslog
rsyslogd
service ipsec restart
sed -i '\|pluto\.pid|a rm -f /var/run/rsyslogd.pid; rsyslogd' /opt/src/run.sh
exit
```

**注：** 如果你在不启用 privileged 模式的情况下使用本镜像，则错误 `rsyslogd: imklog: cannot open kernel log` 是正常的。

完成后你可以这样查看 Libreswan 日志：

```
docker exec -it ipsec-vpn-server grep pluto /var/log/auth.log
```

如需查看 xl2tpd 日志，请运行 `docker logs ipsec-vpn-server`。

## 查看服务器状态

检查 IPsec VPN 服务器状态：

```
docker exec -it ipsec-vpn-server ipsec status
```

查看当前已建立的 VPN 连接：

```
docker exec -it ipsec-vpn-server ipsec trafficstatus
```

## 从源代码构建

高级用户可以从 GitHub 下载并自行编译源代码：

```
git clone https://github.com/hwdsl2/docker-ipsec-vpn-server
cd docker-ipsec-vpn-server
# To build Alpine-based image
docker build -t hwdsl2/ipsec-vpn-server .
# To build Debian-based image
docker build -f Dockerfile.debian -t hwdsl2/ipsec-vpn-server:debian .
```

若不需要改动源码，也可以这样：

```
# To build Alpine-based image
docker build -t hwdsl2/ipsec-vpn-server github.com/hwdsl2/docker-ipsec-vpn-server
# To build Debian-based image
docker build -f Dockerfile.debian -t hwdsl2/ipsec-vpn-server:debian \
  github.com/hwdsl2/docker-ipsec-vpn-server
```

## 在容器中运行 Bash shell

在正在运行的 Docker 容器中开始一个 Bash 会话：

```
docker exec -it ipsec-vpn-server env TERM=xterm bash -l
```

（可选步骤）安装 `nano` 编辑器：

```
# For Alpine-based image
apk add --no-cache nano
# For Debian-based image
apt-get update && apt-get -y install nano
```

然后在容器中运行你的命令。完成后退出并重启 Docker 容器（如果需要）：

```
exit
docker restart ipsec-vpn-server
```

## 绑定挂载 env 文件

作为 `--env-file` 选项的替代方案，高级用户可以绑定挂载 `env` 文件。该方法的好处是你在更新 `env` 文件之后可以重启 Docker 容器以生效，而不需要重新创建它。要使用这个方法，你必须首先编辑你的 `env` 文件并将所有的变量值用单引号 `''` 括起来。然后（重新）创建 Docker 容器（将第一个 `vpn.env` 替换为你自己的 `env` 文件）：

```
docker run \
    --name ipsec-vpn-server \
    --restart=always \
    -v "$(pwd)/vpn.env:/opt/src/env/vpn.env:ro" \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

## 部署 Google BBR 拥塞控制

VPN 服务器搭建完成后，可以通过在 Docker 主机上部署 Google BBR 拥塞控制算法提升性能。

这通常只需要在配置文件 `/etc/sysctl.conf` 中插入设定即可完成。但是部分 Linux 发行版可能需要额外更新 Linux 内核。

详细的部署方法，可以参考[这篇文档](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/bbr-zh.md)。在完成后重启 Docker 容器：

```
docker restart ipsec-vpn-server
```

## 授权协议

**注：** 预构建镜像中的软件组件（例如 Libreswan 和 xl2tpd）在其各自版权所有者选择的相应许可下。对于任何预构建的镜像的使用，用户有责任确保对该镜像的任何使用符合其中包含的所有软件的任何相关许可。

版权所有 (C) 2016-2026 [Lin Song](https://github.com/hwdsl2) [](https://www.linkedin.com/in/linsongui)

[](http://creativecommons.org/licenses/by-sa/3.0/)   
这个项目是以[知识共享署名-相同方式共享3.0](http://creativecommons.org/licenses/by-sa/3.0/) 许可协议授权。   
必须署名： 请包括我的名字在任何衍生产品，并且让我知道你是如何改善它的！

---

## File: docs/vpn-book.md

[&laquo; Back to home page](../README.md) | [English](vpn-book.md) | [简体中文](vpn-book-zh.md) | [繁體中文](vpn-book-zh-Hant.md)

## New: Privacy Tools in the Age of AI

Learn how to build next-level privacy protection in the age of AI. This book is available in eBook, print and audiobook formats on:

&raquo; [Amazon](https://books2read.com/privacy?store=amazon)   
&raquo; [Google Play](https://books2read.com/privacy?store=google)   
&raquo; [Apple Books](https://books2read.com/privacy?store=apple)   
&raquo; [Hoopla](https://books2read.com/privacy?store=hoopla)   
&raquo; [Other Platforms](https://books2read.com/privacy)

Other language versions: [Español](https://books2read.com/privacyes), [Deutsch](https://books2read.com/privacyde), [Français](https://books2read.com/privacyfr), [Italiano](https://books2read.com/privacyit).

## Build Your Own VPN Server: A Step by Step Guide

This book is a **step-by-step guide** to building your own IPsec VPN, OpenVPN and WireGuard server. Available in eBook, print and audiobook formats on:

&raquo; [Amazon](https://books2read.com/vpnguide?store=amazon)   
&raquo; [Google Play](https://books2read.com/vpnguide?store=google)   
&raquo; [Apple Books](https://books2read.com/vpnguide?store=apple)   
&raquo; [Hoopla](https://books2read.com/vpnguide?store=hoopla)   
&raquo; [Other Platforms](https://books2read.com/vpnguide)

Other language versions: [简体中文](https://books2read.com/vpnguidezh), [繁體中文](https://books2read.com/vpnguidezht), [Español](https://books2read.com/vpnguidees), [Deutsch](https://books2read.com/vpnguidede), [Français](https://books2read.com/vpnguidefr), [Italiano](https://books2read.com/vpnguideit), [Nederlands](https://books2read.com/vpnguidenl), [Português](https://books2read.com/vpnguidept), [日本語](https://books2read.com/vpnguideja).

## Set Up Your Own IPsec VPN, OpenVPN and WireGuard Server

This book is a **comprehensive guide** to building your own IPsec VPN, OpenVPN and WireGuard server. Available in eBook, print and audiobook formats on:

&raquo; [Amazon](https://books2read.com/vpn?store=amazon)   
&raquo; [Google Play](https://books2read.com/vpn?store=google)   
&raquo; [Apple Books](https://books2read.com/vpn?store=apple)   
&raquo; [Hoopla](https://books2read.com/vpn?store=hoopla)   
&raquo; [Other Platforms](https://books2read.com/vpn)

Other language versions: [简体中文](https://books2read.com/vpnzh), [繁體中文](https://books2read.com/vpnzht), [Español](https://books2read.com/vpnes), [Deutsch](https://books2read.com/vpnde), [Français](https://books2read.com/vpnfr), [Italiano](https://books2read.com/vpnit), [日本語](https://books2read.com/vpnja).

Author page: [amazon.com/author/linsong](https://amazon.com/author/linsong)

---

## File: docs/vpn-book-zh.md

[&laquo; 返回主页](../README-zh.md) | [English](vpn-book.md) | [简体中文](vpn-book-zh.md) | [繁體中文](vpn-book-zh-Hant.md)

## 新：Privacy Tools in the Age of AI

了解如何在人工智能时代构建更高级别的隐私保护。本书提供电子书、精装本、平装本和有声读物格式。

&raquo; [Amazon](https://books2read.com/privacy?store=amazon)   
&raquo; [Google Play](https://books2read.com/privacy?store=google)   
&raquo; [Apple Books](https://books2read.com/privacy?store=apple)   
&raquo; [Hoopla](https://books2read.com/privacy?store=hoopla)   
&raquo; [其他平台](https://books2read.com/privacy)

其他语言版本：[Español](https://books2read.com/privacyes)、[Deutsch](https://books2read.com/privacyde)、[Français](https://books2read.com/privacyfr)、[Italiano](https://books2read.com/privacyit)。

## 搭建自己的 VPN 服务器：IPsec VPN、OpenVPN 与 WireGuard 实战指南

本书是搭建你自己的 IPsec VPN、OpenVPN 和 WireGuard 服务器的**实战指南**。提供电子书和平装本格式。

&raquo; [Google Play](https://books2read.com/vpnguidezh?store=google)   
&raquo; [Apple Books](https://books2read.com/vpnguidezh?store=apple)   
&raquo; [Amazon](https://books2read.com/vpnguidezh?store=amazon)   
&raquo; [Amazon 平装本](https://books2read.com/vpnguidezh?store=amazon-paperback&format=PAPERBACK)   
&raquo; [其他平台](https://books2read.com/vpnguidezh)

其他语言版本：[繁體中文](https://books2read.com/vpnguidezht)、[English](https://books2read.com/vpnguide)、[Español](https://books2read.com/vpnguidees)、[Deutsch](https://books2read.com/vpnguidede)、[Français](https://books2read.com/vpnguidefr)、[Italiano](https://books2read.com/vpnguideit)、[Nederlands](https://books2read.com/vpnguidenl)、[Português](https://books2read.com/vpnguidept)、[日本語](https://books2read.com/vpnguideja)。

## 搭建自己的 VPN 服务器：IPsec VPN、OpenVPN 与 WireGuard 完整指南

本书是搭建你自己的 IPsec VPN、OpenVPN 和 WireGuard 服务器的**完整指南**。提供电子书和平装本格式。

&raquo; [Google Play](https://books2read.com/vpnzh?store=google)   
&raquo; [Apple Books](https://books2read.com/vpnzh?store=apple)   
&raquo; [Amazon](https://books2read.com/vpnzh?store=amazon)   
&raquo; [Amazon 平装本](https://books2read.com/vpnzh?store=amazon-paperback&format=PAPERBACK)   
&raquo; [其他平台](https://books2read.com/vpnzh)

其他语言版本：[繁體中文](https://books2read.com/vpnzht)、[English](https://books2read.com/vpn)、[Español](https://books2read.com/vpnes)、[Deutsch](https://books2read.com/vpnde)、[Français](https://books2read.com/vpnfr)、[Italiano](https://books2read.com/vpnit)、[日本語](https://books2read.com/vpnja)。

作者页面：[amazon.com/author/linsong](https://amazon.com/author/linsong)

---

## File: README-zh.md

[English](README.md) | [简体中文](README-zh.md) | [繁體中文](README-zh-Hant.md) | [Русский](README-ru.md)

# Docker 上的 IPsec VPN 服务器

[](https://github.com/hwdsl2/docker-ipsec-vpn-server/actions/workflows/main-alpine.yml) [](https://github.com/hwdsl2/docker-ipsec-vpn-server/stargazers) [](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server/) [](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server/)

使用这个 Docker 镜像快速搭建 IPsec VPN 服务器。支持 IPsec/L2TP，Cisco IPsec 和 IKEv2 协议。

本镜像以 Alpine 3.23 或 Debian 12 为基础，并使用 [Libreswan](https://libreswan.org) (IPsec VPN 软件) 和 [xl2tpd](https://github.com/xelerance/xl2tpd) (L2TP 服务进程)。

IPsec VPN 可以加密你的网络流量，以防止在通过因特网传送时，你和 VPN 服务器之间的任何人对你的数据的未经授权的访问。在使用不安全的网络时，这是特别有用的，例如在咖啡厅，机场或旅馆房间。

**功能特性：**

- 首次启动时自动生成 VPN 凭证和 IKEv2 配置
- 支持具有强大和快速加密算法（例如 AES-GCM）的 IKEv2 模式
- 生成 VPN 配置文件以自动配置 iOS, macOS 和 Android 设备
- 支持 Windows, macOS, iOS, Android, Chrome OS 和 Linux 客户端
- 包括辅助脚本以管理 IKEv2 用户和证书
- 通过 [GitHub Actions](https://github.com/hwdsl2/docker-ipsec-vpn-server/actions) 自动构建和发布
- 使用 Docker 卷实现数据持久化
- 多架构支持：`linux/amd64`、`linux/arm64`、`linux/arm/v7`

**另提供：**

- VPN：[IPsec 无 Docker 版](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/README-zh.md)、[WireGuard](https://github.com/hwdsl2/docker-wireguard/blob/main/README-zh.md)、[OpenVPN](https://github.com/hwdsl2/docker-openvpn/blob/main/README-zh.md)、[Headscale](https://github.com/hwdsl2/docker-headscale/blob/main/README-zh.md)
- AI：[自托管 AI 套件](https://github.com/hwdsl2/self-hosted-ai-stack/blob/main/README-zh.md)，用于本地 LLM、聊天、RAG、语音和 AI 工具
- :books: **图书：**[The Self-Hosted AI Builder’s Guide](https://books2read.com/aiguide?store=amazon)、[Privacy Tools in the Age of AI](docs/vpn-book-zh.md)

## 快速开始

使用以下命令在 Docker 上快速搭建 IPsec VPN 服务器：

```bash
docker run \
    --name ipsec-vpn-server \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

你的 VPN 登录凭证将会被自动随机生成。请参见[获取 VPN 登录信息](#获取-vpn-登录信息)。

另外，你也可以在不使用 Docker 的情况下[安装 IPsec VPN](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/README-zh.md)。要了解更多有关如何使用本镜像的信息，请继续阅读以下部分。

## 社区

- 📬 [订阅项目更新](https://selfhostedstack.beehiiv.com/subscribe?utm_campaign=vpn-zh)（每月 1–2 封邮件）——获取免费的 VPN 和 AI 部署指南（PDF，英文）
- 💬 加入 [r/selfhostedstack](https://www.reddit.com/r/selfhostedstack/) 社区参与讨论
- ⭐ 如果你觉得本项目有用，请为仓库加星——这有助于让更多人发现它。

## 系统要求

- 具有公网 IP 地址或 DNS 名称的 Linux 服务器
- 已安装 Docker
- 在防火墙中开放 VPN 端口（UDP 500 和 4500）
- 你也可以使用 [Podman](https://docs.podman.io) 运行本镜像，需要首先为 `docker` 命令创建一个别名

**注：** 高级用户可以在 macOS 上通过安装 [Docker for Mac](https://docs.docker.com/desktop/setup/install/mac-install/) 使用本镜像。在使用 IPsec/L2TP 模式之前，你可能需要运行 `docker restart ipsec-vpn-server` 重启一次容器。本镜像不支持 Docker for Windows。

## 下载

预构建的可信任镜像可在 [Docker Hub registry](https://hub.docker.com/r/hwdsl2/ipsec-vpn-server/) 下载：

```bash
docker pull hwdsl2/ipsec-vpn-server
```

或者，你也可以从 [Quay.io](https://quay.io/repository/hwdsl2/ipsec-vpn-server) 下载：

```bash
docker pull quay.io/hwdsl2/ipsec-vpn-server
docker image tag quay.io/hwdsl2/ipsec-vpn-server hwdsl2/ipsec-vpn-server
```

支持的平台：`linux/amd64`、`linux/arm64` 和 `linux/arm/v7`。

高级用户可以自己从 GitHub [编译源代码](docs/advanced-usage-zh.md#从源代码构建)。

### 镜像对照表

有两个预构建的镜像可用。默认的基于 Alpine 的镜像大小仅 ~19 MB。

|                 | 基于 Alpine               | 基于 Debian                     |
| --------------- | ------------------------ | ------------------------------ |
| 镜像名称          | hwdsl2/ipsec-vpn-server  | hwdsl2/ipsec-vpn-server:debian |
| 压缩后大小        | ~ 19 MB                  | ~ 62 MB                        |
| 基础镜像          | Alpine Linux 3.23        | Debian Linux 12                |
| 系统架构          | amd64, arm64, arm/v7     | amd64, arm64, arm/v7           |
| Libreswan 版本   | 5.3.2                    | 5.3.2                          |
| IPsec/L2TP      | ✅                       | ✅                              |
| Cisco IPsec     | ✅                       | ✅                              |
| IKEv2           | ✅                       | ✅                              |

**注：** 要使用基于 Debian 的镜像，请将本自述文件中所有的 `hwdsl2/ipsec-vpn-server` 替换为 `hwdsl2/ipsec-vpn-server:debian`。这些镜像当前与 Synology NAS 系统不兼容。



我需要使用较旧版本的 Libreswan 版本 4。


一般建议使用最新的 [Libreswan](https://libreswan.org/) 版本 5，它是本项目的默认版本。但是，如果你想要使用较旧版本的 Libreswan 版本 4，你可以从源代码构建 Docker 镜像：

```bash
git clone https://github.com/hwdsl2/docker-ipsec-vpn-server
cd docker-ipsec-vpn-server
# Specify Libreswan version 4
sed -i 's/SWAN_VER=5\..*/SWAN_VER=4.15/' Dockerfile Dockerfile.debian
# To build Alpine-based image
docker build -t hwdsl2/ipsec-vpn-server .
# To build Debian-based image
docker build -f Dockerfile.debian -t hwdsl2/ipsec-vpn-server:debian .
```


## 如何使用本镜像

### 环境变量

**注：** 所有这些变量对于本镜像都是可选的，也就是说无需定义它们就可以搭建 IPsec VPN 服务器。你可以运行 `touch vpn.env` 创建一个空的 `env` 文件，然后跳到下一节。

这个 Docker 镜像使用以下几个变量，可以在一个 `env` 文件中定义（参见[示例](vpn.env.example)）：

```
VPN_IPSEC_PSK=your_ipsec_pre_shared_key
VPN_USER=your_vpn_username
VPN_PASSWORD=your_vpn_password
```

这将创建一个用于 VPN 登录的用户账户，它可以在你的多个设备上使用[\*](#重要提示)。 IPsec PSK (预共享密钥) 由 `VPN_IPSEC_PSK` 环境变量指定。 VPN 用户名和密码分别在 `VPN_USER` 和 `VPN_PASSWORD` 中定义。

支持创建额外的 VPN 用户，如果需要，可以像下面这样在你的 `env` 文件中定义。用户名和密码必须分别使用空格进行分隔，并且用户名不能有重复。所有的 VPN 用户将共享同一个 IPsec PSK。

```
VPN_ADDL_USERS=additional_username_1 additional_username_2
VPN_ADDL_PASSWORDS=additional_password_1 additional_password_2
```

以上变量仅适用于 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式。对于 IKEv2，参见[配置并使用 IKEv2 VPN](#配置并使用-ikev2-vpn)。

**注：** 在你的 `env` 文件中，**不要**为变量值添加 `""` 或者 `''`，或在 `=` 两边添加空格。**不要**在值中使用这些字符： `\ " '`。一个安全的 IPsec PSK 应该至少包含 20 个随机字符。

**注：** 如果在创建 Docker 容器后修改 `env` 文件，则必须删除并重新创建容器才能使更改生效。参见[更新 Docker 镜像](#更新-docker-镜像)。

### 其他环境变量

高级用户可以指定一个域名，客户端名称和/或另外的 DNS 服务器。这是可选的。



了解如何指定一个域名，客户端名称和/或另外的 DNS 服务器。


高级用户可以指定一个域名作为 IKEv2 服务器地址。这是可选的。该域名必须是一个全称域名 (FQDN)。示例如下：

```
VPN_DNS_NAME=vpn.example.com
```

你可以指定第一个 IKEv2 客户端的名称。该名称不能包含空格或者除 `-` `_` 之外的任何特殊字符。如果未指定，则使用默认值 `vpnclient`。

```
VPN_CLIENT_NAME=your_client_name
```

在 VPN 已连接时，客户端默认配置为使用 [Google Public DNS](https://developers.google.com/speed/public-dns/)。你可以为所有的 VPN 模式指定另外的 DNS 服务器。示例如下：

```
VPN_DNS_SRV1=1.1.1.1
VPN_DNS_SRV2=1.0.0.1
```

有关详细信息以及一些流行的公共 DNS 提供商的列表，参见[使用其他的 DNS 服务器](docs/advanced-usage-zh.md)。

默认情况下，导入 IKEv2 客户端配置时不需要密码。你可以选择使用随机密码保护客户端配置文件。

```
VPN_PROTECT_CONFIG=yes
```

**注：** 如果在 Docker 容器中已经配置了 IKEv2，则以上变量对 IKEv2 模式无效。在这种情况下，你可以移除 IKEv2 并使用自定义选项重新配置它。参见[配置并使用 IKEv2 VPN](#配置并使用-ikev2-vpn)。


### 运行 IPsec VPN 服务器

使用本镜像创建一个新的 Docker 容器（将 `./vpn.env` 替换为你自己的 `env` 文件）：

```bash
docker run \
    --name ipsec-vpn-server \
    --env-file ./vpn.env \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -v /lib/modules:/lib/modules:ro \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

在该命令中，我们使用 `docker run` 的 `-v` 选项来创建一个名为 `ikev2-vpn-data` 的新 [Docker 卷](https://docs.docker.com/storage/volumes/)，并且将它挂载到容器内的 `/etc/ipsec.d` 目录下。IKEv2 的相关数据（比如证书和密钥）在该卷中保存，之后当你需要重新创建 Docker 容器的时候，只需指定同一个卷。

推荐在使用本镜像时启用 IKEv2。如果你不想启用 IKEv2 而仅使用 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式连接到 VPN，可以去掉上面 `docker run` 命令中的第一个 `-v` 选项。

**注：** 高级用户也可以[不启用 privileged 模式运行](docs/advanced-usage-zh.md#不启用-privileged-模式运行)。

### 获取 VPN 登录信息

如果你在上述 `docker run` 命令中没有指定 `env` 文件，`VPN_USER` 会默认为 `vpnuser`，并且 `VPN_IPSEC_PSK` 和 `VPN_PASSWORD` 会被自动随机生成。要获取这些登录信息，可以查看容器的日志：

```bash
docker logs ipsec-vpn-server
```

在命令输出中查找这些行：

```
Connect to your new VPN with these details:

Server IP: 你的VPN服务器IP
IPsec PSK: 你的IPsec预共享密钥
Username: 你的VPN用户名
Password: 你的VPN密码
```

在命令输出中也会包含 IKEv2 配置信息（如果已启用）。

（可选步骤）备份自动生成的 VPN 登录信息（如果有）到当前目录：

```bash
docker cp ipsec-vpn-server:/etc/ipsec.d/vpn-gen.env ./
```

## 使用 docker-compose

```bash
cp vpn.env.example vpn.env
# 如果需要，编辑 vpn.env，然后：
docker compose up -d
docker logs ipsec-vpn-server
```

示例 `docker-compose.yml`（已包含在内）：

```yaml
volumes:
  ikev2-vpn-data:

services:
  vpn:
    image: hwdsl2/ipsec-vpn-server
    restart: always
    env_file:
      - ./vpn.env
    ports:
      - "500:500/udp"
      - "4500:4500/udp"
    privileged: true
    hostname: ipsec-vpn-server
    container_name: ipsec-vpn-server
    volumes:
      - ikev2-vpn-data:/etc/ipsec.d
      - /lib/modules:/lib/modules:ro
```

## 下一步

*其他语言版本: [English](README.md#next-steps), [简体中文](README-zh.md#下一步), [繁體中文](README-zh-Hant.md#下一步), [Русский](README-ru.md#следующие-шаги)。*

配置你的计算机或其它设备使用 VPN。请参见：

**[配置并使用 IKEv2 VPN（推荐）](#配置并使用-ikev2-vpn)**

**[配置 IPsec/L2TP VPN 客户端](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-zh.md)**

**[配置 IPsec/XAuth ("Cisco IPsec") VPN 客户端](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-xauth-zh.md)**

**阅读 [:book: VPN book](docs/vpn-book-zh.md) 以访问[额外内容](https://ko-fi.com/post/Support-this-project-and-get-access-to-supporter-o-X8X5FVFZC)。**

开始使用自己的专属 VPN! :sparkles::tada::rocket::sparkles:

## 重要提示

**Windows 用户** 对于 IPsec/L2TP 模式，在首次连接之前需要[修改注册表](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-zh.md#windows-错误-809)，以解决 VPN 服务器或客户端与 NAT（比如家用路由器）的兼容问题。

同一个 VPN 账户可以在你的多个设备上使用。但是由于 IPsec/L2TP 的局限性，如果需要连接在同一个 NAT（比如家用路由器）后面的多个设备，你必须使用 [IKEv2](#配置并使用-ikev2-vpn) 或者 [IPsec/XAuth](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-xauth-zh.md) 模式。

如需添加，修改或者删除 VPN 用户账户，首先更新你的 `env` 文件，然后你必须按照[下一节](#更新-docker-镜像)的说明来删除并重新创建 Docker 容器。高级用户可以[绑定挂载](docs/advanced-usage-zh.md#绑定挂载-env-文件) `env` 文件。

对于有外部防火墙的服务器（比如 [EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)/[GCE](https://cloud.google.com/vpc/docs/firewalls)），请为 VPN 打开 UDP 端口 500 和 4500。阿里云用户请参见 [#433](https://github.com/hwdsl2/setup-ipsec-vpn/issues/433)。

在 VPN 已连接时，客户端配置为使用 [Google Public DNS](https://developers.google.com/speed/public-dns/)。如果偏好其它的域名解析服务，请看[这里](docs/advanced-usage-zh.md#使用其他的-dns-服务器)。

## 更新 Docker 镜像

要更新 Docker 镜像和容器，首先[下载](#下载)最新版本：

```bash
docker pull hwdsl2/ipsec-vpn-server
```

如果 Docker 镜像已经是最新的，你会看到提示：

```
Status: Image is up to date for hwdsl2/ipsec-vpn-server:latest
```

否则将会下载最新版本。要更新你的 Docker 容器，首先记下你所有的 [VPN 登录信息](#获取-vpn-登录信息)。然后删除 Docker 容器： `docker rm -f ipsec-vpn-server`。最后按照[如何使用本镜像](#如何使用本镜像)的说明来重新创建它。

## 配置并使用 IKEv2 VPN

IKEv2 模式是比 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 更佳的连接模式，该模式无需 IPsec PSK, 用户名或密码。更多信息请看[这里](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/ikev2-howto-zh.md)。

首先，查看容器的日志以获取 IKEv2 配置信息：

```bash
docker logs ipsec-vpn-server
```

**注：** 如果你无法找到 IKEv2 配置信息，IKEv2 可能没有在容器中启用。尝试按照[更新 Docker 镜像](#更新-docker-镜像)一节的说明更新 Docker 镜像和容器。

在 IKEv2 安装过程中会创建一个 IKEv2 客户端（默认名称为 `vpnclient`），并且导出它的配置到 **容器内** 的 `/etc/ipsec.d` 目录下。你可以将配置文件复制到 Docker 主机：

```bash
# 查看容器内的 /etc/ipsec.d 目录的文件
docker exec -it ipsec-vpn-server ls -l /etc/ipsec.d
# 示例：将一个客户端配置文件从容器复制到 Docker 主机当前目录
docker cp ipsec-vpn-server:/etc/ipsec.d/vpnclient.p12 ./
```

**下一步：** [配置你的设备](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/ikev2-howto-zh.md)以使用 IKEv2 VPN。



了解如何管理 IKEv2 客户端。


你可以使用辅助脚本管理 IKEv2 客户端。示例如下。如需自定义客户端选项，可以在不添加参数的情况下运行脚本。

```bash
# 添加一个客户端（使用默认选项）
docker exec -it ipsec-vpn-server ikev2.sh --addclient [client name]
# 导出一个已有的客户端的配置
docker exec -it ipsec-vpn-server ikev2.sh --exportclient [client name]
# 列出已有的客户端
docker exec -it ipsec-vpn-server ikev2.sh --listclients
# 显示使用信息
docker exec -it ipsec-vpn-server ikev2.sh -h
```

**注：** 如果你遇到错误 "executable file not found"，将上面的 `ikev2.sh` 换成 `/opt/src/ikev2.sh`。



了解如何更改 IKEv2 服务器地址。


在某些情况下，你可能需要更改 IKEv2 服务器地址。例如切换为使用域名，或者在服务器的 IP 更改之后。要更改 IKEv2 服务器地址，首先[在容器中运行 Bash shell](docs/advanced-usage-zh.md#在容器中运行-bash-shell)，然后[按照这里的说明操作](https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/ikev2-howto-zh.md#更改-ikev2-服务器地址)。请注意，容器的日志在你重启 Docker 容器之前将不显示新的 IKEv2 服务器地址。



移除 IKEv2 并使用自定义选项重新配置。


在某些情况下，你可能需要移除 IKEv2 并使用自定义选项重新配置它。

**警告：** 这将**永久删除**所有的 IKEv2 配置（包括证书和密钥），并且**不可撤销**！

**选项 1:** 使用辅助脚本移除 IKEv2 并重新配置。

请注意，这将覆盖你在 `env` 文件中指定的变量，例如 `VPN_DNS_NAME` 和 `VPN_CLIENT_NAME`，并且容器的日志将不再显示 IKEv2 的最新信息。

```bash
# 移除 IKEv2 并删除所有的 IKEv2 配置
docker exec -it ipsec-vpn-server ikev2.sh --removeikev2
# 使用自定义选项重新配置 IKEv2
docker exec -it ipsec-vpn-server ikev2.sh
```

**选项 2:** 移除 `ikev2-vpn-data` 并重新创建容器。

1. 在纸上记下你所有的 [VPN 登录信息](#获取-vpn-登录信息)。
1. 删除 Docker 容器：`docker rm -f ipsec-vpn-server`。
1. 删除 `ikev2-vpn-data` 卷：`docker volume rm ikev2-vpn-data`。
1. 更新你的 `env` 文件并添加自定义 IKEv2 选项，例如 `VPN_DNS_NAME` 和 `VPN_CLIENT_NAME`，然后重新创建容器。参见[如何使用本镜像](#如何使用本镜像)。


## 高级用法

请参见[高级用法](docs/advanced-usage-zh.md)。

- [使用其他的 DNS 服务器](docs/advanced-usage-zh.md#使用其他的-dns-服务器)
- [不启用 privileged 模式运行](docs/advanced-usage-zh.md#不启用-privileged-模式运行)
- [选择 VPN 模式](docs/advanced-usage-zh.md#选择-vpn-模式)
- [启用 IKEv2 前向保密](docs/advanced-usage-zh.md#启用-ikev2-前向保密)
- [访问 Docker 主机上的其它容器](docs/advanced-usage-zh.md#访问-docker-主机上的其它容器)
- [指定 VPN 服务器的公有 IP](docs/advanced-usage-zh.md#指定-vpn-服务器的公有-ip)
- [为 VPN 客户端指定静态 IP](docs/advanced-usage-zh.md#为-vpn-客户端指定静态-ip)
- [自定义 VPN 子网](docs/advanced-usage-zh.md#自定义-vpn-子网)
- [IPv6 支持](docs/advanced-usage-zh.md#ipv6-支持)
- [VPN 分流](docs/advanced-usage-zh.md#vpn-分流)
- [关于 host network 模式](docs/advanced-usage-zh.md#关于-host-network-模式)
- [启用 Libreswan 日志](docs/advanced-usage-zh.md#启用-libreswan-日志)
- [查看服务器状态](docs/advanced-usage-zh.md#查看服务器状态)
- [从源代码构建](docs/advanced-usage-zh.md#从源代码构建)
- [在容器中运行 Bash shell](docs/advanced-usage-zh.md#在容器中运行-bash-shell)
- [绑定挂载 env 文件](docs/advanced-usage-zh.md#绑定挂载-env-文件)
- [部署 Google BBR 拥塞控制](docs/advanced-usage-zh.md#部署-google-bbr-拥塞控制)

## 技术细节

需要运行以下两个服务：`Libreswan (pluto)` 提供 IPsec VPN，`xl2tpd` 提供 L2TP 支持。

默认的 IPsec 配置支持以下协议：

* IPsec/L2TP with PSK
* IKEv1 with PSK and XAuth ("Cisco IPsec")
* IKEv2

所需端口：`500/udp` 和 `4500/udp`（IPsec）

## 授权协议

**注：** 预构建镜像中的软件组件（例如 Libreswan 和 xl2tpd）在其各自版权所有者选择的相应许可下。对于任何预构建的镜像的使用，用户有责任确保对该镜像的任何使用符合其中包含的所有软件的任何相关许可。

版权所有 (C) 2016-2026 [Lin Song](https://github.com/hwdsl2) [](https://www.linkedin.com/in/linsongui)   
基于 [Thomas Sarlandie 的工作](https://github.com/sarfata/voodooprivacy) (版权所有 2012)

[](http://creativecommons.org/licenses/by-sa/3.0/)   
这个项目是以[知识共享署名-相同方式共享3.0](http://creativecommons.org/licenses/by-sa/3.0/) 许可协议授权。   
必须署名： 请包括我的名字在任何衍生产品，并且让我知道你是如何改善它的！