openvpn搭建及使用配置之管理接口Management Interface

OpenVPN 管理界面注意事项

OpenVPN 管理界面允许 OpenVPN
通过外部程序进行管理控制
TCP 或 unix 域套接字。

该界面专为开发人员设计
谁想以编程方式或远程控制
一个 OpenVPN 守护进程,可以在 OpenVPN 运行时使用
作为客户端或服务器。

管理接口使用客户端/服务器 TCP 实现
OpenVPN 将在其中侦听的连接或 unix 域套接字
为传入的管理客户端连接提供了 IP 地址和端口。

管理协议目前是明文,没有明确的
安全层。为此,建议
管理接口要么监听 Unix 域套接字,
localhost (127.0.0.1),或本地 VPN 地址。这是可能的
通过 VPN 本身远程连接到管理界面,
尽管在此模式下某些功能会受到限制,例如
提供私钥密码的能力。

在 OpenVPN 中启用了管理界面
使用以下指令的配置文件:

  • 管理

有关此和相关的文档,请参见手册页
指令。

一旦 OpenVPN 启动并启用管理层,
您可以远程登录到管理端口(确保使用
理解“原始”模式的 telnet 客户端)。

连接到管理端口后,您可以使用
“帮助”命令列出所有命令。

命令 – bytecount

bytecount 命令用于请求实时通知
OpenVPN 带宽使用情况。

命令语法:

bytecount n (where n > 0) – set up automatic notification of
bandwidth usage once every n seconds
bytecount 0 – turn off bytecount notifications

如果 OpenVPN 作为客户端运行,字节计数通知
看起来像这样:

BYTECOUNT:{BYTES_IN},{BYTES_OUT}

BYTES_IN 是已收到的字节数
服务器和 BYTES_OUT 是已发送的字节数
发送到服务器。

如果 OpenVPN 作为服务器运行,字节计数通知
看起来像这样:

BYTECOUNT_CLI:{CID},{BYTES_IN},{BYTES_OUT}

CID 是客户端 ID,BYTES_IN 是拥有的字节数
从客户端收到,BYTES_OUT 是
已发送到客户端的字节数。

请注意,当在服务器上使用 bytecount 命令时,每个
连接的客户端将每 n 一次报告其带宽数
秒。

当客户端断开连接时,最终带宽数将为
放置在 ‘bytes_received’ 和 ‘bytes_sent’ 环境变量中
包含在 >CLIENT:DISCONNECT 通知中。

COMMAND – echo

回声功能用于允许特定于 GUI
嵌入在 OpenVPN 配置文件中的参数
或从服务器推送到 OpenVPN 客户端。

命令示例:

echo on – turn on real-time notification of echo messages
echo all – print the current echo history list
echo off – turn off real-time notification of echo messages
echo on all – atomically enable real-time notification,
plus show any messages in history buffer

例如,假设您正在开发 OpenVPN GUI,并且
你想让 OpenVPN 服务器能够询问
GUI 忘记任何保存的密码。

在 OpenVPN 服务器配置文件中,添加:

push “echo forget-passwords”

当 OpenVPN 客户端收到其拉取的指令列表时
从服务器,“echo forget-passwords”指令将
在列表中,会导致管理界面
将“忘记密码”字符串保存在其 echo 列表中
参数。

管理客户端可以使用“echo all”输出完整的
回显参数列表,“回显”实时开启
通过 “>ECHO:” 前缀通知回显参数,
或“回声关闭”关闭实时通知。

当 GUI 连接到 OpenVPN 管理套接字时,它
可以发出“echo all”命令,该命令将产生输出
像这样:

1101519562,forget-passwords
END

本质上,echo 命令允许我们从
OpenVPN 服务器到 OpenVPN 客户端,然后到
管理客户端(例如 GUI)。 大整数是
收到 echo 参数的 unix 日期/时间。

如果管理客户端发出了命令“echo on”,
它将启用回声的实时通知
参数。 在这种情况下,我们的“忘记密码”消息
会像这样输出:

ECHO:1101519562,forget-passwords

和 log 命令一样,echo 命令可以原子地显示
历史记录,同时激活实时更新:

echo on all

回显缓冲区的大小目前被硬编码为 100
消息。

COMMAND – exit, quit

关闭管理会话,然后继续收听
用于来自其他客户端的连接的管理端口。 目前,
OpenVPN 守护进程最多可以支持单个管理客户端
任何时候。

COMMAND – help

打印命令摘要。

COMMAND – hold

保持命令可用于操作保持标志,
或从保持状态释放 OpenVPN。

如果在初始启动时设置了保持标志或
重启,OpenVPN 将在初始化之前休眠
隧道直到管理接口收到
“保持释放”命令。

可以使用 OpenVPN 的 --management-hold 指令
以设置保持标志启动 OpenVPN。

保持标志设置是持久的,不会
通过重新启动来重置。

OpenVPN 将通过以下方式指示它处于保持状态
向管理层发送实时通知
客户:

HOLD:Waiting for hold release

Command examples:

hold – show current hold flag, 0=off, 1=on.
hold on – turn on hold flag so that future restarts
will hold.
hold off – turn off hold flag so that future restarts will
not hold.
hold release – leave hold state and start OpenVPN, but
do not alter the current hold flag setting.

COMMAND – kill

在服务器模式下,杀死一个特定的客户端实例。
命令示例:

kill Test-Client – kill the client instance having a
common name of “Test-Client”.
kill 1.2.3.4:4000 – kill the client instance having a
source address and port of 1.2.3.4:4000

使用“status”命令查看连接了哪些客户端。

COMMAND – log

显示 OpenVPN 日志文件。 只有最近的 n 行
的日志文件由管理接口缓存,其中
n 由 OpenVPN --management-log-cache 指令控制。

Command examples:

log on – Enable real-time output of log messages.
log all – Show currently cached log file history.
log on all – Atomically show all currently cached log file
history then enable real-time notification of
new log file messages.
log off – Turn off real-time notification of log messages.
log 20 – Show the most recent 20 lines of log file history.

实时通知格式:

实时日志消息以“>LOG:”前缀开头
通过以下逗号分隔的字段:

(a) unix integer date/time,
(b) zero or more message flags in a single string:
I – informational
F – fatal error
N – non-fatal error
W – warning
D – debug, and
(c) message text.

COMMAND – mute

更改 OpenVPN --mute 参数。 静音参数是
用于使同一消息的重复消息静音
类别。

命令示例:

mute 40 – change the mute parameter to 40
mute – show the current mute setting

COMMAND – net

(仅限 Windows)产生与 OpenVPN 等效的输出
–show-net 指令。 输出包括 OpenVPN 的视图
基于系统网络适配器列表和路由表的
Windows IP 帮助程序 API 返回的信息。

COMMAND – pid

显示当前 OpenVPN 进程的进程 ID。

COMMAND – password and username

password 命令用于将密码传递给 OpenVPN。

如果 OpenVPN 使用 --management-query-passwords 运行
指令,它将查询 RSA 的管理接口
私钥密码和 --auth-user-pass
用户名密码。

当 OpenVPN 需要来自管理界面的密码时,
它将产生一个实时的“>密码:”消息。

示例 1:

>PASSWORD:Need 'Private Key' password

OpenVPN 表明它需要密码类型
“私钥”。

管理客户端应按如下方式响应此查询:

password "Private Key" foo

Example 2:

>PASSWORD:Need 'Auth' username/password

OpenVPN 需要一个 --auth-user-pass 密码。 管理
客户应回复:

username "Auth" foo
password "Auth" bar

用户名/密码本身可以用引号括起来,并且可以是特殊的
双引号或反斜杠等字符必须转义,
例如,

password "Private Key" "foo\"bar"

转义规则与配置文件相同。
有关详细信息,请参阅下面的“命令解析”部分。

PASSWORD 实时消息类型也可用于
指示密码或其他类型的身份验证失败:

例3:私钥密码不正确,OpenVPN
正在退出:

>PASSWORD:Verification Failed: 'Private Key'

示例 4:–auth-user-pass 用户名/密码失败,
并且 OpenVPN 正在退出:

>PASSWORD:Verification Failed: 'Auth'

示例 5:–auth-user-pass 用户名/密码失败,
并且服务器提供了一个自定义的客户端原因文本字符串
使用客户端拒绝服务器端管理接口命令。

>PASSWORD:Verification Failed: 'custom server-generated string'

COMMAND – forget-passwords

忘记密码命令将导致守护程序忘记密码
在会话期间输入。

