OpenVPN как не принять предложение сервера о настройке интерфейсов

В повседневной работе я пользуюсь десятками включённых VPN клиентов. Эти клиенты соединяются с разными серверами, а серверы имеют разные настройки. Так например у меня возникала ситуация когда нужный мне роут пробрасывался через TUN интерфейс который PUSH-ился с сервера. Если бы сервер использовал только я стоило бы перенастроить только сервер чтобы это исправить. Однако сервером пользуются и другие люди и там этот PUSH необходим. Сначала я руками переписывал роут и забывал до следующего переподключения. Но последнее время часто приходилось переподключаться и вечное переписывание роута стало раздражать. В документации к OpenVPN написано что в настройках с недавнего времени появился ключ который поможет клиенту отвергнуть то что ему предлагает сервер.

–route-noexec
Don’t add or remove routes automatically. Instead pass routes to –route-up script using environmental variables.

Не добавлять маршруты автоматически. Вместо этого передавать маршруты в –route-up скрипт используя переменные окружения.

–route-nopull
When used with –client or –pull, accept options pushed by server EXCEPT for routes and dhcp options like DNS servers.
When used on the client, this option effectively bars the server from adding routes to the client’s routing table, however note that this option still allows the server to set the TCP/IP properties of the client’s TUN/TAP interface.

Когда используется опция –client или –pull, принять опции переданные сервером ИСКЛЮЧАЯ опции для маршрутов и dhcp опции например DNS серверы.
Когда используется на клиенте, эта опция эффективно “затыкает” сервер от попытки добавить маршруты в таблицу маршрутизации клиента, хотя имейте ввиду что эта опция по прежднему позволяет серверу устанавливать свойства TCP/IP для клиентского TUN/TAP интерфейса.

Эти две опции помогут избавиться от роутов которые насаждает сервер. Но так как мне нужно избавиться только от маршрута по-умолчанию (default route) но оставить другие то придётся воспользоваться скриптом который это сделает самостоятельно.

В конфигурационный файл клиента нужно добавить следующие строки:

# disable accept push options from server
route-noexec
route-nopull

script-security 2
up /etc/openvpn/vpn.setuproute.sh
down /etc/openvpn/vpn.setuproute.sh

А это содержимое файла /etc/openvpn/vpn.setuproute.sh

#!/bin/bash

IP="/usr/sbin/ip"

function LOGMSG {
  echo -e "OpenVPN script: $1" >&2
}

case "${script_type}" in
  up)
    LOGMSG "Up script..."
    if [ -n "${ifconfig_remote}" ] && [ -n "${dev}" ] ; then
      result=`${IP} route add 10.5.0.0/16 via ${ifconfig_remote} dev ${dev} 2>&1`
      if [ $? -ne 0 ] ; then
        LOGMSG "route add error: ${result}"
      else
        LOGMSG "route to 10.5.0.0/16 was added OK"
      fi
    else
      message=`echo -e "Some variables are empty:\ndeclare -x ifconfig_remote=\"${ifconfig_remote}\"\ndeclare -x dev=\"${dev}\""`
      LOGMSG "${message}"
    fi
  ;;
  down)
    LOGMSG "Down script..."
  ;;
  *)
    LOGMSG "No type script..."
  ;;
esac

exit 0

Так как скрипт я писал на быструю руку то решил сильно не париться и использовать не очень универсальный подход: статический маршрут в сеть за TUN интерфейсом. Может когда конфигурация сервера будет меняться часто — я сделаю на основе переменных окружения. Также я не стал обрабатывать ситуацию с опусканием интерфейса и удалением маршрута, а оставил лишь заготовку.