[HowTo] NordVPN - Usage, Installation, Updating and Troubleshooting

NordVPN


NordVPN is a popular provider with extensive coverage. To use NordVPN you install a CLI application which is very easy to use.

Synopsis


  1. Installation
  2. Help
  3. Usage
  4. WAN IP check
  5. Firewall
  6. Update
  7. Remove
  8. Troubleshooting
  9. Reload after suspend/hibernation
  10. PaC

1. Install NordVPN


The package is in AUR and must be installed using an AUR helper. Most Manjaro distribution comes with the Pamac software tool and this is what we will use to install NordVPN client.

pamac build nordvpn-bin

When you have installed the package you need to enable/start the service daemon to use it.

sudo systemctl enable --now nordvpnd

2. Help


To get an idea of how to use the CLI you use the help command which will display options and some example usage.

$ nordvpn -h
~ >>> nordvpn -h
Welcome to NordVPN Linux client app!
Version 3.1.0-4
Website: https://nordvpn.com

Usage: nordvpn [global options] command [command options] [arguments...]

Commands:
     cities         Shows a list of cities where servers are available
     connect, c     Connects you to VPN
     countries      Shows a list of countries where servers are available
     disconnect, d  Disconnects you from VPN
     groups         Shows a list of available server groups
     login          Logs you in
     logout         Logs you out
     set, s         Sets a configuration option
     settings       Shows current settings
     status         Shows connection status
     whitelist      Adds or removes an option from a whitelist
     help, h        Shows a list of commands or help for one command

Global options:
   --help, -h     show help
   --version, -v  print the version

For more detailed information, please check manual page.

Our customer support works 24/7 so if you have any questions or issues, drop us a line at https://support.nordvpn.com/

For help with a specific command use e.g. for the set command

nordvpn set help

3. Using NordVPN CLI


Before using the vpn client you need to start the service daemon.

If you have enabled the service at boot you don't need to start the service and you can skip it.

sudo systemctl start nordvpnd

Next you need to login - the client very convenient remembers your credentials so you don't have to input these every time you connect. The login command will only be needed on the first login

nordvpn login

You may have different needs for connecting for example you might want to be in US if you want to watch some TV show.

You can get a list of countries you can connect to by using the countries command. You can connect to a country using the name or the country code e.g. Australia or us.

nordvpn connect us

When you are done you use the disconnect command.

nordvpn disconnect

4. Verify your IP address


To verify your ip address you can create a small script which connects to a service providing your ip address. Several of such services exist - just google for what is my ip. I use a danish service called myip.dk - which also has an api which returns only a string with your ip.

Create a file in your home folder - preferably in your local path e.g. ~/.local/bin or ~/bin is a common folder for this (Manjaro Openbox creates the folder ~/.local/bin and symlinks ~/bin to ~/.local/bin).

touch ~/.local/bin/myip
chmod +x ~/local/bin/myip
#!/bin/bash
curl https://get.geojs.io/v1/ip

If you would like a nice message box install yad and replace above content with

