6 - Services & Software

Lists and information about services hosted on the mesh

Alerting and monitoring system

Out of date

Existing systems




Proposed software

Next Steps


Bookstack wiki software

Bookstack wiki software

Adding attachments

Only logged in Editors can add attachments.

Click the paper clip icon on the right menu in edit mode:

Click "Upload File":


Once the file is uploaded click the link button to add a link to the current page:


Bookstack wiki software

Bookstack wiki tips

Bookstack wiki software

How to create pages

To create a page:

  1. Navigate to the "Book" or "Chapter" where you page will be located.


  2. From the right hand menu select "New Page".


  3. Edit the page and select "Save Page" from the right hand menu.


Connection Troubleshooting

Restart Network If Ping Google.Com && Fails 4 Times

Wireless networks have a bit of a reputation for instability. Modern hardware has fixed most hardware problems, but there is work that needs to be done to make the firmware reliable. You can do this with "watchdog" scripts. I haven't had to reboot a router that is running our watchdog script.

Our firmware image (based on qMp) comes with a "bmx6health" script that checks whether the mesh software is running correctly and restarts it if necessary. This script by default runs once per day. I've found it better to run this every 5 minutes. You can do this by editing the crontab-

ssh into the router and in the terminal-

crontab -e

This opens a vi editor and you can change or add different scripts to run at different times. (The vi commands you need are "i" to insert, "esc" to stop editing, and ":x" to save and eXit.)

For some nodes, their main purpose is to be an internet gateway. To ensure that they always try to be online, you can add a watchdog script that pings a known website and calls "network restart" if it fails. These kind of scripts often ping, which is Google's DNS server.

I've discovered 3 ways to recover a qMp mesh router that has functioning wifi but has lost internet- network restart, bmx6 restart and restarting dnsmasq-killall dnsmasq; dnsmasq start. Sometimes the dns forwarder, dnsmasq will stop working correctly letting you ping some things and not others. dnsmasq will then forward bad dns info to the other routers too so it needs to be fixed quickly! killall dnsmasq; dnsmasq start will fix it.

gwck is a qMp utility that is restarted after network restart.

Another problem I've had occasionally is that the wifi will lose connections. Even though the radio is on and the router lights are normal you can't connect. I've written a simple script to restart wifi if both the ad-hoc and access point interfaces have no connections. It is a bit of a hack since the interface may be ok, but since nothing is connected via wifi it doesn't hurt too much to restart it. I've also found that a network restart is necessary to make the wifi stable.

By default wlan0 is the ad-hoc interface that is used to mesh the routers and wlan0ap is the access point. This script checks to see the number of wireless interfaces so it works with dual-band routers and routers that are only ad-hoc or ap.

I'm using "Signal: unknown" to show there is no connection. It seems to work reliably. You could also try iwinfo wlan0 assoclist.

"sleep 5" is usual between "wifi down" and "wifi up". I've found it not necessary when there are no connections, but I'll leave it there in case.

You can download the watchdog here

in the terminal-

vi /root/mesh-watchdog.sh

and paste this:

# mesh-watchdog v1.1.1, NYC Mesh, Brian Hall

  wifi down
  sleep 5
  wifi up

  /etc/init.d/network restart
  if /etc/init.d/gwck enabled; then
    /etc/init.d/gwck restart
  /etc/init.d/bmx6 restart
  sleep 4
  killall dnsmasq
  /etc/init.d/dnsmasq start

#gets date-time from log and exit if recently run. date-time is first two words of last line
if [ -e $LOG ]; then
  set -- `tail -1 $LOG`
  LASTRUN=`date --date="$1 $2" +%s`
  if [ "$?" = "0" ]; then
    #don't run for 1200s (20 minutes)
    NEXTRUN=$(($LASTRUN + 1200))
    NOW=`date +%s`
    es=$(($NOW - $LASTRUN))
    printf "time since last restartNetwork: "
    printf '%dd %dh:%dm:%ds\n' $(($es/86400)) $(($es%86400/3600)) $(($es%3600/60)) $(($es%60))
    if [ $NOW -lt $NEXTRUN ]; then
      echo "waiting $(($NEXTRUN - $NOW)) seconds, use option -f to force"
      exit 1
      echo "run tests-"
    echo "invalid date from log, run tests-"
 echo "no log, run tests-"


