GithubHelp home page GithubHelp logo

evgeny-gridasov / openvpn-otp Goto Github PK

View Code? Open in Web Editor NEW
276.0 25.0 74.0 99 KB

OpenVPN OTP token support plugin

License: GNU General Public License v3.0

Shell 0.08% C 93.02% Makefile 1.86% M4 5.04%

openvpn-otp's Introduction

OpenVPN OTP Authentication support

This plug-in adds support for time based OTP (totp) and HMAC based OTP (hotp) tokens for OpenVPN. Compatible with Google Authenticator software token, other software and hardware based OTP tokens.

Compile and install openvpn-otp.so file to your OpenVPN plugins directory (usually /usr/lib/openvpn or /usr/lib64/openvpn/plugins).

Be sure you've installed the following packages first:

  • openvpn
  • openvpn-devel (Some distros have openvpn-plugin.h file in a separate package)
  • autoconf
  • automake
  • libtool
  • libssl-dev/openssl-devel/libressl-devel

To bootstrap autotools (generate configure and Makefiles):

./autogen.sh

Build and install with:

./configure --prefix=/usr
make install

The default install location (PREFIX/LIB/openvpn) can be changed by passing the directory with --with-openvpn-plugin-dir to ./configure:

./configure --with-openvpn-plugin-dir=/plugin/dir

Add the following lines to your OpenVPN server configuration file to deploy OTP plugin with default settings. For OpenVPN <=2.3.x, use:

# use otp passwords with default settings (OpenVPN<=2.3.x syntax)
plugin /usr/lib64/openvpn/plugins/openvpn-otp.so

For OpenVPN 2.4, use double quotes:

# use otp passwords with default settings (OpenVPN>=2.4 syntax)
plugin "/usr/lib64/openvpn/plugins/openvpn-otp.so"

By default the following settings are applied:

otp_secrets=/etc/ppp/otp-secrets      # OTP secret file
otp_slop=180                          # Maximum allowed clock slop (seconds)
totp_t0=0                             # T0 value for TOTP (time drift in seconds)
totp_step=30                          # Step value for TOTP (seconds), should be 30 seconds for soft tokens and 60 seconds for hardware tokens
totp_digits=6                         # Number of digits to use from TOTP hash
motp_step=10                          # Step value for MOTP
hotp_syncwindow=2                     # Maximum drifts allowed for clients to resynchronise their tokens' counters (see rfc4226#section-7.4)
hotp_counters=/var/spool/openvpn/hotp-counters/      # HOTP counters directory
password_is_cr=0                      # If set to 1, openvtp-otp will expect password as result of a challenge/response protocol  
debug=0                               # Debug mode: 0=disabled, 1=enabled

Add these variables on the same line as plugin /.../openvpn-otp.so line if you want different values. If you skip one of the variables, the default value will be applied. For OpenvVPN <=2.3.x, the configuration item should look like this:

# use otp passwords with custom settings (OpenVPN<=2.3.x syntax)
plugin /usr/lib64/openvpn/plugins/openvpn-otp.so otp_secrets=/etc/my_otp_secret_file otp_slop=300 totp_t0=2 totp_step=30 totp_digits=8 motp_step=10

OpenVPN 2.4 requires plugin parameters to be put in double quotes:

# use otp passwords with custom settings (OpenVPN>=2.4 syntax)
plugin "/usr/lib64/openvpn/plugins/openvpn-otp.so" "otp_secrets=/etc/my_otp_secret_file otp_slop=300 totp_t0=2 totp_step=30 totp_digits=8 motp_step=10"

It is important to mention that totp_step has to be same on both, the client and server, because it is used for calculation of current token value.

Add the following lines to your OpenVPN clients' configuration files:

# use username/password authentication
auth-user-pass
# do not cache auth info
auth-nocache

OpenVPN will re-negotiate username/password details every 3600 seconds by default. To disable that behaviour, add the following line to both client and server configs:

# disable username/password renegotiation
reneg-sec 0

