Search code examples
bashsudoopenvpn

Set openvpn username and password via env-variable


I have a rather long password that I want to automate using a secret manager, I don't want to store it in plaintext.

Judging from this answer, I can achieve this using env-variables, which is great.

A quick check using sudo openvpn --config ~/Documents/config.ovpn --auth-user-pass test.txt works, also great! I need sudo, otherwise openvpn doesn't work.

But I can't get the command right, I am probably making some trivial mistake.

I tried:

sudo openvpn --config ~/Documents/config.ovpn --auth-user-pass <(echo -e $VPN_USER"\n"$VPN_PASS)

but that results in:

2024-04-13 20:11:43 WARNING: cannot stat file '/proc/self/fd/14': No such file or directory (errno=2)
Options error: --auth-user-pass fails with '/proc/self/fd/14': No such file or directory (errno=2)

which I think is due to my sudo usage. So I tried something else (I am not exactly a bash-pro):

cat <(echo -e $VPN_USER"\n"$VPN_PASS) | sudo /usr/sbin/openvpn --config ~/Documents/config.ovpn --auth-user-pass 

but that results in:

Password entry required for 'Enter Auth Username:' (PID 191957).
Please enter password with the systemd-tty-ask-password-agent tool.

It's probably an easy question.


Solution

  • sudo by default closes all file descriptors other than stdin, stdout and stderr -- so it deliberately invalidates /dev/fd references.

    You can avoid this problem by using a named FIFO -- just like bash does for >(...) and <(...) when running on operating systems that don't support /dev/fd.

    #!/usr/bin/env bash
    
    tempdir=$(mktemp -t -d authsock.d.XXXXXX) || exit
    trap 'rm -rf "$tempdir"; [[ $write_pid ]] && kill "$write_pid"' EXIT
    
    mkfifo "$tempdir/sock" || exit
    printf '%s\n' "$VPN_USER" "$VPN_PASS" >"$tempdir/sock" & write_pid=$!
    
    sudo openvpn \
      --config /home/leander/Documents/Informatics-EdLAN-Forum.ovpn \
      --auth-user-pass "$tempdir/sock"