if [ "$1" = "-n" ]; then
  echo "restartNetwork"
  exit 1
elif [ "$1" = "-f" ]; then
  echo "force tests-"
elif [ "$1" = "-w" ]; then
  echo "restartWifi"
  exit 1
elif [ "$1" = "-b" ]; then
  echo "restart wifi, wait, restart network"
  restartWifi; wait 60; restartNetwork
  exit 1
elif [ "$1" != "" ]; then
  echo -e "Usage: `basename $0` [OPTION]\n\nTests wifi and internet connections and restarts if necessary (default)\n\n\t-f\tforce test\n\t-n\trestart network\n\t-w\trestart wifi\n\t-b\trestart both wifi and network\n\t-h\toptions\n"
  exit 1

if [ $FORCE != 1 ]; then

DATE=`date +%Y-%m-%d\ %H:%M:%S`  

# find lines containing "ESSID"|get name (previous word)|replace return with ","
WI=`echo "$IWINFO" | grep ESSID | grep -Eo '^[^ ]+' | sed ':a;N;$!ba;s/\n/, /g`
# count the number of wlan interfaces, and number of wlans with 'no signal'
WLAN=`echo "$WI" | wc -w`
NOSIGNAL=`echo "$IWINFO" | grep 'Signal: unknown' | wc -l`

if [ $WLAN -eq 0 ]; then
  echo "no wlan interfaces, wifi is probably disabled"
elif [ $WLAN -eq $NOSIGNAL ]; then
  # all wlan interfaces are down, so restart wifi
  echo "$DATE restart wifi- wlans:$WLAN no-signal:$NOSIGNAL interfaces:$WI" | tee -a $LOG
  sleep 60
  exit 1
  echo "wifi:ok wlans:$WLAN no-signal:$NOSIGNAL interfaces:$WI"

# restart network if ping google.com && fails 4 times
while [ "$count" -le 4 ]
   if /bin/ping -c 1 google.com >/dev/null && /bin/ping -c 1 >/dev/null; then
      echo "wan:ok  ping-count:$count"
      exit 0
 let count++
echo "$DATE network restart" | tee -a $LOG

Make it executable-

chmod +x /root/mesh-watchdog.sh

Afterwards, add the following entry with crontab -e

* * * * * /root/mesh-watchdog.sh

It can run once a minute as it detects whether a network restart has just occurred and will wait 20 minutes before restarting again. I added the 20 minute delay so the router is still functional without an internet gateway.

Thanks to Nitin for help with the wifi problem and Zach for help with dnsmasq.

Email me if you have any questions or suggestions.

Grafana Monitoring




Updating SNMP Data Scraper 



Ever wanted to play with the OSPF link data yourself but didn’t want to take the time to build an OSPF node or parse the output from bird? Look no further than the OSPF JSON API:
> curl http://api.andrew.mesh/api/v1/ospf/linkdb
{"areas": {"": {"routers": ... }}}

Data Available

