robonuka/openvpn

By robonuka

Updated 20 days ago

Debian 13.5 + OpenVPN 2.7.5-trixie1 + EasyRSA 3.2.2-1 + OpenSSL 3.5.6-1~deb13u2 + LZO 2.10-3+b1

Image
Security
3

10K+

robonuka/openvpn repository overview

OpenVPN server

It is yet another docker version of OpenVPN server with some conveniences

Homepage of sources: https://openvpn.net/community-downloads/

Base OS for Docker image till 2.14.x is Alpine Linux (Egde)

Base OS for Docker image since 2.16.x is Debian 13 (Trixie)

The reasons are: PKCS11 and DCO modules absence in Alpine's OpenVPN and whole unstable situation with OpenVPN package building in Alpine Linux at all.

ALPINE:
OpenVPN 2.6.16 x86_64-alpine-linux-musl [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD]

DEBIAN:
OpenVPN 2.6.16 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]

This docker image has some scripts for simplifying ordinary Easy-RSA tasks.

Install and run OpenVPN server

To make a permanent docker volume for storing any OpenVPN and Easy-RSA CA settings and data please create the /opt/openvpn folder on the host of your OpenVPN server, and put this docker-compose.yml file anywhere you want in this host:

Many variables of this example has default values. You should reassign them with your needs before start the container!

services:
  openvpn:
    container_name: openvpn
    image: robonuka/openvpn:latest
    restart: unless-stopped
    network_mode: 'host'
    privileged: true
    ulimits:
      memlock:
        soft: -1
        hard: -1
    environment:
      - 'TUNX=tun0'
      - 'PROTOCOL=tcp4'
      - 'PORT=1194'
      - 'EASYRSA_ALGO=ed'
      - 'TLS_VERSION_MIN=1.3'
      - 'TLS_CIPHERSUITES=TLS_AES_256_GCM_SHA384'
      - 'DATA_CIPHERS=AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305'
      - 'DATA_CIPHERS_FALLBACK=AES-256-CBC'
      - 'AUTH=SHA256'
      - 'MAXCLIENTS=253'
      - 'SERVER_ADDR_PORT=example.com 1194'
      - 'SUBNET=10.8.0.0'
      - 'NETMASK=255.255.255.0'
      - 'DNS1=8.8.8.8'
      - 'DNS2=1.1.1.1'
      - 'KEY_COUNTRY=XX'
      - 'KEY_PROVINCE=XX'
      - 'KEY_CITY=XX'
      - 'KEY_ORG=XX'
      - '[email protected]'
      - 'KEY_OU=xxx'
      - 'CA_EXPIRE=3650'
      - 'CERT_EXPIRE=3650'
      - 'CRL_DAYS=3650'
      - 'VERB=4'
      - 'MUTE=20'
      - 'MANAGEMENT_IP=localhost'
      - 'MANAGEMENT_PORT=7505'
      - 'MANAGEMENT_PW_FILE=/etc/openvpn/server.pass'
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /opt/openvpn:/etc/openvpn

Then run docker container as usually:

cd /opt && sudo docker compose up -d openvpn

See the log of docker container with command:

sudo docker logs -f openvpn

OpenVPN server log file will be stored in: /opt/openvpn/server.log

Important notes:
  1. OpenVPN server re-generate it's server.conf file everytime when you start the container.
  2. If you want to use your own/custom server.conf file you should add # symbol in begin of the 1st line of your server.conf file.

Docker container environment variables description

