File: README.md
English | 简体中文 | 繁體中文 | Русский
IPsec VPN Server on Docker
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 (IPsec VPN software) and 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
- Persistent data via a Docker volume
- Multi-arch:
linux/amd64,linux/arm64,linux/arm/v7
Also available:
- VPN: IPsec without Docker, WireGuard, OpenVPN, Headscale
- AI: Self-Hosted AI Stack for local LLMs, chat, RAG, voice and AI tools
- :books: Books: The Self-Hosted AI Builder’s Guide, Privacy Tools in the Age of AI
Quick start
Use this command to set up an IPsec VPN server on Docker:
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-serverYour VPN login details will be randomly generated. See Retrieve VPN login details.
Alternatively, you may set up IPsec VPN without Docker. To learn more about how to use this image, read the sections below.
Community
- 📬 Subscribe for project updates (1–2 emails/month) — get free VPN and AI deployment guides (PDF)
- 💬 Join the 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 to run this image, after creating an alias for
docker
Note: Advanced users can use this image on macOS with Docker for Mac. 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:
docker pull hwdsl2/ipsec-vpn-serverAlternatively, you may download from Quay.io:
docker pull quay.io/hwdsl2/ipsec-vpn-server
docker image tag quay.io/hwdsl2/ipsec-vpn-server hwdsl2/ipsec-vpn-serverSupported platforms: linux/amd64, linux/arm64 and linux/arm/v7.
Advanced users can 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 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:
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_IPSEC_PSK=your_ipsec_pre_shared_key
VPN_USER=your_vpn_username
VPN_PASSWORD=your_vpn_passwordThis will create a user account for VPN login, which can be used by your multiple devices*. 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_2The variables above are only for IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes. For IKEv2, see 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.
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.comYou 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_nameBy default, clients are set to use Google 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.1For more details and a list of some popular public DNS providers, see Use alternative DNS servers.
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=yesNote: 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.
Start the IPsec VPN server
Create a new Docker container from this image (replace ./vpn.env with your own env file):
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-serverIn this command, we use the -v option of docker run to create a new Docker volume 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.
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:
docker logs ipsec-vpn-serverSearch 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_passwordThe output will also include details for IKEv2 mode, if enabled.
(Optional) Backup the generated VPN login details (if any) to the current directory:
docker cp ipsec-vpn-server:/etc/ipsec.d/vpn-gen.env ./Using docker-compose
cp vpn.env.example vpn.env
# Edit vpn.env if needed, then:
docker compose up -d
docker logs ipsec-vpn-serverExample docker-compose.yml (already included):
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:roNext steps
Read this in other languages: English, 简体中文, 繁體中文, Русский.
Get your computer or device to use the VPN. Please refer to:
Configure and use IKEv2 VPN (recommended)
Configure IPsec/L2TP VPN Clients
Configure IPsec/XAuth ("Cisco IPsec") VPN Clients
Read :book: VPN book to access extra content.
Enjoy your very own VPN! :sparkles::tada::rocket::sparkles:
Important notes
Windows users: For IPsec/L2TP mode, a one-time registry change 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 or IPsec/XAuth 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. Advanced users can bind mount the env file.
For servers with an external firewall (e.g. EC2/GCE), open UDP ports 500 and 4500 for the VPN. Aliyun users, see #433.
Clients are set to use Google Public DNS when the VPN is active. If another DNS provider is preferred, read this section.
Update Docker image
To update the Docker image and container, first download the latest version:
docker pull hwdsl2/ipsec-vpn-serverIf the Docker image is already up to date, you should see:
Status: Image is up to date for hwdsl2/ipsec-vpn-server:latestOtherwise, it will download the latest version. To update your Docker container, first note your 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.
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.
First, check container logs to view details for IKEv2:
docker logs ipsec-vpn-serverNote: 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 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:
# 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 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.
# 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 -hNote: 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, then follow these instructions. 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.
# 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.shOption 2: Remove ikev2-vpn-data and re-create the container.
- Write down all your VPN login details.
- Remove the Docker container:
docker rm -f ipsec-vpn-server. - Remove the
ikev2-vpn-datavolume:docker volume rm ikev2-vpn-data. - Update your
envfile and add custom IKEv2 options such asVPN_DNS_NAMEandVPN_CLIENT_NAME, then re-create the container. Refer to How to use this image.
Advanced usage
See Advanced usage.
- Use alternative DNS servers
- Run without privileged mode
- Select VPN modes
- Enable IKEv2 perfect forward secrecy
- Access other containers on the Docker host
- Specify VPN server's public IP
- Assign static IPs to VPN clients
- Customize VPN subnets
- IPv6 support
- Split tunneling
- About host network mode
- Enable Libreswan logs
- Check server status
- Build from source code
- Bash shell inside container
- Bind mount the env file
- 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
Based on the work of Thomas Sarlandie (Copyright 2012)
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License
Attribution required: please include my name in any derivative and let me know how you have improved it!
File: docs/advanced-usage.md
Advanced Usage
- Use alternative DNS servers
- Run without privileged mode
- Select VPN modes
- Enable IKEv2 perfect forward secrecy
- Access other containers on the Docker host
- Specify VPN server's public IP
- Assign static IPs to VPN clients
- Customize VPN subnets
- IPv6 support
- Split tunneling
- About host network mode
- Enable Libreswan logs
- Check server status
- Build from source code
- Bash shell inside container
- Bind mount the env file
- Deploy Google BBR congestion control
Use alternative DNS servers
By default, clients are set to use Google 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 to re-create the Docker container. Example:
VPN_DNS_SRV1=1.1.1.1
VPN_DNS_SRV2=1.0.0.1Use 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 | 8.8.8.8 | 8.8.4.4 | Default in this project |
| Cloudflare | 1.1.1.1 | 1.0.0.1 | See also: Cloudflare for families |
| Quad9 | 9.9.9.9 | 149.112.112.112 | Blocks malicious domains |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | Blocks phishing domains, configurable. |
| CleanBrowsing | 185.228.168.9 | 185.228.169.9 | Domain filters available |
| NextDNS | Varies | Varies | Ad blocking, free tier available. Learn more. |
| Control D | Varies | Varies | Ad blocking, configurable. Learn more. |
Run without privileged mode
Advanced users can create a Docker container from this image without using privileged mode (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. 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-serverWhen 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 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.
After creating the Docker container, see Retrieve VPN login details.
Similarly, if using Docker compose, you may replace privileged: true in 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=1For more information, see compose file reference.
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 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, then run:
sed -i 's/pfs=no/pfs=yes/' /etc/ipsec.d/ikev2.confWhen finished, exit the container and restart it:
docker restart ipsec-vpn-serverAfter enabling PFS, the following client configurations must be updated:
- macOS / iOS: Re-export the client
.mobileconfigby runningdocker exec -it ipsec-vpn-server ikev2.sh --exportclient <name>and copying it to your Docker host, then edit the exported file to enable PFS:Re-import the updated file on your device.bashsed -i '/EnablePFS/{n;s/0/1/;}' <name>.mobileconfig - 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=nonetopfs-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.2Note 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.
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.2To 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.
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, then follow the steps in section "IKEv2 mode: Assign static IPs to VPN clients" of 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.2In 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.250This 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.254Note: 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 or WireGuard.
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.
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix ::/1
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix 8000::/1macOS: 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 ipsec0When 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
2or3). Link-local (fe80::/10) addresses are not sufficient. - IPv6 must be enabled for the Docker container. See Enable IPv6 support in Docker.
- 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:
{
"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.
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.
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::/64Split 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/24Note 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, 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.
Alternatively, Windows users can enable split tunneling by manually adding routes. For more details, see Split tunneling.
About host network mode
Advanced users can run this image in host network mode, 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 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 -lThen 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
exitNote: 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.logTo 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 statusShow currently established VPN connections:
docker exec -it ipsec-vpn-server ipsec trafficstatusBuild 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-serverBash 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 nanoThen run your commands inside the container. When finished, exit the container and restart if needed:
exit
docker restart ipsec-vpn-serverBind 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-serverDeploy 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. When finished, restart the Docker container:
docker restart ipsec-vpn-serverLicense
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
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License
Attribution required: please include my name in any derivative and let me know how you have improved it!
File: docs/advanced-usage-zh.md
高级用法
- 使用其他的 DNS 服务器
- 不启用 privileged 模式运行
- 选择 VPN 模式
- 启用 IKEv2 前向保密
- 访问 Docker 主机上的其它容器
- 指定 VPN 服务器的公有 IP
- 为 VPN 客户端指定静态 IP
- 自定义 VPN 子网
- IPv6 支持
- VPN 分流
- 关于 host network 模式
- 启用 Libreswan 日志
- 查看服务器状态
- 从源代码构建
- 在容器中运行 Bash shell
- 绑定挂载 env 文件
- 部署 Google BBR 拥塞控制
使用其他的 DNS 服务器
在 VPN 已连接时,客户端默认配置为使用 Google Public DNS。如果偏好其它的域名解析服务,你可以在 env 文件中定义 VPN_DNS_SRV1 和 VPN_DNS_SRV2(可选),然后按照说明重新创建 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 | 8.8.8.8 | 8.8.4.4 | 本项目默认 |
| Cloudflare | 1.1.1.1 | 1.0.0.1 | 另见:Cloudflare for families |
| Quad9 | 9.9.9.9 | 149.112.112.112 | 阻止恶意域 |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | 阻止网络钓鱼域,可配置。 |
| CleanBrowsing | 185.228.168.9 | 185.228.169.9 | 域过滤器可用 |
| NextDNS | 按需选择 | 按需选择 | 广告拦截,免费套餐可用。了解更多。 |
| Control D | 按需选择 | 按需选择 | 广告拦截,可配置。了解更多。 |
不启用 privileged 模式运行
高级用户可以在不启用 privileged 模式的情况下使用本镜像创建一个 Docker 容器(将以下命令中的 ./vpn.env 替换为你自己的 env 文件)。
注: 如果你的 Docker 主机运行 CentOS Stream, Oracle Linux 8+, Rocky Linux 或者 AlmaLinux,推荐使用 privileged 模式。如果你想要不启用 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 需要另外在 docker run 命令添加 --sysctl net.ipv4.ip_no_pmtu_disc=1 才有效。如果你遇到任何问题,可以尝试换用 privileged 模式重新创建容器。
在创建 Docker 容器之后,请转到获取 VPN 登录信息。
类似地,如果你使用 Docker compose,可以将 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。
选择 VPN 模式
在使用此 Docker 镜像时,默认启用 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式。此外,如果在创建 Docker 容器时在 docker run 命令中指定了 -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,然后运行:
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:在设备上重新导入更新后的文件。bashsed -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。
如果你想要 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",你可以在该客户端上打开浏览器并到这里检测 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,然后按照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 或 WireGuard。
Windows:通过 VPN 路由 IPv6 流量
如果你使用了 ikev2_config_import.cmd 脚本导入 IKEv2 配置,可以在提示时输入 y 以自动添加 IPv6 路由。否则,你需要在 PowerShell 窗口中运行以下命令一次,以通过 VPN 路由 IPv6 流量。将 IKEv2 VPN X.X.X.X 替换为你的 VPN 连接的实际名称。完成后,重新连接到 IKEv2 VPN。
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix ::/1
Add-VpnConnectionRoute -ConnectionName "IKEv2 VPN X.X.X.X" -DestinationPrefix 8000::/1macOS:通过 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 支持。
- Libreswan 5.0 或更新版本(Docker 镜像默认包含 5.x)。
- IPv6 仅支持 IKEv2 模式。IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式不支持 IPv6。
要为 Docker 容器启用 IPv6,首先在 Docker 宿主机上将以下内容添加到 /etc/docker/daemon.json,然后重启 Docker:
{
"ipv6": true,
"fixed-cidr-v6": "fddd:1::/64"
}然后重新创建容器。run.sh 脚本将检测容器的公共 IPv6 地址并自动配置 IPv6 支持。
要验证 IPv6 是否正常工作,请使用 IKEv2 连接到 VPN,然后检查你的 IPv6 地址,例如使用 test-ipv6.com。
现有容器注意事项: 如果你的容器中已经配置了 IKEv2(即 ikev2-vpn-data 卷中已存在 ikev2.conf),在容器重启或重新创建时 IPv6 不会自动添加到现有的 IKEv2 配置中。要为 IKEv2 启用完整的 IPv6 支持,必须移除 IKEv2 并重新配置。参见配置并使用 IKEv2 VPN 中的"移除 IKEv2"部分。
你也可以在 env 文件中设置 VPN_IP6_NET,在重新创建容器之前自定义 IPv6 地址池子网:
# 示例:为 IKEv2 模式指定自定义 IPv6 地址池子网
# 必须是 ULA 范围内的 /64 子网
VPN_IP6_NET=fddd:1234:5678:9012::/64VPN 分流
在启用 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,然后编辑 /etc/ipsec.d/ikev2.conf 并将 leftsubnet=0.0.0.0/0 替换为你想要的子网。在完成后,退出容器并运行 docker restart ipsec-vpn-server。
选项 2: 删除 Docker 容器以及 ikev2-vpn-data 卷,然后重新创建容器。这将永久删除所有的 VPN 配置。参见配置并使用 IKEv2 VPN 中的"移除 IKEv2"部分。
另外,Windows 用户也可以通过手动添加路由的方式启用 VPN 分流。有关详细信息,请参阅 VPN 分流。
关于 host network 模式
高级用户可以使用 host network 模式运行本镜像,通过为 docker run 命令添加 --network=host 参数来实现。
在非必要的情况下,不推荐使用 host network 模式运行本镜像。在该模式下,容器的网络栈未与 Docker 主机隔离,从而在使用 IPsec/L2TP 模式连接之后,VPN 客户端可以使用 Docker 主机的 VPN 内网 IP 192.168.42.1 访问主机上的端口或服务。请注意,当你不再使用本镜像时,你需要手动清理 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 内核。
详细的部署方法,可以参考这篇文档。在完成后重启 Docker 容器:
docker restart ipsec-vpn-server授权协议
注: 预构建镜像中的软件组件(例如 Libreswan 和 xl2tpd)在其各自版权所有者选择的相应许可下。对于任何预构建的镜像的使用,用户有责任确保对该镜像的任何使用符合其中包含的所有软件的任何相关许可。
版权所有 (C) 2016-2026 Lin Song
这个项目是以知识共享署名-相同方式共享3.0 许可协议授权。
必须署名: 请包括我的名字在任何衍生产品,并且让我知道你是如何改善它的!
File: docs/vpn-book.md
« Back to home page | English | 简体中文 | 繁體中文
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:
» Amazon
» Google Play
» Apple Books
» Hoopla
» Other Platforms
Other language versions: Español, Deutsch, Français, Italiano.
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:
» Amazon
» Google Play
» Apple Books
» Hoopla
» Other Platforms
Other language versions: 简体中文, 繁體中文, Español, Deutsch, Français, Italiano, Nederlands, Português, 日本語.
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:
» Amazon
» Google Play
» Apple Books
» Hoopla
» Other Platforms
Other language versions: 简体中文, 繁體中文, Español, Deutsch, Français, Italiano, 日本語.
Author page: amazon.com/author/linsong
File: docs/vpn-book-zh.md
« 返回主页 | English | 简体中文 | 繁體中文
新:Privacy Tools in the Age of AI
了解如何在人工智能时代构建更高级别的隐私保护。本书提供电子书、精装本、平装本和有声读物格式。
» Amazon
» Google Play
» Apple Books
» Hoopla
» 其他平台
其他语言版本:Español、Deutsch、Français、Italiano。
搭建自己的 VPN 服务器:IPsec VPN、OpenVPN 与 WireGuard 实战指南
本书是搭建你自己的 IPsec VPN、OpenVPN 和 WireGuard 服务器的实战指南。提供电子书和平装本格式。
» Google Play
» Apple Books
» Amazon
» Amazon 平装本
» 其他平台
其他语言版本:繁體中文、English、Español、Deutsch、Français、Italiano、Nederlands、Português、日本語。
搭建自己的 VPN 服务器:IPsec VPN、OpenVPN 与 WireGuard 完整指南
本书是搭建你自己的 IPsec VPN、OpenVPN 和 WireGuard 服务器的完整指南。提供电子书和平装本格式。
» Google Play
» Apple Books
» Amazon
» Amazon 平装本
» 其他平台
其他语言版本:繁體中文、English、Español、Deutsch、Français、Italiano、日本語。
作者页面:amazon.com/author/linsong
File: README-zh.md
English | 简体中文 | 繁體中文 | Русский
Docker 上的 IPsec VPN 服务器
使用这个 Docker 镜像快速搭建 IPsec VPN 服务器。支持 IPsec/L2TP,Cisco IPsec 和 IKEv2 协议。
本镜像以 Alpine 3.23 或 Debian 12 为基础,并使用 Libreswan (IPsec VPN 软件) 和 xl2tpd (L2TP 服务进程)。
IPsec VPN 可以加密你的网络流量,以防止在通过因特网传送时,你和 VPN 服务器之间的任何人对你的数据的未经授权的访问。在使用不安全的网络时,这是特别有用的,例如在咖啡厅,机场或旅馆房间。
功能特性:
- 首次启动时自动生成 VPN 凭证和 IKEv2 配置
- 支持具有强大和快速加密算法(例如 AES-GCM)的 IKEv2 模式
- 生成 VPN 配置文件以自动配置 iOS, macOS 和 Android 设备
- 支持 Windows, macOS, iOS, Android, Chrome OS 和 Linux 客户端
- 包括辅助脚本以管理 IKEv2 用户和证书
- 通过 GitHub Actions 自动构建和发布
- 使用 Docker 卷实现数据持久化
- 多架构支持:
linux/amd64、linux/arm64、linux/arm/v7
另提供:
- VPN:IPsec 无 Docker 版、WireGuard、OpenVPN、Headscale
- AI:自托管 AI 套件,用于本地 LLM、聊天、RAG、语音和 AI 工具
- :books: 图书:The Self-Hosted AI Builder’s Guide、Privacy Tools in the Age of AI
快速开始
使用以下命令在 Docker 上快速搭建 IPsec VPN 服务器:
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 登录信息。
另外,你也可以在不使用 Docker 的情况下安装 IPsec VPN。要了解更多有关如何使用本镜像的信息,请继续阅读以下部分。
社区
- 📬 订阅项目更新(每月 1–2 封邮件)——获取免费的 VPN 和 AI 部署指南(PDF,英文)
- 💬 加入 r/selfhostedstack 社区参与讨论
- ⭐ 如果你觉得本项目有用,请为仓库加星——这有助于让更多人发现它。
系统要求
- 具有公网 IP 地址或 DNS 名称的 Linux 服务器
- 已安装 Docker
- 在防火墙中开放 VPN 端口(UDP 500 和 4500)
- 你也可以使用 Podman 运行本镜像,需要首先为
docker命令创建一个别名
注: 高级用户可以在 macOS 上通过安装 Docker for Mac 使用本镜像。在使用 IPsec/L2TP 模式之前,你可能需要运行 docker restart ipsec-vpn-server 重启一次容器。本镜像不支持 Docker for Windows。
下载
预构建的可信任镜像可在 Docker Hub registry 下载:
docker pull hwdsl2/ipsec-vpn-server或者,你也可以从 Quay.io 下载:
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 编译源代码。
镜像对照表
有两个预构建的镜像可用。默认的基于 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 版本 5,它是本项目的默认版本。但是,如果你想要使用较旧版本的 Libreswan 版本 4,你可以从源代码构建 Docker 镜像:
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_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。
注: 在你的 env 文件中,不要为变量值添加 "" 或者 '',或在 = 两边添加空格。不要在值中使用这些字符: \ " '。一个安全的 IPsec PSK 应该至少包含 20 个随机字符。
注: 如果在创建 Docker 容器后修改 env 文件,则必须删除并重新创建容器才能使更改生效。参见更新 Docker 镜像。
其他环境变量
高级用户可以指定一个域名,客户端名称和/或另外的 DNS 服务器。这是可选的。
了解如何指定一个域名,客户端名称和/或另外的 DNS 服务器。
高级用户可以指定一个域名作为 IKEv2 服务器地址。这是可选的。该域名必须是一个全称域名 (FQDN)。示例如下:
VPN_DNS_NAME=vpn.example.com你可以指定第一个 IKEv2 客户端的名称。该名称不能包含空格或者除 - _ 之外的任何特殊字符。如果未指定,则使用默认值 vpnclient。
VPN_CLIENT_NAME=your_client_name在 VPN 已连接时,客户端默认配置为使用 Google Public DNS。你可以为所有的 VPN 模式指定另外的 DNS 服务器。示例如下:
VPN_DNS_SRV1=1.1.1.1
VPN_DNS_SRV2=1.0.0.1有关详细信息以及一些流行的公共 DNS 提供商的列表,参见使用其他的 DNS 服务器。
默认情况下,导入 IKEv2 客户端配置时不需要密码。你可以选择使用随机密码保护客户端配置文件。
VPN_PROTECT_CONFIG=yes注: 如果在 Docker 容器中已经配置了 IKEv2,则以上变量对 IKEv2 模式无效。在这种情况下,你可以移除 IKEv2 并使用自定义选项重新配置它。参见配置并使用 IKEv2 VPN。
运行 IPsec VPN 服务器
使用本镜像创建一个新的 Docker 容器(将 ./vpn.env 替换为你自己的 env 文件):
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 卷,并且将它挂载到容器内的 /etc/ipsec.d 目录下。IKEv2 的相关数据(比如证书和密钥)在该卷中保存,之后当你需要重新创建 Docker 容器的时候,只需指定同一个卷。
推荐在使用本镜像时启用 IKEv2。如果你不想启用 IKEv2 而仅使用 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 模式连接到 VPN,可以去掉上面 docker run 命令中的第一个 -v 选项。
注: 高级用户也可以不启用 privileged 模式运行。
获取 VPN 登录信息
如果你在上述 docker run 命令中没有指定 env 文件,VPN_USER 会默认为 vpnuser,并且 VPN_IPSEC_PSK 和 VPN_PASSWORD 会被自动随机生成。要获取这些登录信息,可以查看容器的日志:
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 登录信息(如果有)到当前目录:
docker cp ipsec-vpn-server:/etc/ipsec.d/vpn-gen.env ./使用 docker-compose
cp vpn.env.example vpn.env
# 如果需要,编辑 vpn.env,然后:
docker compose up -d
docker logs ipsec-vpn-server示例 docker-compose.yml(已包含在内):
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, 简体中文, 繁體中文, Русский。
配置你的计算机或其它设备使用 VPN。请参见:
配置 IPsec/XAuth ("Cisco IPsec") VPN 客户端
阅读 :book: VPN book 以访问额外内容。
开始使用自己的专属 VPN! :sparkles::tada::rocket::sparkles:
重要提示
Windows 用户 对于 IPsec/L2TP 模式,在首次连接之前需要修改注册表,以解决 VPN 服务器或客户端与 NAT(比如家用路由器)的兼容问题。
同一个 VPN 账户可以在你的多个设备上使用。但是由于 IPsec/L2TP 的局限性,如果需要连接在同一个 NAT(比如家用路由器)后面的多个设备,你必须使用 IKEv2 或者 IPsec/XAuth 模式。
如需添加,修改或者删除 VPN 用户账户,首先更新你的 env 文件,然后你必须按照下一节的说明来删除并重新创建 Docker 容器。高级用户可以绑定挂载 env 文件。
对于有外部防火墙的服务器(比如 EC2/GCE),请为 VPN 打开 UDP 端口 500 和 4500。阿里云用户请参见 #433。
在 VPN 已连接时,客户端配置为使用 Google Public DNS。如果偏好其它的域名解析服务,请看这里。
更新 Docker 镜像
要更新 Docker 镜像和容器,首先下载最新版本:
docker pull hwdsl2/ipsec-vpn-server如果 Docker 镜像已经是最新的,你会看到提示:
Status: Image is up to date for hwdsl2/ipsec-vpn-server:latest否则将会下载最新版本。要更新你的 Docker 容器,首先记下你所有的 VPN 登录信息。然后删除 Docker 容器: docker rm -f ipsec-vpn-server。最后按照如何使用本镜像的说明来重新创建它。
配置并使用 IKEv2 VPN
IKEv2 模式是比 IPsec/L2TP 和 IPsec/XAuth ("Cisco IPsec") 更佳的连接模式,该模式无需 IPsec PSK, 用户名或密码。更多信息请看这里。
首先,查看容器的日志以获取 IKEv2 配置信息:
docker logs ipsec-vpn-server注: 如果你无法找到 IKEv2 配置信息,IKEv2 可能没有在容器中启用。尝试按照更新 Docker 镜像一节的说明更新 Docker 镜像和容器。
在 IKEv2 安装过程中会创建一个 IKEv2 客户端(默认名称为 vpnclient),并且导出它的配置到 容器内 的 /etc/ipsec.d 目录下。你可以将配置文件复制到 Docker 主机:
# 查看容器内的 /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 ./下一步: 配置你的设备以使用 IKEv2 VPN。
了解如何管理 IKEv2 客户端。
你可以使用辅助脚本管理 IKEv2 客户端。示例如下。如需自定义客户端选项,可以在不添加参数的情况下运行脚本。
# 添加一个客户端(使用默认选项)
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,然后按照这里的说明操作。请注意,容器的日志在你重启 Docker 容器之前将不显示新的 IKEv2 服务器地址。
移除 IKEv2 并使用自定义选项重新配置。
在某些情况下,你可能需要移除 IKEv2 并使用自定义选项重新配置它。
警告: 这将永久删除所有的 IKEv2 配置(包括证书和密钥),并且不可撤销!
选项 1: 使用辅助脚本移除 IKEv2 并重新配置。
请注意,这将覆盖你在 env 文件中指定的变量,例如 VPN_DNS_NAME 和 VPN_CLIENT_NAME,并且容器的日志将不再显示 IKEv2 的最新信息。
# 移除 IKEv2 并删除所有的 IKEv2 配置
docker exec -it ipsec-vpn-server ikev2.sh --removeikev2
# 使用自定义选项重新配置 IKEv2
docker exec -it ipsec-vpn-server ikev2.sh选项 2: 移除 ikev2-vpn-data 并重新创建容器。
- 在纸上记下你所有的 VPN 登录信息。
- 删除 Docker 容器:
docker rm -f ipsec-vpn-server。 - 删除
ikev2-vpn-data卷:docker volume rm ikev2-vpn-data。 - 更新你的
env文件并添加自定义 IKEv2 选项,例如VPN_DNS_NAME和VPN_CLIENT_NAME,然后重新创建容器。参见如何使用本镜像。
高级用法
请参见高级用法。
- 使用其他的 DNS 服务器
- 不启用 privileged 模式运行
- 选择 VPN 模式
- 启用 IKEv2 前向保密
- 访问 Docker 主机上的其它容器
- 指定 VPN 服务器的公有 IP
- 为 VPN 客户端指定静态 IP
- 自定义 VPN 子网
- IPv6 支持
- VPN 分流
- 关于 host network 模式
- 启用 Libreswan 日志
- 查看服务器状态
- 从源代码构建
- 在容器中运行 Bash shell
- 绑定挂载 env 文件
- 部署 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
基于 Thomas Sarlandie 的工作 (版权所有 2012)
这个项目是以知识共享署名-相同方式共享3.0 许可协议授权。
必须署名: 请包括我的名字在任何衍生产品,并且让我知道你是如何改善它的!