The otp-secrets file format is exactly the same as for ppp-otp plugin, which makes it very convenient to have PPP and OpenVPN running on the same machine and using the same secrets file. The secrets file has the following layout:

# user server type:hash:encoding:key:pin:udid client
# where type is totp, totp-60-6 or motp
#       hash should be sha1 in most cases
#       encoding is base32, hex or text
#       key is your key in encoding format
#       pin may be a number or a string (may be empty)
#       udid is used only in motp mode and ignored in totp mode
#
# use sha1/base32 for Google Authenticator with a simple pin
bob otp totp:sha1:base32:K7BYLIU5D2V33X6S:1234:xxx *

# use sha1/base32 for Google Authenticator with a strong pin
alice otp totp:sha1:base32:46HV5FIYE33TKWYP:5uP3rH4x0r:xxx *

# use sha1/base32 for Google Authenticator without a pin
john otp totp:sha1:base32:LJYHR64TUI7IL3RD::xxx *

# use sha1/base32 for HOTP without a pin
lucie otp hotp:sha1:base32::MT4GWEZTSRBV2QQC:xxx *

# use totp-60-6 and sha1/hex for hardware based 60 seconds / 6 digits tokens
mike otp totp-60-6:sha1:hex:5c5a75a87ba1b48cb0b6adfd3b7a5a0e:6543:xxx *

# use text encoding for clients supporting plain text keys
jane otp totp:sha1:text:1234567890:9876:xxx *

# allow multiple tokens without a pin for a specific user
hobbes otp totp:sha1:base32:LJYHR64TUI7IL3RD::xxx *
hobbes otp totp:sha1:base32:7VXNJAFPYYKO3ILO::xxx *

When users vpn in, they will need to provide their username and pin+current OTP number from the OTP token. Examples for users bob, alice and john:

username: bob
password: 1234920151

username: alice
password: 5uP3rH4x0r797104

username: john
password: 408923

Using OpenVPN OTP for Multi-Factor Authentication

You can use this plugin to do multi-factor authentication, by using the OpenVPN Challenge/Response feature. For the moment this is supported by two plugins: OpenVPN OTP and a fork of OpenVPN Auth-LDAP.

There are three side to this OpenVPN, the users and the plugins.

OpenVPN

The feature needs to be activated in the client configuration file with the static-challenge flag:

# use Google Authenticator OTP
static-challenge "Enter Google Authenticator Token" 1

From the OpenVPN manual: static-challenge t e : Enable static challenge/response protocol using challenge text t, with echo flag given by e (0|1). The echo flag indicates whether or not the user's response to the challenge should be echoed.
Also, you need to add both plugins to your openvpn server configuration. Having the two auth plugins present, will require that both of them authenticate the user, ie it is not one of the two, it's both.

#PLUGIN SECTION
#LDAP (Active Directory Authentication) PLUGIN
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/auth-ldap.conf
#OTP PLUGIN
plugin /usr/local/lib/openvpn/openvpn-otp.so "password_is_cr=1 otp_secrets=/etc/openvpn/auth/otp-secrets"

Users

If the static-challenge flag is set when the users vpn in, they will be asked for a username, a password and a pin+current OTP number from the OTP token. The prompt for the pin+current OTP number will be the first argument of the static-challenge option (the second argument controls if the input is masked or clear-type when the user enters it). The input for both fields is combined and passed to both plug-ins as a specially formatted password.

Plug-ins

If the static-challenge flag is set, passwords that are passed to plugins, will have a special format. So plug-ins need to be signalled about this in their configuration:

  • In openvpn-otp this is controlled by the password_is_cr flag and disabled by default. So to enable it, set password_is_cr=1 in your openvpn-otp configuration.
  • In openvpn-auth-ldap this is controlled by the PasswordIsCR flag in the configuration file:
# Uncomment and set to true to support OpenVPN Challenge/Response
# PasswordIsCR	true

The various settings will pass username, password and the response to the challenge to both plug-ins. The plug-ins will parse this response (triggered by the flags in their configuration) and each plugin will authenticate the user by looking at the field that's relevant. Examples for users bob, alice and john:

username: bob
password: password1         # this is the LDAP password, verified by openvpn-auth-ldap
response: 1234920151        # this is a (simple) pin plus a Google OTP, verified by openvpn-otp

username: alice
password: password2         # this is the LDAP password, verified by openvpn-auth-ldap
response: 5uP3rH4x0r797104  # this is a (strong) pin plus a Google OTP, verified by openvpn-otp

username: john
password: password3         # this is the LDAP password, verified by openvpn-auth-ldap
response: 408923            # this is the Google OTP, verified by openvpn-otp

The last example (user john) is probably the most typical use case: a first level of authentication of username and password against the LDAP and then a second level of authenitcation using an OTP, which doesn't require a pin, because the LDAP authentication already uses a password.

Please note: the various flags go together, i.e. making the changes only in the openvpn-otp or openvpn-auth-ldap config and not in the client config or vice versa will break the system. Also, please make sure that you're using a forked version of Auth-LDAP plugin.

HOTP counters initialisation

HOTP counters are stored in files, which reside under the hotp-counters directory (/var/spool/openvpn/hotp-counters/ by default). OpenVPN server process should have enough permissions to read and modify files in that directory.

For each HOTP entry in the otp-secrets files, we compute the SHA1 checksum of the secret key, and use the resulting lower case string as the filename.

For example, the following HOTP entry

lucie otp hotp:sha1:base32::MT4GWEZTSRBV2QQC:xxx *

has SHA1(MT4GWEZTSRBV2QQC) = a0b2e3795f7ca9e60183af274a004cdd0ac9276f and the HOTP counter file should be read and stored in /var/spool/openvpn/hotp-counters/a0b2e3795f7ca9e60183af274a004cdd0ac9276f.

The administrator has to create and populate each HOTP counter file with initial value after adding new HOTP records to otp-secrets file. The following command will do the job:

    echo -n 0 > /var/spool/openvpn/hotp-counters/"$(echo -n 'secretkey' | sha1sum | cut -c-40)"

SELinux

The following exceptions are required for this plugin to work properly on a system with Security Enhanced Linux running in enforcing mode:

#============= openvpn_t ==============

allow openvpn_t auth_home_t:file { unlink open };
allow openvpn_t user_home_dir_t:dir { write remove_name add_name };
allow openvpn_t user_home_dir_t:file { rename write getattr read create unlink open };
allow openvpn_t pppd_etc_t:dir search;
allow openvpn_t pppd_etc_t:file { read getattr open };

Alternative SELinux policy reported to work with CentOS:

$ yum install policycoreutils-python \
    selinux-policy-devel
$ cat - <<EOF > openvpn_otp.te
module openvpn_otp 1.0;

require {
        type openvpn_t;
        type pppd_etc_t;
        class dir { search getattr open };
        class file { ioctl lock read getattr open };
}

#============= openvpn_t ==============
read_files_pattern(openvpn_t, pppd_etc_t, pppd_etc_t)
EOF
$ make -f /usr/share/selinux/devel/Makefile openvpn_otp.pp
$ semodule --install openvpn_otp.pp

Using Google Authenticator on your server and mobile

  • install google-authenticator on your server
  • run google-authenticator --time-based --disallow-reuse --force --rate-limit=3 --rate-time=30 --window-size=17 --issuer=foocorp --label=user@hostname --secret=/root/.user.google_authenticator > /root/user.auth
  • user.auth file will contain the key for entry into opt-secrets, and the Google URL containing the image to be scanned with the Google Authenticator mobile app

Supported Operating Systems

This plugin has been successfully compiled and tested with:

  • Ubuntu Linux 14.04 / 16.04 / 18.04
  • CentOS / RHEL 7
  • FreeBSD 11.2
  • Archlinux
  • OpenBSD 6.4
  • NetBSD 8.0
  • DragonFly BSD 5.4

In OpenBSD, please use autoconf 2.69 and automake 1.15.1. You might have to export version numbers before running ./autogen.sh:

export AUTOMAKE_VERSION=1.15
export AUTOCONF_VERSION=2.69

It should work in other *NIX environments, please raise an issue if it does not.

Troubleshooting

Make sure that time is in sync on the server and on your phone/tablet/other OTP client device. You may use oathtool for token verification on your OpenVPN server:

# for TOTP, type:
$ oathtool --totp -b K7BYLIU5D2V33X6S
995277

# for HOTP, type:
$ oathtool -b -c 5 NFIJ5GSNU574OU6B
214648

The tokens should be identical on your OTP client and OpenVPN server. You may also enable debug mode to log user-provided and expected credentials (do not use in production environments):

# use otp passwords with custom settings
plugin /usr/lib64/openvpn/plugins/openvpn-otp.so debug=1 [...other settings...]

Also check that /etc/ppp/otp-secrets file:

  • is accessible by OpenVPN
  • has spaces as field separators
  • has UNIX style line separator (new line only without CR)

Make sure that OpenVPN server process can read and modify files in /var/spool/openvpn/hotp-counters/ directory.

Inspired by ppp-otp plugin written by GitHub user kolbyjack. This plugin written by Evgeny Gridasov ([email protected])

openvpn-otp's People

Contributors

aioue avatar calve avatar danpopp avatar evgeny-gridasov avatar fabn avatar fredriklindberg avatar guywyers avatar johnrvt avatar k0ste avatar patrickhulce avatar phreaker0 avatar shafer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openvpn-otp's Issues

Scratch codes

Hello,

Is there a way to support scratch codes generated by google authenticator?

./configure fails on centos7 with 'OpenVPN headers missing'

The openvpn RPM shipped with EPEL for CentOS7 places openvpn-plugin.h in /usr/include.

# ./configure --prefix=/usr
...
checking openvpn/openvpn-plugin.h usability... no
checking openvpn/openvpn-plugin.h presence... no
checking for openvpn/openvpn-plugin.h... no
configure: error: OpenVPN headers missing

Quick fix

# rpm -ql openvpn |grep openvpn-plugin.h
/usr/include/openvpn-plugin.h
# mkdir /usr/include/openvpn
# ln -sf /usr/include/openvpn-plugin.h /usr/include/openvpn/

Should something like this be mentioned within the README?

Plaintext PIN/password

It's a bit disappointing to see plaintext password storage in 2021, eg:

alice otp totp:sha1:base32:46HV5FIYE33TKWYP:5uP3rH4x0r:xxx *

It should be relatively simple to shim in crypt-compatible hashing, eg:

alice otp totp:sha1:base32:46HV5FIYE33TKWYP:$2y$10$HM6II7ESXVFq1XaylSa1R.8rNEhhlY4r74tRNFxIzWt94wyjJlDFW:xxx *

disable OTP for a given user

It would be nice to disable OTP for a given user.

For example in otp-secrets:
myuser otp disabled *

Thank you.

Support for SHA2

Hi,

SHA1 is being deprecated in most places. Are there plans to support SHA2?

Thanks!

openvpn-otp didn't working on debian stretch

Good day. I receive this error after run openvpn server with plugin openvpn-otp:

/usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --reneg-sec 86400  --cd /etc/openvpn --config /etc/openvpn/server.conf

/var/log/openvpn/openvpn-server.log <==
Mon Aug 17 15:15:18 2020 PLUGIN_INIT: could not load plugin shared object /usr/lib/openvpn/openvpn-otp.so: /usr/lib/openvpn/openvpn-otp.so: undefined symbol: EVP_MD_CTX_free: No such file or directory (errno=2)
Mon Aug 17 15:15:18 2020 Exiting due to fatal error

Server config:

/etc/openvpn/server.conf:
...
plugin "/usr/lib/openvpn/openvpn-otp.so" otp_secrets=/etc/openvpn/otp_secrets

Verion OS: Debian GNU/Linux 9.12 (stretch)
openvpn-otp build as debian package.

dpkg -l | grep openvp
ii  openvpn                       2.4.8-stretch0                    amd64        virtual private network daemon
ii  openvpn-otp                   1.0-1~stretch                     amd64        This plug-in adds support for time based OTP (totp) and HMAC