Environment variableDetailsDefault value
TUNXSpecify TUN-device. For example: tun0 or tun23 If the variable value is not specified, then the server config file will contain the line dev tunN/A
PROTOCOLUse protocol udp4 or tcp4 for communicating with remote host.udp4
PORTSet OpenVPN server TCP/UDP port number1194
DISABLE_DCOActivate/Deactivate DCO-featuretrue
TCP_QUEUE_LIMITMaximum number of output packets queued before TCP. When OpenVPN is tunneling data from a TUN/TAP device to a remote client over a TCP connection, it is possible that the TUN/TAP device might produce data at a faster rate than the TCP connection can support. When the number of output packets queued before sending to the TCP socket reaches this limit for a given client connection, OpenVPN will start to drop outgoing packets directed at this client.
Works with tcp4 protocol only!
256
KEEPALIVEA helper directive designed to simplify the expression of --ping and --ping-restart. This option can be used on both client and server side, but it is enough to add this on the server side as it will push appropriate --ping and --ping-restart options to the client. If used on both server and client, the values pushed from server will override the client local values. The timeout argument will be twice as long on the server side. This ensures that a timeout is detected on client side before the server side drops the connection.10 30
USE_DHTo use yes or not no DH key fileno
DH_KEY_SIZEKey length in bits for DH key file. Should be 2048, 3072, 4096 и 81922048
DATA_CIPHERSSet the data channel ciphers list.
Show list of supported data channel ciphers:
docker exec openvpn openvpn --show-ciphers
AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
DATA_CIPHERS_FALLBACKSet a single data channel cipher name for dummy OpenVPN clients which can't recognize no one of data channel ciphers specified above.AES-256-CBC
TLS_VERSION_MINEnforce a minimum TLS version1.0
TLS_VERSION_MAXRestrict a maximum TLS version1.3
TLS_CIPHERSUITESSet a list of ciphers for tls-auth connection.
Show list of supported TLS-ciphers:
docker exec openvpn openvpn --show-tls
TLS_AES_256_GCM_SHA384
TLS_AUTH_METHODSet tls-auth method: TA or CRYPT_V2CRYPT_V2
AUTHAuthenticate data channel packets and (if enabled) tls-auth control channel packets with HMAC using message digest algorithm alg. (The default is SHA1 ). HMAC is a commonly used message authentication algorithm (MAC) that uses a data string, a secure hash algorithm, and a key, to produce a digital signature.The OpenVPN data channel protocol uses encrypt-then-mac (i.e. first encrypt a packet, then HMAC the resulting ciphertext), which prevents padding oracle attacks.
Show list of supported HMAC digests:
docker exec openvpn openvpn --show-digests
SHA256
TUN_MTUTake the TUN device MTU to be n bytes and derive the link MTU from it. In most cases, you will probably want to leave this parameter set to its default value.The MTU (Maximum Transmission Units) is the maximum datagram size in bytes that can be sent unfragmented over a particular network path. OpenVPN requires that packets on the control or data channels be sent unfragmented.1500
TUN_MTU_EXTRAAssume that the TUN/TAP device might return as many as n bytes more than the --tun-mtu size on read. This parameter defaults to 0, which is sufficient for most TUN devices. TAP devices may introduce additional overhead in excess of the MTU size, and a setting of 32 is the default when TAP devices are used. This parameter only controls internal OpenVPN buffer sizing, so there is no transmission overhead associated with using a larger value.0
TXQUEUELENSet the TX queue length in bytes on the TUN/TAP interface.1000
MSSFIXWill try to keep TCP from needing packet fragmentation in the first place, and if big packets come through anyhow (from protocols other than TCP). Option only makes sense when you are using the UDP protocol for OpenVPN peer-to-peer communication.1450
SNDBUFSet the TCP/UDP socket send buffer size in bytes. Defaults to operation system default.524288
RCVBUFSet the TCP/UDP socket receive buffer size in bytes. Defaults to operation system default.524288
CLIENT_TO_CLIENTBecause the OpenVPN server mode handles multiple clients through a single tun or tap interface, it is effectively a router. The --client-to-client flag tells OpenVPN to internally route client-to-client traffic rather than pushing all client-originating traffic to the TUN/TAP interface.When this option is used, each client will "see" the other clients which are currently connected. Otherwise, each client will only see the server. Don't use this option if you want to firewall tunnel traffic using custom, per-client rules. Allowed: yes or no.yes
DUPLICATE_CNAllow multiple clients with the same common name to concurrently connect. In the absence of this option, OpenVPN will disconnect a client instance upon connection of a new client having the same common name. Allowed: yes or no.no
MAXCLIENTSLimit server to a maximum of n concurrent clients.253
SERVER_POLL_TIMEOUTWhen connecting to a remote server do not wait for more than N seconds for a response before trying the next server. The default value is 120. This timeout includes proxy and TCP connect timeouts.N/A
CONNECT_TIMEOUTIs the same as SERVER_POLL_TIMEOUTN/A
CONNECT_RETRY_MAXN specifies the number of times each --remote or entry is tried. Specifying N as 1 would try each entry exactly once. A successful connection resets the counter. (default unlimited).N/A
SERVER_ADDR_PORTSet address/hostname and port by which OpenVPN server assigned for OpenVPN clients. Used while generating client's .ovpn file by docker exec openvpn gen ... command.example.com 1194
SUBNETSet up an OpenVPN server subnet which will allocate addresses to clients out of the given network. The server itself will take the ".1" address of the given network for use as the server-side endpoint of the local TUN/TAP interface.10.8.0.0
NETMASKSet up an OpenVPN server netmask of the given subnet above.255.255.255.0
DNS1Set the primary DNS server address pushing to OpenVPN clients.8.8.8.8
DNS2Set the secondary DNS server address pushing to OpenVPN clients.1.1.1.1
KEY_COUNTRYSet the DN country with org mode.US
KEY_PROVINCESet the DN state/province with org mode.N/A
KEY_CITYSet the DN city/locality with org mode.San Francisco
KEY_ORGSet the DN organization with org mode.Fort-Funston
KEY_EMAILSet the DN email with org mode.[email protected]
KEY_OUSet the DN organizational unit with org mode.MyOrganizationalUnit
KEY_SIZESet the keysize in bits to generate.2048
EASYRSA_ALGOSet the crypto alg to use: rsa, ec or edrsa
CA_EXPIRESet the CA expiration time in days.3650
CERT_EXPIRESet the issued cert expiration time in days.3650
CRL_DAYSSet the CRL 'next publish' time in days.3650
CLIENT_CONFIG_DIRSpecify a directory dir for custom client config files. After a connecting client has been authenticated, OpenVPN will look in this directory for a file having the same name as the client's X509 common name. If a matching file exists, it will be opened and parsed for client-specific configuration options. If no matching file is found, OpenVPN will instead try to open and parse a default file called "DEFAULT", which may be provided but is not required. Note that the configuration files must be readable by the OpenVPN process after it has dropped it's root privileges.
This file can specify a fixed IP address for a given client using --ifconfig-push, as well as fixed subnets owned by the client using --iroute.
One of the useful properties of this option is that it allows client configuration files to be conveniently created, edited, or removed while the server is live, without needing to restart the server.
The following options are legal in a client-specific context: --push, --push-reset, --push-remove, **--iroutev, --ifconfig-push, and --config.
/etc/openvpn/ccd
IFCONFIG_POOL_PERSISTPersist/unpersist ifconfig-pool data to file, at seconds intervals, as well as on program startup and shutdown. The goal of this option is to provide a long-term association between clients (denoted by their common name) and the virtual IP address assigned to them from the ifconfig-pool. Maintaining a long-term association is good for clients because it allows them to effectively use the --persist-tun option. File is a comma-delimited ASCII file, formatted as <Common-Name>,<IP-address>. If seconds = 0, file will be treated as read-only. This is useful if you would like to treat file as a configuration file. Note that the entries in this file are treated by OpenVPN as suggestions only, based on past associations between a common name and IP address. They do not guarantee that the given common name will always receive the given IP address. If you want guaranteed assignment, use --ifconfig-push/etc/openvpn/ipp.txt 600
STATUS_FILEWrite operational status to file every n seconds.
Status can also be written to the syslog by sending a SIGUSR2 signal.
With multi-client capability enabled on a server, the status file includes a list of clients and a routing table. The output format can be controlled by the --status-version option in that case.For clients or instances running in point-to-point mode, it will contain the traffic statistics.
/etc/openvpn/server.status 30
STATUS_VERSIONSet the status file format version number to n. This only affects the status file on servers with multi-client capability enabled.
1 - traditional format (default). The client list contains the following fields comma-separated: Common Name, Real Address, Bytes Received, Bytes Sent, Connected Since.
2 - a more reliable format for external processing. Compared to version 1, the client list contains some additional fields: Virtual Address, Virtual IPv6 Address, Username, Client ID, Peer ID. Future versions may extend the number of fields.
3 - identical to 2, but fields are tab-separated.
2
LOGAppend logging messages to file. If file does not exist, it will be created./etc/openvpn/server.log
VERBSet output verbosity to n (default=1).
Each level shows all info from the previous levels.
Level 3 is recommended if you want a good summary of what's happening without being swamped by output.
0 - No output except fatal errors.
1 to 4 - Normal usage range.
5 - Output R and W characters to the console for each packet read and write, uppercase is used for TCP/UDP packets and lowercase is used for TUN/TAP packets.
6 to 11 - Debug info range (see errlevel.h for additional information on debug levels).
1
MUTELog at most n consecutive messages in the same category. This is useful to limit repetitive logging of similar message types.20
MANAGEMENT_IPSet a management server listening addresslocalhost
MANAGEMENT_PORTSet a management server listening port7505
MANAGEMENT_PW_FILESet a management server full path to the password file/etc/openvpn/server.pass
TMP_DIRSpecify a directory for temporary files. This directory will be used by openvpn processes and script to communicate temporary data with openvpn main process. Note that the directory must be writable by the OpenVPN process after it has dropped it's root privileges.
This directory will be used by in the following cases:
- client-connect scripts to dynamically generate client-specific configuration files.
- OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY plugin hook to return success/failure via auth_control_file when using deferred auth method
- OPENVPN_PLUGIN_ENABLE_PF plugin hook to pass filtering rules via pf_file
/tmp
FIREWALL_RULESSet this option as manual will stop automatic adding firewall rules every time you run openvpn container.N/A

