We offer complete REST based API in FastNetMon Advanced.

API is disabled by default because it has blank password by default. You need to generate new password to enable it.

Generate secure password and specify it as API password:

sudo fcli set main web_api_login admin
sudo fcli set main web_api_password your_password_replace_it
sudo fcli set main web_api_port 10007
sudo fcli set main web_api_host 127.0.0.1

Optionally you can bind API daemon to IPv6 addresses that way:

sudo fcli set main web_api_host ::1

If you experience any issues, we suggest checking logs:

sudo tail -f /var/log/fastnetmon/api_gateway.log

You may enable detailed logging level this way:

sudo fcli set main web_api_trace_queries true
sudo fcli commit

sudo systemctl restart fastnetmon_web_api

After making this change you will see very detailed information about all actions in log file api_gateway.log.

Optionally you can enable SSL/TLS enabled endpoint on another port this way. You need to use your own SSL certificates created manually:

sudo fcli set main web_api_ssl true
sudo fcli set main web_api_ssl_host 127.0.0.1
sudo fcli set main web_api_ssl_port 10443
sudo fcli set main web_api_ssl_private_key_path /etc/ssl.key
sudo fcli set main web_api_ssl_certificate_path /etc/ssl.certificate

sudo systemctl restart fastnetmon_web_api

To listen on localhost and all external interfaces in same time you can set web_api_ssl_host to 0.0.0.0. For security reasons we recommend using only HTTPS enabled API port for external connections.

FastNetMon’s API does not provide fine grained permission control and we advice strongly against exposing it to non trusted systems / clients.

Execute example query to get license:

curl -X GET -u admin:YOU_PASSWORD http://127.0.0.1:10007/license

FastNetMon API based on well known fcli tool.

For debugging purposes, you could switch fcli to JSON mode this way:

JSON_MODE=on sudo -E fcli show bgp

It will provide same messages as API provides.

Instead of “set” command, you will need to use PUT HTTP method, for example (be careful, we use URL Encode for network name because it consists slash symbol):

curl -X PUT -u apiuser:securepass9 http://127.0.0.1:10007/main/networks_list/11.22.33.44%2f22

Instead of “delete” command you will need to use DELETE HTTP method, for example:

curl -X DELETE -u apiuser:securepass9 http://127.0.0.1:10007/main/networks_list/11.22.33.44%2f22

To show something, you could use GET HTTP method:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/hostgroup/global/threshold_mbps

To show whole category use:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/hostgroup

As you can see, in almost all cases you could replace space symbol by slash and use fcli’s format of command to talk with API.

If method failed for some reasons we return following document:

{"success":false,"error_text":"Category name hostgroupddd is not supported"}

If we command returns single value we return it in “value” field.

Example for boolean value:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/main/sflow
{"success":true,"error_text":"","value":true}

Example for string value:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/main/sflow_host
{"success":true,"error_text":"","value":"94.76.167.202"}

If command returns multiple elements, we return it in “values” field:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/main/sflow_ports
{"success":true,"error_text":"","values":["3432","6343"]}

If command returns hash map / table / dictionary FastNetMon encodes them as JSON dictionary:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/main/influxdb_tags_table
{"success":true,"error_text":"","table":{"ddd":"vvvv","foo":"bar"}}

If command returns document (hash map, dictionary) we return it in “object” field:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/bgp/connection_to_my_router
{"success":true,"error_text":"","values":[{"name":"connection_to_my_router","description":"","local_asn":65001,"local_address":"11.22.33.44","subnet_learning":false,"remote_asn":65001,"remote_address":"22.33.44.55","device_vendor":"","device_model":"","multihop":false,"md5_auth":true,"md5_auth_password":"suxx","snmp_address":"","snmp_version":"","snmp_community":"","ipv4_unicast":true,"ipv6_unicast":false,"ipv4_flowspec":true,"ipv6_flowspec":false,"ipv4_unicast_announces_limit":0,"ipv6_unicast_announces_limit":0,"ipv4_flowspec_announces_limit":0,"ipv6_flowspec_announces_limit":0,"active":true}]}

But we have some pretty complicated examples, for example for blackhole announces:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/blackhole
{"success":true,"values":[{"uuid":"6575af53-301a-4dae-ab9d-7e89c2a1fada","ip":"127.0.0.1/32"},{"uuid":"22965d4e-83b0-42c0-a442-848cd80a9ca7","ip":"127.0.0.2/32"}]}

Or flow spec announces:

curl -X GET -u apiuser:securepass9 http://127.0.0.1:10007/flowspec
{"success":true,"values":[{"uuid":"00fde1c5-bce4-4752-9d08-4e5be115e1c0","announce":{"source_prefix":"4.0.0.0/32","destination_prefix":"127.0.0.0/32","destination_ports":[80],"source_ports":[53,5353],"packet_lengths":[777,1122],"protocols":["tcp"],"fragmentation_flags":["is-fragment","dont-fragment"],"tcp_flags":["syn"],"action_type":"rate-limit","action":{"rate":1024}}},{"uuid":"7bc20126-ae1e-4e5b-8bc6-3493a55a0511","announce":{"source_prefix":"4.0.0.0/32","destination_prefix":"127.0.0.0/32","destination_ports":[80],"source_ports":[53,5353],"packet_lengths":[777,444],"protocols":["tcp"],"fragmentation_flags":["is-fragment","dont-fragment"],"tcp_flags":["syn"],"action_type":"rate-limit","action":{"rate":1024}}}]}

To put blackhole host, use this:

curl -X PUT -u admin:securepass9 http://127.0.0.1:10007/blackhole/127.0.0.1

After making any changes, you have to trigger commit command to apply changes for FastNetMon’s engine:

curl -X PUT -u admin:securepass9 http://127.0.0.1:10007/commit

Complete example to ban and then unban host

Ban it:

curl -X PUT -u admin:securepass9 http://127.0.0.1:10007/blackhole/127.0.0.1

Check list of banned hosts:

curl -X GET -u admin:securepass9 http://127.0.0.1:10007/blackhole

Output:

{"success":true,"values":[{"uuid":"a1080f8f-46bb-4fcf-932c-5cc837105589","ip":"127.0.0.1/32"}]}

And finally unban it by UUID:

curl -X DELETE -u admin:securepass9 http://127.0.0.1:10007/blackhole/a1080f8f-46bb-4fcf-932c-5cc837105589

Some some command which expect large JSON documents you may pass JSON documents as part of JSON query:

curl -vv -X PUT -u admin:securepass9 http://127.0.0.1:10007/flowspec  -H "Content-Type: application/json" -d '{"source_prefix":"11.22.33.44/32", "destination_prefix":"11.22.33.44/32", "action_type":"discard"}'

How to get per host counters?

Example:

curl -s -X GET -u admin:securepass9 http://127.0.0.1:10007/host_counters/incoming/bytes

Feel free to replace “incoming” by “outgoing” and “bytes” by “packets” or “flows” to change ordering.

Example output:

{
  "success": true,
  "values": [
    {
      "host": "192.168.1.125",
      "incoming_packets": 0,
      "incoming_bytes": 0,
      "incoming_flows": 0,
      "fragmented_incoming_packets":0,
      "fragmented_incoming_bytes":0,
      "dropped_incoming_packets":0,
      "dropped_incoming_bytes":0,
      "tcp_incoming_packets":1468,
      "tcp_incoming_bytes":2226553,
      "tcp_syn_incoming_packets":0,
      "tcp_syn_incoming_bytes":0,
      "udp_incoming_packets":0,
      "udp_incoming_bytes":0,
      "icmp_incoming_packets":0,
      "icmp_incoming_bytes":0
    },
    {
      "host": "192.168.1.109",
      "incoming_packets": 0,
      "incoming_bytes": 0,
      "incoming_flows": 0,
      "fragmented_incoming_packets":0,
      "fragmented_incoming_bytes":0,
      "dropped_incoming_packets":0,
      "dropped_incoming_bytes":0,
      "tcp_incoming_packets":1468,
      "tcp_incoming_bytes":2226553,
      "tcp_syn_incoming_packets":0,
      "tcp_syn_incoming_bytes":0,
      "udp_incoming_packets":0,
      "udp_incoming_bytes":0,
      "icmp_incoming_packets":0,
      "icmp_incoming_bytes":0
    }
  ]
}

How to get traffic counters for single IP?

You can do it this way:

curl -X GET -u 'admin:password' http://127.0.0.1:10007/single_host_counters/1.2.3.4