The full state of the entire OSPF network on the mesh is available via this endpoint. The format is as follows:

  "areas": {
    "": {
      "routers": {
        "<router_id>": {
          "links": {
          	"router": [
          	  {"id": "<other router id>", "metric": <integer link cost>},
          	  {"id": "<other router id>", "metric": <integer link cost>, "via": "<another router id>"},
            "external": [
              {"id": "<external CIDR>", "metric": <integer link cost>},
            "stubnet": [
              {"id": "<stubnet CIDR>", "metric": <integer link cost>},
			"network": [
              {"id": "<network CIDR>", "metric": <integer link cost>},
              {"id": "<network CIDR>", "metric2": <integer link cost>},
      "networks": {
        "<network CDIR>": {
          "dr": "<router id>",
          "routers": [
            "<router id>",
  "updated": <integer epoch timestamp>

For each router, you can see the OSPF links it is advertising, and which type of link they are. Some links have a metric2 value instead of a metric value. This represents a semantically meaningful difference in that router's configuration and the OSPF behavior for that node, but one that is is beyond the scope of this document to explain.

Update Frequency

The server refreshes the JSON data blob once per minute, see the updated field in the top-level JSON object to confirm data freshness.


None. This data is publicly available to any OSPF node, so no authentication is needed when accessing from the mesh private IP space.

Source Code?

GitHub Link!


The OSPF data API is maintained by Andrew Dickinson. Reach out to @Andrew Dickinson on slack for questions and comments. I'd love to see what you build.


This page intends to list the services "hosted" on NYC Mesh and available directly to NYC Mesh members. Some may be available only to NYC Mesh members while some may as well be available from the Internet via a Public IP address (or through Public DNS)

They are different type of services. Some are network specific or meant for devices, such as DNS or NTP, others are more people oriented such as an email server or video chat server.

If you do host a service that you would like to make available to the Mesh Community please let us know so we can add it here.

You can also discuss services on our slack channel #mesh-services

Network services

Public services

It is a free file host hosted on sn3. Anyone can get 10G of free storage. It can support around ~25 users for now.
"I choose Nextcloud because it is very user friendly, and there is a nice mobile app, and desktop sync app. I have also enabled contacts + calendar sync. I use it myself coz i want to rely on other services less; to be more autonomous :)"

Projects Services that are in development...

Phone System and Configuration

Call routing and automation flow spanning two third-party services for Voice-over-IP (VoIP) operation from publicly switched telephone network (PSTN) to virtual and physical endpoints.

Phone System and Configuration

Call Termination: Google Voice and Callcentric


Early 2022 the 833-NYC-MESH number was parked at NumberBarn until further research could be done on how to implement the number. In the meantime the Google for Nonprofits platform was used to get access to Google Voice for a preliminary IVR/auto-attendant solution for routing calls to particular Google Workspace users and email to Slack for voicemail.

Google Voice does not support porting-in toll-free numbers for terminating calls and thus an external provider must be used in conjunction with the 833-NYC-MESH number. Currently, Callcentric has been chosen as our SIP provider due to widespread adoption, low rates, and positive testimonial, though the features it provides can all be replicated using a SIP Trunk->IP PBX architecture.


The 833-NYC-MESH number is ported into Callcentric for inbound termination and outbound origination. Currently, the Call Treatments feature forwards all incoming calls to the Google Voice auto-attendant "Hotline - Main", though the beta IVR setup through Callcentric's internal portal is partially configured and can be switched over at any time for testing.

Block Diagram 9_1.drawio.png


After a rigorous cost-benefit analysis on the plans available through Callcentric compared to the cost of expanding the Google Voice service further, multiple scenarios were drawn out to compare the price per a fixed number of minutes per month.

This Google Sheet has the pricing for pay-as-you-go inbound and outbound calls (which results in a double charge due to the forward to the Google Voice Hotline Root is billed as well as the inbound to the toll-free number), the 500-minute package for outbound calls (to eliminate the double charge for forwarding to Google Voice and regular outbound calls, and eliminating forward to Google Voice all together and handle calls entirely internally.

Based on findings after testing the plans and billing behavior in Callcentric, it was determined that the 500-minute package makes the most sense for preserving Google Voice auto-attendant integration while saving a small amount of funds, while switching entirely to Callcentric for IVR handling is most cost-effective, though there are drawbacks to needing to manually configure SIP endpoints for all users (though those endpoints are more flexibly configured than Google Voice Users.

Callcentric Cost Calculator - Google Sheets

Phone System and Configuration

Callcentric Inbound/Call Treatments

Call Treatments in this context are practically synonymous with Inbound Routes, which may be more commonly seen in VoIP configuration software. NYC Mesh owns two direct-inbound-dialing (DID) numbers registered with Callcentric, toll-free DID 833-NYC-MESH (18336926374) and local DID 13475147546. For more information about how calls are routed through the Callcentric portal, see this separate page, but this page outlines both currently used and unused options that can and are be used in routing NYC Mesh calls.





The Callcentric-provided documentation can be found here.

The main nuance with the currently-implemented setup is the use of "Ring for (seconds)". In all Treatments and IVRs, any SIP extensions are set to time out at 20 seconds of ringing, while the forward to the Google Voice endpoints is set to 60 seconds of ringing. This is to allow the Google Voice endpoint to connect the call to its voicemail for now.

Phone System and Configuration

Callcentric IVR Setup

Callcentric has a built-in IVR utility that allows for practically infinite permutations of menus, auto attendant scripts, and scriptable interactive call flows using Call Treatments. The flow itself can be found here, but this page is solely to contain the scripts for uploaded recordings for all announcement and menu audio files when read through NaturalReader software "Guy Online (Natural) (Free)" voice read at x1 speed extracted using Audacity software using the Windows WASAPI loopback device as an audio recording into a WAV file, which can be easily uploaded through the portal as described below.



On the left, you can add and configure IVRs and their menu trees which follow the structure and naming convention listed in the below section. On the right, MP3 or WAV audio files below 1Mb can be uploaded to be used within the IVRs. There is a built-in validator to ensure there are audio files in the mandatory places for calls to be handled correctly.


When adding an IVR or clicking "modify" on an existing IVR, the Edit IVR screen will open. On the left, the Announcement Audio selection is for audio files to be played only once when entering the IVR, and the Menu Audio selection is for audio files to be played after the Accountment Audio, and repeatedly after User error events such as timeout or invalid entry. This audio can be controlled in the User error audio selection, which currently only plays a built-in female voice "Sorry".

On the right, there are multiple options to route calls based on user entry, between direct transfers to extensions, sending to other IVRs, or connecting to other menus through a transfer. Depending on the setting of Repeat on error, after the error limit is reached the call will terminate.

Call Tree Key

Audio file names are based off of the menus where they are used, either as a menu option or as an announcement. Files that begin with 0 refer to common elements shared among multiple root hotlines. Items in red are options are either planned but not implemented or ideas pending discussion.

IVRs in the 0 zone:

Hotline Roots:

  1. Main - Language (Root Hotline)
    a. Main - English - Menu
    Non-Default Parameters: Repeat on error: 3, User error audio: Sorry
    i. To Get Connected: Simultaneous ringing to Mesh Room and Marco/VM
    ii. Tech Support: Single forward to Marco/VM
    iii. Buildings Projects Fiber: Single foward to Mesh Room
    iiii. Org Info: Special forward to IVR 0.a.iv - Org Info
    b.  Grand - Spanish- Menu (doesn't exist yet!)
    c. Grand - Chinese- Menu (doesn't exist yet!)
  2. Grand - Language (Root Hotline)
    a. Grand - English - Menu
    Non-Default Parameters: Repeat on error: 3, User error audio: Sorry
    i. To Get Connected: Simultaneous ringing to Mesh Room and Marco/VM
    ii. Tech Support: Single forward to Marco/VM
    iiii. Org Info: Special forward to IVR 0.a.iv - Org Info
    b.  Grand - Spanish- Menu (doesn't exist yet!)
    c. Grand - Chinese- Menu (doesn't exist yet!)

Text-to-Speech Audio Files and Scripts

Comment: The pound keys are not truly configurable in Callcentric, and despite the script advising its use to repeat the menu, it triggers the User error audio and subsequently the Last route if pressed after the third failure, which disconnects the call.

0 - Repeat Menu (#)

To repeat this menu, press pound.

0a - Root - Language - English 

To continue in English, press 1.

0ai - Root - English - Get Connected

To get connected to the mesh, press 1.

0aii - Root - English - Tech Support

For technical support, press 2.

0aiv - Root - Org Info

For more information about our organization, press 4.

0aiv - Root - Org Info - Info

NYC Mesh is a community network offering fast, affordable, and fair access to the Internet for all New Yorkers. By joining NYC Mesh, you can access the Internet while helping your neighbors get better and more accessible internet access. NYC Mesh is a neutral network and we do not monitor, collect, or store any user data or content.

For more information about our community network, visit our website at n y c mesh dot net, and find a list of frequently asked questions and answers at n y c mesh dot net slash f a q.

1 - Main - Language - Thank You

Thank you for calling NYC Mesh.

1aiii - Main - English - Buildings Projects Fiber

For buildings, projects, and fiber installs, press 3.

2 - Grand - Thank You

Thank you for calling NYC Mesh at Grand Street Guild.

2a - Grand - Menu - Community

NYC Mesh is glad to be part of your Grand Street Guild community.

Incomplete Recordings

The Callcentric call handling only has IVRs with English. The entry points for other languages would be formatting along the lines of the below:

0b - Root - Language - Spanish

0C - Root - Language - Chinese

Security (outdated)


The goal of this document is to provide the most useful information for anyone interested in the security of the network. If there is missing information that would help understand and improve our network, please reach out to contact@nycmesh.net or join our slack.

We are actively looking for ways to improve the security, resiliancy, and ease-of-use of the network to help the widest range of use cases. If you have ideas on how to improve anything, please join our slack

Our current threat landscape is most concerned with in-mesh security - once traffic is routed over an IXP, provider gateway, or peer, its equivalent to what people are used to.

In mesh threats include:



A typical home install creates two wireless networks - one open 802.11 access point (with a captive portal), and one WPA2 encrypted upstream gateway. You can change the open access point to be encrypted if you wish.


The default setup routes .mesh tld DNS requests to, which is anycast. Multiple people are running our knot-dns setup available on github (including supernode 1 at, but a malicious actor that is closer could take advantage of this.

Slack Support Follow Up Bot


Problems to solve





out of date

Software services list

Incomplete list - add your service!

Wiki (Bookstack)

Bookstack is a user friendly Wiki software which the NYC Mesh Wiki is built on.

MVP Wiki Launch Features

Before the Wiki can be more broadly used (and and possibly replace docs.nycmesh.net) we must add some key features:


Nice to have


Zabbix lives at http://zabbix.mesh.nycmesh.net

Zabbix is used primarily for historical data collection and Slack. There are a handful of dashboards configured for a few devices, but for the most part, the rest of its configuration is unused.

Data Collection

Zabbix is fed through the following sources:

Custom Templates

We have a variety of custom templates, some of which were set up manually at one point, the rest either auto-generated or managed by one of the above tools.


The main purpose of Zabbix is Alerting. Alerting can be found in the #zabbix-alerts channel. Alerts need to be tuned to what we really care about, such as the antennas on the larger links.

To make a trigger show up in Slack, add the slack tag to it.

The trigger can be any severity level. By default, many triggers are straight-up disabled. Alerting is, unfortunately, a manual process. We're still figuring out what is important and what isn't. 

Weekly reports of noisy triggers are published in #zabbix-reports, where the top 20 noisiest triggers are aggregated. This can help us identify problems over time.


More Info

For (outdated-ish) information on how this was set up, including how Slack alerting was configured, refer to this doc: https://docs.google.com/document/d/1mJI8DWe882P6GCEGdT0xazxwrrCQZD7qEBcsDEjDU7Q/edit?usp=sharing




Website Update Ideas

Add your website update ideas!