命令示例:

forget-passwords – forget passwords entered so far.

COMMAND – signal

signal 命令将向 OpenVPN 守护程序发送信号。
该信号可以是 SIGHUP、SIGTERM、SIGUSR1 或 SIGUSR2 之一。

命令示例:

signal SIGUSR1 – send a SIGUSR1 signal to daemon

COMMAND – state

显示当前 OpenVPN 状态,显示状态历史,或
启用状态更改的实时通知。

这些是 OpenVPN 状态:

CONNECTING – OpenVPN’s initial state.
WAIT – (Client only) Waiting for initial response
from server.
AUTH – (Client only) Authenticating with server.
GET_CONFIG – (Client only) Downloading configuration options
from server.
ASSIGN_IP – Assigning IP address to virtual network
interface.
ADD_ROUTES – Adding routes to system.
CONNECTED – Initialization Sequence Completed.
RECONNECTING – A restart has occurred.
EXITING – A graceful exit is in progress.

Command examples:

state – Print current OpenVPN state.
state on – Enable real-time notification of state changes.
state off – Disable real-time notification of state changes.
state all – Print current state history.
state 3 – Print the 3 most recent state transitions.
state on all – Atomically show state history while at the
same time enable real-time state notification
of future state transitions.

输出格式由 4 个逗号分隔的参数组成:
(a) 整数 unix 日期/时间,
(b) 州名,
(c) 可选的描述性字符串(主要用于 RECONNECTING
和 EXITING 以显示断开连接的原因),
(d) 可选的 TUN/TAP 本地 IP 地址(显示为 ASSIGN_IP
和连接),和
(e) 远程服务器的可选地址(OpenVPN 2.1 或更高版本)。

实时状态通知将带有“>STATE:”前缀
放在他们面前。

COMMAND – status

显示当前守护进程状态信息,格式与
由 OpenVPN --status 指令产生的。

命令示例:

status – 使用默认状态显示状态信息
格式版本。

status 3 – 使用以下格式显示状态信息
–status-版本 3。

COMMAND – username

See the “password” section above.

COMMAND – verb

更改 OpenVPN --verb 参数。 动词参数
控制输出的详细程度,范围为 0(无输出)
至 15(最大输出)。 有关其他信息,请参阅 OpenVPN 手册页
有关详细程度的信息。

命令示例:

verb 4 – change the verb parameter to 4
mute – show the current verb setting

COMMAND – version

显示当前的 OpenVPN 和管理界面版本。

COMMAND – auth-retry

设置 --auth-retry 设置来控制 OpenVPN 如何响应
用户名/密码验证错误。 请参阅手册页
了解更多信息。

命令示例:

auth-retry interact – 输入错误的用户名/密码时不要退出。
查询新输入并重试。

COMMAND – needok (OpenVPN 2.1 or higher)

确认“NEED-OK”实时通知,通常由
OpenVPN 在等待特定用户操作时进行阻止。

例子:

OpenVPN 需要用户插入一个加密令牌,
所以它发送一个实时通知:

>NEED-OK:Need 'token-insertion-request' confirmation MSG:Please insert your cryptographic token

管理客户端,如果是 GUI,可以闪现一个对话框
包含“MSG:”标记后的文本的框给用户。
当用户确认对话框时,
管理客户端可以发出以下命令:

 needok token-insertion-request ok
 or
 needok token-insertion-request cancel

COMMAND – needstr (OpenVPN 2.1 or higher)

确认“NEED-STR”实时通知,通常由
OpenVPN 在等待特定用户输入时进行阻止。

例子:

OpenVPN 需要用户指定一些输入,所以它发送一个
实时通知:

>NEED-STR:Need 'name' input MSG:Please specify your name

管理客户端,如果是 GUI,可以闪现一个对话框
包含“MSG:”标记后的文本的框给用户。
当用户确认对话框时,
管理客户端可以发出以下命令:

 needstr name "John"

COMMAND – pkcs11-id-count (OpenVPN 2.1 or higher)

检索可用的证书数量。

例子:

 pkcs11-id-count
 >PKCS11ID-COUNT:5

COMMAND – pkcs11-id-get (OpenVPN 2.1 or higher)

按索引检索证书,应提供 ID 字符串
作为 PKCS#11 身份,blob 是 BASE64 编码的证书。

例子:

 pkcs11-id-get 1
 PKCS11ID-ENTRY:'1', ID:'', BLOB:''

COMMAND – client-auth (OpenVPN 2.1 or higher)

授权“>CLIENT:CONNECT”或“>CLIENT:REAUTH”请求并指定
后续文本块中的“client-connect”配置指令。

OpenVPN 服务器应该已经启动了
–management-client-auth 指令,以便它会询问管理
批准客户端连接的接口。

client-auth {CID} {KID}
line_1
line_2

line_n
END

CID,KID – 客户端 ID 和密钥 ID。 请参阅“>客户:”的文档
通知以获取更多信息。

line_1 到 line_n – 客户端连接配置文本块,原样
由 --client-connect 脚本返回。 文本块可能为空,带有
紧跟在“client-auth”行之后的“END”(使用空文本
块相当于使用 client-auth-nt 命令)。

客户端连接配置文本块包含 OpenVPN 指令
这将应用于代表新的客户端实例对象
连接的客户端。

COMMAND – client-auth-nt (OpenVPN 2.1 or higher)

授权 “>CLIENT:CONNECT” 或 “>CLIENT:REAUTH” 请求而不指定
客户端连接配置文本。

OpenVPN 服务器应该已经启动了
–management-client-auth 指令,以便它会询问管理
批准客户端连接的接口。

client-auth-nt {CID} {KID}

CID,KID – client ID and Key ID. See documentation for “>CLIENT:”
notification for more info.

COMMAND – client-deny (OpenVPN 2.1 or higher)

拒绝“>CLIENT:CONNECT”或“>CLIENT:REAUTH”请求。

客户拒绝 {CID} {KID} “原因文本” [“客户原因文本”]

CID,KID – 客户端 ID 和密钥 ID。请参阅“>客户:”的文档
通知以获取更多信息。

原因文本:解释身份验证原因的人类可读消息
请求被拒绝。此消息将输出到 OpenVPN 日志
文件或系统日志。

client-reason-text:将发送给客户端的消息
AUTH_FAILED 消息的一部分。

请注意,client-deny 拒绝特定的密钥 ID(与
TLS 重新协商)。响应于发出的客户端拒绝命令
初始 TLS 密钥协商(由“>CLIENT:CONNECT”通知)将
向客户端返回“AUTH-FAILED”后终止客户端会话。
另一方面,发出客户端拒绝命令以响应
TLS 重新协商 (">CLIENT:REAUTH") 将使重新协商的
键,但是与当前活动关联的 TLS 会话
密钥将在 --tran-window 秒之前继续存在
到期。

要立即终止客户端会话,请使用“client-kill”。

COMMAND – client-kill (OpenVPN 2.1 or higher)

立即通过 CID 杀死客户端实例。

client-kill {CID}

CID – client ID. See documentation for “>CLIENT:” notification for more
info.

COMMAND – client-pf (OpenVPN 2.1 or higher)

将包过滤文件推送到特定客户端。

OpenVPN 服务器应该已经启动了
–management-client-pf 指令,以便它需要
客户端实例发送或接收的 VPN 隧道数据包必须
符合该客户端的数据包过滤器配置。

client-pf {CID}
line_1
line_2

line_n
END

CID – client ID. See documentation for “>CLIENT:” notification for
more info.

line_1 to line_n – the packet filter configuration file for this
client.

Packet filter file grammar:

[CLIENTS DROP|ACCEPT]
{+|-}common_name1
{+|-}common_name2
. . .
[SUBNETS DROP|ACCEPT]
{+|-}subnet1
{+|-}subnet2
. . .
[END]

Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS | “unknown”

CLIENTS 是指一组客户(通过他们的共同名称)
允许 (’+’) 连接或排除此实例 (’-’)
从连接到。请注意,在客户端到客户端的情况下
连接,这样的通信必须被包过滤器允许
两个客户端的配置文件和 --client-to-client
指令必须在 OpenVPN 服务器配置中指定。

SUBNETS 是指 IP 地址或 IP 地址子网,这
客户端实例可能连接到 (’+’) 或被排除 (’-’)
连接并适用于 IPv4 和 ARP 数据包。特别的
“未知”标签是指未知类型的数据包,即一个数据包
不是 IPv4 或 ARP。

