CyberNinjas / pam_aad

Azure Active Directory PAM Module
GNU General Public License v3.0
55 stars 19 forks source link

OpenVPN Performance issues with multiple users #39

Closed Jnchi closed 5 years ago

Jnchi commented 5 years ago

Multiple users are unable to login using pam_aad in combination with the openvpn pam plugin.

I went to the device login page and it said I logged in, but OpenVPN is stuck on 'Connecting'

openvpn

See also: https://github.com/CyberNinjas/pam_aad/issues/14, openvpn #1194

Jnchi commented 5 years ago

TODO

Note: The code polls Microsoft every 5 seconds, however it will wait indefinitely until either A) the token is invalid or B) the user successfully logs in.

Source: https://github.com/CyberNinjas/pam_aad/blob/master/pam_aad.c#L194

The fact that nanosleep() sleeps for a relative interval can be problematic if the call is repeatedly restarted after being interrupted by signals, since the time between the interruptions and restarts of the call will lead to drift in the time when the sleep finally completes. --http://man7.org/linux/man-pages/man2/nanosleep.2.html

Jnchi commented 5 years ago

#201 (auth-pam leaves file descriptors open) - OpenVPN Community

Jnchi commented 5 years ago

The auth-pam plugin gets forked to run in background and kept stdin/stdout/stderr open. This might block the callee of the OpenVPN which expect that it nicely turns into a daemon. --https://github.com/OpenVPN/openvpn/pull/84

This sounds like what we are experiencing..

Jnchi commented 5 years ago

Reproduction Steps

1) On the OpenVPN server, install and configure pam_aad following the instructions, then start the server and tail the logs,

tail -f /var/log/openvpn/*.log /var/log/auth.log

2) Setup at least two OpenVPN clients, then attempt to connect the first client.

3) After attempting to authenticate the first client via the device code, attempt to connect the second client.

Note: The second client never receives an email address.

Configuration

/etc/openvpn/server.conf

port 1194
proto udp
dev tun
dh keys/dh2048.pem
ca keys/ca.crt
cert keys/server.crt
key keys/server.key  # This file should be kept secret

;topology subnet
server 10.8.0.0 255.255.255.0
;route 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120

cipher AES-256-CBC
comp-lzo
persist-key
persist-tun

status /var/log/openvpn/openvpn-status.log
log         /var/log/openvpn/openvpn.log
log-append  /var/log/openvpn/openvpn.log
verb 3

;duplicate-cn
;max-clients 30
;user nobody
;group nogroup
;mute 20
;explicit-exit-notify 1

plugin /usr/lib/x86_64-linux-gnu/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn
verify-client-cert optional
username-as-common-name

push "redirect-gateway def1"
;push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.220.220"
push "dhcp-option DNS 208.67.222.222"
;push "route 10.8.0.0 255.255.255.0"

/etc/openvpn/client.conf

client
dev tun
proto udp
remote 192.168.88.130 1194
resolv-retry 3
nobind
persist-key
persist-tun
ca ca.crt
cipher AES-256-CBC
comp-lzo
redirect-gateway def1
verb 3
;explicit-exit-notify 3
auth-user-pass
auth-nocache
remote-cert-tls server

/etc/pam.d/openvpn

# PAM configuration for the Secure Shell service

auth required pam_aad.so

# Standard Un*x authentication.
#@include common-auth

# Disallow non-root logins when /etc/nologin exists.
account    required     pam_nologin.so

# Uncomment and edit /etc/security/access.conf if you need to set complex
# access limits that are hard to express in sshd_config.
# account  required     pam_access.so

# Standard Un*x authorization.
@include common-account

# SELinux needs to be the first session rule.  This ensures that any
# lingering context has been cleared.  Without this it is possible that a
# module could execute code in the wrong domain.
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so close

# Set the loginuid process attribute.
session    required     pam_loginuid.so

# Create a new session keyring.
session    optional     pam_keyinit.so force revoke

# Standard Un*x session setup and teardown.
@include common-session

# Print the message of the day upon successful login.
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session    optional     pam_motd.so  motd=/run/motd.dynamic
session    optional     pam_motd.so noupdate

# Print the status of the user's mailbox upon successful login.
session    optional     pam_mail.so standard noenv # [1]

# Set up user limits from /etc/security/limits.conf.
session    required     pam_limits.so

# Read environment variables from /etc/environment and
# /etc/security/pam_env.conf.
session    required     pam_env.so # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale

# SELinux needs to intervene at login time to ensure that the process starts
# in the proper default security context.  Only sessions which are intended
# to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so open

# Standard Un*x password updating.
@include common-password
Jnchi commented 5 years ago
CFLAGS="${CFLAGS} -pg" make -e

https://sourceware.org/binutils/docs/gprof/Compiling.html#Compiling

Jnchi commented 5 years ago

Created new plugin: https://github.com/CyberNinjas/openvpn-auth-aad

Jnchi commented 5 years ago
docker run --cap-add=NET_ADMIN --device /dev/net/tun:/dev/net/tun -it openvpn-client:pam_aad
Jnchi commented 5 years ago

https://github.com/mozilla-it/openvpn_defer_auth

https://github.com/AzureAD/azure-activedirectory-library-for-python/blob/dev/sample/device_code_sample.py