dpkg -L openvpn-otp
/usr/lib/openvpn/openvpn-otp.la
/usr/lib/openvpn/openvpn-otp.so
dpkg -l | grep ssl
ii  libssl-dev:amd64              1.1.0l-1~deb9u1                   amd64        Secure Sockets Layer toolkit - development files
ii  libssl-doc                    1.1.0l-1~deb9u1                   all          Secure Sockets Layer toolkit - development documentation
ii  libssl1.0.2:amd64             1.0.2u-1~deb9u1                   amd64        Secure Sockets Layer toolkit - shared libraries
ii  libssl1.1:amd64               1.1.0l-1~deb9u1                   amd64        Secure Sockets Layer toolkit - shared libraries
ii  openssl                       1.1.0l-1~deb9u1                   amd64        Secure Sockets Layer toolkit - cryptographic utility


openssl version
OpenSSL 1.1.0l  10 Sep 2019

ldd /usr/lib/openvpn/openvpn-otp.so
	linux-vdso.so.1 (0x00007ffff62bd000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8afdbd3000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f8afe17b000)

I saw old issue with comment - #29 (comment), but I try install different verions of openvpn server (2.4.9, 2.4.8, 2.4.7 - use repo from openvpn ) - error is the same.
I suspect that trouble with openssl, but I don't know how fix that.

Segmentation fault

Hi,

I tried your code on Debian 8.3 and compiled 1864afd as follows:
./autogen.sh
./configure --prefix=/usr
make
sudo make install

I have used the following libraries:

  • libssl-dev:amd64 1.0.1k-3+deb8u2
  • libtool 2.4.2-1.11
  • openvpn 2.3.4-5+deb8u1

When starting openvpn it terminates with a segmentation fault:

# openvpn /etc/openvpn/default/local.conf
...
Fri Feb  5 20:16:12 2016 us=916315 OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Dec  1 2014
Fri Feb  5 20:16:12 2016 us=916357 library versions: OpenSSL 1.0.1k 8 Jan 2015, LZO 2.08 OTP-AUTH: otp_secrets=/etc/openvpn/default/otp-secrets
Segmentation fault

Openvpn has the following configuration:

plugin /usr/lib/openvpn/openvpn-otp.so otp_secrets=/etc/openvpn/otp-secrets

The otp-secrets file has:

ls -l /etc/openvpn/otp-secrets
-rwxrwxrwx 1 root root 54 Feb  5 20:29 /etc/openvpn/otp-secrets
cat /etc/openvpn/otp-secrets 
bob otp totp:sha1:base32:K7BYLIU5D2V33X6S:1234:xxx *

Any idea what's wrong here?

Thanks
Stefan

tls-auth with otp

Is it possible to use openvpn-otp plugin with certificate based auth (tls-auth)

Extended Setup Process for the Google Authenticator Package

Have modified an existing OpenVPN install and followed the install process for openvpn-otp.

How do I generate values for the opt-secrets "key" (token?), and how do I link it to Google Authenticator on my phone?

Would like to use "sha1/base32 for Google Authenticator with a simple pin".

Compatible with user key files

I managed to install this plugin to my server but now I cannot log in while it is enabled. Could it be that otp does not work alongside with user key files?

Or maybe I am doing something wrong with the google auth key.
I understand from the readme, that in the /etc/ppp/otp-secrets file the key needs to be put in base32 format.
What about in the google auth app? base32 or plain?
Also, does the key need to have a specific length?

LDAP Integration

Hi,
Not reporting a bug - more of a support request.
I have OpenVPN set up with LDAP authentication and now openvpn-otp - but I can only use one at a time.

plugin /usr/lib/openvpn/openvpn-otp.so "debug=1"
plugin /usr/lib/openvpn/openvpn-auth-ldap.so "/etc/openvpn/auth/ldap.conf"

