Connect VPN during CI/CD


I need to connect to a VPN server during my deployment in .gitlab-ci.yml
I’m using openvpn but my issue is that openvpn command keep console with no return and my CI still running for ever.

I would need that my process continue if connection is ok.

Do you have an idea?

Here is my command:
sudo /usr/sbin/openvpn /home/gitlab-runner/myconf.conf

I have tried with & to put in background. Process go forward but still running at the end.

Note: I added this command in /etc/sudoers for my gitlab-runner user.

Thank you for your help

Hi Louis,

Have you tried running openvn as a deamon ?

Your command would become:
sudo /usr/sbin/openvpn --config /home/gitlab-runner/myconf.conf --daemon

Also, if your server requires authentication with a username and password, you can create a secrets.txt file with your credentials and add this to your command.
sudo /usr/sbin/openvpn --config /home/gitlab-runner/myconf.conf --auth-user-pass secrets.txt --daemon



After this you can continue with your deploy actions.

If you have more questions, please feel free to ask.

1 Like

I would recommend you to use FastestVPN, it works very well on all platforms, further they have 7 days money back policy so in case if you have any issue, so you can refund your money back.

I know this is an old thread, but it is google result #1 when looking for this topic so I’ll share my solution here.

  ## VPN
  ## Inspiration from:
  ## And
  ## Content from Variables to files:
  ## Waiting for opnevpn connect would be better than sleeping, the closest would be
  ## Maybe this would work
  - which openvpn || (apt-get update -y -qq && apt-get install -y -qq openvpn) # Install openvpn if not available.
  - cat <<< $CLIENT_OVPN > /etc/openvpn/client.conf # Move vpn config from gitlab variable to config file.
  - cat <<< $VPN_U > /etc/openvpn/pass.txt # Move vpn user from gitlab variable to pass file.
  - cat <<< $VPN_P >> /etc/openvpn/pass.txt # Move vpn password from gitlab variable to pass file.
  - cat <<< "auth-user-pass /etc/openvpn/pass.txt" >> /etc/openvpn/client.conf # Tell vpn config to use password file.
  - cat <<< "log /etc/openvpn/client.log" >> /etc/openvpn/client.conf # Tell vpn config to use log file.
  - openvpn --config /etc/openvpn/client.conf --daemon # Start openvpn with config as a deamon.
  - sleep 30s # Wait for some time so the vpn can connect before doing anything else.
  - cat /etc/openvpn/client.log # Print the vpn log.
  - ping -c 1 <IP> # Ping the server I want to deploy to. If not available this stops the deployment process.

  ## SSH
  ## Inspiration for gitlab from
  ## Inpsiration for new key from
  - which ssh-agent || (apt-get update -y -qq && apt-get install openssh-client -y -qq) # Install ssh-agent if not available.
  - eval $(ssh-agent -s) # Run ssh-agent.
  - mkdir -p ~/.ssh # Create ssh directory.
  - cat <<< $SSH_PRIVATE_KEY > ~/.ssh/id_rsa # Move ssh key from gitlab variable to file.
  - chmod 700 ~/.ssh/id_rsa  # Set permissions so only I am allowed to access my ssh key.
  - ssh-add # Add the key (no params -> default file name assumed).
  - cat <<< $SSH_KNOWN_HOSTS_DMS > ~/.ssh/known_hosts # Add the servers SSH Key to known_hosts prevent man in the middle attack.

When you add this before_script you are connected via VPN and you can simply use ssh and rsync as:
ssh username@ ‘command to execute’

I’m not completely happy with the sleep, but it was the easiest, yet reliable thing I could come up with.
If you have any suggestions for improvements let me know :slight_smile:



This is good, however my VPN connection expects Authenticator code as well

@bechtold did you run this on a gitlab shared runner? Asking because I’m getting the error

Options error: You must define TUN/TAP device (--dev)

which I believe is caused by the docker environment not passing the network devices, or something like that. I don’t fully understand it though since shared runners are running in privileged mode so should have full access.

Yes, I did and didn’t setup anything else. Maybe something changed on the shared runners? Haven’t been working on that project for a while, so I can’t say if it still works.

Thanks for your reply! Would you mind sharing your .gitlab-ci.yml if you still have it? Much appreciated.

Perfect! It worked to me! Thanks!
However later I will try to make a solution to get rid of the sleep

I have applied this script to use as part of a deployment step that needs to happen over a VPN connection but cannot get it to work. From what I have googled it seams a very hit or miss thing, with some saying it just works and others saying just to use X or Y flag. But nothing fits the bill.

Has anyone had any luck getting this to operate on a shared runner?

I have a shared runner on a server with:

  • Ubuntu 20.04, up to date
  • GitLab Runner
    • Version: 13.5.0
    • Git revision: ece86343
    • Git branch: 13-5-stable
    • GO version: go1.13.8
    • Built: 2020-10-20T12:05:22+0000
    • OS/Arch: linux/amd64
  • Docker 19.03.13, build 4484c46d9d

My current config.toml file has

tls_verify = false
image = "ubuntu:20.04"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
devices = ["/dev/net/tun"]

I have tried various combinations before my current config above:

privileged = true/false
devices = ["/dev/net/tun"]
cap_add = ["NET_ADMIN"]

From my understanding using privileged = true should make using cap_add unneeded but I tried both as well anyways

Running the original script resulted in an error of

Thu Oct 22 16:22:11 2020 ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)

Doing some googling I applied the following suggestion to the before_script section of my .gitlab-ci.yml file:

  • mkdir -p /dev/net
  • mknod /dev/net/tun c 10 200
  • chmod 600 /dev/net/tun

This resulted in a new error of

Thu Oct 22 16:26:37 2020 ERROR: Cannot ioctl TUNSETIFF tun: Operation not permitted (errno=1)

More googling says to just run the openvpn command via sudo but docker does not like that, even in privileged mode.

Any ideas?