products:software:edgeos:api

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
products:software:edgeos:api [2020/06/07 10:41] matthew1471products:software:edgeos:api [2025/05/12 13:37] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== EdgeOS API Guide ====== ====== EdgeOS API Guide ======
  
-The EdgeOS API is largely undocumented. However as the requests and responses can be monitored in a web-browser a lot of information on how it works can be derived.+The EdgeOS API is not publicly documented. However as the requests and responses can be monitored in a web-browser along with the JavaScript source being available, a lot of information on how it works can be derived. 
 + 
 +A subset of the information here was taken from https://github.com/matthew1471/EdgeOS-API/tree/master/Documentation
  
 ===== Authentication ===== ===== Authentication =====
Line 145: Line 147:
 ===== Websocket - Stats ===== ===== Websocket - Stats =====
  
-You can get streaming statistical data from the endpoint ''<nowiki>wss://host-or-ip/ws/stats</nowiki>'' The data from the WebSocket is framed oddly, it's actually a streaming protocol that has been sent and received over WebSocket.  The data will not arrive like you might expect.  You *MUST* reassemble the web socket data fragments since the frames may not align with data boundaries.  Commands must be sent with a valid SESSION_ID.+You can get streaming statistical data from the endpoint ''<nowiki>wss://host-or-ip/ws/stats</nowiki>'' The data from the WebSocket is framed oddly, it's actually a streaming protocol that has been sent and received over WebSocket.  The data will not arrive like you might expect.  You *MUST* reassemble the web socket data fragments since the frames may not align with data boundaries.  Commands must be sent with a valid SESSION_ID.  Origin header is not needed for the 2.x branch of the firmware but is needed for 1.x branches.
  
 The format of data to and from the WebSocket stream is "LENGTH\nJSON_PAYLOAD". Failure of sending properly formed messages to start the streaming will result in no messages from server aka "dead air". The format of data to and from the WebSocket stream is "LENGTH\nJSON_PAYLOAD". Failure of sending properly formed messages to start the streaming will result in no messages from server aka "dead air".
Line 168: Line 170:
 The webUI sends a non-standard ping every 30 seconds which consists of the following string with NO length prefix <code>{"CLIENT_PING"}</code> The webUI sends a non-standard ping every 30 seconds which consists of the following string with NO length prefix <code>{"CLIENT_PING"}</code>
  
-==== Websocket Endpoints: JSON Based ====+==== WebSocket Subscriptions: JSON Based ====
  
-Each one of these subscriptions will output data with a headers indicating what datapoint they are returning.+Each one of these subscriptions will output data with the response being full JSON objects:
  
   * system-stats: Returns cpu, memory and uptime <code>{'system-stats': {'cpu': '35', 'mem': '22', 'uptime': '3321154'}}   * system-stats: Returns cpu, memory and uptime <code>{'system-stats': {'cpu': '35', 'mem': '22', 'uptime': '3321154'}}
Line 186: Line 188:
   * udapi-statistics: System information formatted for udapi, odd dialect   * udapi-statistics: System information formatted for udapi, odd dialect
  
-==== Websocket Endpoint: RAW ====+==== WebSocket Subscriptions: RAW Console Output ====
  
-Each one of these endpoints just dumps data with the dict <code>{'': '<line of text>\n' }</code>+Each one of these endpoints just dumps the raw console output data within a string <code>{'<<Request sub_id>>': '<line of text>\n' }</code>
  
-  * log-feed: Basically tail -f /var/log/messages +These are subscribed to in the same way as the JSON subscriptions above but some additional parameters may need to be specified.
-  * fw-stats: Returns per-rule firewall stats +
-  * pf-stats: Not sure +
-  * nat-stats: Returns per-rule nat stats+
  
-Example fw-stats.+=== Log File ("log-feed") === 
 +Basically a ''tail -f /var/log/messages'' 
 + 
 +=== Firewall Statistics ("fw-stats") === 
 +Returns per-rule firewall stats: 
 + 
 +Request: 
 +<code>142 
 +{"SUBSCRIBE":[{"name":"fw-stats","sub_id":"fwstat:WAN_IN","chain":"WAN_IN"}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code>
  
 <code> <code>
-{'': 'MGT_IN 10 11604461 1380173884 ACCEPT ""\n'+{'fwstat:WAN_IN': 'MGT_IN 10 11604461 1380173884 ACCEPT ""\n'
-{'': 'MGT_IN 20 0 0 DROP "drop direct stun"\n'+{'fwstat:WAN_IN': 'MGT_IN 20 0 0 DROP "drop direct stun"\n'
-{'': 'MGT_IN 30 24 1152 ACCEPT "stun"\n'+{'fwstat:WAN_IN': 'MGT_IN 30 24 1152 ACCEPT "stun"\n'
-{'': 'MGT_IN 10000 8417 670074 DROP "DEFAULT ACTION"\n\n'+{'fwstat:WAN_IN': 'MGT_IN 10000 8417 670074 DROP "DEFAULT ACTION"\n\n'
-{'': 'WAN_IN 10 747540714 999952823643 ACCEPT "Allow established/related"\n'+{'fwstat:WAN_IN': 'WAN_IN 10 747540714 999952823643 ACCEPT "Allow established/related"\n'
-{'': 'WAN_IN 20 0 0 DROP "Drop invalid state"\n'+{'fwstat:WAN_IN': 'WAN_IN 20 0 0 DROP "Drop invalid state"\n'
-{'': 'WAN_IN 30 1095 52610 DROP "block ET"\n'+{'fwstat:WAN_IN': 'WAN_IN 30 1095 52610 DROP "block ET"\n'
-{'': 'WAN_IN 40 0 0 DROP "block TOR"\n'+{'fwstat:WAN_IN': 'WAN_IN 40 0 0 DROP "block TOR"\n'
-{'': 'WAN_IN 50 0 0 DROP "block EDROP"\n'+{'fwstat:WAN_IN': 'WAN_IN 50 0 0 DROP "block EDROP"\n'
-{'': 'WAN_IN 60 0 0 DROP "block China" DISABLED\n'+{'fwstat:WAN_IN': 'WAN_IN 60 0 0 DROP "block China" DISABLED\n'
-{'': 'WAN_IN 70 92712 5078903 ACCEPT "server - web ports - tcp"\n'+{'fwstat:WAN_IN': 'WAN_IN 70 92712 5078903 ACCEPT "server - web ports - tcp"\n'
-{'': 'WAN_IN 80 65556 3923195 ACCEPT "server - ssh"\n'+{'fwstat:WAN_IN': 'WAN_IN 80 65556 3923195 ACCEPT "server - ssh"\n'
-{'': 'WAN_IN 90 877 52516 ACCEPT "server - gitlab ssh"\n'+{'fwstat:WAN_IN': 'WAN_IN 90 877 52516 ACCEPT "server - gitlab ssh"\n'
-{'': 'WAN_IN 100 142 33791 ACCEPT "server - mosh"\n'+{'fwstat:WAN_IN': 'WAN_IN 100 142 33791 ACCEPT "server - mosh"\n'
-{'': 'WAN_IN 110 3926 143574 ACCEPT "server - unifi stun"\n'+{'fwstat:WAN_IN': 'WAN_IN 110 3926 143574 ACCEPT "server - unifi stun"\n'
-{'': 'WAN_IN 10000 259 136357 DROP "DEFAULT ACTION"\n\n'+{'fwstat:WAN_IN': 'WAN_IN 10000 259 136357 DROP "DEFAULT ACTION"\n\n'
-{'': 'WAN_LOCAL 10 55434 36097276 ACCEPT "Allow established/related"\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 10 55434 36097276 ACCEPT "Allow established/related"\n'
-{'': 'WAN_LOCAL 20 87599 17248696 DROP "Drop invalid state"\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 20 87599 17248696 DROP "Drop invalid state"\n'
-{'': 'WAN_LOCAL 61 41787 1761510 DROP "block ET"\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 61 41787 1761510 DROP "block ET"\n'
-{'': 'WAN_LOCAL 62 0 0 DROP "block TOR"\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 62 0 0 DROP "block TOR"\n'
-{'': 'WAN_LOCAL 63 100 4160 DROP "block EDROP"\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 63 100 4160 DROP "block EDROP"\n'
-{'': 'WAN_LOCAL 64 0 0 DROP "block China" DISABLED\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 64 0 0 DROP "block China" DISABLED\n'
-{'': 'WAN_LOCAL 65 21894 1372976 ACCEPT "ICMP"\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 65 21894 1372976 ACCEPT "ICMP"\n'
-{'': 'WAN_LOCAL 10000 241941 37301536 DROP "DEFAULT ACTION"\n\n'+{'fwstat:WAN_IN': 'WAN_LOCAL 10000 241941 37301536 DROP "DEFAULT ACTION"\n\n'}</code> 
-</code>+ 
 +=== Port Forwarding Statistics ("pf-stats") === 
 +Contains the statistics from Port Forwarding. 
 + 
 +=== NAT Statistics ("nat-stats") === 
 +Returns per-rule NAT stats: 
 + 
 +<code>1115 
 +
 +    "nat-stats": "1 15 DST eth0 \"Allow OpenVPN To VPN\"\n2 0 DST eth1 \"Allow OpenVPN To VPN (Hairpin)\"\n3 28 DST eth0 \"Allow qBittorrent\"\n4 0 DST eth0 \"Allow Emergency iLO (HTTP)\" DISABLED\n5 0 DST eth0 \"Allow Emergency iLO (Console)\" DISABLED\n6 7192 DST eth1 \"Redirect Google DNS To Router\"\n7 3920 DST eth1 \"Redirect Google ICMP To Router\"\n5001 46501 MASQ eth0 \"Masquerade For WAN\"\n5002 0 MASQ eth1 \"Allow OpenVPN To VPN (Hairpin)\"\n1 15 DST eth0 \"Allow OpenVPN To VPN\"\n2 0 DST eth1 \"Allow OpenVPN To VPN (Hairpin)\"\n3 28 DST eth0 \"Allow qBittorrent\"\n4 0 DST eth0 \"Allow Emergency iLO (HTTP)\" DISABLED\n5 0 DST eth0 \"Allow Emergency iLO (Console)\" DISABLED\n6 7192 DST eth1 \"Redirect Google DNS To Router\"\n7 3920 DST eth1 \"Redirect Google ICMP To Router\"\n5001 46501 MASQ eth0 \"Masquerade For WAN\"\n5002 0 MASQ eth1 \"Allow OpenVPN To VPN (Hairpin)\"\n1 15 DST eth0 \"Allow OpenVPN To VPN\"\n2 0 DST eth1 \"Allow OpenVPN To VPN (Hairpin)\"\n3 28 DST eth0 \"Allow qBittorrent\"\n4 0 DST eth0 \"Allow Emergency iLO (HTTP)\" DISABLED\n5 0 DST eth0 \"Allow Emergency iLO " 
 +}</code> 
 + 
 +=== Ping ("ping-feed") === 
 + 
 +<code>163 
 +{"SUBSCRIBE":[{"name":"ping-feed","sub_id":"ping1","target":"192.168.0.1","count":"1","size":""}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code> 
 + 
 +with the response being pretty similar to a raw feed: 
 + 
 +<code>76 
 +
 +    "ping1": "PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.\n\n" 
 +}</code> 
 + 
 +=== Traceroute ("traceroute-feed") === 
 + 
 +<code>165 
 +{"SUBSCRIBE":[{"name":"traceroute-feed","sub_id":"trace6","target":"192.168.0.254","resolve":true}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code> 
 + 
 +with the response being pretty similar to a raw feed: 
 + 
 +<code>98 
 +
 +    "trace6": "traceroute to 192.168.0.254 (192.168.0.254), 30 hops max, 38 byte packets\n 1" 
 +}</code> 
 + 
 +=== Packet Capture ("packets-feed") === 
 + 
 +<code>224 
 +{"SUBSCRIBE":[{"name":"packets-feed","sub_id":"packets4","interface":"1","pkt_count":"1","resolve":true,"f_proto":"","f_address":"","f_port":"","f_neg":true}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code> 
 + 
 +=== Bandwidth Test ("bwtest-feed") === 
 +Client: 
 + 
 +<code>150 
 +{"SUBSCRIBE":[{"name":"bwtest-feed","sub_id":"bandwidth5","server":"192.168.0.253"}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code>
  
-===== WebsocketsAction Endpoints =====+or with advanced properties set:
  
-Each one of these endpoints performs a toolbox action.+<code>273 
 +{"SUBSCRIBE":[{"name":"bwtest-feed","sub_id":"bandwidth2","server":"192.168.0.254","duration":"1","protocol":"udp","udp-bandwidth":"500","parallel-flows":"1","tcp-window-size":"64","reverse-direction":true}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code>
  
-  * ping-feed +Server: 
-  * traceroute-feed +<code>144 
-  * packets-feed +{"SUBSCRIBE":[{"name":"bwtest-feed","sub_id":"bandwidth5","server-mode":true}],"UNSUBSCRIBE":[],"SESSION_ID":"9a00126c5bf04e29835f7c13fe5ab155"}</code>
-  * bwtest-feed+
  
 ===== Websockets: Other Endpoints ===== ===== Websockets: Other Endpoints =====
Line 243: Line 295:
 ===== Third Party Unofficial APIs ===== ===== Third Party Unofficial APIs =====
 There are a few developers who have worked on creating unofficial APIs: There are a few developers who have worked on creating unofficial APIs:
-  * https://github.com/matthew1471/EdgeOS-API (written in C#) +  * https://github.com/matthew1471/EdgeOS-API C# 
-  * https://github.com/andrewstuart/edgeos-rest (written in Go)+  * https://github.com/andrewstuart/edgeos-rest Go 
 +  * https://github.com/brontide/aioedgeos : Python with influx collector including DPI
  
  • products/software/edgeos/api.1591544507.txt.gz
  • Last modified: 2025/05/12 13:37
  • (external edit)