Automating unifi port forwarding based upon presence detection

awesome, if it even helps one person I’m happy - I’ve received so much help from super smart people on the forums here, figured its nice to be able to contribute back :smiley:

This is great, thanks! I’d like to use this to create a simple switch to turn on or off a specific port forward rule. This should do the trick fine. Thanks.

1 Like

Hey @jon102034050,

Love what you’ve done here.

I’m hoping to do the same thing but for my Remote Desktop port, forwarding to a specific client IP.

I’ve tried to give the api a bit of a look but I’m not positive how it translates.
Do you think you could help me modify the above?

Also, how do you get the last secret - id_from_unifi?
Is there a way to debug this?

I’m using a UDM and it’s my only site (I’m brand spanking new to Unifi) so I assume the site id is ‘default’?

Thank you

Linton

If you only have a single site, the site name should probably be default. You can get the ID of the port forwarding item by clicking edit on the port forward that you want to toggle. It’ll be at the end of the URL

So I got it working and it was amazing! Thank you.

But, I had to update to use my new U6-Lite AP and now it won’t :frowning:

Seems it was a large update to the unifi controller.
The config URL port changed to 443 (well, there is no longer a port so I assume 443)

I’ve tried changing the string in the script to :443 and removing it completely.

I’ve also tried putting in raw data instead of secrets.

Unifi controller ver is now 6.0.43
UDM firmware 1.8.6.2969

Can this be debugged?

Thank you

Linton

Here’s a link to my commit where I fix the issue you’re describing. I probably should update my OP with this as well: https://github.com/JonGilmore/ha-personal/commit/65b99934b10bbd138d98539e62d7785adcf12631

the tl;dr of it is the X-CSRF-Token was breaking stuff, and it seems unifi changed the behavior of this.

WORKING!!! :smiley: :smiley:

thanks mate

nice! I spent WAY too long trying to figure out what the hell broke when I updated as well, hopefully I saved you some time, hah!

Seems to be a common theme in the Unifi world :stuck_out_tongue:

@jon102034050 thanks for the workaround.

I have created a feature request to make controlling Port Forwarding part of the Unifi integration: Unifi Integration: Ability to control Port Forwarding . Feel free to vote for it to get some attention to this feature.

1 Like

@jon102034050

Hey mate, still can’t thank you enough for these port forwarding switches. You wouldn’t happen to have a solution for triggering a reboot for a UDM device?

Sad reality is that these still need semi-regular reboots to keep them working at their best and I’d love to schedule this rather than cut the power in times of need.

Cheers :slight_smile:

Linton

glad you’ve found it useful! I personally use a UXG and haven’t really had too many issues with it that require a reboot (totally glossing over the fact that it’s missing a LOT of features that are in older hardware). As I find time, I’ll see if I can work something up though. As a workaround in the meantime, you could always just put it on a smart plug and cycle that via automation

Yeah I’ve got one of those dumb power timers I used to do a similar thing with for my old router. Ubiquiti equipment just feels a bit more delicate to be doing that all the time.

apparently in an SSH terminal you would simply type ‘reboot’ to execute what i’m doing if that helps.

Alrighty, did a little testing and here’s what I came up with:

I’m not entirely sure this will work perfectly for you though as I don’t personally own a UDM device. This works for rebooting an AP for me, so hopefully it’ll just be plug-n-play for a UDM as well.
Let me know how it goes!

Just noticed that with the latest unifi update, they must have changed the case of the x-csrf-token which busted this script :frowning:
This commit fixes that though: fix(unifi): csrf case sensitivity · JonGilmore/ha-personal@76c17a1 · GitHub

Can you explain what the “id from unifi ui” bit means? Pretty sure I have the rest of this sorted, but I’m not sure where to get that. I’m looking at my ui, under “port forwarding”, and I don’t see any id?

Thanks!

Sorry, thats not super clear :smiley: It’s the ID in the URL when you click on edit for the port forward

1 Like

That was my guess, but better safe than sorry. Thank you so much for the speedy reply!!

1 Like

Ok, I’ve been messing with this for hours now, and I just cannot get it to work. I’m still pretty new to Home Assistant, so I’m doing most things in the UI yet, with minimal yaml when absolutely necessary.

Because of that, I couldn’t use the secrets file because you cannot access !secret from within the automations UI - and when I attempted to manually add the automations to the yaml file, it blew up ALL my automations and I got nothing but error 500.

So, I tried typing out all the required fields in the data of the service call in automations, so my automation looks like this:

- id: '164228015xxxx'
  alias: Disable HA Port fwd
  description: ''
  trigger:
  - platform: state
    entity_id: input_boolean.everybody_home
    from: 'off'
    to: 'on'

  condition: []

  action:
  - service: shell_command.unifi_portfwd
    data:
      username: root
      password: password!
      baseurl: 10.x.x.x
      name: HA
      enabled: 'false'
      dst_port: '8123'
      ip: 10.x.x.x
      fwd_port: '8123'
      proto: tcp
      id: 654sfghbsfg6h54sfg6b5th
      unifi_site: default
  mode: single

The script I copied from your git:

#!/bin/sh
cookie=$(mktemp)
headers=$(mktemp)
curl_cmd="curl --silent --output /dev/null --cookie ${cookie} --cookie-jar ${cookie} --insecure"
portfwd() {

  # authenticate against unifi controller
  ${curl_cmd} -H 'Content-Type: application/json' -D ${headers} -d "{\"username\":\"$1\", \"password\":\"$2\"}" https://${3}/api/auth/login

  # grab the `x-csrf-token` and strip the newline (added when upgraded to controller 6.1.26)
  csrf="$(awk -v FS=': ' '/^x-csrf-token/{print $2}' "${headers}" | tr -d '\r')"

  # enable/disable firewall rule
  ${curl_cmd} -k -X PUT https://${3}/proxy/network/api/s/default/rest/portforward/${10} -H "Content-Type: application/json" -H "x-csrf-token: ${csrf}" -d @- <<-EOF
  {
    "name":"$4",
    "enabled":$5,
    "src":"any",
    "dst_port":"$6",
    "fwd":"$7",
    "fwd_port":"$8",
    "proto":"$9",
    "log":false,
    "_id":"$10",
    "site_id":"$11",
    "pfwd_interface":"wan",
    "destination_ip":"any"
  }
EOF
}
"$@"

The line I added to configuration.yaml:

shell_command:
    unifi_portfwd: /bin/bash /config/scripts/unifi.sh portfwd {{ username }} {{ password }} {{ baseurl }} {{ name }} {{ enabled }} {{ dst_port }} {{ ip }} {{ fwd_port }} {{ proto }} {{ id }} {{ unifi_site }}

After a bit more screwing around and trying to do some of this manually to see what’s broken, the result of both curl commands is “Invalid CSRF Token”.

I’m running UniFi OS UDM Pro 1.11.0 and Network 6.5.54 (Build: atag_6.5.54_16676)

Any help you can offer would be GREATLY appreciated!

UPDATE: Got it working!

For anyone else that’s new at this that may bang their head against the wall in the future… The user account that you attempt to authenticate with is very important! The ssh account (root) will NOT work! After much messing around (and LOTS of googling), I created a limited admin LOCAL user, and used those credentials for the automations. Works like a charm! Thank you much, @jon102034050! Awesome!!!

1 Like