Rather than having the PIN/password listed in the opt-secrets file I would rather they entered their LDAP password with their OTP token. Or enter their LDAP username and password first and then be prompted fort eh OTP. I can't see a way to do this so I would appreciate any feedback/discussion. Cheers,
jonny

Bind OTP to a certificate and/or a keys for a specific client

So I am a no expert on OpenVPN I just followed this nice tutorial to set my VPN https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-14-04 and then added OTP support via your plugin. Everything works great. However, I have notice one issue. I would like to use an OTP only on a certain key or certificate for a given client, currently the configuration in otp-secrets is kind of global and can unlock every key and certificate for a given client. Here is an example of what i mean:

Lets say we want to have 2 users on our VPN called of course Alice and Bob. So we generate a certificate for each of them and we distribute alice.crt and alice.key to Alice and give bob.crt and bob.key to Bob. Then we crate an OTP entry for Bob and Alice in otp-secrets and they can login with their TOTPs using Google Authenticator. Great. However, if for some reason Alice gets a hold of bob.crt and bob.key she can still use her TOTP and not Bob's one to authenticate. So IMHO this is an issue and the TOTP secret in the otp-secrets file should only be bound to a certificate and a key. Or at least we should be able to specify for which user in the otp-secrets which certificates are available.

Various `HMAC_*` functions are deprecated since OpenSSL 3.0

Compiling openvpn-otp against OpenSSL 3.0 results in various deprecation warnings:

otp.c: In function 'otp_verify':
otp.c:415:13: warning: 'HMAC_CTX_new' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  415 |             HMAC_CTX* hmac = HMAC_CTX_new();
      |             ^~~~~~~~
In file included from otp.c:22:
/usr/include/openssl/hmac.h:33:33: note: declared here
   33 | OSSL_DEPRECATEDIN_3_0 HMAC_CTX *HMAC_CTX_new(void);
      |                                 ^~~~~~~~~~~~
otp.c:440:17: warning: 'HMAC_CTX_reset' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  440 |                 HMAC_CTX_reset(hmac);
      |                 ^~~~~~~~~~~~~~
/usr/include/openssl/hmac.h:34:27: note: declared here
   34 | OSSL_DEPRECATEDIN_3_0 int HMAC_CTX_reset(HMAC_CTX *ctx);
      |                           ^~~~~~~~~~~~~~
otp.c:441:17: warning: 'HMAC_Init_ex' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  441 |                 HMAC_Init_ex(hmac, otp_key, key_len, otp_digest, NULL);
      |                 ^~~~~~~~~~~~
/usr/include/openssl/hmac.h:43:27: note: declared here
   43 | OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
      |                           ^~~~~~~~~~~~
otp.c:442:17: warning: 'HMAC_Update' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  442 |                 HMAC_Update(hmac, (uint8_t *)&Tn, sizeof(Tn));
      |                 ^~~~~~~~~~~
/usr/include/openssl/hmac.h:45:27: note: declared here
   45 | OSSL_DEPRECATEDIN_3_0 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
      |                           ^~~~~~~~~~~
otp.c:443:17: warning: 'HMAC_Final' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  443 |                 HMAC_Final(hmac, mac, &maclen);
      |                 ^~~~~~~~~~
/usr/include/openssl/hmac.h:47:27: note: declared here
   47 | OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
      |                           ^~~~~~~~~~
otp.c:466:13: warning: 'HMAC_CTX_free' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  466 |             HMAC_CTX_free(hmac);
      |             ^~~~~~~~~~~~~
/usr/include/openssl/hmac.h:35:28: note: declared here
   35 | OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_free(HMAC_CTX *ctx);
      |                            ^~~~~~~~~~~~~
otp.c:471:13: warning: 'HMAC_CTX_new' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  471 |             HMAC_CTX* hmac = HMAC_CTX_new();
      |             ^~~~~~~~
/usr/include/openssl/hmac.h:33:33: note: declared here
   33 | OSSL_DEPRECATEDIN_3_0 HMAC_CTX *HMAC_CTX_new(void);
      |                                 ^~~~~~~~~~~~