当没有显式匹配时,DROP 或 ACCEPT 定义默认策略
对于公用名或子网。 [END] 标签必须存在。

笔记:

  • SUBNETS 部分目前仅支持 IPv4 地址和
    子网。

  • 给定的客户端或子网规则适用于传入和
    传出的数据包。

  • CLIENTS 列表是顺序不变的。因为列表是存储的
    作为哈希表,列表的顺序不会影响其功能。

  • SUBNETS 表顺序扫描,第一项到
    匹配被选中。因此 SUBNETS 表不是顺序不变的。

  • 不允许客户端到客户端的通信,除非
    –client-to-client 配置指令已启用并且
    两个客户端的 CLIENTS 列表允许通信。

传输到管理接口的示例包过滤规范:

client-pf 42
[CLIENTS ACCEPT]
-accounting
-enigma
[SUBNETS DROP]
-10.46.79.9
+10.0.0.0/8
[END]
END

上例为客户端设置包过滤策略
由 CID=42 标识。 此客户端可以连接到所有其他客户端
除了具有“会计”或“谜”的通用名称。
客户端只能与外部 IP 地址交互
10.0.0.0/8 子网,但是专门访问 10.46.79.9
排除。

另一个示例包过滤规范,如传输到
管理界面:

client-pf 99
[CLIENTS DENY]
+public
[SUBNETS ACCEPT]
+10.10.0.1
-10.0.0.0/8
-unknown
[END]
END

上例为客户端设置包过滤策略
由 CID=99 标识。 此客户端可能无法连接到任何其他
客户,但具有共同名称“公共”的客户除外。 有可能
与任何外部 IP 地址进行交互,除了那些在
10.0.0.0/8 网络块。 然而,与一个地址的交互
允许 10.0.0.0/8 网络块:10.10.0.1。 另外,客户端
可能无法使用“未知”与外部 IP 地址交互
协议(即不是 IPv4 或 ARP 的协议)。

COMMAND – remote (OpenVPN AS 2.1.5/OpenVPN 2.3 or higher)

提供远程主机/端口以响应 >REMOTE 通知
(仅限客户端)。 需要 --management-query-remote
使用指令。

remote ACTION [HOST PORT]

“remote”命令只能在响应 >REMOTE 时给出
通知。 比如下面的 >REMOTE 通知
表示客户端配置文件通常会连接
vpn.example.com 端口 1194 (UDP):

REMOTE:vpn.example.com,1194,udp

现在,假设我们要覆盖主机和端口,连接
改为 vpn.otherexample.com 端口 1234。收到后
上面的通知,使用这个命令:

remote MOD vpn.otherexample.com 1234

接受与客户端通常相同的主机和端口
已连接,请使用以下命令:

remote ACCEPT

要跳过当前连接条目并前进到下一个,
使用这个命令:

remote SKIP

COMMAND – proxy (OpenVPN 2.3 or higher)

提供代理服务器主机/端口和标志以响应 >PROXY
通知(仅限客户端)。 需要 --management-query-proxy
使用指令。

proxy TYPE HOST PORT [“nct”]

“代理”命令只能在响应 >PROXY 时给出
通知。 如果您只想允许,请使用“nct”标志
与代理服务器的非明文身份验证。 以下>代理
通知表明客户端配置文件通常会
使用 TCP 连接到第一个配置的 --remote vpn.example.com

PROXY:1,TCP,vpn.example.com

现在,假设我们要使用代理服务器连接到远程主机
如果需要,proxy.intranet 端口 8080 仅具有安全身份验证。
收到上述通知后,使用以下命令:

proxy HTTP proxy.intranet 8080 nct

You can also use the SOCKS keyword to pass a SOCKS server address, like:

proxy SOCKS fe00::1 1080

To accept connecting to the host and port directly, use this command:

proxy NONE

COMMAND – rsa-sig (OpenVPN 2.3 or higher)

提供对私钥外部存储的支持。 需要
–management-external-key 选项。 这个选项可以用来代替“key”
在客户端模式下,并允许客户端运行而无需加载
实际的私钥。 当 SSL 协议需要执行 RSA 签名时
操作,将要签名的数据发送到管理界面
通过如下通知:

RSA_SIGN:[BASE64_DATA]