#!/bin/bash
IP=$(curl -s https://get.geojs.io/v1/ip)
yad --title="Public IP" --text="Your public IP is '"$IP"'" --button=OK --center --width=300 --height=100

20191202-114624_323x158_screenshot

Or you could use notify daemon instead of yad - replace the yad line

notify-send --urgency=critical --expire-time=5000 "Public IP" "\nYour public IP address is $IP"

20191203-154024_532x188_screenshot

5. NordVPN and firewall


The popular UFW firewall package do not work well with NordVPN and my attempts to understand why was not a success so I have chosen to use the Fedora developed firewalld package available in the official repo.

Use Firewalld

To avoid these firewall issues - use the package firewalld instead.

sudo systemctl disable ufw
sudo systemctl stop ufw
sudo pacman -Syu firewalld
sudo systemctl enable --now firewalld

To set the preferred zone use the GUI tools or use the CLI

sudo firewall-cmd --set-default-zone=drop

You can of course uninstall the UFW and it's GUI but you may also leave it in case you should change your mind.

sudo pacman -Rns ufw gufw

6. Update NordVPN


The NordVPN binary is updated frequently and the maintainer of the AUR package can not always keep up with the changes, so this section describes how you can do it yourself when the binary tells you a new version is available.

IMPORTANT

Stop the nordvpn daemon while you update the package and then start it.

sudo systemctl stop nordvpnd

Start after update

sudo systemctl start nordvpnd

What is the new version

Verify the release number of new version using the uri for the debian packages.

https://repo.nordvpn.com/deb/nordvpn/debian/pool/main

Clone the AUR package

git clone https://aur.archlinux.org/nordvpn-bin

Edit the PKGBUILD

Change to the folder and edit the PKGBUILD. Modify the PKGBUILD for a standard x86_64 system and save the changes.

Note that the dash (-) in the original version number is replaced with underscore (_). This is done because pacman uses the dash (-) to signify pkgrel - so just change the digits - not dots/dashes/underscore.

cd nordvpn-bin
nano PKGBUILD
PKGBUILD
# Maintainer: metiis <aur at metiis dot com>
# Maintainer: Julio Gutierrez <bubuntux at gmail dot com>
# Maintainer: Martoko <mbastholm at gmail dot com>

pkgname=nordvpn-bin
pkgver=3.3.1_1
pkgrel=1
pkgdesc="NordVPN CLI tool for Linux"
#arch=('i686' 'x86_64' 'armv7h' 'aarch64')
arch=('x86_64')
url="https://nordvpn.com/download/linux/"
_deb_uri="https://repo.nordvpn.com/deb/nordvpn/debian/pool/main"
license=('custom')
depends=('net-tools' 'libxslt' 'iptables' 'procps' 'iproute2')
optdepends=('wireguard-tools: nordlynx support' 'wireguard-module: nordlynx support')
provides=('nordvpn')
conflicts=('openvpn-nordvpn')
install=nordvpn-bin.install
#source_i686=("${_deb_uri}/nordvpn_${pkgver//_/-}_i386.deb")
source_x86_64=("${_deb_uri}/nordvpn_${pkgver//_/-}_amd64.deb")
#source_armv7h=("${_deb_uri}/nordvpn_${pkgver//_/-}_armhf.deb")
#source_aarch64=("${_deb_uri}/nordvpn_${pkgver//_/-}_aarch64.deb")
#sha256sums_i686=('90277bbbcfb76eca4f891b125571373c9f1fd2b743fde390df8ee3bc3c8238c2')
sha256sums_x86_64=('2cfadc4475c1061bf3d194a5d0faef1d89be7fd61392339304b9f24c52b7aa10')
#sha256sums_armv7h=('4140d53d231050055ff0cedd9d50613f605bc82cb7478df1eee9f1fb4a988f6c')
#sha256sums_aarch64=('536fbbd7f387ea2d6b24839f62d0c55d2298a2f8dd0ab9f97632c2efc6009c18')

package() {
    bsdtar -O -xf *.deb data.tar.xz | bsdtar -C "${pkgdir}" -xJf -

    mv "${pkgdir}/usr/sbin/nordvpnd" "${pkgdir}/usr/bin"
    rm -r "${pkgdir}/etc/init.d"
    rm -r "${pkgdir}/usr/sbin"
}

Download, build and install

Then update the checksum

updpkgsums

Build the package with makepkg and install it

makepkg -i

7. Remove NordVPN


Connection errors

If you get connection errors - my regular use has shown - the best way of solving those is to completely remove the package and files and then rebuild it.

Removal procedure

Removing NordVPN may leave files behind - files created at run time. The uninstallation should remove these but should you be in need of do it manually here is some hints. If you do not succeed removing them they are probably immutable. Remove the immutable bit by executing

sudo chattr -i filename

Immutable files may exist in the folder /var/lib/nordvpn/data folder.

[thinkstation data]# ls -la /var/lib/nordvpn/data
-rw------- 1 root root      67 Jul 20 14:46 cybersec.dat
-rw------- 1 root root     137 Jul 26 08:30 insights.dat
-rw------- 1 root root    3465 Jul 20 14:46 ovpn_template.xslt
-rw------- 1 root root    4109 Jul 20 14:46 ovpn_xor_template.xslt
-rw------- 1 root root 3165760 Jul 26 08:30 servers.dat
-rw------- 1 root root      60 Jul 20 14:48 settings.dat

Also check your ~/.config/openvpn as the content of this folder also has been seen creating issues connecting to NordVPN service.

~ >>> ls -la ~/.config/nordvpn                                                  
-rw-------  1 fh fh  427 Jul 25 13:00 nordvpn.conf

The insights.dat filename screams privacy issue but it is not. A post on Reddit explains what the file is and does.

TL:DR The file contains the encrypted coordinates of your current IP and is used for finding an optimal server.

The files mentioned is immutable and as such not removable not even be root - which will create a conflict upon reinstallation.

At least two threads has been opened on this issue and the solution is

  1. Identify nordvpn services
systemctl list-unit-files | grep nordvpn
  1. Stop and disable relevant services
sudo systemctl disable <name.service>
sudo systemctl stop <name.service>
  1. Uninstall the package
sudo pacman -Rns nordvpn-bin
  1. Change attributes for the insights.dat, version.dat and servers.dat
sudo chattr -i /var/lib/nordvpn/data/*.dat
  1. Remove the remaining files and folders
sudo rm -rf /var/lib/nordvpn/

8. Troubleshooting


If you use the killswitch command your file /etc/resolv.conf will be locked using chattr command.

This is normally no problem as your previous config will be restored when you close the nordvpn connection.

If you have made a forceful shutdown of your system - for any reason - the previous configuration is not restored and your network manager cannot connect to the internet.

You need to manually unlock the resolver configuration

sudo chattr -i /etc/resolv.conf

Reload after suspend/hibernation


Create service following the great advice from @Ataraxy in this post

/etc/systemd/system/nordvpnd-restart-after-network-online.service:

# Prevent immutable /etc/resolv.conf
# https://archived.forum.manjaro.org/t/internet-blocked-by-nordvpn-killswitch/108413
# https://bbs.archlinux.org/viewtopic.php?id=246004

# If using NetworkManager, requires NetworkManager-wait-online.service to be started
# https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

[Unit]
Description=restart nordvpnd after network online
After=NetworkManager-wait-online.service
# Uncomment if using networkd, and comment previous line
; Before=systemd-networkd-wait-online.service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart nordvpnd

[Install]
WantedBy=NetworkManager-wait-online.service
# Uncomment if using networkd, and comment previous line
; WantedBy=systemd-networkd-wait-online.service

Enable both required services:

sudo systemctl daemon-reload
sudo systemctl enable NetworkManager-wait-online.service nordvpnd-restart-after-network-online.service 

Now, immediately after NetworkManager says it's online, the nordvpnd service will be automatically restarted.

10. PaC interface


For those of you preferring PaC you can build the package nordpy from AUR.

pamac build nordpy
26 Likes

Thanks for sharing this.
I have been configuring the vpn through network manager using NordVPN's .ovpn files. Would that work equally good as the method you are describing above?

Thanks in advance!

I don't have this env in my Plasma. Actually, I don't even have $VISUAL.. :astonished:
Should I worry?
I haven't tried the script, just giving feedback..
I tried the "script" and created a infinite loop for bash command..
I think there must be a typo or needs formatting.. (remove the $EDITOR command from the script?)

Nevertheless, the curl command returns my IP fine!

OK - the first line was the actual edit command

The next lines the script.

I have fixed it.

It should - only thing is that NetworkManager often leaks dns as it uses the systems dns.

I have not tested with NordVPN's config files.

Me - worry?
alfred

No - don't worry

1 Like

Great!
Do you have an easy/short answer on the env in question, or should I make a troubleshooting topic?

These commands give nothing in terminal

echo $EDITOR
env | grep EDIT
env | grep VISUAL

Are https://www.dnsleaktest.com/ and/or https://ipleak.net/ reliable means for checking dns leakage?

I have run those tests and the only servers that show up seem to belong to NordVPN.

If you are seeing your vpn providers dns - then you are ok.

I only mention it because I have found that with some providers I have had to alter their profile to allow for script execution and add script to the up and down hooks for the actual changes to resolv conf, so the dns is not leaking.

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

The actual script is from the Arch wiki.

Thanks for the confirmation! I appreciate it.

greetings.
Marte

Edit: BTW, in case of dns leakage, should I add

up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

to the appropriate config file?

nordnm is a good working script as well.

IF you have dns leaks it is necessary

  1. to modify the config file to allow script and which script
  2. add the script to your openvpn folder in /etc
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

The scripts are from the Arch wiki

Script for Network Manager

update-resolv-conf
#!/bin/bash
# 
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood and Chris Hanson.
# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL. 
# 
# Example envs set from openvpn:
#
#     foreign_option_1='dhcp-option DNS 193.43.27.132'
#     foreign_option_2='dhcp-option DNS 193.43.27.133'
#     foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
#

[ -x /sbin/resolvconf ] || exit 0
[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0

split_into_parts()
{
	part1="$1"
	part2="$2"
	part3="$3"
}

case "$script_type" in
  up)
	NMSRVRS=""
	SRCHS=""
	for optionvarname in ${!foreign_option_*} ; do
		option="${!optionvarname}"
		echo "$option"
		split_into_parts $option
		if [ "$part1" = "dhcp-option" ] ; then
			if [ "$part2" = "DNS" ] ; then
				NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
			elif [ "$part2" = "DOMAIN" ] ; then
				SRCHS="${SRCHS:+$SRCHS }$part3"
			fi
		fi
	done
	R=""
	[ "$SRCHS" ] && R="search $SRCHS
"
	for NS in $NMSRVRS ; do
        	R="${R}nameserver $NS
"
	done
	echo -n "$R" | /sbin/resolvconf -a "${dev}.openvpn"
	;;
  down)
	/sbin/resolvconf -d "${dev}.openvpn"
	;;
esac

Script for Systemd Resolved

update-systemd-resolved
#!/usr/bin/env bash
#
# OpenVPN helper to add DHCP information into systemd-resolved via DBus.
# Copyright (C) 2016, Jonathan Wright <jon@than.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# This script will parse DHCP options set via OpenVPN (dhcp-option) to update
# systemd-resolved directly via DBus, instead of updating /etc/resolv.conf. To
# install, set as the 'up' and 'down' script in your OpenVPN configuration file
# or via the command-line arguments, alongside setting the 'down-pre' option to
# run the 'down' script before the device is closed. For example:
#   up /etc/openvpn/scripts/update-systemd-resolved
#   down /etc/openvpn/scripts/update-systemd-resolved
#   down-pre

# Define what needs to be called via DBus
DBUS_DEST="org.freedesktop.resolve1"
DBUS_NODE="/org/freedesktop/resolve1"

SCRIPT_NAME="${BASH_SOURCE[0]##*/}"

log() {
  logger -s -t "$SCRIPT_NAME" "$@"
}

for level in emerg err warning info debug; do
  printf -v functext -- '%s() { log -p user.%s -- "$@" ; }' "$level" "$level"
  eval "$functext"
done

usage() {
  err "${1:?${1}. }. Usage: ${SCRIPT_NAME} up|down device_name."
}

busctl_call() {
  # Preserve busctl's exit status
  busctl call "$DBUS_DEST" "$DBUS_NODE" "${DBUS_DEST}.Manager" "$@" || {
    local -i status=$?
    emerg "'busctl' exited with status $status"
    return $status
  }
}

get_link_info() {
  dev="$1"
  shift

  link=''
  link="$(ip link show dev "$dev")" || return $?

  echo "$dev" "${link%%:*}"
}

dhcp_settings() {
  for foreign_option in "${!foreign_option_@}"; do
    foreign_option_value="${!foreign_option}"

    [[ "$foreign_option_value" == *dhcp-option* ]] \
      && echo "${foreign_option_value#dhcp-option }"
  done
}

up() {
  local link="$1"
  shift
  local if_index="$1"
  shift

  info "Link '$link' coming up"

  # Preset values for processing -- will be altered in the various process_*
  # functions.
  local -a dns_servers=() dns_domain=() dns_search=() dns_routed=()
  local -i dns_server_count=0 dns_domain_count=0 dns_search_count=0 dns_routed_count=0
  local dns_sec=""

  while read -r setting; do
    setting_type="${setting%% *}"
    setting_value="${setting#* }"

    process_setting_function="${setting_type,,}"
    process_setting_function="process_${process_setting_function//-/_}"

    if declare -f "$process_setting_function" &>/dev/null; then
      "$process_setting_function" "$setting_value" || return $?
    else
      warning "Not a recognized DHCP setting: '${setting}'"
    fi
  done < <(dhcp_settings)

  if [[ "${#dns_servers[*]}" -gt 0 ]]; then
    busctl_params=("$if_index" "$dns_server_count" "${dns_servers[@]}")
    info "SetLinkDNS(${busctl_params[*]})"
    busctl_call SetLinkDNS 'ia(iay)' "${busctl_params[@]}" || return $?
  fi

  if [[ "${#dns_domain[*]}" -gt 0 \
     || "${#dns_search[*]}" -gt 0 \
     || "${#dns_routed[*]}" -gt 0 ]]; then
    dns_count=$((dns_domain_count+dns_search_count+dns_routed_count))
    busctl_params=("$if_index" "$dns_count")
    if [[ "${#dns_domain[*]}" -gt 0 ]]; then
      busctl_params+=("${dns_domain[@]}")
    fi
    if [[ "${#dns_search[*]}" -gt 0 ]]; then
      busctl_params+=("${dns_search[@]}")
    fi
    if [[ "${#dns_routed[*]}" -gt 0 ]]; then
      busctl_params+=("${dns_routed[@]}")
    fi
    info "SetLinkDomains(${busctl_params[*]})"
    busctl_call SetLinkDomains 'ia(sb)' "${busctl_params[@]}" || return $?
  fi

  if [[ -n "${dns_sec}" ]]; then
    if [[ "${dns_sec}" == "default" ]]; then
      # We need to provide an empty string to use the default settings
      info "SetLinkDNSSEC($if_index '')"
      busctl_call SetLinkDNSSEC 'is' "$if_index" "" || return $?
    else
      info "SetLinkDNSSEC($if_index ${dns_sec})"
      busctl_call SetLinkDNSSEC 'is' "$if_index" "${dns_sec}" || return $?
    fi
  fi
}

