Skip to main content

Tutorial: Configure Domain Routing Rules in Access Server from the Command-Line Interface

Abstract

Need to route specific domains through OpenVPN Access Server? This tutorial shows how to configure domain routing using the CLI with practical command examples.

Overview

Domain routing lets you control whether traffic to specific domains is sent through the VPN tunnel instead of routed directly to the internet. This is useful when IP-based routing is unreliable due to dynamic IPs or CDN-backed services.

You can configure domain routing rules:

  • Globally (applies to all users).

  • Per group.

  • Per individual user.

You can use one, some, or all of these levels at the same time, depending on your access requirements.

Domain routing rules support:

  • Exact domains (for example, example.com): Traffic is routed through the VPN only when the destination matches the exact domain. Subdomains (such as app.example.com) aren't included.

  • Wildcard domains (for example, *.example.com): Traffic is routed through the VPN for the specified domain and all of its subdomains.

  • Wildcard TLDs (for example, *.com): Traffic is routed through the VPN for all the domains that use this top-level domain (TLD).

Prerequisites

  • Access Server 3.1.0 or newer.

  • Root privileges on your Access Server's console.

  • DNS server proxy enabled globally.

  • One or more users or groups configured in Access Server.

Important

Before you begin, be aware of the following behavior:

  • Traffic for domains not explicitly defined in domain routing rules behaves as follows:

    • When using full tunnel routing, traffic to other domains is still routed through the VPN if their resolved IP addresses are public IPs.

    • When using split tunnel routing, only traffic to domains explicitly defined in access rules is routed through the VPN. All other traffic is routed directly to your local internet.

  • When a domain is specified as the destination for a user or group rule:

    • Protocol and port options are disabled.

  • Domain-based access rules require DNS server proxy. This can only be disabled using split tunnel. If DNS server proxy is disabled, the rules remain visible but are marked as inactive with a warning icon.

Before creating a domain routing rule from the CLI, determine whether a ruleset already exists for the scope you want to modify.

Rulesets may already exist if you previously created domain routing rules in the Admin Web UI.

  1. Check for existing rulesets:

    sacli AccessControlRulesetsList
  2. Look for a ruleset where the owner matches what you want to configure:

    Scope

    Owner value

    Global rules

    __DEFAULT__

    User rules

    the username (example: brandon)

    Group rules

    the group name (example: support)

  3. If you find a matching ruleset, follow Option A.

  4. If no matching ruleset exists, follow Option B.

If domain routing rules were previously created in the Admin Web UI, a ruleset already exists. You must add new rules to that ruleset.

  1. To identify the ruleset ID, run:

    sacli AccessControlRulesetsList
    • Example output:

      [
        {
          "comment": "Default ruleset for global domain rules",
          "id": 1,
          "name": "__DEFAULT___default_ruleset",
          "owner": "__DEFAULT__",
          "owner_type": "user_default",
          "position": 0
        }
      ]
  2. Note the id value (in this example: 1).

  3. To check for existing rules in the ruleset, run:

    sacli --ruleset_id1 'id' AccessControlRulesList

    1

    Replace ruleset_id with the id value noted above.

    • Example output:

      [
        {
          "action": "nat",
          "comment": "",
          "id": 1,
          "match_data": "app1.example.com",
          "match_type": "domain",
          "position": 0,
          "ruleset_id": 1,
          "type": "domain_routing"
        }
      ]
  4. Note the position of the last rule.

  5. New rules must use the next available position.

    • Example:

      existing rule position = 0
      next rule position = 1
  6. Create a new, global domain rule:

    sacli --ruleset_id "1" --rule_type "domain_routing" --match_type "domain" --match_data "app2.example.com" --action "nat" --position "1" --comment "" AccessControlRulesAdd

    Parameter

    Value

    ruleset_id

    Use the value from the global ruleset output.

    match_type with domain

    Match an exact domain. For example, app2.example.com.

    match_type with domain_or_subdomain

    Match wildcard domains. For example, example.com.

    Tip

    Wildcard domain syntax differs between interfaces:

    • CLI: example.com

    • Admin Web UI: *.example.com

    match_data

    Domain to route.

    action with nat or route

    How to manage traffic for this domain. NAT: traffic leaves using the server IP. Route: traffic keeps the client VPN IP.

    position

    Use the value for the next available position noted above.

  7. Restart Access Server:

    sacli start
  8. Verify the rule:

    sacli --ruleset_id1 'id' AccessControlRulesList

    1

    Replace ruleset_id with the id noted above.

If no ruleset exists, you must create one before adding rules.

  1. Create a new global ruleset:

    sacli --name "__DEFAULT___default_ruleset" --comment "Default ruleset for global domain rules" AccessControlRulesetsAdd
    • Example output:

      1
  2. Take note of this number as the ruleset id.

  3. Create your new global domain routing rule:

    sacli --ruleset_id "1" --rule_type "domain_routing" --match_type "domain" --match_data "app2.example.com" --action "nat" --position "1" --comment "" AccessControlRulesAdd

    Parameter

    Value

    ruleset_id

    Use the value from the global ruleset output.

    match_type with domain

    Match an exact domain. For example, app2.example.com.

    match_type with domain_or_subdomain

    Match wildcard domains. For example, example.com.

    Tip

    Wildcard domain syntax differs between interfaces:

    • CLI: example.com

    • Admin Web UI: *.example.com

    match_data

    Domain to route.

    action with nat or route

    How to manage traffic for this domain. NAT: traffic leaves using the server IP. Route: traffic keeps the client VPN IP.

    position

    Use the value for the next available position noted above.

  4. Attach the ruleset to the target:

    sacli --user "__DEFAULT__" --position "0" --ruleset_id "1" AccessControlUserRulesetsAdd

    Tip

    Global rules use the __DEFAULT__ user. For users or groups, replace __DEFAULT__ with the username or group name.

  5. Restart Access Server:

    sacli start
  6. Verify the rule:

    sacli --ruleset_id1 'id' AccessControlRulesList

    1

    Replace ruleset_id with the id noted above.

In this step, we assume the following user ruleset and rule.

  • Example ruleset:

    [
        "comment": "Auto-created ruleset for user brandonqa",
        "id": 2,
        "name": "Ruleset for brandonqa",
        "owner": "brandonqa",
        "owner_type": "user_connect",
        "position": 1
    ]
  • Example rule:

    [
      {
        "action": "nat",
        "comment": "",
        "id": 1,
        "match_data": "app3.example.com",
        "match_type": "domain",
        "position": 1,
        "ruleset_id": 2,
        "type": "domain_routing"
      }
    ]

For our example, we will update the rule to change the domain from app3.example.com to app4.example.com.

  1. Run the following command to update the rule:

    sacli --rule_id '1' --ruleset_id '2' --rule_type 'domain_routing' --match_type 'domain' --match_data 'app4.example.com' --action 'nat' --position '1' --comment '' AccessControlRulesUpdate

    Parameter

    Value

    ruleset_id

    Use the value from the global ruleset output.

    match_type with domain

    Match an exact domain. For example, app2.example.com.

    match_type with domain_or_subdomain

    Match wildcard domains. For example, example.com.

    Tip

    Wildcard domain syntax differs between interfaces:

    • CLI: example.com

    • Admin Web UI: *.example.com

    match_data

    Domain to route.

    action with nat or route

    How to manage traffic for this domain. NAT: traffic leaves using the server IP. Route: traffic keeps the client VPN IP.

    position

    Use the value for the next available position noted above.

    Tip

    In our example, we modify only the domain, but you can modify any value based on your needs.

  2. Restart services:

    sacli start
  3. Verify the rule:

    sacli --ruleset_id1 'id' AccessControlRulesList

    1

    Replace ruleset_id with the id noted above.

In this step, we assume the following user ruleset and rule.

  • Example ruleset:

    [
        "comment": "Auto-created ruleset for user brandonqa",
        "id": 2,
        "name": "Ruleset for brandonqa",
        "owner": "brandonqa",
        "owner_type": "user_connect",
        "position": 1
    ]
  • Example rule:

    [
      {
        "action": "nat",
        "comment": "",
        "id": 1,
        "match_data": "app5.example.com",
        "match_type": "domain",
        "position": 1,
        "ruleset_id": 2,
        "type": "domain_routing"
      }
    ]
  1. Run the following command to delete the rule:

    sacli --rule_id1 '1' AccessControlRulesDelete

    1

    Replace rule_id with the id from the rule you're deleting.

  2. Restart services:

    sacli start
  3. Verify the rule was deleted:

    sacli --ruleset_id1 'id' AccessControlRulesList

    1

    Replace ruleset_id with the id noted above.