otp.c:493:19: warning: 'HMAC_CTX_reset' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  493 |                   HMAC_CTX_reset(hmac);
      |                   ^~~~~~~~~~~~~~
/usr/include/openssl/hmac.h:34:27: note: declared here
   34 | OSSL_DEPRECATEDIN_3_0 int HMAC_CTX_reset(HMAC_CTX *ctx);
      |                           ^~~~~~~~~~~~~~
otp.c:494:19: warning: 'HMAC_Init_ex' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  494 |                   HMAC_Init_ex(hmac, otp_key, key_len, otp_digest, NULL);
      |                   ^~~~~~~~~~~~
/usr/include/openssl/hmac.h:43:27: note: declared here
   43 | OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
      |                           ^~~~~~~~~~~~
otp.c:495:19: warning: 'HMAC_Update' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  495 |                   HMAC_Update(hmac, (uint8_t *)&Tn, sizeof(Tn));
      |                   ^~~~~~~~~~~
/usr/include/openssl/hmac.h:45:27: note: declared here
   45 | OSSL_DEPRECATEDIN_3_0 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
      |                           ^~~~~~~~~~~
otp.c:496:19: warning: 'HMAC_Final' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  496 |                   HMAC_Final(hmac, mac, &maclen);
      |                   ^~~~~~~~~~
/usr/include/openssl/hmac.h:47:27: note: declared here
   47 | OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
      |                           ^~~~~~~~~~
otp.c:521:13: warning: 'HMAC_CTX_free' is deprecated: Since OpenSSL 3.0 [-Wdeprecated-declarations]
  521 |             HMAC_CTX_free(hmac);
      |             ^~~~~~~~~~~~~
/usr/include/openssl/hmac.h:35:28: note: declared here
   35 | OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_free(HMAC_CTX *ctx);
      |                            ^~~~~~~~~~~~~

SELinux policy for CentOS7

Below is the SELinux policy I had to implement for CentOS7 which differs from what is found within the README. I was running the targeted policy.

allow openvpn_t pppd_etc_t:dir search;
allow openvpn_t pppd_etc_t:file { read getattr open };

Below also works.

$ yum install policycoreutils-python \
    selinux-policy-devel
$ cat - <<EOF > openvpn_otp.te
module openvpn_otp 1.0;

require {
        type openvpn_t;
        type pppd_etc_t;
        class dir { search getattr open };
        class file { ioctl lock read getattr open };
}

#============= openvpn_t ==============
read_files_pattern(openvpn_t, pppd_etc_t, pppd_etc_t)
EOF
$ make -f /usr/share/selinux/devel/Makefile openvpn_otp.pp
$ semodule --install openvpn_otp.pp 

HOTP counter issue

Hello,
I'm trying to make this work with Google Authenticator and HOTP type and it looks like counter writed to /var/spool/openvpn/hotp-counters/* is calculated incorrectly - on every authentication attempt the counter is decremented(-1) instead of being incremented(+1). Could you please check this?

Thank you!

Docker build

To ease building package to each distribution, below a sample docker debian:latest compilation workflow. Can be extend to other system. Tested with Debian (buster) and Ubuntu (focal).

$ git clone https://github.com/evgeny-gridasov/openvpn-otp
Debian:
$ docker run -v $(pwd)/openvpn-otp:/openvpn-otp -it debian bash
Ubuntu:
$ docker run -v $(pwd)/openvpn-otp:/openvpn-otp -it ubuntu bash
# apt update
# apt upgrade
# apt install openvpn autoconf automake libtool libssl-dev make
# cd /openvpn-otp
# ./autogen.sh
# ./configure --prefix=/usr --disable-dependency-tracking
# make install
# ls src/.libs/openvpn-otp.*
src/.libs/openvpn-otp.la  src/.libs/openvpn-otp.lai  src/.libs/openvpn-otp.so
$ mkdir -p /usr/lib/openvpn/
$ cp src/.libs/openvpn-otp.* /usr/lib/openvpn/

Optional PIN

