Jump to content
Not connected, Your IP: 18.222.78.65
tamitos

Can I store multiple VPN server in DD WRT?

Recommended Posts

I want to use airvpn on my R7000. Currently, I can add single airvpn server to my router. I want to be able to switch to other airvpn server without reconfigure my router. Is there any possible chance to do it?

Share this post


Link to post

I just have a text file that has the IP addresses of all the servers I frequently use.  If one is acting up, I'll just copy-paste it into the DD-WRT admin's VPN field and apply changes.

Share this post


Link to post

I have them in the startup command section of DD-WRT...like this.

 

# Air Server List 10/1/2015

# USA
# Chicago - 46.21.154.82, 149.255.33.154
# Fremont Cali - 46.21.151.106, 94.100.23.162
# Jacksonville - 198.203.28.42
# Miami - 96.47.229.58, 173.44.55.154, 173.44.55.178
# Pennsylvania - 104.243.24.235
# Phoenix - 104.219.251.46

 

It doesn't actually do anything but it's nice to have a list within the router settings.

Share this post


Link to post

@MrConducter nice idea.

 

By the way, do we have to change CA Cert, Private Client Key, TLS Auth Key, Public Cert every time we change server?

Share this post


Link to post

Hello, 

 

I am trying do set up my dd-wrt server with multiple servers. My configuration works when in put a specific ip of a server in the "Server/IP name" field (see attached screenhot). But when I try to enter something like europe.all.vpn.airdns.org in this field the connection does not work. I get the attached error message in the log. What should I enter in the "Server/IP name" field to be able to connect to different servesr in the case on of them is down?

 

 

 

 

Share this post


Link to post

Hello!

 

The name can not be resolved: please check the DNS settings. Also keep in mind that VPN DNS can be accessed only from inside the VPN.

 

Kind regards

Share this post


Link to post

Here's something I do for randomly connecting to preferred servers via a shell script on Linux. This might give you some ideas:

 

  • Create a directory containing ovpn config files of your favorite nodes, e.g. /etc/airvpn
  • Connect to a random preferred node:
vpnconfig=$(ls -1 /etc/airvpn/*.ovpn | sort -R | tail -1) # this will sort ovpn files in random order and pick the last one in the list
openvpn --config $vpnconfig
 
  • Check if openvpn is running, and if not, run a script that restarts it or does something else
pidof openvpn > /dev/null 2>&1
if [ $? = 1 ]; then
        echo "do some stuff here"
        /usr/local/sbin/somescript.sh # run some other script
fi
  • Check your exit IP and maybe script some logic around the result. wget works too.
echo $(curl -s ifconfig.me/ip)
198.203.28.43
 

 

It's been a while since I've used DD-WRT, but you could add some scripts to crontab to make sure the VPN is always up, and add a script to the startup script section of the router.  You would then no longer need to use the web ui input fields for VPN server / IP, etc.

Share this post


Link to post

The method I use is a custom Tampermonkey (browser plugin) "userscript", that calls the AirVPN API "status" endpoint and swaps out the DD-WRT GUI IP/port text input fields on the "VPN" page with select versions with current AirVPN server info, when that page loads.
 
I'll add some screen shots showing the script behaviour. Maybe others might find it useful, so I've posted it below.
 
I use Linux Mint 18.3, latest Chromium (71.0.3578.98[/size]) and Tampermonkey 4.7.63, no guarantees it works with other setups (although it should).
 
Here's the script:
 
You will need to replace the script header value "<YOUR_ROUTER_IP>" with your router IP address.

 

And, the forum software is encoding the "dollar" character as "36;". You may need to do a find/replace on that.
 

// ==UserScript==
// @name        DD-WRT AirVPN server select
// @namespace   https://dd-wrt-userscripts.org/gmscripts
// @version     1.0
// @description Augments the DD-WRT VPN client form, changing the VPN server IP and port input fields into selection lists
// @author      Anon
// @include     http://<YOUR_ROUTER_IP>/PPTP.asp
// @include     http://<YOUR_ROUTER_IP>/applyuser.cgi
// @grant       GM_xmlhttpRequest
// @require     https://code.jquery.com/jquery-3.3.1.min.js
// @connect     airvpn.org
// @run-at      document-end
// ==/UserScript==

 (function ($) {
  'use strict';

  /**
   * AirVPN server(s)/connection data.
   */
  function AirVpn() {
    this.api_data = [];
    this.country_list = [];
    this.server_list = [];
    this.port_list = [53, 80, 443, 1194, 2018, 28439, 38915, 41185];
    this.base_api_url = 'https://airvpn.org/api';

    this.callStatusApi = function() {
      var that = this;

      return new Promise(function(resolve, reject) {
        var result = GM_xmlhttpRequest({
          'method': 'GET',
          'url': that.base_api_url + '?service=status&format=json',
          'timeout': 5000,
          'onload': function(response) {
            if (response.status == 200) {
              resolve(response.responseText);
            }
            else {
              reject(Error(response.statusText));
            }
          }
        });
      });
    }

    this.getCountryList = function(api_country_list) {
      if (this.country_list.length === 0) {
        this.setCountryList(api_country_list);
      }

      return this.country_list;
    }

    this.getServerList = function(country_list, api_server_list) {
      if (this.server_list.length === 0) {
        this.setServerList(country_list, api_server_list);
      }

      return this.server_list;
    }

    this.getPortList = function() {
      return this.port_list;
    }

    this.getApiCountryList = function() {
      return this.api_data.countries;
    }

    this.getApiServerList = function() {
      return this.api_data.servers;
    }

    this.setCountryList = function(api_country_list) {
      var that = this;

      api_country_list.forEach(function(item) {
        that.country_list[item.country_code] = item;
      });
    }

    this.setServerList = function(country_list, api_server_list) {
      // The .sort() here is a performance hit, but we don't have an option to
      // sort via the API call, so we do it here instead.
      this.server_list = api_server_list.map(function(server_details) {
        var server = new Server(server_details);
        server.best = (country_list[server_details.country_code].server_best === server_details.public_name);

        return server;
      }).sort(function(a,  {
        if (a.country > b.country) {
          return 1;
        }

        if (a.country < b.country) {
          return -1;
        }

        return 0;
      });
    }

    this.setApiData = function(api_data) {
      this.api_data = api_data;
    }

  }

  /**
   * Define a server.
   */
  function Server(server_details) {
    this.country = server_details.country_code.toUpperCase();
    this.group_name = server_details.location + ' ' + server_details.public_name;
    this.name = server_details.public_name;
    this.entry_ips = [
      server_details.ip_v4_in1,
      server_details.ip_v4_in2,
      server_details.ip_v4_in3,
      server_details.ip_v4_in4
    ];
    this.status = server_details.health;
    this.best = false;
  }

  /**
   * Define DD-WRT VPN page elements the script will interact with.
   */
  function DdwrtGuiElementInfo() {
    this.ip = 'openvpncl_remoteip';
    this.port = 'openvpncl_remoteport';
    this.vpn_client_started = 'openvpncl_enable';

    this.getIpControlName = function() {
      return this.ip;
    }

    this.getIpControlSelector = function() {
      return 'input[name = "' + this.ip + '"]';
    };

    this.getPortControlName = function() {
      return this.port;
    }

    this.getPortControlSelector = function() {
      return 'input[name = "' + this.port + '"]';
    };

    this.getVpnClientStartedName = function() {
      return this.vpn_client_started;
    }

    this.getVpnClientStartedSelector = function() {
      return 'input[name = "' + this.vpn_client_started + '"]:checked';
    }

  };

  /**
   * Allow representation/interaction with the DD-WRT GUI.
   */
  function DdwrtGui() {

    this.getControlValue = function(selector) {
      var value = '';

      if ($(selector).length) {
        var $element = $(selector);
        value = $element.val().trim();
      }

      return value;
    };

    this.isVpnPage = function(gui_element_info) {
      var selector = gui_element_info.getIpControlSelector();

      if ($(selector).length) {
        return true;
      }

      return false;
    }

    this.isVpnClientStarted = function(gui_element_info) {
      var selector = gui_element_info.getVpnClientStartedSelector();

      return (this.getControlValue(selector) == 1);
    }

    this.replaceFormControls = function(airvpn, gui_element_info) {
      this.replaceIpControl(
        gui_element_info.getIpControlName(),
        airvpn.getServerList(
          airvpn.getCountryList(airvpn.getApiCountryList()),
          airvpn.getApiServerList()
        ),
        gui_element_info.getIpControlSelector()
      );

      this.replacePortControl(
        gui_element_info.getPortControlName(),
        airvpn.getPortList(),
        gui_element_info.getPortControlSelector()
      );
    }

    this.replaceIpControl = function(control_name, server_list, control_selector) {
      var markup = this.buildIpSelect(
        control_name,
        server_list,
        this.getControlValue(control_selector)
      );

      $(control_selector).replaceWith(markup);
    }

    this.replacePortControl = function(control_name, port_list, control_selector) {
      var markup = this.buildPortSelect(
        control_name,
        port_list,
        this.getControlValue(control_selector)
      );

      $(control_selector).replaceWith(markup);
    }

    this.buildIpSelect = function(control_name, servers, current_server_ip) {
      var markup = '<select name="' + control_name + '">';

      for (var i = 0; i < servers.length; i++) {
        var server = servers[i];
        markup += '<optgroup label="' + this.buildIpOptGroupLabel(server) + '" style="' + this.buildIpOptGroupCss(server) + '">';

        for (var j = 0; j < server.entry_ips.length; j++) {
          var option_label = this.buildIpOptionLabel(server, j);
          markup += this.buildSelectOption(current_server_ip, server.entry_ips[j], option_label);
        }

        markup += '</optgroup>';
      }

      markup += '</select>';

      return markup;
    }

    this.buildIpOptGroupLabel = function(server) {
      var label = '(' + server.country + ') ';
      var name = server.group_name;

      if (server.best) {
        name += ' *';
      }

      return label + name;
    }

    this.buildIpOptGroupCss = function(server) {
      var css = '';

      if (server.status == 'warning') {
        css = 'background-color: #F8C471;';
      } else if(server.status == 'error') {
        css = 'background-color: #F1948A;';
      }

      return css;
    }

    this.buildIpOptionLabel = function(server, zero_based_entry_ip_index) {
      var name = server.name;

      if (server.best) {
        name = '* ' + name;
      }

      return '(' + server.country + ') ' + name + ', entry IP ' + (zero_based_entry_ip_index + 1) + ' (' + server.entry_ips[zero_based_entry_ip_index] + ')';
    }

    this.buildPortSelect = function(control_name, port_list, current_server_port) {
      var markup = '<select name="' + control_name + '">';

      for (var i = 0; i < port_list.length; i++) {
        markup += this.buildSelectOption(current_server_port, port_list[i], port_list[i]);
      }

      markup += '</select>';

      return markup;
    }

    this.buildSelectOption = function(current_value, option_value, option_label) {
      var markup = '<option value="' + option_value + '"';

      if (current_value == option_value) {
        markup += ' selected="selected"';
      }

      markup += '>' + option_label + '</option>';

      return markup;
    }

    this.showApiCallStatus = function(status) {
      var message = '<span class="progress-message">' + status + '</span>';

      if ($('.vpn-api-call').length) {
        $('.vpn-api-call .progress-message').replaceWith(message);
      }
      else {
        var markup = '<div class="setting vpn-api-call"><div class="label">"status" API call:</div>' + message + '</div>';

        $('#idvpncl').prepend(markup);
      }
    }

    this.alterVpnPage = function(gui_element_info, airvpn) {
      // VPN service page is available under 2 separate URLs. Instead of
      // relying on the URLs, check for form control existence before trying to
      // update the page.
      if (this.isVpnPage(gui_element_info) && this.isVpnClientStarted(gui_element_info)) {
        var that = this;
        this.showApiCallStatus('Ready');

        airvpn.callStatusApi().then(function(response) {
          that.showApiCallStatus('Parsing response...');
          return JSON.parse(response);
        }).then(function(api_response_json) {
          that.showApiCallStatus('Complete');
          airvpn.setApiData(api_response_json);
          that.replaceFormControls(airvpn, gui_element_info);
        }).catch(function(error) {
          that.showApiCallStatus(error);
        });
      }
    }

  }

  var gui = new DdwrtGui();
  gui.alterVpnPage(new DdwrtGuiElementInfo(), new AirVpn());

})(window.jQuery.noConflict(true));

I'm unsure if the DD-WRT GUI changes between builds, if it does, you might need to alter the form control properties in the "DdwrtGuiElementInfo" object.

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Security Check
    Play CAPTCHA Audio
    Refresh Image

×
×
  • Create New...