Commands to simple manage OpenVPN clients

All commands below should be run in OpenVPN server host where is docker container working!

Show help info about available commands
sudo docker exec openvpn help
Show userlist
sudo docker exec openvpn list [full]

Optional parameter full adds two columns in list:
1 - User's private key crypto algorhytm name.
2 - User's certificate full path inside Easy-RSA CA.

New user creation
sudo docker exec -ti [-e 'EASYRSA_ALGO=<rsa|ec|ed>'] openvpn create <new_username> [days]
  1. With optional parameter -e 'EASYRSA_ALGO=<rsa|ec|ed>' you can temporarily re-define value of EASYRSA_ALGO variable specified in docker-compose.yml. For example, if you need to encrypt new user's private key with other crypto algorythm without changing docker-compose.yml and restarting OpenVPN server to apply changes.
  2. With optional parameter days you can temporarily re-define value of CERT_EXPIRE variable specified in docker-compose.yml.
    If you specify a number of days greater than days left to expire the server certificate - your number of days will be rewrited with number of days left to expire the server certificate.

Important notes:

  1. Users private keys are stored encryped in СА. Private key encryption occurs while you creating a new user. You'll be asked about entering passphrase for private key encryption: Enter PEM pass phrase: and then again: Verifying - Enter PEM pass phrase:
    Advice to save entered passphrases in safe place. Each new user have to know his own private key passhrase when you'll send his personal .ovpn file to him.
    You should revoke user's certificate from CA immediately if you suspect that user's private key passphrase was compromised! Then investigate the reasons why private key passphrase was compromised, then fix these reasons and only then re-create this user again with a new private key passphrase.
  2. You can create a new user only if there are no the same usernames exist in CA in active state.
  3. In the usernames allowing only lowercase latin alphanumeric charaters, dots, dashes and underscores.