Example output:

{
  "success": true,
  "error_text": "",
  "object": {
    "dropped_in_bytes": 0,
    "dropped_in_packets": 0,
    "dropped_out_bytes": 0,
    "dropped_out_packets": 0,
    "fragmented_in_bytes": 0,
    "fragmented_in_packets": 0,
    "fragmented_out_bytes": 0,
    "fragmented_out_packets": 0,
    "icmp_in_bytes": 123,
    "icmp_in_packets": 0,
    "icmp_out_bytes": 244,
    "icmp_out_packets": 0,
    "in_bytes": 9199870,
    "in_flows": 23,
    "in_packets": 7034,
    "out_bytes": 506644,
    "out_flows": 22,
    "out_packets": 3135,
    "tcp_in_bytes": 5415572,
    "tcp_in_packets": 4022,
    "tcp_out_bytes": 362532,
    "tcp_out_packets": 2278,
    "tcp_syn_in_bytes": 848007,
    "tcp_syn_in_packets": 636,
    "tcp_syn_out_bytes": 37889,
    "tcp_syn_out_packets": 374,
    "udp_in_bytes": 3783062,
    "udp_in_packets": 2987,
    "udp_out_bytes": 135935,
    "udp_out_packets": 826
  }
}

Create / read / update for for hostgroups

Starting from FastNetMon 2.0.332 you can use single large JSON document to create new hostgroup or completely overwrite configuration for existing hostgroup.

The easiest way to get all field names to manually create hostgroup via fcli and then get JSON output from it this way:

JSON_MODE=on sudo -E fcli show hostgroup servers

You will see document like this:

{
"success":true,
"error_text":"",
"values":[ {
"name":"servers",
"parent_name":"",
"description":"",
"calculation_method":"per_host",
"enable_ban":false,
"ban_for_pps":false,
"ban_for_bandwidth":false,
"ban_for_flows":false,
"threshold_pps":0,
"threshold_mbps":0,
"threshold_flows":0,
"ban_for_tcp_bandwidth":false,
"ban_for_udp_bandwidth":false,
"ban_for_icmp_bandwidth":false,
"ban_for_tcp_pps":false,
"ban_for_udp_pps":false,
"ban_for_icmp_pps":false,
"threshold_tcp_mbps":0,
"threshold_udp_mbps":0,
"threshold_icmp_mbps":0,
"threshold_tcp_pps":0,
"threshold_udp_pps":0,
"threshold_icmp_pps":0,
"ban_for_tcp_syn_pps":false,
"threshold_tcp_syn_pps":0,
"ban_for_tcp_syn_bandwidth":false,
"threshold_tcp_syn_mbps":0,
"ban_for_ip_fragments_pps":false,
"threshold_ip_fragments_pps":0,
"ban_for_ip_fragments_bandwidth":false,
"threshold_ip_fragments_mbps":0,
"enable_ban_incoming":false,
"enable_ban_outgoing":false,
"ban_for_pps_outgoing":false,
"ban_for_bandwidth_outgoing":false,
"ban_for_flows_outgoing":false,
"threshold_pps_outgoing":0,
"threshold_mbps_outgoing":0,
"threshold_flows_outgoing":0,
"ban_for_tcp_bandwidth_outgoing":false,
"ban_for_udp_bandwidth_outgoing":false,
"ban_for_icmp_bandwidth_outgoing":false,
"ban_for_tcp_pps_outgoing":false,
"ban_for_udp_pps_outgoing":false,
"ban_for_icmp_pps_outgoing":false,
"threshold_tcp_mbps_outgoing":0,
"threshold_udp_mbps_outgoing":0,
"threshold_icmp_mbps_outgoing":0,
"threshold_tcp_pps_outgoing":0,
"threshold_udp_pps_outgoing":0,
"threshold_icmp_pps_outgoing":0,
"ban_for_tcp_syn_pps_outgoing":false,
"threshold_tcp_syn_pps_outgoing":0,
"ban_for_tcp_syn_bandwidth_outgoing":false,
"threshold_tcp_syn_mbps_outgoing":0,
"ban_for_ip_fragments_pps_outgoing":false,
"threshold_ip_fragments_pps_outgoing":0,
"ban_for_ip_fragments_bandwidth_outgoing":false,
"threshold_ip_fragments_mbps_outgoing":0
} ] }