I would like to vote to make the PIN optional. I use OTP daily with Google, AWS, etc. and none of them require a separate PIN. It's not a huge deal, but it would be great if the PIN could be optional.

Add option to skip token auth and rely on cert auth for specific users?

Hello!

First of all, thanks for the plugin and all the work you're putting into it. It's much appreciated.

With that being said, I'd like to ask if it would be possible for you to add an option (e.g. in the otp_secrets file) that would allow me to tell the plugin that this particular user doesn't require token auth. The thing is, I have a bunch of different devices connecting to my server. Some of them are other servers and there's no way for me to enter OTPs when they connect to the VPN. OTOH, I have devices like my phone that would greatly benefit from OTPs.

In any case, thanks again for the plugin and have a nice day :).

OTP-AUTH: authentication failed for username 'xxxxxxx', remote 10.0.19.23:47776

10.0.19.23:47776 PLUGIN_CALL: POST /usr/local/lib/openvpn-auth-ldap.so/PLUGIN_AUTH_USER_PASS_VERIFY status=0
OTP-AUTH: authentication failed for username 'zhaowei', remote 10.0.19.23:47776
10.0.19.23:47776 PLUGIN_CALL: POST /usr/lib64/openvpn/plugins/openvpn-otp.so/PLUGIN_AUTH_USER_PASS_VERIFY status=1
10.0.19.23:47776 PLUGIN_CALL: plugin function PLUGIN_AUTH_USER_PASS_VERIFY failed with status 1: /usr/lib64/openvpn/plugins/openvpn-otp.so
10.0.19.23:47776 TLS Auth Error: Auth Username/Password verification failed for peer
10.0.19.23:47776 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384
10.0.19.23:47776 Peer Connection Initiated with [AF_INET]10.0.19.23:47776
10.0.19.23:47776 PUSH: Received control message: 'PUSH_REQUEST'
10.0.19.23:47776 Delayed exit in 5 seconds
10.0.19.23:47776 SENT CONTROL [UNDEF]: 'AUTH_FAILED' (status=1)
10.0.19.23:47776 Connection reset, restarting [0]
10.0.19.23:47776 SIGUSR1[soft,connection-reset] received, client-instance restarting
TCP connection established with [AF_INET]10.0.19.23:47810
10.0.19.23:47810 TLS: Initial packet from [AF_INET]10.0.19.23:47810, sid=6b61e65e f000465b

Client compatibility

This looks really interesting!
Before I upgrade my server though, I would like to know:
Does each client have to support this login method specifically or is it delivered through a generic password prompt?
I access my server via the openvpn android app a lot so this would need to be compatible for me.
Thanks for clarifing!

Rejects passwords

Hello,

I'm trying to set this up on pfSense. I managed to get it compiled and loaded, but all I'm ever getting are failed authentications. Is there some way to increase log verbosity so I can see what's going on? It would be very useful if this plugin could log (temporarily) what passwords it expects and which ones it receives.

Thanks!

'reneg-sec 0' is not a good idea, and is not necessary in OpenVPN >= 2.4

Setting your tunnel to never renegotiate is a security problem for long-running tunnels, and OpenVPN added the auth-gen-token config parameter specifically for cases like OTP authentication. In short, after authentication OpenVPN will generate a token to be used for renegotiation in place of re-sending the username and password.

Please add a mention of auth-gen-token for OpenVPN >= 2.4 in the README.

openssl-1.1.0 not supported

/tmp/cc6coz4M.o: In function `main':
/*/xxx/openvpn-otp/conftest.c:34: undefined reference to `HMAC_CTX_init'
collect2: error: ld returned 1 exit status
configure:16580: $? = 1

HMAC_CTX_init() was replaced with HMAC_CTX_reset() in OpenSSL versions 1.1.0.

Yubikey support?

Hi, this work looks great! I'm looking to set up OpenVPN with both LDAP and Yubikey support (and optionally Google Auth). This plugin looks almost close enough for my needs. Is it possible to use with a Yubikey directly, or would more development be necessary? If work is needed, would it be easier to execute an external script (which I already have working) with the username + OTP to return valid or not?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.