Get user's personal .ovpn file
sudo docker exec openvpn get <tls_auth_method> <active_username> [key-passphrase]
  1. Parameter tls_auth_method should be ta or crypt_v2. OpenVPN server supports both methods simultaneously. New method crypt_v2 is more secure than the old one ta.
  2. Parameter active_username should contains existing in the CA username with active state.
  3. Optional parameter key-passphrase will store decripted user's private key inside .ovpn. It is not recommended in most of cases, because security risks will increase , but sometimes it may be only way to user. For example, in case of using non-interactive OpenVPN clients.

Important notes:

  1. You can't get .ovpn file for username server.
  2. You can't get .ovpn file for any not exists or revoked user.
Revoke user's certificate from CA
sudo docker exec -ti openvpn revoke <active_username>

It may need if you suspect that user's private key passphrase was compromised or if you just decide that this user is not welcomed on your OpenVPN server anymore.

Important notes:

  1. You can't revoke the OpenVPN server's certificate.
  2. You can't revoke certificate of an absent or already revoked user.
Renew user's certificate
sudo docker exec openvpn renew <active/expired_username> [days]
  1. User's certificate renewing may be need when it has expired, almost expired or you just decide to change the expiration days number for this user's certificate.
  2. With optional parameter days you can temporarily re-define value of CERT_EXPIRE variable specified in docker-compose.yml.
    If you specify a number of days greater than days left to expire the server certificate - your number of days will be rewrited with number of days left to expire the server certificate.

Important notes:

  1. You can't renew the OpenVPN server's certificate.
  2. You can't renew certificate of an absent or already revoked user.
  3. Renewing process will use the existing user's private key file. So you can't change private key encryption apgorhytm when you doing certificate renewing.
  4. Certificate renewing process won't ask you about user's private key passphrase.

Tag summary

Content type

Image

Digest

sha256:57e636c38

Size

39.3 MB

Last updated

20 days ago

docker pull robonuka/openvpn