0

Full Disclosure:

I am writing this question to then answer it myself. I searched the internet for a full day at work and was not able to find a solution that worked for me. I even compiled my own GoogleAuthenticator PAM module to add more logging. Not even running strace on the OpenVPN process and its children led me to a solution.

Use Case

  • Launch VPN using OpenVPN in an EC2
  • Use PAM GoogleAuthenticator Module
  • OS: CentOS

Setup

  • login to the EC2
  • create a client
  • add MFA token to user (client) using the provided token generator while also saving this token to the proper location for the PAM module to detect it
    • create the <user>.ovpn file for this user

The below script will create a Linux user, and then create an MFA secret saved to the location specified in the PAM config, note the permissions 600, MFA_USER is a pre-created user that I created named gauth

function generate_mfa() { user_id=$1 if [ "$user_id" == "" ]; then echo "ERROR: No user id provided to generate MFA token" >&2 exit 1 fi echo "INFO: Creating user ${user_id}" >&2 useradd -s /bin/nologin "$user_id" echo "> Please provide a password for the user" >&2 passwd "$user_id" echo "INFO: Generating MFA Token" >&2 google-authenticator -t -d -r3 -R30 -f -l "${MFA_LABEL}" -s "${MFA_DIR}/${user_id}" chown "${MFA_USER}:${MFA_USER}" "$MFA_DIR/${user_id}" chmod 600 "${MFA_DIR}/${user_id}" } 

PAM Config for OpenVPN

auth required /usr/lib64/security/pam_google_authenticator.so secret=/etc/openvpn/google-authenticator/${USER} user=gauth forward_pass auth include system-auth use_first_pass account include system-auth use_first_pass password include system-auth use_first_pass session include system-auth use_first_pass auth required pam_deny.so 

Issue

  • Using Tunnelblick configured with my client.ovpn, I am then prompted to log in with my username and password.
    • The format of password is inline: <password><MFA_TOKEN>, this is stripped out with the forward_pass directive
  • I enter in my proper credentials and am always met with unauthorized

Logs

  • To check out my issue I logged onto the VPN instance via ssh and inspected my PAM/auth logs tail /var/log/secure
Sep 10 22:33:43 ip-OMITTED openvpn(pam_google_authenticator)[12862]: Accepted google_authenticator for ryan Sep 10 22:33:43 ip-OMITTED openvpn(pam_google_authenticator)[12862]: Failed to update secret file "/etc/openvpn/google-authenticator/ryan": Permission denied 

Aha! "Permission Denied"

So then check my permissions:

[root@ip-OMITTED centos]# ls -lah /etc/openvpn/google-authenticator/ drwxr-xr-x. gauth gauth . drwxr-xr-x. root root .. -rw-------. gauth gauth ryan 
  • Hmm, these permissions 600 seem right. The directories are executable and I am using the gauth user in my PAM config.

What on earth could be wrong with my configuration?

  • the gauth user exists :check:
  • the permissions are right :check:

1 Answer 1

2

THE AHA MOMENT

what are those .'s at the end of my permissions listing?

[root@ip-OMITTED centos]# ls -lah /etc/openvpn/google-authenticator/ drwxr-xr-x. gauth gauth . drwxr-xr-x. root root .. -rw-------. gauth gauth ryan 

...Searchin' the web...

  • So apparently there's this thing called SELinux (security enhanced linux)

That is what those dots were at the end of the file permissions when running ls -lah, it indicated that special contexts/ACL stuff existed for the file.

Before one login

The file context was unconfined_u:object_r:openvpn_etc_t:s0

[root@ip-OMITTED centos]# ls -lahZ /etc/openvpn/google-authenticator/ drwxr-xr-x. gauth gauth unconfined_u:object_r:openvpn_etc_t:s0 . drwxr-xr-x. root root system_u:object_r:openvpn_etc_t:s0 .. -rw-------. gauth gauth unconfined_u:object_r:openvpn_etc_t:s0 ryan 
  • Then I temporarily disabled selinux with setenforce 0

After one login

The file was able to be written to and the context was coerced to system_u:object_r:openvpn_etc_rw_t:s0

[root@ip-OMITTED centos]# ls -lahZ /etc/openvpn/google-authenticator/ drwxr-xr-x. gauth gauth unconfined_u:object_r:openvpn_etc_t:s0 . drwxr-xr-x. root root system_u:object_r:openvpn_etc_t:s0 .. -r--------. gauth gauth system_u:object_r:openvpn_etc_rw_t:s0 ryan 
  • reenable SELinux: setenforce 1

  • still able to log in. :)

Commands to run to fix a file with SELinux turned on:

semanage fcontext -a -t openvpn_etc_rw_t "${MFA_DIR}/${user}" restorecon "${MFA_DIR}/${user}"

  • This allows the rw bits!

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.