You need to use first element from array values to get whole document which describes hostgroup. Then you need to adjust required fields and pass them via API using PUT method to main hostgroup endpoint (/hostgroup) this way:

curl -vv -X PUT -u admin:securepass9 http://127.0.0.1:10007/hostgroup -H "Content-Type: application/json"  -d '{"name":"servers","parent_name":"","description":"","calculation_method":"per_host","enable_ban":false,"ban_for_pps":false,"ban_for_bandwidth":false,"ban_for_flows":false,"threshold_pps":0,"threshold_mbps":0,"threshold_flows":0,"ban_for_tcp_bandwidth":false,"ban_for_udp_bandwidth":false,"ban_for_icmp_bandwidth":false,"ban_for_tcp_pps":false,"ban_for_udp_pps":false,"ban_for_icmp_pps":false,"threshold_tcp_mbps":0,"threshold_udp_mbps":0,"threshold_icmp_mbps":0,"threshold_tcp_pps":0,"threshold_udp_pps":0,"threshold_icmp_pps":0,"ban_for_tcp_syn_pps":false,"threshold_tcp_syn_pps":0,"ban_for_tcp_syn_bandwidth":false,"threshold_tcp_syn_mbps":0,"ban_for_ip_fragments_pps":false,"threshold_ip_fragments_pps":0,"ban_for_ip_fragments_bandwidth":false,"threshold_ip_fragments_mbps":0,"enable_ban_incoming":false,"enable_ban_outgoing":false,"ban_for_pps_outgoing":false,"ban_for_bandwidth_outgoing":false,"ban_for_flows_outgoing":false,"threshold_pps_outgoing":0,"threshold_mbps_outgoing":0,"threshold_flows_outgoing":0,"ban_for_tcp_bandwidth_outgoing":false,"ban_for_udp_bandwidth_outgoing":false,"ban_for_icmp_bandwidth_outgoing":false,"ban_for_tcp_pps_outgoing":false,"ban_for_udp_pps_outgoing":false,"ban_for_icmp_pps_outgoing":false,"threshold_tcp_mbps_outgoing":0,"threshold_udp_mbps_outgoing":0,"threshold_icmp_mbps_outgoing":0,"threshold_tcp_pps_outgoing":0,"threshold_udp_pps_outgoing":0,"threshold_icmp_pps_outgoing":0,"ban_for_tcp_syn_pps_outgoing":false,"threshold_tcp_syn_pps_outgoing":0,"ban_for_tcp_syn_bandwidth_outgoing":false,"threshold_tcp_syn_mbps_outgoing":0,"ban_for_ip_fragments_pps_outgoing":false,"threshold_ip_fragments_pps_outgoing":0,"ban_for_ip_fragments_bandwidth_outgoing":true,"threshold_ip_fragments_mbps_outgoing":12345}'

You can create new hostgroup by setting field “name” to name of new hostgroup.

Starting from 2.0.360 you can control number of entries returned by API calls asn_counters_v4, asn_counters_v6, host_counters_v6, host_counters, host_counters_per_hostgroup_v4, host_counters_per_hostgroup_v6, remote_host_counters using query parameter max_elements

curl -s -X GET -u admin:your_password_replace_it http://[::1]:10007/asn_counters_v4/outgoing?max_elements=50

Examples

We have number of example tools implemented for our API to provide examples:

  • API client which creates and removes networks from FastNetMon
  • API client which can block and unblock IP address

Technical details

FastNetMon REST API is implemented as gateway which accepts HTTP / HTTPS queries from end client and then reaches FastNetMon daemon using internal non public gRPC based API (which listens TCP port 50052 by default ) to execute command. For configuration management commands REST API reached MongoDB or FerretDB directly.

In case of FastNetMon daemon reachability issues you will see following error:

Show function returned error: XXX call failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:50052: connect: connection refused"

Schema reflection API

Our normal API endpoints do not provide detailed information about fields in main and hostgroup categories.

You can get it using special API calls:

curl -s -X GET -u admin:your_password_replace_it http://127.0.0.1:10007/fields/main 

Example answer:

{
  "success": true,
  "error_text": "",
  "values": [
    {
      "name": "enable_ban",
      "type": "bool",
      "unit": "",
      "description": "Completely enable or disable all ban actions",
      "tooltip": "",
      "category": "ban_management",
      "group": "",
      "pretty_name": "Enable blocking",
      "manage_with_web": true
    },
    {
      "name": "enable_ban_hostgroup",
      "type": "bool",
      "unit": "",
      "description": "Completely enable or disable all ban for total traffic per hostgroup",
      "tooltip": "",
      "category": "ban_management",
      "group": "",
      "pretty_name": "Enable blocking per hostgroup",
      "manage_with_web": true
    },
    {
      "name": "web_api_password",
      "type": "string",
      "unit": "",
      "description": "Password for web API",
      "tooltip": "",
      "category": "web_api",
      "group": "",
      "pretty_name": "Password",
      "sensitive": true,
      "manage_with_web": true
    }
   ]
}

For hostgroup configuration it will look this way:

curl -s -X GET -u admin:your_password_replace_it http://127.0.0.1:10007/fields/hostgroup

Example output:

{
  "success": true,
  "error_text": "",
  "values": [
    {
      "name": "name",
      "type": "string",
      "unit": "",
      "description": "Name of host group",
      "tooltip": "Name of newly created group of hosts",
      "category": "",
      "group": "",
      "pretty_name": "Host group name",
      "manage_with_web": true
    },
    {
      "name": "parent_name",
      "type": "string",
      "unit": "",
      "description": "Parent host group name",
      "tooltip": "Parent host group name",
      "category": "",
      "group": "",
      "pretty_name": "Parent host group name",
      "manage_with_web": true
    }
  ]
}

Due to large number of configuration option in main configuration we distinguish them into categories and full list of categories with description can be requested this way:

curl -s -X GET -u admin:your_password_replace_it http://127.0.0.1:10007/configuration_categories/main

Example output:

{
  "success": true,
  "error_text": "",
  "values": [
    {
      "name": "traffic_calculation_management",
      "pretty_name": "Traffic calculation",
      "manage_with_web": true
    },
    {
      "name": "ban_management",
      "pretty_name": "Attack detection",
      "manage_with_web": true
    },
    {
      "name": "network_management",
      "pretty_name": "Networks configuration",
      "manage_with_web": true
    },
    {
      "name": "af_packet",
      "pretty_name": "Mirror / SPAN AF_PACKET",
      "manage_with_web": true
    },
    {
      "name": "xdp",
      "pretty_name": "Mirror / SPAN AF_XDP",
      "manage_with_web": true
    },
    {
      "name": "sflow",
      "pretty_name": "sFlow",
      "manage_with_web": true
    },
    {
      "name": "netflow",
      "pretty_name": "Netflow / IPFIX",
      "manage_with_web": true
    },
    {
      "name": "tera_flow",
      "pretty_name": "Tera Flow",
      "manage_with_web": true
    },
    {
      "name": "bgp",
      "pretty_name": "BGP settings",
      "manage_with_web": true
    },
    {
      "name": "email_notification",
      "pretty_name": "Email notification",
      "manage_with_web": true
    },
    {
      "name": "notify_script",
      "pretty_name": "Notify script",
      "manage_with_web": true
    },
    {
      "name": "web_callback",
      "pretty_name": "Web hooks",
      "manage_with_web": true
    },
    {
      "name": "influxdb",
      "pretty_name": "InfluxDB metrics",
      "manage_with_web": true
    },
    {
      "name": "clickhouse_metrics",
      "pretty_name": "Clickhouse metrics",
      "manage_with_web": true
    },
    {
      "name": "graphite",
      "pretty_name": "Graphite metrics",
      "manage_with_web": true
    },
    {
      "name": "traffic_db",
      "pretty_name": "Traffic persistency",
      "manage_with_web": true
    },
    {
      "name": "redis",
      "pretty_name": "Redis configuration",
      "manage_with_web": true
    },
    {
      "name": "system",
      "pretty_name": "System options",
      "manage_with_web": true
    },
    {
      "name": "web_api",
      "pretty_name": "Web API",
      "manage_with_web": true
    },
    {
      "name": "logging",
      "pretty_name": "Log configuration",
      "manage_with_web": true
    }
  ]
}

24/7 Tech Support

support@fastnetmon.com

Email Us

sales@fastnetmon.com