This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Reset POE Port on Unifi Switch - Connecting to a device via SSH Key
#1
Hi

I'd like to automate the power cycle of a POE port on a Unifi Switch.   The Unifi docs say this can be achieved by connecting to the device via a SSH key and then issuing some telnet commands.   I can run these commands ok from the terminal window of my desktop, however am not to sure how to initial a ssh connection from logic machine / CBUS SHAC.

Here the sequence of commands that run ok from my desktop Mac to power cycle port 15.

Code:
ssh -i /Users/james/.ssh/id_rsa admin@192.168.1.100#
telnet localhost 23
enable
configure
interface 0/15
poe opmode shutdown
poe opmode auto
exit
exit
exit
telnet localhost 23
exit


Here's the beginnings of my LM script to issue the telnet commands.  Can anyone advise how to modify the script to SSH to the switch with an SSH key (the key is in the id_rsa file in the above example)

Code:
function resetPOESwitchPort(switchport)
 
local socket = require("socket").tcp()
local response, err = socket:connect('192.168.1.100', 23)

if response then

  -- SSH connection established so issue telnet commands
  socket:send('telnet localhost 23\r\n')

  response = socket:receive(5)
  log(response)
  socket:send('telnet localhost 23\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('enable\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('configure\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('interface 0/' .. switchport .. '\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('poe opmode shutdown\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('poe opmode auto\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('exit\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('exit\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('exit\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('telnet localhost 23\r\n')
   
  response = socket:receive(5)
  log(response)
  socket:send('exit\r\n')

  response = socket:receive()
  log(response)
  socket:close()
 
else
 
  -- No connnection response
    log ('Unable to connect to switch')
  tcp:close()
 
end

end


Any advice would be greatly appreciated 

Kind Regards
James
Reply
#2
Which switch model do you have? At least some should have a web interface which you access from scripts. This is much easier than SSH.
Reply
#3
Have a look at this unifi API: https://ubntwiki.com/products/software/u...roller/api
Posting to the endpoint `api/s/{site}/cmd/<manager>` with the `json {"cmd": "command"}` you can invoke commands on the controller.

Power cycle poe port:
devmgr power-cycle mac = switch mac ( required ), port_idx = PoE port to cycle ( required )
Reply
#4
See this topic for an example that you can use: https://forum.logicmachine.net/showthread.php?tid=2450
Reply
#5
Hi

I'm attempting to control Unifi US-48-500W and US-8-60W switches (all running the latest firmware - cloud key firmware 2.0.27 which changes the access url from https://controllerip:8443 to https://controllerip/network/site) and I think breaks the reverse engineered API.

I was under the impression that the API (https://ubntwiki.com/products/software/u...roller/api) was a reverse engineered project and that the telnet control which was officially supported by Unifi.

Is there an example of how to make the SSH connection and execute the telnet commands with Logic Machine?

Kind Regards
James
Reply
#6
(03.02.2021, 02:43)jamesng Wrote: Hi 

I'm attempting to control Unifi US-48-500W and US-8-60W switches (all running the latest firmware - cloud key firmware 2.0.27 which changes the access url from https://controllerip:8443 to https://controllerip/network/site) and I think breaks the reverse engineered API.

I was under the impression that the API (https://ubntwiki.com/products/software/u...roller/api) was a reverse engineered project and that the telnet control which was officially supported by Unifi.

Is there an example of how to make the SSH connection and execute the telnet commands with Logic Machine? 

Kind Regards
James

Hi jamesng, 
from the last unifi update 2 things have changed, 1- controller access is no longer avalible on port 8443, this is now https on port 443 and 2- end points have changed for login endpoint  api/auth/login and for api endpoint prefix with /proxy/network see below code , change to suit your requirements 

Code:
htps = require("ssl.https")
       require('json')

htps.TIMEOUT = 5

usr_credenitals = json.encode({
    username = 'XXXXXXXXXXXXXX',
  password = 'XXXXXXXX'
})

login = 'https://192.168.1.10:443/api/auth/login'

sta = 'https://192.168.1.10:443/proxy/network/api/s/d5gh60j5/stat/sta'
                             
get_sites = 'https://192.168.1.10:443/proxy/network/api/self/sites'

Post_response = {}

local res, err, response_headers, status = htps.request
  {
    url = login,
    method = "POST",
    protocol = 'tlsv12',
    headers =
    {
    ["Accept"] = "*/*",
    ["Content-Type"] = "application/json",
    ["Content-Length"] = usr_credenitals:len()
    },

  source = ltn12.source.string(usr_credenitals),     
  sink = ltn12.sink.table(Post_response)
  }

if Post_response then
  --log(res, code, response_headers)
mmm_cookies = response_headers['set-cookie']
  if mmm_cookies then
  token = mmm_cookies:match('(TOKEN=[^;]+)'..';')
  end

  Get_response ={}

  res, err = htps.request({
     url = sta,
     method = "GET",
     protocol = 'tlsv12',
     headers = {
     cookie = token,
    ['X-CSRF-Token'] = response_headers['x-csrf-token']
    },
    sink = ltn12.sink.table(Get_response),
  })

  if Get_response then

    Get_response = table.concat(Get_response)
    dec = json.decode(Get_response)
   
    -- get all mac adresses currently connected to site
    for i = 1, #dec.data do
      log(dec.data[i].mac)
      -- return boolean if mac adress is connected
      is_mac = dec.data[i].mac =='42:45:05:39:0f:d9'
     
     if is_mac then
        log(is_mac)
      end
    end
   
  else
    log('could not get stat ' .. tostring(err))
  end
  else
  log('login failed ' .. tostring(err))
end
Reply


Forum Jump: