41

I'd like to write a script that calls openvpn first, followed by ssh. When typing the command

sudo openvpn ~/my_connection.ovpn

in the command prompt I get the following output:

...
Wed Jan  4 21:04:35 2017 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Wed Jan  4 21:04:35 2017 /sbin/ip link set dev tun0 up mtu 1500
Wed Jan  4 21:04:35 2017 /sbin/ip addr add dev tun0 local IP_FOO peer IP_FOO
Wed Jan  4 21:04:35 2017 Initialization Sequence Completed

This command is blocking and the shell is not released. In order to start an ssh connection afterwards I need to push the openvpn process into the background by typing Ctrl+Z followed by a bg.

However, I'd like to call the openvpn connection step and the ssh automatically by calling just my bash file. How do I manage to emulate the Ctrl+Z and bg steps in this file?

I've tried to append a & to the openvpn command and to place nohup in front of it. Neither works.

5
  • This sort of question has been asked multiple times . If you need help you really need to post your script.
    – Panther
    Jan 4, 2017 at 20:21
  • use sudo -b to run the command that follows it in the background Jan 4, 2017 at 22:03
  • 1
    It seems to me that this is really not a duplicate of that question, which hardly covers running background programs as root, and does not at all cover how to properly daemonize OpenVPN. Jan 8, 2017 at 20:12
  • Then we should change the title again to point out that I tried to run a background program as root.
    – null
    Jan 8, 2017 at 20:29
  • @null I've re-edited the title, as requested. OpenVPN is often run as root and, in the situations where it isn't, the --daemon option may still be used, but you're right that the part about running it as root is central to this question and ought to be reflected in its title. Thanks for pointing this out! Jan 8, 2017 at 21:38

3 Answers 3

69

TL;DR: Use sudo -b or, better, openvpn [...] --daemon.

Since you're running openvpn (and, less specifically, since you wish to run a program as root in the background), the most commonly dispensed information about how to run commands in the background does not address your situation. You said:

I've tried to append a & to the cpenvpn command and to place nohop in front of it. Both does not work.

Your command is:

sudo openvpn ~/my_connection.ovpn

Under sudo's default configuration, if you haven't recently entered your password for sudo in the same terminal (or have logged out and back in on that terminal) then it will ask for your password. But if you run the command in the background by appending & then you won't be shown the [sudo] password for user: line or given the opportunity to type it in.

So in this situation, running the command, entering your password, and sending it to the background afterwards is an reasonable way to do it, for interactive use.

But it's not the only way and, as you say, you will not want to do that in a script.

Way 1: Make sure sudo has a fresh timestamp.

You can ensure that sudo has a current timestamp when it is used to run your command, by first running:

sudo -v

Then, after that, you can run:

sudo openvpn ~/my_connection.ovpn &

However, it is usually better to avoid & (and nohup) altogether when you want to run a command in the background with sudo. This is especially the case for scripting.

Way 2: Use sudo -b. In general, this is usually what you want.

Instead, you can run sudo itself in the foreground, but pass the -b flag so sudo causes the command to be run in the background.

sudo -b openvpn ~/my_connection.ovpn

This is usually a better way, especially if you are putting the command in a script. With sudo -b you don't get job control, but in a shell script job control is disabled by default and you shouldn't usually use it.

As man sudo explains:

     -b, --background
                 Run the given command in the background.  Note that it is not
                 possible to use shell job control to manipulate background
                 processes started by sudo.  Most interactive commands will
                 fail to work properly in background mode.

This works because nothing is running in the background until after sudo has recieved your password (if necessary) and determined that you are permitted to run the command.

Way 3: But for openvpn, you should probably just run it with --daemon.

openvpn will run in the background automatically if you run it with the --daemon option:

sudo openvpn ~/my_connection.ovpn --daemon

Pass --daemon after your .opvn filename rather than before; the argument following --daemon, if any, is interpreted as the name that the daemonized openvpn process should use. (Do not also append &.)

Whether or not this is appropriate depends on whether or not any interaction must occur after openvpn has been run but before it daemonizes. And that depends, in part, on what is set up in ~/my_connection.ovpn. But if openvpn couldn't immediately daemonize, then all the other ways of immediately running it in the background will break, too.

Therefore, in any situation where you know you want openvpn to start running in the background, and you know you won't want to bring it back into the foreground, you should strongly consider the method of invoking it with the --daemon option. This is specific to openvpn--most programs do not support a --daemon option, though many server programs do have some such option. (The name and syntax vary, however.)

To decide whether or not to use this option (and how you want to use it), I recommend you read the openvpn manual page, especially in the section on --daemon. It has a lot of useful information, and I am only quoting the first paragraph here:

       --daemon [progname]
              Become  a  daemon  after  all   initialization   functions   are
              completed.   This option will cause all message and error output
              to be sent to  the  syslog  file  (such  as  /var/log/messages),
              except  for  the  output of scripts and ifconfig commands, which
              will go to /dev/null unless otherwise  redirected.   The  syslog
              redirection  occurs  immediately  at  the point that --daemon is
              parsed on the command line even though the  daemonization  point
              occurs  later.   If one of the --log options is present, it will
              supercede syslog redirection.

              The optional progname parameter [...]

Way 4: Sometimes it's reasonable to run the whole script as root.

If you have a script that carries out multiple actions as root, it doesn't have any significant activity that would reasonably be run not as root, and there's never anything useful to come from running the script as a non-root user, then the user of the script should probably just run it as root.

If this is the case, then you should remove sudo from commands in the script. When the script runs as root, there's no need for sudo. (Though the root user can, by default, run any command as any user including itself with sudo and doesn't need a password to do so. So if you do leave instances of sudo in the script then it will probably still work.)

If you have any instances of sudo in the script that are actually used to run commands as some other user than root (with -u user), then you should still keep those instances.

If the whole script is being run as root, then most of the typical ways of making commands run in the background apply, including appending & and, where needed, the use of nohup (which you already know about). For this, though, you should still strongly consider using openvpn with the --daemon option.

5
  • 2
    An awesomely comprehensive and thoughtful answer. Well done.
    – gwideman
    Oct 26, 2018 at 2:34
  • 1
    Great answer. It was a real pleasure to give an upvote to it.
    – Akito
    Mar 5, 2020 at 16:01
  • 3
    sudo openvpn --config ~/my_connection.ovpn --daemon Dec 16, 2020 at 4:29
  • 1
    @HasanAlsawadi I needed to add --config also to make it work Apr 5, 2021 at 13:46
  • sudo openvpn ~/my_connection.ovpn & This will spam messages to your shell, even when started from cron. The --daemon option is preferable. Mar 15, 2022 at 10:26
12

TL;DR Run it in daemon mode: openvpn --config Windscribe-Japan.ovpn --daemon

Passing the configuration (.ovpn) filename to openvpn command works only if no other options are specified. If I specify --daemon option then openvpn tries to parse the filename as an options parameter and throws Options error: I'm trying to parse "Windscribe.ovpn" as an --option parameter but I don't see a leading '--'.

Answer:

To avoid this, the file name has to be specified with --config option. For example, openvpn --config Windscribe.ovpn --daemon. Then tail the syslog with tail -f /var/log/syslog, for further inspection.

You can also check the before and after output of this curl command curl ifconfig.co to make sure that VPN is connected.

Note: This will keep the daemon running even after you logout from the SSH session.

4

You can just copy your

.conf file into /etc/openvpn/

Then ask 'service openvpn@confName start' to handle all the daemonizing and sudo for you.

See https://unix.stackexchange.com/a/366680/198666

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .