diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | doc/Makefile.in | 20 | ||||
-rw-r--r-- | doc/interactive-service-notes.rst | 330 | ||||
-rw-r--r-- | doc/management-notes.txt | 228 | ||||
-rw-r--r-- | doc/openvpn.8 | 40 |
5 files changed, 535 insertions, 85 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am index f3a24a7..c091ce0 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -18,7 +18,7 @@ dist_doc_DATA = \ management-notes.txt dist_noinst_DATA = \ - README.plugins + README.plugins interactive-service-notes.rst if WIN32 dist_noinst_DATA += openvpn.8 diff --git a/doc/Makefile.in b/doc/Makefile.in index 4ac438e..11d3d54 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -169,7 +169,8 @@ am__installdirs = "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(htmldir)" NROFF = nroff MANS = $(dist_man_MANS) -am__dist_noinst_DATA_DIST = README.plugins openvpn.8 +am__dist_noinst_DATA_DIST = README.plugins \ + interactive-service-notes.rst openvpn.8 DATA = $(dist_doc_DATA) $(dist_noinst_DATA) $(nodist_html_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in @@ -342,7 +343,6 @@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sampledir = @sampledir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ @@ -361,7 +361,8 @@ CLEANFILES = openvpn.8.html dist_doc_DATA = \ management-notes.txt -dist_noinst_DATA = README.plugins $(am__append_1) +dist_noinst_DATA = README.plugins interactive-service-notes.rst \ + $(am__append_1) @WIN32_TRUE@nodist_html_DATA = openvpn.8.html @WIN32_FALSE@dist_man_MANS = openvpn.8 all: all-am @@ -384,8 +385,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -494,7 +495,10 @@ ctags CTAGS: cscope cscopelist: -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ diff --git a/doc/interactive-service-notes.rst b/doc/interactive-service-notes.rst new file mode 100644 index 0000000..32c7f2b --- /dev/null +++ b/doc/interactive-service-notes.rst @@ -0,0 +1,330 @@ +OpenVPN Interactive Service Notes +================================= + + +Introduction +------------ + +OpenVPN Interactive Service, also known as "iservice" or +"OpenVPNServiceInteractive", is a Windows system service which allows +unprivileged openvpn.exe process to do certain privileged operations, such as +adding routes. This removes the need to always run OpenVPN as administrator, +which was the case for a long time, and continues to be the case for OpenVPN +2.3.x. + +The 2.4.x release and git "master" versions of OpenVPN contain the Interactive +Service code and OpenVPN-GUI is setup to use it by default. Starting from +version 2.4.0, OpenVPN-GUI is expected to be started as user (do not right-click +and "run as administrator" or do not set the shortcut to run as administrator). +This ensures that OpenVPN and the GUI run with limited privileges. + + +How It Works +------------ + +Here is a brief explanation of how the Interactive Service works, based on +`Gert's email`_ to openvpn-devel mailing list. The example user, *joe*, is not +an administrator, and does not have any other extra privileges. + +- OpenVPN-GUI runs as user *joe*. + +- Interactive Service runs as a local Windows service with maximum privileges. + +- OpenVPN-GUI connects to the Interactive Service and asks it to "run + openvpn.exe with the given command line options". + +- Interactive Service starts openvpn.exe process as user *joe*, and keeps a + service pipe between Interactive Service and openvpn.exe. + +- When openvpn.exe wants to perform any operation that require elevation (e.g. + ipconfig, route, configure DNS), it sends a request over the service pipe to + the Interactive Service, which will then execute it (and clean up should + openvpn.exe crash). + +- ``--up`` scripts are run by openvpn.exe itself, which is running as user + *joe*, all privileges are nicely in place. + +- Scripts run by the GUI will run as user *joe*, so that automated tasks like + mapping of drives work as expected. + +This avoids the use of scripts for privilege escalation (as was possible by +running an ``--up`` script from openvpn.exe which is run as administrator). + + +Client-Service Communication +---------------------------- + +Connecting +~~~~~~~~~~ + +The client (OpenVPN GUI) and the Interactive Service communicate using a named +message pipe. By default, the service provides the ``\\.\pipe\openvpn\service`` +named pipe. + +The client connects to the pipe for read/write and sets the pipe state to +``PIPE_READMODE_MESSAGE``:: + + HANDLE pipe = CreateFile(_T("\\\\.\\pipe\\openvpn\\service"), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (pipe == INVALID_HANDLE_VALUE) + { + // Error + } + + DWORD dwMode = PIPE_READMODE_MESSAGE; + if (!SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL) + { + // Error + } + + +openvpn.exe Startup +~~~~~~~~~~~~~~~~~~~ + +After the client is connected to the service, the client must send a startup +message to have the service start the openvpn.exe process. The startup message +is comprised of three UTF-16 strings delimited by U0000 zero characters:: + + startupmsg = workingdir WZERO openvpnoptions WZERO stdin WZERO + + workingdir = WSTRING + openvpnoptions = WSTRING + stdin = WSTRING + + WSTRING = *WCHAR + WCHAR = %x0001-FFFF + WZERO = %x0000 + +``workingdir`` + Represents the folder openvpn.exe process should be started in. + +``openvpnoptions`` + String contains ``--config`` and other OpenVPN command line options, without + the ``argv[0]`` executable name ("openvpn" or "openvpn.exe"). When there is + only one option specified, the ``--config`` option is assumed and the option + is the configuration filename. + + Note that the interactive service validates the options. OpenVPN + configuration file must reside in the configuration folder defined by + ``config_dir`` registry value. The configuration file can also reside in any + subfolder of the configuration folder. For all other folders the invoking + user must be a member of local Administrators group, or a member of the group + defined by ``ovpn_admin_group`` registry value ("OpenVPN Administrators" by + default). + +``stdin`` + The content of the ``stdin`` string is sent to the openvpn.exe process to its + stdin stream after it starts. + + When a ``--management ... stdin`` option is present, the openvpn.exe process + will prompt for the management interface password on start. In this case, the + ``stdin`` must contain the password appended with an LF (U000A) to simulate + the [Enter] key after the password is "typed" in. + + The openvpn.exe's stdout is redirected to ``NUL``. Should the client require + openvpn.exe's stdout, one should specify ``--log`` option. + +The message must be written in a single ``WriteFile()`` call. + +Example:: + + // Prepare the message. + size_t msg_len = + wcslen(workingdir) + 1 + + wcslen(options ) + 1 + + wcslen(manage_pwd) + 1; + wchar_t *msg_data = (wchar_t*)malloc(msg_len*sizeof(wchar_t)); + _snwprintf(msg_data, msg_len, L"%s%c%s%c%s", + workingdir, L'\0', + options, L'\0', + manage_pwd) + + // Send the message. + DWORD dwBytesWritten; + if (!WriteFile(pipe, + msg_data, + msg_len*sizeof(wchar_t), + &dwBytesWritten, + NULL)) + { + // Error + } + + // Sanitize memory, since the stdin component of the message + // contains the management interface password. + SecureZeroMemory(msg_data, msg_len*sizeof(wchar_t)); + free(msg_data); + + +openvpn.exe Process ID +~~~~~~~~~~~~~~~~~~~~~~ + +After receiving the startup message, the Interactive Service validates the user +and specified options before launching the openvpn.exe process. + +The Interactive Service replies with a process ID message. The process ID +message is comprised of three UTF-16 strings delimited by LFs (U000A):: + + pidmsg = L"0x00000000" WLF L"0x" pid WLF L"Process ID" + + pid = 8*8WHEXDIG + + WHEXDIG = WDIGIT / L"A" / L"B" / L"C" / L"D" / L"E" / L"F" + WDIGIT = %x0030-0039 + WLF = %x000a + +``pid`` + A UTF-16 eight-character hexadecimal process ID of the openvpn.exe process + the Interactive Service launched on client's behalf. + + +openvpn.exe Monitoring and Termination +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After the openvpn.exe process is launched, the client can disconnect the pipe to +the interactive service. However, it should monitor the openvpn.exe process +itself. OpenVPN Management Interface is recommended for this. + +The client may choose to stay connected to the pipe. When the openvpn.exe +process terminates, the service disconnects the pipe. Should the openvpn.exe +process terminate with an error, the service sends an error message to the +client before disconnecting the pipe. + +Note that Interactive Service terminates all child openvpn.exe processes when +the service is stopped or restarted. This allows a graceful elevation-required +clean-up (e.g. restore ipconfig, route, DNS). + + +Error Messages +~~~~~~~~~~~~~~ + +In case of an error, the Interactive Service sends an error message to the +client. Error messages are comprised of three UTF-16 strings delimited by LFs +(U000A):: + + errmsg = L"0x" errnum WLF func WLF msg + + errnum = 8*8WHEXDIG + func = WSTRING + msg = WSTRING + +``errnum`` + A UTF-16 eight-character hexadecimal error code. Typically, it is one of the + Win32 error codes returned by ``GetLastError()``. + + However, it can be one of the Interactive Service specific error codes: + + ===================== ========== + Error Code + ===================== ========== + ERROR_OPENVPN_STARTUP 0x20000000 + ERROR_STARTUP_DATA 0x20000001 + ERROR_MESSAGE_DATA 0x20000002 + ERROR_MESSAGE_TYPE 0x20000003 + ===================== ========== + +``func`` + The name of the function call that failed or an error description. + +``msg`` + The error description returned by a + ``FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, errnum, ...)`` call. + + +Interactive Service Configuration +--------------------------------- + +The Interactive Service settings are read from the +``HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN`` registry key by default. + +All the following registry values are of the ``REG_SZ`` type: + +*Default* + Installation folder (required, hereinafter ``install_dir``) + +``exe_path`` + The absolute path to the openvpn.exe binary; defaults to + ``install_dir "\bin\openvpn.exe"``. + +``config_dir`` + The path to the configuration folder; defaults to ``install_dir "\config"``. + +``priority`` + openvpn.exe process priority; one of the following strings: + + - ``"IDLE_PRIORITY_CLASS"`` + - ``"BELOW_NORMAL_PRIORITY_CLASS"`` + - ``"NORMAL_PRIORITY_CLASS"`` (default) + - ``"ABOVE_NORMAL_PRIORITY_CLASS"`` + - ``"HIGH_PRIORITY_CLASS"`` + +``ovpn_admin_group`` + The name of the local group, whose members are authorized to use the + Interactive Service unrestricted; defaults to ``"OpenVPN Administrators"`` + + +Multiple Interactive Service Instances +-------------------------------------- + +OpenVPN 2.4.5 extended the Interactive Service to support multiple side-by-side +running instances. This allows clients to use different Interactive Service +versions with different settings and/or openvpn.exe binary version on the same +computer. + +OpenVPN installs the default Interactive Service instance only. The default +instance is used by OpenVPN GUI client and also provides backward compatibility. + + +Installing a Non-default Interactive Service Instance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Choose a unique instance name. For example: "$v2.5-test". The instance name + is appended to the default registry path and service name. We choose to start + it with a dollar "$" sign analogous to Microsoft SQL Server instance naming + scheme. However, this is not imperative. + + Appending the name to the registry path and service name also implies the + name cannot contain characters not allowed in Windows paths: "<", ">", double + quote etc. + +2. Create an ``HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN$v2.5-test`` registry key and + configure the Interactive Service instance configuration appropriately. + + This allows using slightly or completely different settings from the default + instance. + + See the `Interactive Service Configuration`_ section for the list of registry + values. + +3. Create and start the instance's Windows service from an elevated command + prompt:: + + sc create "OpenVPNServiceInteractive$v2.5-test" \ + start= auto \ + binPath= "<path to openvpnserv.exe> -instance interactive $v2.5-test" \ + depend= tap0901/Dhcp \ + DisplayName= "OpenVPN Interactive Service (v2.5-test)" + + sc start "OpenVPNServiceInteractive$v2.5-test" + + This allows using the same or a different version of openvpnserv.exe than the + default instance. + + Note the space after "=" character in ``sc`` command line options. + +4. Set your OpenVPN client to connect to the + ``\\.\pipe\openvpn$v2.5-test\service``. + + This allows the client to select a different installed Interactive Service + instance at run-time, thus allowing different OpenVPN settings and versions. + + At the time writing, the OpenVPN GUI client supports connecting to the + default Interactive Service instance only. + +.. _`Gert's email`: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg00097.html diff --git a/doc/management-notes.txt b/doc/management-notes.txt index 908b981..96a0d7d 100644 --- a/doc/management-notes.txt +++ b/doc/management-notes.txt @@ -12,7 +12,8 @@ as a client or server. The management interface is implemented using a client/server TCP connection or unix domain socket where OpenVPN will listen on a -provided IP address and port for incoming management client connections. +provided IP address and port for incoming management interface client +connections. The management protocol is currently cleartext without an explicit security layer. For this reason, it is recommended that the @@ -104,7 +105,7 @@ be in the list, and it will cause the management interface to save the "forget-passwords" string in its list of echo parameters. -The management client can use "echo all" to output the full +The management interface client can use "echo all" to output the full list of echoed parameters, "echo on" to turn on real-time notification of echoed parameters via the ">ECHO:" prefix, or "echo off" to turn off real-time notification. @@ -118,10 +119,10 @@ like this: Essentially the echo command allowed us to pass parameters from the OpenVPN server to the OpenVPN client, and then to the -management client (such as a GUI). The large integer is the +management interface client (such as a GUI). The large integer is the unix date/time when the echo parameter was received. -If the management client had issued the command "echo on", +If the management interface client had issued the command "echo on", it would have enabled real-time notifications of echo parameters. In this case, our "forget-passwords" message would be output like this: @@ -139,10 +140,10 @@ messages. COMMAND -- exit, quit --------------------- -Close the managment session, and resume listening on the +Close the management session, and resume listening on the management port for connections from other clients. Currently, -the OpenVPN daemon can at most support a single management client -any one time. +the OpenVPN daemon can at most support a single management interface +client any one time. COMMAND -- help --------------- @@ -167,7 +168,7 @@ The hold flag setting is persistent and will not be reset by restarts. OpenVPN will indicate that it is in a hold state by -sending a real-time notification to the management +sending a real-time notification to the management interface client, the parameter indicates how long OpenVPN would wait without UI (as influenced by connect-retry exponential backoff). The UI needs to wait for releasing the hold if it @@ -275,7 +276,7 @@ COMMAND -- password and username OpenVPN is indicating that it needs a password of type "Private Key". - The management client should respond to this query as follows: + The management interface client should respond as follows: password "Private Key" foo @@ -283,8 +284,8 @@ COMMAND -- password and username >PASSWORD:Need 'Auth' username/password - OpenVPN needs a --auth-user-pass password. The management - client should respond: + OpenVPN needs a --auth-user-pass username and password. The + management interface client should respond: username "Auth" foo password "Auth" bar @@ -307,7 +308,8 @@ COMMAND -- password and username >PASSWORD:Verification Failed: 'Private Key' Example 4: The --auth-user-pass username/password failed, - and OpenVPN is exiting: + and OpenVPN will exit with a fatal error if '--auth-retry none' + (which is the default) is in effect: >PASSWORD:Verification Failed: 'Auth' @@ -322,6 +324,37 @@ COMMAND -- password and username >PASSWORD:Auth-Token:foobar + Example 7: Static challenge/response: + + >PASSWORD:Need 'Auth' username/password SC:1,Please enter token PIN + + OpenVPN needs an --auth-user-pass username and password and the + response to a challenge. The user's response to "Please enter + token PIN" should be obtained and included in the management + interface client's response along with the username and password + formatted as described in the Challenge/Response Protocol section + below. + + Example 8: Dynamic challenge/response: + + >PASSWORD:Verification Failed: ['CRV1:R,E:Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l:Y3Ix:Please enter token PIN'] + + The previous --auth-user-pass username/password failed or is not + fully complete, and the server provided a custom + client-reason-text string indicating that a dynamic + challenge/response should occur the next time that a "Need 'Auth' + username/password" message is seen. + + When the next "Need 'Auth' username/password" without a static + challenge is seen, the user's response to "Please enter token PIN" + should be obtained and included in the management interface client's + response along with the username and password formatted as described + in the Challenge/Response Protocol section below + +See the "Challenge/Response Protocol" section below for more details +about examples 7 and 8, including how the management interface client +should respond. + COMMAND -- forget-passwords --------------------------- @@ -460,10 +493,10 @@ Example: >NEED-OK:Need 'token-insertion-request' confirmation MSG:Please insert your cryptographic token - The management client, if it is a GUI, can flash a dialog + The management interface client, if it is a GUI, can flash a dialog box containing the text after the "MSG:" marker to the user. When the user acknowledges the dialog box, - the management client can issue this command: + the management interface client should issue either: needok token-insertion-request ok or @@ -482,10 +515,10 @@ Example: >NEED-STR:Need 'name' input MSG:Please specify your name - The management client, if it is a GUI, can flash a dialog + The management interface client, if it is a GUI, can flash a dialog box containing the text after the "MSG:" marker to the user. When the user acknowledges the dialog box, - the management client can issue this command: + the management interface client should issue this command: needstr name "John" @@ -503,7 +536,7 @@ COMMAND -- pkcs11-id-get (OpenVPN 2.1 or higher) ------------------------------------------------- Retrieve certificate by index, the ID string should be provided -as PKCS#11 identity, the blob is BASE64 encoded certificate. +as PKCS#11 identity, the blob is a base 64 encoded certificate. Example: @@ -807,7 +840,7 @@ to the management interface with a hint as follows: >NEED-CERTIFICATE:macosx-keychain:subject:o=OpenVPN-TEST The management interface client should use the hint to obtain the specific -SSL certificate and then return base64 encoded certificate as follows: +SSL certificate and then return base 64 encoded certificate as follows: certificate [BASE64_CERT_LINE] @@ -880,7 +913,7 @@ 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 +PASSWORD -- Used to tell the management interface client that OpenVPN needs a password, also to indicate password verification failure. @@ -978,70 +1011,116 @@ 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 protocol can be used to implement multi-factor authentication +because the user must enter an additional piece of information, +in addition to a username and password, to successfully authenticate. +In multi-factor authentication, this information is used to prove +that the user possesses a certain key-like device such as +cryptographic token or a particular mobile phone. + +Two variations on the challenge/response protocol are supported: +the "static" and "dynamic" protocols: + + * The static protocol uses OpenVPN's "--static-challenge" option. -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. + * The dynamic protocol does not involve special OpenVPN options + or actions. It is an agreement between the auth-user-pass + verification process on the server and the management interface + client to use custom strings that begin with "['CRV1" in + "Verification Failed" messages. (The "[" character and a matching + "]" character at the end of the message are added by the client + OpenVPN program, and are not present in the string generated by the + auth-user-pass verification process or in the string sent by the + server.) 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: +authentication. The error message has two purposes: + + 1. It causes OpenVPN to restart the connection attempt. + + 2. It contains information about the challenge, which should be used + to construct the response to the next authentication request (which + will occur after the restart). + +Notes: - CRV1:<flags>:<state_id>:<username_base64>:<challenge_text> + * '--auth-retry interact' must be in effect so that the + connection is restarted and credentials are requested again. -flags: a series of optional, comma-separated flags: - E : echo the response when the user types it - R : a response is required + * '--auth-retry none' (which is the default) will cause + OpenVPN to exit with a fatal error without retrying and the dynamic + challenge/response will never happen because "Need 'Auth' + username/password" will not be sent. -state_id: an opaque string that should be returned to the server - along with the response. +The error message is formatted as follows: -username_base64 : the username formatted as base64 + >PASSWORD:Verification Failed: 'Auth' ['CRV1:<flags>:<state_id>:<username_base64>:<challenge_text>'] -challenge_text : the challenge text to be shown to the user +<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 encoded as base 64. + +<challenge_text>: the challenge text to be shown to the user. + +<state_id> may not contain colon characters (":"), but <challenge_text> +may. 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: +The next time the username and password are requested with + + >PASSWORD:Need 'Auth' username/password + +the management interface client should display the challenge text and, +if the R flag is specified, get a response from the user. The management +interface client should respond: -Username: [username decoded from username_base64] -Password: CRV1::<state_id>::<response_text> + username "Auth" <username> + password "Auth" CRV1::<state_id>::<response_text> -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. +Where <username> is the username decoded from <username_base64>, +<state_id> is taken from the challenge request, and <response_text> +is what the user entered in response to the challenge, which can be an +empty string. If the R flag is not present, <response_text> should +be an empty string. + +(As in all username/password responses described in the "COMMAND -- +password and username" section above, the username and/or password +can be in quotes, and special characters such as double quotes or +backslashes must be escaped. See the "Command Parsing" section above +for more info.) Example response (suppose the user enters "8675309" for the token PIN): - Username: cr1 ("Y3Ix" base64 decoded) - Password: CRV1::Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l::8675309 + username "Auth" cr1 + password "Auth" CRV1::Om01u7Fh4LrGBS7uh0SWmzwabUiGiW6l::8675309 + +("Y3Ix" is the base 64 encoding of "cr1".) 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. +challenge question is sent to the management interface client in a +a username/password request, and the username, password, and +response are delivered back to the server in response to that +request. -The "static-challenge" directive is used to give the challenge text -to OpenVPN and indicate whether or not the response should be echoed. +OpenVPN's --static-challenge option is used to provide 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: +When credentials are needed and the --static-challenge option is +used, the management interface will send: >PASSWORD:Need 'Auth' username/password SC:<ECHO>,<TEXT> @@ -1054,28 +1133,35 @@ 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. +username and 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: +enter a response. Then the management interface client should pack the +password and response together into an encoded password and send: - username "Auth" foo - password "Auth" "SCRV1:<BASE64_PASSWORD>:<BASE64_RESPONSE>" + username "Auth" <username> + password "Auth" "SCRV1:<password_base64>:<response_base64>" -For example, if the user entered "bar" as the password and 8675309 +Where <username> is the username entered by the user, <password_base64> +is the base 64 encoding of the password entered by the user, and +<response_base64> is the base 64 encoding of the response entered by +the user. The <password_base64> and/or the <response_base64> can be +empty strings. + +(As in all username/password responses described in the "COMMAND -- +password and username" section above, the username can be in quotes, +and special characters such as double quotes or backslashes must be +escaped. See the "Command Parsing" section above for more info.) + +For example, if user "foo" 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: + password "Auth" "SCRV1:YmFy:ODY3NTMwOQ==" -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. + ("YmFy" is the base 64 encoding of "bar" and "ODY3NTMwOQ==" is the + base 64 encoding of "8675309".) diff --git a/doc/openvpn.8 b/doc/openvpn.8 index 7512bfb..7801701 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -1181,7 +1181,7 @@ Option flags: .B local \-\- Add the .B local -flag if both OpenVPN servers are directly connected via a common subnet, +flag if both OpenVPN peers are directly connected via a common subnet, such as with wireless. The .B local flag will cause step @@ -2516,6 +2516,16 @@ If the parameter is empty, compression will be turned off, but the packet framing for compression will still be enabled, allowing a different setting to be pushed later. + +.B Security Considerations + +Compression and encryption is a tricky combination. If an attacker knows or is +able to control (parts of) the plaintext of packets that contain secrets, the +attacker might be able to extract the secret if compression is enabled. See +e.g. the CRIME and BREACH attacks on TLS which also leverage compression to +break encryption. If you are not entirely sure that the above does not apply +to your traffic, you are advised to *not* enable compression. + .\"********************************************************* .TP .B \-\-comp\-lzo [mode] @@ -3057,7 +3067,7 @@ IV_NCP=2 \-\- negotiable ciphers, client supports pushed by the server, a value of 2 or greater indicates client supports AES\-GCM\-128 and AES\-GCM\-256. -IV_UI_VER=<gui_id> <version> \-\- the UI version of a UI if one is +IV_GUI_VER=<gui_id> <version> \-\- the UI version of a UI if one is running, for example "de.blinkt.openvpn 0.5.47" for the Android app. @@ -4920,11 +4930,13 @@ determines the derivation of the tunnel session keys. .\"********************************************************* .TP .B \-\-tls\-cipher l +.TQ +.B \-\-tls\-ciphersuites l A list .B l of allowable TLS ciphers delimited by a colon (":"). -This setting can be used to ensure that certain cipher suites are used (or +These setting can be used to ensure that certain cipher suites are used (or not used) for the TLS connection. OpenVPN uses TLS to secure the control channel, over which the keys that are used to protect the actual VPN traffic are exchanged. @@ -4933,20 +4945,32 @@ The supplied list of ciphers is (after potential OpenSSL/IANA name translation) simply supplied to the crypto library. Please see the OpenSSL and/or mbed TLS documentation for details on the cipher list interpretation. +For OpenSSL, the +.B \-\-tls-cipher +is used for TLS 1.2 and below. For TLS 1.3 and up, the +.B \-\-tls\-ciphersuites +setting is used. mbed TLS has no TLS 1.3 support yet and only the +.B \-\-tls-cipher +setting is used. + Use .B \-\-show\-tls to see a list of TLS ciphers supported by your crypto library. Warning! .B \-\-tls\-cipher -is an expert feature, which \- if used correcly \- can improve the security of -your VPN connection. But it is also easy to unwittingly use it to carefully +and +.B \-\-tls\-ciphersuites +are expert features, which \- if used correcly \- can improve the security of +your VPN connection. But it is also easy to unwittingly use them to carefully align a gun with your foot, or just break your connection. Use with care! The default for \-\-tls\-cipher is to use mbed TLS's default cipher list when using mbed TLS or "DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:!SRP:!kRSA" when using OpenSSL. + +The default for \-\-tls\-ciphersuites is to use the crypto library's default. .\"********************************************************* .TP .B \-\-tls\-cert\-profile profile @@ -5314,6 +5338,12 @@ into the file/buffer for dynamic configuration data. This will then make the OpenVPN server to push this value to the client, which replaces the local password with the UNIQUE_TOKEN_VALUE. + +Newer clients (2.4.7+) will fall back to the original password method +after a failed auth. Older clients will keep using the token value +and react acording to +.B \-\-auth-retry +. .\"********************************************************* .TP .B \-\-tls\-verify cmd |