然后管理接口客户端应该签署 BASE64_DATA
使用私钥并返回 SSL 签名,如下所示:

rsa-sig
[BASE64_SIG_LINE]
.
.
.
END

RSA_sign(NID_md5_sha1,… 的 Base64 编码输出将提供
正确的签名。

此功能旨在允许使用任意密码
通过管理界面使用 OpenVPN 的服务提供商。

OUTPUT FORMAT

(1) “SUCCESS: [text]”指示的命令成功/失败或
“错误:[文本]”。

(2) 对于打印多行输出的命令,
最后一行将是“END”。

(3) 实时消息将采用“>[source]:[text]”的形式,
其中源是“CLIENT”、“ECHO”、“FATAL”、“HOLD”、“INFO”、“LOG”、
“需要确定”、“密码”或“状态”。

REAL-TIME MESSAGE FORMAT

The OpenVPN management interface produces two kinds of
output: (a) output from a command, or (b) asynchronous,
real-time output which can be generated at any time.

Real-time messages start with a ‘>’ character in the first
column and are immediately followed by a type keyword
indicating the type of real-time message. The following
types are currently defined:

BYTECOUNT – Real-time bandwidth usage notification, as enabled
by “bytecount” command when OpenVPN is running as
a client.

BYTECOUNT_CLI – Real-time bandwidth usage notification per-client,
as enabled by “bytecount” command when OpenVPN is
running as a server.

CLIENT – Notification of client connections and disconnections
on an OpenVPN server. Enabled when OpenVPN is started
with the --management-client-auth option. CLIENT
notifications may be multi-line. See “The CLIENT
notification” section below for detailed info.

ECHO – Echo messages as controlled by the “echo” command.

FATAL – A fatal error which is output to the log file just
prior to OpenVPN exiting.

HOLD – Used to indicate that OpenVPN is in a holding state
and will not start until it receives a
“hold release” command.

INFO – Informational messages such as the welcome message.

LOG – Log message output as controlled by the “log” command.

NEED-OK – OpenVPN needs the end user to do something, such as
insert a cryptographic token. The “needok” command can
be used to tell OpenVPN to continue.

NEED-STR – OpenVPN needs information from end, such as
a certificate to use. The “needstr” command can
be used to tell OpenVPN to continue.

PASSWORD – Used to tell the management client that OpenVPN
needs a password, also to indicate password
verification failure.

STATE – Shows the current OpenVPN state, as controlled
by the “state” command.

The CLIENT notification

“>CLIENT:” 通知由 --management-client-auth 启用
提供管理接口客户端的 OpenVPN 配置指令
有责任在客户端之后对 OpenVPN 客户端进行身份验证
证书已经过验证。 客户通知可能是多行的,并且
给定 CLIENT 通知的顺序,其相关的环境
变量,并且终止的 “>CLIENT:ENV,END” 行保证为
原子。

客户通知类型:

(1) 通知新客户端连接(“CONNECT”)或现有客户端 TLS 会话
重新协商(“REAUTH”)。 提供有关客户的信息
通过 OpenVPN 中记录的环境变量列表
手册页。 传递的环境变量等价于那些
这将被传递给 --auth-user-pass-verify 脚本。

>CLIENT:CONNECT|REAUTH,{CID},{KID}
>CLIENT:ENV,name1=val1
>CLIENT:ENV,name2=val2
>CLIENT:ENV,...
>CLIENT:ENV,END

(2) 通知客户端认证和会话发起成功。
在 CONNECT 之后调用。

>CLIENT:ESTABLISHED,{CID}
>CLIENT:ENV,name1=val1
>CLIENT:ENV,name2=val2
>CLIENT:ENV,...
>CLIENT:ENV,END

(3) 通知现有客户端断线。 传递的环境变量
等同于那些将被传递给 --client-disconnect
脚本。

>CLIENT:DISCONNECT,{CID}
>CLIENT:ENV,name1=val1
>CLIENT:ENV,name2=val2
>CLIENT:ENV,...
>CLIENT:ENV,END

(4) 通知特定的虚拟地址或子网
现在与特定客户端相关联。

>CLIENT:ADDRESS,{CID},{ADDR},{PRI}

Variables:

CID – Client ID, numerical ID for each connecting client, sequence = 0,1,2,…
KID – Key ID, numerical ID for the key associated with a given client TLS session,
sequence = 0,1,2,…
PRI – Primary (1) or Secondary (0) VPN address/subnet. All clients have at least
one primary IP address. Secondary address/subnets are associated with
client-specific “iroute” directives.
ADDR – IPv4 address/subnet in the form 1.2.3.4 or 1.2.3.0/255.255.255.0

In the unlikely scenario of an extremely long-running OpenVPN server,
CID and KID should be assumed to recycle to 0 after (2^32)-1, however this
recycling behavior is guaranteed to be collision-free.

Command Parsing

The management interface uses the same command line lexical analyzer
as is used by the OpenVPN config file parser.

Whitespace is a parameter separator.

Double quotation or single quotation characters ("", ‘’) can be used
to enclose parameters containing whitespace.

Backslash-based shell escaping is performed, using the following
mappings, when not in single quotations:

\ Maps to a single backslash character ().
" Pass a literal doublequote character ("), don’t
interpret it as enclosing a parameter.
[SPACE] Pass a literal space or tab character, don’t
interpret it as a parameter delimiter.

Challenge/Response Protocol

The OpenVPN Challenge/Response Protocol allows an OpenVPN server to
generate challenge questions that are shown to the user, and to see
the user’s responses to those challenges. Based on the responses, the
server can allow or deny access.

In this way, the OpenVPN Challenge/Response Protocol can be used
to implement multi-factor authentication. Two different
variations on the challenge/response protocol are supported: the
“Dynamic” and “Static” protocols.

The basic idea of Challenge/Response is that the user must enter an
additional piece of information, in addition to the username and
password, to successfully authenticate. Normally, this information
is used to prove that the user posesses a certain key-like device
such as cryptographic token or a particular mobile phone.

Dynamic protocol:

The OpenVPN dynamic challenge/response protocol works by returning
a specially formatted error message after initial successful
authentication. This error message contains the challenge question,
and is formatted as such:

CRV1::::

flags: a series of optional, comma-separated flags:
E : echo the response when the user types it
R : a response is required

state_id: an opaque string that should be returned to the server
along with the response.

username_base64 : the username formatted as base64

challenge_text : the challenge text to be shown to the user

Example challenge:

CRV1:R,E:Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l:Y3Ix:Please enter token PIN

After showing the challenge_text and getting a response from the user
(if R flag is specified), the client should submit the following
auth creds back to the OpenVPN server:

Username: [username decoded from username_base64]
Password: CRV1::::

Where state_id is taken from the challenge request and response_text
is what the user entered in response to the challenge_text.
If the R flag is not present, response_text may be the empty
string.

Example response (suppose the user enters “8675309” for the token PIN):

Username: cr1 (“Y3Ix” base64 decoded)
Password: CRV1::Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l::8675309

Static protocol:

The static protocol differs from the dynamic protocol in that the
challenge question and response field is given to the user in the
initial username/password dialog, and the username, password, and
response are delivered back to the server in a single transaction.

The “static-challenge” directive is used to give the challenge text
to OpenVPN and indicate whether or not the response should be echoed.

When the “static-challenge” directive is used, the management
interface will respond as such when credentials are needed:

PASSWORD:Need ‘Auth’ username/password SC:,

ECHO: “1” if response should be echoed, “0” to not echo
TEXT: challenge text that should be shown to the user to
facilitate their response

For example:

PASSWORD:Need ‘Auth’ username/password SC:1,Please enter token PIN

The above notification indicates that OpenVPN needs a --auth-user-pass
password plus a response to a static challenge (“Please enter token PIN”).
The “1” after the “SC:” indicates that the response should be echoed.

The management interface client in this case should add the static
challenge text to the auth dialog followed by a field for the user to
enter a response. Then the client should pack the password and response
together into an encoded password:

username “Auth” foo
password “Auth” “SCRV1::”

For example, if the user entered “bar” as the password and 8675309
as the PIN, the following management interface commands should be
issued:

username “Auth” foo
password “Auth” “SCRV1:Zm9v:ODY3NTMwOQ==”

Client-side support for challenge/response protocol:

Currently, the Access Server client and standalone OpenVPN
client support both static and dynamic challenge/response
protocols. However, any OpenVPN client UI that drives OpenVPN
via the management interface needs to add explicit support
for the challenge/response protocol.