down() {
  local link="$1"
  shift
  local if_index="$1"
  shift

  info "Link '$link' going down"
  if [[ "$(whoami 2>/dev/null)" != "root" ]]; then
    # Cleanly handle the priviledge dropped case by not calling RevertLink
    info "Priviledges dropped in the client: Cannot call RevertLink."
  else
    busctl_call RevertLink i "$if_index"
  fi
}

process_dns() {
  address="$1"
  shift

  if looks_like_ipv6 "$address"; then
    process_dns_ipv6 "$address" || return $?
  elif looks_like_ipv4 "$address"; then
    process_dns_ipv4 "$address" || return $?
  else
    err "Not a valid IPv6 or IPv4 address: '$address'"
    return 1
  fi
}

looks_like_ipv4() {
  [[ -n "$1" ]] && {
    local dots="${1//[^.]}"
    (( ${#dots} == 3 ))
  }
}

looks_like_ipv6() {
  [[ -n "$1" ]] && {
    local colons="${1//[^:]}"
    (( ${#colons} >= 2 ))
  }
}

process_dns_ipv4() {
  local address="$1"
  shift

  info "Adding IPv4 DNS Server ${address}"
  (( dns_server_count += 1 ))
  dns_servers+=(2 4 ${address//./ })
}

# Enforces RFC 5952:
#   1. Don't shorten a single 0 field to '::'
#   2. Only longest run of zeros should be compressed
#   3. If there are multiple longest runs, the leftmost should be compressed
#   4. Address must be maximally compressed, so no all-zero runs next to '::'
#
# ...
#
# Thank goodness we don't have to handle port numbers, though :)
parse_ipv6() {
  local raw_address="$1"

  log_invalid_ipv6() {
    local message="'$raw_address' is not a valid IPv6 address"
    emerg "${message}: $*"
  }

  trap -- 'unset -f log_invalid_ipv6' RETURN

  if [[ "$raw_address" == *::*::* ]]; then
    log_invalid_ipv6 "address cannot contain more than one '::'"
    return 1
  elif [[ "$raw_address" =~ :0+:: ]] || [[ "$raw_address" =~ ::0+: ]]; then
    log_invalid_ipv6 "address contains a 0-group adjacent to '::' and is not maximally shortened"
    return 1
  fi

  local -i length=8
  local -a raw_segments=()

  IFS=$':' read -r -a raw_segments <<<"$raw_address"

  local -i raw_length="${#raw_segments[@]}"

  if (( raw_length > length )); then
    log_invalid_ipv6 "expected ${length} segments, got ${raw_length}"
    return 1
  fi

  # Store zero-runs keyed to their sizes, storing all non-zero segments prefixed
  # with a token marking them as such.
  local nonzero_prefix=$'!'
  local -i zero_run_i=0 compressed_i=0
  local -a tokenized_segments=()
  local decimal_segment='' next_decimal_segment=''

  for (( i = 0 ; i < raw_length ; i++ )); do
    raw_segment="${raw_segments[i]}"

    printf -v decimal_segment -- '%d' "0x${raw_segment:-0}"

    # We're in the compressed group.  The length of this run should be
    # enough to bring the total number of segments to 8.
    if [[ -z "$raw_segment" ]]; then
      (( compressed_i = zero_run_i ))

      # `+ 1' because the length of the current segment is counted in
      # `raw_length'.
      (( tokenized_segments[zero_run_i] = ((length - raw_length) + 1) ))

      # If we have an address like `::1', skip processing the next group to
      # avoid double-counting the zero-run, and increment the number of
      # 0-groups to add since the second empty group is counted in
      # `raw_length'.
      if [[ -z "${raw_segments[i + 1]}" ]]; then
        (( i++ ))
        (( tokenized_segments[zero_run_i]++ ))
      fi

      (( zero_run_i++ ))
    elif (( decimal_segment == 0 )); then
      (( tokenized_segments[zero_run_i]++ ))

      # The run is over if the next segment is not 0, so increment the
      # tracking index.
      printf -v next_decimal_segment -- '%d' "0x${raw_segments[i + 1]}"

      (( next_decimal_segment != 0 )) && (( zero_run_i++ ))
    else
      # Prefix the raw segment with `nonzero_prefix' to mark this as a
      # non-zero field.
      tokenized_segments[zero_run_i]="${nonzero_prefix}${decimal_segment}"
      (( zero_run_i++ ))
    fi
  done

  if [[ "$raw_address" == *::* ]]; then
    if (( ${#tokenized_segments[*]} == length )); then
      log_invalid_ipv6 "single '0' fields should not be compressed"
      return 1
    else
      local -i largest_run_i=0 largest_run=0

      for (( i = 0 ; i < ${#tokenized_segments[@]}; i ++ )); do
        # Skip groups that aren't zero-runs
        [[ "${tokenized_segments[i]:0:1}" == "$nonzero_prefix" ]] && continue

        if (( tokenized_segments[i] > largest_run )); then
          (( largest_run_i = i ))
          largest_run="${tokenized_segments[i]}"
        fi
      done

      local -i compressed_run="${tokenized_segments[compressed_i]}"

      if (( largest_run > compressed_run )); then
        log_invalid_ipv6 "the compressed run of all-zero fields is smaller than the largest such run"
        return 1
      elif (( largest_run == compressed_run )) && (( largest_run_i < compressed_i )); then
        log_invalid_ipv6 "only the leftmost largest run of all-zero fields should be compressed"
        return 1
      fi
    fi
  fi

  for segment in "${tokenized_segments[@]}"; do
    if [[ "${segment:0:1}" == "$nonzero_prefix" ]]; then
      printf -- '%04x\n' "${segment#${nonzero_prefix}}"
    else
      for (( n = 0 ; n < segment ; n++ )); do
        echo 0000
      done
    fi
  done
}

process_dns_ipv6() {
  local address="$1"
  shift

  info "Adding IPv6 DNS Server ${address}"

  local -a segments=()
  segments=($(parse_ipv6 "$address")) || return $?

  # Add AF_INET6 and byte count
  dns_servers+=(10 16)
  for segment in "${segments[@]}"; do
    dns_servers+=("$((16#${segment:0:2}))" "$((16#${segment:2:2}))")
  done

  (( dns_server_count += 1 ))
}

process_domain() {
  local domain="$1"
  shift

  info "Setting DNS Domain ${domain}"
  (( dns_domain_count = 1 ))
  dns_domain=("${domain}" false)
}

process_adapter_domain_suffix() {
  # This enables support for ADAPTER_DOMAIN_SUFFIX which is a Microsoft standard
  # which works in the same way as DOMAIN to set the primary search domain on
  # this specific link.
  process_domain "$@"
}

process_domain_search() {
  local domain="$1"
  shift

  info "Adding DNS Search Domain ${domain}"
  (( dns_search_count += 1 ))
  dns_search+=("${domain}" false)
}

process_domain_route() {
  local domain="$1"
  shift

  info "Adding DNS Routed Domain ${domain}"
  (( dns_routed_count += 1 ))
  dns_routed+=("${domain}" true)
}

process_dnssec() {
  local option="$1" setting=""
  shift

  case "${option,,}" in
    yes|true)
      setting="yes" ;;
    no|false)
      setting="no" ;;
    default)
      setting="default" ;;
    allow-downgrade)
      setting="allow-downgrade" ;;
    *)
      local message="'$option' is not a valid DNSSEC option"
      emerg "${message}"
      return 1 ;;
  esac

  info "Setting DNSSEC to ${setting}"
  dns_sec="${setting}"
}

main() {
  local script_type="$1"
  shift
  local dev="$1"
  shift

  if [[ -z "$script_type" ]]; then
    usage 'No script type specified'
    return 1
  elif [[ -z "$dev" ]]; then
    usage 'No device name specified'
    return 1
  elif ! declare -f "${script_type}" &>/dev/null; then
    usage "Invalid script type: '${script_type}'"
    return 1
  else
    if ! read -r link if_index _ < <(get_link_info "$dev"); then
      usage "Invalid device name: '$dev'"
      return 1
    fi

    "$script_type" "$link" "$if_index" "$@"
  fi
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]] || [[ "$AUTOMATED_TESTING" == 1 ]]; then
  set -o nounset

  main "${script_type:-}" "${dev:-}" "$@"
fi

Thanks for the tip! I'll have a look.

greetings
Marte

Thank you @linux-aarhus! This is great info.

I'll bookmark this thread for future reference in case I encounter any leak problem further down the road.

As said earlier, the leak tests on the sites mentioned above don't show the servers belonging to my ISP. The one and only server that shows belong to the VPN provider, I assume.

greetings,
Marte

Is it possible to use NordVPN with GUI interface on Manjaro?

Maybe - the only options for running NordVPN is installed through AUR.

I have never used any other method than the CLI - which in my opinion is by far the simplest.

But have a look at the possibilities in AUR.
https://aur.archlinux.org/packages/?O=0&K=nordvpn

Be advised that none of the methods - including the CLI mentioned in this wiki - is officially supported by Manjaro.

NordVPN have a deb-file: Maybe that's GUI?
And maybe someone has converted it to Arch?

It is the debian package from NordVPN which is the applicaiton used in this wiki.

The AUR package nordvpn-bin is a repackage of the file

https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn_2.2.0-2_amd64.deb

Thanks for info fhdk :slight_smile:

nordpy doesn't support NordLynx.

May be worth noting above.

I want to add NordVPN status to my i3status bar I can not figured out what command in terminal gives me status like UP or DOWN or something simple. Does anyone know hot to?

echo "NordVPN is $(nordvpn status | grep 'Status' | cut -d':' -f2)"
1 Like

Forum kindly sponsored by