As described in a few previous blog posts I needed to set some configuration through the command line for my USG. But every time you provision the USG the changes will be lost. This can be solved to store the changes in the config.gateway.json file on my cloud key. Since the cloud key is running Ubuntu I can find that file in /usr/lib/unifi/data/sites/default (your site can be named differently, but mine is the default).
This is my current configuration, it both contains the IPV6 configuration for Comcast and my VPN routing information. Line 74-89, Line 135-173 are the lines specific to my source address based routing setup.
"description":"Allow Enabled/Related state",
"description":"Drop Invalid state",
"description":"Allow Enabled/Related state",
"description":"Drop Invalid state",
"description":"traffic from eth1.100 to VPN NL",
What I did to create this file was login to my USG, via configure set 1 configuration file. Entered the command mca-ctrl -t dump-cfg to see what the config looked like and copied the correct node into the file. After saving I did a forced provisioning of the USG from the UI and checked if it worked (show configuration).
Updated 10/24/2018 since routing didn’t work anymore. You have to disable source-validation, thanks to Roelf for the comment with the correct command.
For some time now I wanted to be able to test some network stuff. I want to be able to connect certain devices over a VPN to the Netherlands but without the need to configure every client with VPN connections.
With this scenario it is possible to test different geo stuff accessing my network from different places in the world, it also helps me test the different latencies when going across the ocean and back. It also could be used to access certain video services in another country or access a different Netflix catalog, but I would never use it for something like that obviously
After reading up on the different forums and asking some questions I was able to configure my USG in a way which gives me the most flexibility possible for my scenario. This is the step by step guide how to configure your USG and network so all your network on that special network will be routed over the VPN connection to the Netherlands.
The first step is to configure my ‘hoekstraonline NL’ network as described in this blogpost. Connecting through my ‘hoekstraonline NL’ wireless network and specific ports on my router (tagged with the same VLAN 100) will be the basis of my configuration. I want all that network going over the VPN connection to NL. All me regular traffic will go over my Comcast connection as usual but machines connected to that wireless network and specific ports on my routers will be routed over the VPN connection.
So lets create the VPN Client network first. Nowadays this can be done through the UI (I am running Unify version 5.6.20 stable candidate when I am writing this)
After you create this network you can check on your USG how the routing table looks like. It should have added the VPN NL network. Enter the following command on your USG (via SSH):
ubnt@USG:~$ netstat -r
My routing table looks like this:
the pptpc0 interface is the VPN connection I just defined, you can see from the flags the connection is up (U). The eth1.100 is the virtual network which was added in the previous blogpost.
The next step is to change the routing depending on the source address. Unfortunately this can’t be done through the GUI from Unifi. They add more and more functionality every month, but this has to be done through the command line. so fire up your bash shell or putty and connect to your firewall (USG in my case).
In the shell type; configure
We have to define a new routing table we call table 1 which will route traffic to my VPN connection on the 10.0.0.0/24 network.
Now we have to define the modify policy. A modify policy allows us to modify various items when the rule matches. So if the source address came from 192.168.2.0, then we want to use routing table 1:
ubnt@RTR# set firewall modify SOURCE_ROUTE rule 10 description ‘traffic from eth1.100 to VPN NL’
ubnt@RTR# set firewall modify SOURCE_ROUTE rule 10 source address 192.168.2.0/24
ubnt@RTR# set firewall modify SOURCE_ROUTE rule 10 modify table 1
Now we need to apply this policy to the interface. When it comes to applying a policy to an interface, it needs to be done on the input interface before the routing lookup takes place.
ubnt@USG# set interfaces ethernet eth1 vif 100 firewall in modify SOURCE_ROUTE
A last step which you need to add (this changed so this step was added 10/24/2018) is to disable source validation (thanks to Roelf for the comment and help)
ubnt@USG# set firewall source-validation disable 
After this you can give the commit and save command and you can test your network routing. From a client in the 192.168.1.x range nothing should be different. But when you test it from a 192.168.2.x client you see the traceroute change to the 10.0.0.1 hop and than off to the Netherlands.
The first tracert is from a machine in the 192.168.1.x range. You see the first hop is my USG gateway and than it goes out to the internet.
The second tracert is from the machine when it’s in the 192.168.2.x range. You see the second hop goes through the 10.0.0.0 VPN gateway and you also see the response times go up since it’s traveling the ocean now.
The last step is to add these settings to the provisioning script stored on my cloudkey, so when I reset the USG the settings won’t be lost.
Some time ago I bought new network gear for my home from Ubiquiti. The Unifi range of hardware is very nice. It’s a bit pricy but you can do so much interesting stuff with it and the hardware is rock solid.
I am configuring my network to be able to use a VPN connection to The Netherlands depending on what wireless network or what physical network port the client is using. To be able to do that I first needed to add a network which operates on a different IP range. My network is by default configured to use the 192.168.1.0/24 range. But for this network I need to add a 192.168.2.0/24 range. The following steps is what I used to configure this.
Fortunately all steps can be done through the UI. I am running Unifi version 5.6.20 stable candidate when writing this. Depending on the version you are running the screens might look a bit different since they are adding more and more functionality every month.
First I created a new network with the following settings:
I tagged the network with VLAN value 100. This value we need in the next part of the setup. I also configured the DHCP server for the 192.168.2.0/24 range. When you fill in these numbers it will automatically calculate the subnet mask etc.
Once that is done I needed to configure the new wireless network. I called my network Hoekstraonline NL so it’s easy to identify. By itself this network would get the same IP addresses as my other wireless networks. But since I needed a seperate network which is also by default blocked through the firewall from my other networks, I tagged this network with the VLAN value 100 as well.
That was all. When I connect my devices to this wireless network they receive an IP address in the 192.168.2.x range. When I tag a network port on my switch with VLAN 100 the devices connected to that port will also get an IP address in that range.
Next step is configuring source address based policies.
As every year, Windows was a big part of BUILD. For convenience (and my own) I listed all recorded and pre-recorded sessions from Windows below. Enjoy (Click the title of the session to go to the Channel9 page).
Update (11/22/2017) for Unifi 5.7.7 or higher which added ipv6 support in the UI.
FInally ubnt added IPv6 support to the UI of Unifi. This was introduced in the 5.7.7 release. I removed the changes below from the config.gateway.json file. Provisioned the USG and confirmed all IPV6 settings were gone. My clients on the network didn’t get an IPv6 address anymore either. If you check your interfaces on the USG you should see an ipv6 address from Comcast. Your eht1 interface will only have a ipv4 address.
First open your USG device in your Unifi Dashboard and enable ipv6 as follows, for Comcast I filled in 64 as the Prefix Delegation Size
Next you have to configure ipv6 for all your networks. Go to Networks. open LAN (edit) and select the IPv6 interface type. Click save and your are set. You can enable this on other networks you have configured as well of course.
Now check your clients if they get an iIPv6 address and you can test at http://test-ipv6.com/ to see if everything works. Way simpler than with the config file. Cool new feature is you have IPv6 firewall rules in the UI as well under the Routing & Firewall chapter.
Information for Unifi below 5.7.7
So far there is no way to configure IPv6 through the UI, it’s on the roadmap though. But you can very easily set it up through the command line or through provisioning a configuration file. I have been searching in the forum and found several posts explaining how to do it but neither seemed to work 100% or perhaps I did something wrong.
The easiest is go through the command line. Make an SSH connection to you USG. I use Bash on Windows to be able to use SSH.
ssh firstname.lastname@example.org (type yes if this is the first time you connect) enter your password to login to your gateway. You can enter show configuration to see what the current configuration is.
run the configure command and than run the following commands (I assume eth0 is your WAN connection with Comcast and eth1 is your internal LAN):
set interfaces ethernet eth0 dhcpv6-pd pd 0
set interfaces ethernet eth0 dhcpv6-pd pd 0 interface eth1
set interfaces ethernet eth0 dhcpv6-pd pd 0 prefix-length 64
set interfaces ethernet eth1 ipv6 router-advert prefix ::/64
set interfaces ethernet eth1 ipv6 router-advert managed-flag true
set interfaces ethernet eth1 ipv6 router-advert send-advert true
then enter the command commit
You will see some messages about Re-generating radvd config file for eth1… and Re-starting radvd: radvd.
type the command save
The next thing you might want to do is setup some firewall rules so you won’t expose all your machines with an ipv6 address directly to the internet. The following commands need to be entered in configuration mode again:
set firewall ipv6-name wan_in-6 default-action drop
set firewall ipv6-name wan_in-6 description wan_in
set firewall ipv6-name wan_in-6 enable-default-log
set firewall ipv6-name wan_in-6 rule 1 action accept
set firewall ipv6-name wan_in-6 rule 1 state established enable
set firewall ipv6-name wan_in-6 rule 1 state related enable
set firewall ipv6-name wan_in-6 rule 1 description “Allow Enabled/Related state”
set firewall ipv6-name wan_in-6 rule 2 action drop
set firewall ipv6-name wan_in-6 rule 2 log enable
set firewall ipv6-name wan_in-6 rule 2 state invalid enable
set firewall ipv6-name wan_in-6 rule 2 description “Drop Invalid state”
set firewall ipv6-name wan_in-6 rule 5 action accept
set firewall ipv6-name wan_in-6 rule 5 log enable
set firewall ipv6-name wan_in-6 rule 5 protocol icmpv6
set firewall ipv6-name wan_in-6 rule 5 description “Allow ICMPv6”
set firewall ipv6-name wan_local-6 default-action drop
set firewall ipv6-name wan_local-6 description wan_local
set firewall ipv6-name wan_local-6 enable-default-log
set firewall ipv6-name wan_local-6 rule 1 action accept
set firewall ipv6-name wan_local-6 rule 1 state established enable
set firewall ipv6-name wan_local-6 rule 1 state related enable
set firewall ipv6-name wan_local-6 rule 1 description “Allow Enabled/Related state”
set firewall ipv6-name wan_local-6 rule 2 action drop
set firewall ipv6-name wan_local-6 rule 2 log enable
set firewall ipv6-name wan_local-6 rule 2 state invalid enable
set firewall ipv6-name wan_local-6 rule 2 description “Drop Invalid state”
set firewall ipv6-name wan_local-6 rule 5 action accept
set firewall ipv6-name wan_local-6 rule 5 log enable
set firewall ipv6-name wan_local-6 rule 5 protocol icmpv6
set firewall ipv6-name wan_local-6 rule 5 description “Allow ICMPv6”
set firewall ipv6-name wan_local-6 rule 6 description “DHCPv6”
set firewall ipv6-name wan_local-6 rule 6 action accept
set firewall ipv6-name wan_local-6 rule 6 destination port 546
set firewall ipv6-name wan_local-6 rule 6 protocol udp
set firewall ipv6-name wan_local-6 rule 6 source port 547
set interfaces ethernet eth0 firewall in ipv6-name wan_in-6
set interfaces ethernet eth0 firewall local ipv6-name wan_local-6
commit and save again and you should be all set.
You can check if you received an ipv6 address by typing show interfaces
matthijs@ubnt:~$ show interfaces
Codes: S – State, L – Link, u – Up, D – Down, A – Admin Down
Interface IP Address S/L Description
——— ———- — ———–
eth0 184.108.40.206/23 u/u
eth1 192.168.1.1/24 u/u
eth2 – A/D
imq0 – u/D
lo 127.0.0.1/8 u/u
And if you have an ipv6 address you can test the connection by using ping6 www.netflix.com
matthijs@ubnt:~$ ping6 www.netflix.com
PING www.netflix.com(2620:108:700f::3425:db06) 56 data bytes
64 bytes from 2620:108:700f::3425:db06: icmp_seq=1 ttl=44 time=30.7 ms
64 bytes from 2620:108:700f::3425:db06: icmp_seq=2 ttl=44 time=33.3 ms
— www.netflix.com ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 30.740/32.035/33.331/1.307 ms
Another way to provision your USG is by creating a config.gateway.json file with your settings and place it in the /srv/unifi/data/sites/default directory on your cloudkey. (or equivalent directory when you are using the management software on another system like Windows or your Mac). You need to trigger a provisioning of your USG to make this configuration happen. This can be done by changing the HDCP lease range from 192.168.1.254 to 192.168.1.253 for example and save the configuration change. The provisioning will merge the USG configuration with the configuration in the json file.
This is the configuration file with the changes done through the command line:
One thing I hear over and over again when talking to (enterprise) developers is that they struggle with configuration management for UWP applications. In the past they just edited a app.config (or web.config) file on the machines to point an app to a test, acceptance or production environment. In UWP we have a app.config file as well but it’s hidden away in some obscure directory protected by some more restricted ACL.
We do have a solution to configure applications through MDM. It’s pretty bad documented though (which is something we will improve) but I needed to figure this out anyway so I thought I should share my findings.
As you might know we have this concept of data or settings folders in UWP. This is a special place in isolated storage where you can store settings, temporary files, settings which roam, but also configuration. The last one isn’t documented anywhere on MSDN but it does exist. There is a folder called “Managed.App.Settings” which will be created by the system if the MDM server sends out the configuration. I will talk about how to do that a little bit later.
This is how the code looks like to retrieve the configuration inside of your application:
You can specify a name and description in the next screen. Save the policy. The next piece is adding the configuration part. So at the OMA-URI Settings section click add. The screen looks like this:
You specify a name and a data type. The OMA-URI string needs to be the following for configuration: ./User/Vendor/MSFT/EnterpriseModernAppManagement/AppManagement/AppStore/3441ffd3-6b54-48b0-ac86-accdd148ea0f_f6s3q6fqr0004/AppSettingPolicy/Welcome
And specify a value of your setting in the Value textbox.
The last part if the name of you setting which you use in your code as well. In this sample it’s called Welcome. That translates back to the value we try to get in the Managed.App.Settings container.
The string after the /AppStore/ is the familypackageID you can get from your manifest. That’s how the system knows for what app it needs to store the settings data and in what location.
That’s all. You can have different type of settings, if you need a lot of data you can select the XML value type.
So next step is to try to get this working through the WMI bridge as well. Once I got that to work you should be able to run a powershell script or console app on your desktop to set this configuration as well. I believe that will help you when you have automatic builds, and test deployments in your environment.
As I described before, i have a few tasks to solve for my home automation project. One of the things I wanted to do is to be able to update my application on the different devices easily. I could publish my home automation app to the store, but it’s hard to provide a test environment for the store testers and it takes a while when the app gets certified before i can roll it out to all my devices. Of course I can sign up for an Intune account and use regular MDM to manage my apps, but 1st i need to have this Intune environment which I think is a bit over the top, and 2nd I would be depending on an internet connection. This is also a topic which comes up with some of my customers so I thought I could solve this differently.
Since the app is going to be side loaded I am allowed to use restricted capabilities. The store app uses these capabilities to be able to download and update apps from the store so what APIs are used by this app? It uses (among others) the PackageManager class. This API is protected by the restricted capability packageManagement.
So the first experiment I tried was to build an update button in a test app and I tried to update myself. I created a version 220.127.116.11 (Project, Store, Create App Package and set the version to 18.104.22.168, I also created a version 22.214.171.124) In my code I added the following line in the click event:
Where the packageLocation pointed to a file on my disk (but could also be a URL to a website). But updating yourself didn’t work. So the next idea I had was to write a little app which I could call with app2app communication and the only thing that little app would do was update the calling app. This works perfectly. So I created a new project called AppUpdate (Blank App). I added another project to the solution called AppUpdaterService (Windows Runtime Component). I defined 2 parameters (I only use 1 currently) to be passed to this background service and that’s the package family name and the package location.
//Uri updatePackage = new Uri("C:\\Users\\matth\\Documents\\Visual Studio 15\\Projects\\MyAppForUpdateTest\\MyAppForUpdateTest\\AppPackages\\MyAppForUpdateTest_126.96.36.199_Debug_Test\\MyAppForUpdateTest_188.8.131.52_x86_Debug.appxbundle");
Uri updatePackage=newUri("<a href="http://192.168.2.250/MyAppForUpdateTest_184.108.40.206_Debug_Test/MyAppForUpdateTest_220.127.116.11_arm_Debug.appxbundle");">http://192.168.2.250/MyAppForUpdateTest_18.104.22.168_Debug_Test/MyAppForUpdateTest_22.214.171.124_arm_Debug.appxbundle");</a>
txtOutput.Text="Update started, time to say goodbye"+response.Message["Status"];
The cool thing that happens is my app is closed when the update starts and automatically restarted after the update. This works on both Desktop as Mobile. I still need to test this on my RPI3 and in combination with Assigned Access/Kiosk mode on mobile.
So what’s left? I need to implement something which checks for a new version regularly. I am still debating if I am going to use the updater app to get registrations from other apps and checks if there is an update and if it finds one starts updating the app, it is more generic this way. On the other hand, the app might know better when it should be updating or not and implement the logic itself and just uses the appupdater to do the update.
I was also thinking about using some kind of broadcast in the app to send an update command to the apps on all devices to be able to force an update after I published a newer version on my internal website.
How I need to check for a newer version could be as simple as providing a little text file on the webserver with the latest version number. If the app has a lower version it will update. Or perhaps I should test what happens if I call the update command and the version of the app on the server is the same. If the update is ignored i don’t need to write any specific code to handle this. It might not be the most optimal solution, although we only download the changes in packages.
As I wrote before, by default when you setup assigned access the UI only shows app which have the aboveLockScreen extension registered. I talked to the PM who owns this feature to ask why and the reason is because we changed the behavior of how assigned access works (lock the screen and launch the app above the lock screen) we found out a lot of existing apps crash when running on the lock screen, so we changed the UI to only show apps which are designed to run above the lock screen.
Although the UI might not show your existing apps anymore you used to run as kiosk app, you can still use those. Obviously you need to test if they work when running above the lock screen.
Besides using MDM or a provisioning package to configure assigned access you can also use PowerShell to setup your app to run. You can find the documentation over here.
You will also find interesting documentation how to setup auto login and how to make a classic windows app the default app on that page as well.
This experience is something MS wants to improve in the future but for now you have to use this trick to setup your old app as assigned access app.
Another one of these little ‘gotchas’. Morten asked the question why he couldn’t debug DirectX on mobile, but it was possible on desktop and the IOT version of windows 10. I am not a DirectX expert at all, but this was weird. So I asked around internally what was going on.
First, if you want to do this on Desktop you need to install the graphics tools as an additional feature before you can do this.
This is something you need to do for Mobile as well, although it happens a bit different. You can do that by hitting ALT-F5 in Visual Studio or use the menu:
btw, you can also use ALT-F5 on desktop and make Visual Studio install the graphic tools for you.
After that you will be able to debug. The following line will return true instead of false:
D3D_DRIVER_TYPE_NULL,// There is no need to create a real hardware device.
D3D11_CREATE_DEVICE_DEBUG,// Check for the SDK layers.
nullptr,// Any feature level will do.
D3D11_SDK_VERSION,// Always set this to D3D11_SDK_VERSION for Windows Store apps.
nullptr,// No need to keep the D3D device reference.
nullptr,// No need to know the feature level.
nullptr// No need to keep the D3D device context reference.