In this how-to we will cover what it takes to setup your Ubiquiti UniFi environment to handle USG products that need to have multiple WAN addresses.


I've used this document to create this how-to.  Please refer to this document for more information.

https://community.ubnt.com/t5/UniFi-Routing-Switching/USG-Pro-Multiple-WAN-IPS-mapped-to-various-internal-locations/m-p/1770942#U1770942


We will be setting up a UniFi management host on Windows and connecting a Ubiquiti USG 3P.

I am currently using:

  • Microsoft Windows Server 2012R2
  • Ubiquiti UniFi Controller version 5.7.20 (current as of 4/4/2018)
  • Ubiquiti USG 3P w/ firmware 4.4.18.5052168 (current as of 4/4/2018)
  • Notepad++ as my text editor


My network configuration, for this example, will be:

  • External network addresses: 
    • 1.2.3.1
    • 1.2.3.2
  • Internal network addresses:
    • 192.168.1.254 (gateway address)
    • 192.168.1.250 (web server address)


NOTE:  The major complaint with Ubiquiti on the USG and multiple WAN IP addresses is that is deviates from the "easy to manage" GUI that we all love.  We will need to create a JSON file (which I will talk about) and place it on our controller to get this working.


Initial Setup.

For this example to work I have setup my USG 3P as:

  • Internal IP address: 192.168.1.254/24
  • External IP address: 1.2.3.1/29
  • Gateway address: 1.2.3.9
  • DNS Server(s): 1.1.1.1 & 1.0.0.1

You can setup these parameters via the GUI after you have adopted the USG.

You would click DEVICES > [Your USG] within the GUI.

When you click on your USG appliance, you will see a "Properties" page (see below).


We need to click on the "Config" tab (step 1 in image above) and then expand "WAN" settings (step 2 in image above).

Once we have all out IP parameters set, we can scroll to the bottom of the page and click on the "Queue Changes" button.

When we do this, our USG will provision the system as our configuration has defined.


The JSON file... what is this thing?

First, what is JSON... JSON stands for JavaScript Object Notation.

This is a way of using a flat file as a data structure, similar to XML.

So, using that example, within the JSON file we declare things... names of parameters or data we choose to define.

We then assign values to those declared things using the notation required within JSON.


For Example:


{
    "interfaces": {
        "ethernet": {
            "eth0": {
                "address": [
                    "1.2.3.1/29",
                    "1.2.3.2/29"
                ]
            }
        }
    }
}

Within this JSON example we declare "interfaces" then "ethernet" then "eth0" then "address" and assign values of "1.2.3.1" and "1.2.3.2" to it.

Or, in other words, we want to assign "1.2.3.1" and "1.2.3.2" as the "address" of the "eth0" "ethernet" interface (as declared by "interfaces").


Where do I put the JSON file?

On Windows, you would put this file in the Ubiquiti UniFi installation folder.

This is held under the profile that installed it.

For my example, I did this as "Administrator" and thus it is in the folder "C:\Users\administrator\Ubiquiti UniFi\"

But, as we know, UniFi can manage multiple sites... so, we need to put this in the site folder that correlates to the site we are working with.

So for my example, I used the "default" site and thus it is in the folder "C:\Users\administrator\Ubiquiti UniFi\data\sites\default".


NOTE:  You will need to check your installation to make sure that your location is similar to the same as mine to follow along.


Within this folder, we need to create a file called "config.gateway.json"... no other name will work.

You can do this by opening Notepad++ and saving your file to this location with this name.

Don't worry, it will not be pushed out until you do it manually.


Declaring my external addresses in the JSON file.

In my above snippet, you saw that I declared two addresses... 1.2.3.1 and 1.2.3.2.

This is the actual code you will use to declare your addresses as well (see below).


{
    "interfaces": {
        "ethernet": {
            "eth0": {
                "address": [
                    "1.2.3.1/29",
                    "1.2.3.2/29"
                ]
            }
        }
    },
...

Things to note about this:

  • The addresses are declared with the subnet mask CIDR (the "/29" in this case representing 255.255.255.248)
  • Each opening bracket must be closed or it will not work.
  • Declaring multiple values requires the use of a comma [,] to separate them
  • Values/Declarations are enclosed in parenthesis ["]
  • Value groups are enclosed in square brackets
  • The "..." declares that this is not the end of the file but just part of it


We could declare more addresses by adding a comma and then a return/CR and then "1.2.3.3/29" or "4.3.2.1/29" or whatever.


If we simply save this as our config.gateway.json file, we would just bind two addresses to the external interface, eth0... which isn't very helpful.


Using our external addresses to separate traffic.

The reason you are reading this is to figure out how to publish multiple things, with multiple addresses, behind a Ubiquiti USG appliance.

For my example, I will be publishing a web server to the internet on address 1.2.3.2 using ports 80 and 443.


NOTE: In my original setup of the USG appliance I configured my WAN address to be "1.2.3.1/29".  This is the address that will be used for NAT/Masquerading addresses from LAN to WAN.


...
    "service": {
        "nat": {
            "rule": {
                "1000": {
                    "description": "Web Server",
                    "destination": {
                        "address": "1.2.3.2",
                        "port": "80,443"
                    },
                    "inbound-interface": "eth0",
                    "inside-address": {
                        "address": "192.168.1.250"
                    },
                    "protocol": "tcp",
                    "type": "destination"
                }
            }
        }
    }
}

Things to note about this:

  • The "..." declares that this is not the start of the file but just part of it
  • We are declaring a "description", "destination", "inbound-interface", "inside-address", "protocol" and "type"
  • We are also declaring "address" and "port" under "destination" and "address" under "inside-address"
  • We are also setting values for some of our declarations.
  • Each declaration is separated by a comma [,] and the entire thing is enclosed in bracket


To break down what this does, let's look at the parts.


We tell UniFi to define a new NAT rule, number 1000, under the NAT service.

We are telling it that we want a description of "Web Server" for our rule.

We are telling it that the destination is address 1.2.3.2 on ports 80 and 443.

We are telling it that it should listen for this on inbound interface eth0.

We then tell it to push this (as the nature of NAT) to inside address 192.168.1.250 using the TCP protocol and this is the destination.


Does that make sense?  If not, re-read it and look at the JSON snippet... it will.


Putting it all together.

When we look at it all together the puzzle starts to make sense.

Here is the entire JSON file that we will put in the site folder on our UniFi Controller host.


{
    "interfaces": {
        "ethernet": {
            "eth0": {
                "address": [
                    "1.2.3.1/29",
                    "1.2.3.2/29"
                ]
            }
        }
    },
    "service": {
        "nat": {
            "rule": {
                "1000": {
                    "description": "Web Server",
                    "destination": {
                        "address": "1.2.3.2",
                        "port": "80,443"
                    },
                    "inbound-interface": "eth0",
                    "inside-address": {
                        "address": "192.168.1.250"
                    },
                    "protocol": "tcp",
                    "type": "destination"
                }
            }
        }
    }
}

Once we have our "config.gateway.json" file in our site's directory on our UniFi Controller host, we need to push this configuration to the USG appliance.

We do this manually by clicking DEVICES > [Your USG] within the GUI.

We need to click on the "Config" tab, then expand "Manage Device" and click the "Provision" button.

Our USG will take you Offline for a moment while it uploads this JSON file and reconfigures the WAN port the first time (subsequent times it should not).


That's all there is too it.


Thank you to each of the writers of the articles I read trying to figure this out.

Thank you to Ubiquiti tech support for chatting with me during my first try of this.


I hope this helps.