{"id":1637,"date":"2012-02-20T19:26:24","date_gmt":"2012-02-20T23:26:24","guid":{"rendered":"http:\/\/www.braindeadprojects.com\/blog\/?p=1637"},"modified":"2012-02-20T19:26:24","modified_gmt":"2012-02-20T23:26:24","slug":"an-upgrade-to-ubiquiti","status":"publish","type":"post","link":"http:\/\/www.braindeadprojects.com\/blog\/what\/an-upgrade-to-ubiquiti\/","title":{"rendered":"An upgrade to Ubiquiti"},"content":{"rendered":"<p>I&#8217;ve been _extremely_ impressed with the quality of <a title=\"Engenius\" href=\"http:\/\/www.engeniustech.com\/\" target=\"_blank\">Engenius<\/a>&#8216; products, most specifically the <a title=\"EOC-2610\" href=\"http:\/\/www.engeniustech.com\/business-networking\/discontinued-eol\/287-80211g-outdoor-high-power-600mw-bridge-access-point-with-dual-antennas\" target=\"_blank\">EOC-2610.<\/a> For the 2 years that I&#8217;ve had my two units in service, I&#8217;ve had very little issue with them.<\/p>\n<p>Recently my workplace ordered a batch of <a title=\"Ubiquiti\" href=\"http:\/\/www.doubleradius.com\/Products\/Ubiquiti-UBNT-Wireless\" target=\"_blank\">Ubiquiti products from DoubleRadius<\/a>. Ubiquiti is loved by the <a title=\"WISPA\" href=\"http:\/\/wispa.org\" target=\"_blank\">WISP<\/a> world, and (mostly) utilize <a title=\"Atheros\" href=\"http:\/\/www.qca.qualcomm.com\/\" target=\"_blank\">Atheros<\/a> boards &#8211; just as the Engenius products do. Both also have stock firmware that&#8217;s also based off <a title=\"OpenWRT\" href=\"https:\/\/openwrt.org\/\" target=\"_blank\">OpenWRT<\/a>. Being inspired, I purchased some equipment myself.<\/p>\n<p>Part of the reason the Ubiquiti gear seems to be more popular is their excellent support and web forum. Engenius is notoriously difficult to get any answers out of. I&#8217;ve still yet to get a copy of their firmware source required by the GPL, and I gave up long ago trying to get anywhere. Luckily, the few questions I did have were answered by simply expirementing.<\/p>\n<p>This weekend I began the migration to Ubiquiti. My first rollout involves a <a title=\"RocketM2\" href=\"www.ubnt.com\/downloads\/rocketM2_DS.pdf\" target=\"_blank\">Rocket M2<\/a> and a <a title=\"120 degree sector\" href=\"ubnt.com\/downloads\/AirMax5GSectors.pd\" target=\"_blank\">120 degree sector antenna<\/a>. For the past few weeks I&#8217;ve been working on adding a more recent version of the excellent CoovaChilli to the device. I have located a version of the <a title=\"CoovaAP\" href=\"http:\/\/coova-ap.s3.amazonaws.com\/ubnt\/index.html\" target=\"_blank\">CoovaAP firmware <\/a>that runs natively on a Rocket M2, however it lacked a number of features (non-Chilli related) that I was hoping for. After much searching, I&#8217;ve been able to locate a 5.3 SDK (which features AirControl and the built-in spectrum analyzer).<\/p>\n<figure id=\"attachment_1757\" aria-describedby=\"caption-attachment-1757\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/AirView.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1757\" title=\"AirView\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/AirView-300x218.png\" alt=\"AirView\" width=\"300\" height=\"218\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/AirView-300x218.png 300w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/AirView.png 1024w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1757\" class=\"wp-caption-text\">The AirView built in spectrum analyzer<\/figcaption><\/figure>\n<p>As I mentioned, it took quite a bit of searching to obtain the SDK. According to Kevin Perry at Ubiquiti\u00a0 &#8220;We&#8217;ve had to temporarily remove the SDKs from our site to comply with US export control regulations. Once approved, we will be able to continue providing SDKs. &#8221;\u00a0 I&#8217;ve not heard anything new, and that correspondence is from September of 2011.<\/p>\n<p>Of course, the Internet is a not only a compendium of 140-word-or-less Tweets about what someone just ate for dinner, it&#8217;s also a <a title=\"The Wayback Machine\" href=\"http:\/\/www.archive.org\/index.php\" target=\"_blank\">giant archive of the past<\/a>. And with a bit of searching, I came across the SDK still hosted (albeit hidden) on Ubiquiti&#8217;s site.<\/p>\n<p>Unfortunately the latest SDK is 5.5, and not 5.3. I&#8217;ve not had luck locating it (and it does contain the patch for the <a title=\"The SkyNet worm\" href=\"http:\/\/forum.ubnt.com\/showthread.php?t=45169&amp;highlight=exploit\" target=\"_blank\">SkyNet worm<\/a>), so I&#8217;m working off 5.3 for the time being. I&#8217;ve locked down access to the web interface to prevent infection from the worm.<\/p>\n<figure id=\"attachment_1762\" aria-describedby=\"caption-attachment-1762\" style=\"width: 175px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/coova.org\/\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1762\" title=\"CoovaLogo2_0\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/CoovaLogo2_0.png\" alt=\"CoovaLogo2_0\" width=\"175\" height=\"175\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/CoovaLogo2_0.png 175w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/CoovaLogo2_0-150x150.png 150w\" sizes=\"(max-width: 175px) 100vw, 175px\" \/><\/a><figcaption id=\"caption-attachment-1762\" class=\"wp-caption-text\">The CoovaChilli Captive Portal<\/figcaption><\/figure>\n<p>With the SDK in tow, I began the work of inserting <a title=\"CoovaChilli\" href=\"http:\/\/coova.org\/CoovaChilli\" target=\"_blank\">CoovaChilli<\/a> into the system. Ubiquiti ensures important services stay running by having them spawned (and respawned if needed) via inittab. The stock inittab on the system is basic, handling only login and a couple of runlevel items. Prior to \/sbin\/init starting, the system runs a bash script \/init. This in turn handles filesystem mounts, makes a handful of device nodes, copies a number of files into place, partially configures sysinit, and sets the timezone. It also calls ubntconf which gleans information from the nvram variables, prior to executing the traditional \/sbin\/init.<\/p>\n<p>ubntconf is a closed source application, although it&#8217;s pretty easy to glean most of it&#8217;s operations by simply running <a title=\"Strings!\" href=\"http:\/\/linux.about.com\/library\/cmd\/blcmdl1_strings.htm\" target=\"_blank\">strings<\/a> on it (It is an <a title=\"Elves in my binaries\" href=\"http:\/\/en.wikipedia.org\/wiki\/Executable_and_Linkable_Format\" target=\"_blank\">ELF<\/a> not a script). Depending upon nvram variables that are set, different scripts are dropped into \/etc\/sysinit. Additionally, items are added to \/etc\/inittab like this:<\/p>\n<blockquote>\n<p>null::respawn:\/bin\/pppd eth0<br \/>\nnull::respawn:\/bin\/lighttpd -D -f \/etc\/lighttpd.conf<br \/>\nnull::respawn:\/bin\/dropbear -F -d \/etc\/persistent\/dropbear_dss_host_key -r \/etc\/<br \/>\npersistent\/dropbear_rsa_host_key -p 22<\/p>\n<\/blockquote>\n<p>Each of these entries will respawn the corresponding service should it crash. Using their system as a model, I created my own config creator &#8220;chilliconf&#8221; to add entries to inittab for the chilli daemon, in addition to the necessary iptables rules in \/etc\/sysinit, and a few modifications to their use of dnsmasq (I wanted to syslog DNS queries offsite). When I later added <a title=\"NProbe\" href=\"http:\/\/www.ntop.org\/products\/nprobe\/\" target=\"_blank\">NProbe<\/a> to my firmware, I also used my chilliconf configurator to add it to the inittab.<\/p>\n<p>My chilliconf configurator, like ubntconf, is called from the \/init script.<\/p>\n<p>One thing of note &#8211; any daemon listed in the inittab file needs to actually run in the foreground (so calling the process a daemon isn&#8217;t entirely accurate). This is for the obvious reason that the initiating process <a title=\"Fork information\" href=\"http:\/\/linux.die.net\/man\/2\/fork\" target=\"_blank\">fork()s<\/a> then exits &#8211; so inittab will continually respawn the service until you run out of resources.<\/p>\n<figure id=\"attachment_1642\" aria-describedby=\"caption-attachment-1642\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/UBNTmainmenu1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1642\" title=\"No Strings Attached\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/UBNTmainmenu1-300x230.png\" alt=\"No Strings Attached\" width=\"300\" height=\"230\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/UBNTmainmenu1-300x230.png 300w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/UBNTmainmenu1-1024x788.png 1024w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/UBNTmainmenu1.png 1280w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1642\" class=\"wp-caption-text\">All original functionality is still there. It&#39;s a like a cyborg version of itself.<\/figcaption><\/figure>\n<p>I used the <a title=\"CoovaAP for 3.3\" href=\"http:\/\/coova-ap.s3.amazonaws.com\/ubnt\/index.html\" target=\"_blank\">3.6SDK version of CoovaAP<\/a> as a model for my web interface. Adding a tab was fairly easy &#8211; the web interface is maintained as the ubnt-web package in the SDK. Most of the web CGI is <a title=\"PHP\/FI\" href=\"http:\/\/php.net\/manual\/phpfi2.php\" target=\"_blank\">PHP\/FI<\/a> (with a couple of functions added to PHP to facilitate saving configs and reading values). The code is extremely readable, and easy to figure out.<\/p>\n<p>When you save your settings in the Ubiquiti web interface, you&#8217;re presented with a blue message bar asking if you&#8217;d like to test or apply your settings. In either case, you&#8217;ll be disconnected for a moment while the system reconfigures itself. This appears to be done via a call to the original \/init script. The blue bar is a bit of a problem when adding a new tab to the menu.<\/p>\n<p>The background image for the blue bar (msg.png) is originally\u00a0 745 pixels, and the screen width is set to 790 pixels. With an added tab, the screen width becomes 866 pixels. Using <a title=\"GIMP, my good friend\" href=\"http:\/\/www.gimp.org\/\" target=\"_blank\">GIMP<\/a> I resized this image to 821 pixels.<\/p>\n<figure id=\"attachment_1644\" aria-describedby=\"caption-attachment-1644\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/BlueMenu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1644\" title=\"The Blue Message Menu\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/BlueMenu-300x57.png\" alt=\"The Blue Message Menu\" width=\"300\" height=\"57\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/BlueMenu-300x57.png 300w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/BlueMenu-1024x196.png 1024w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/BlueMenu.png 1052w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1644\" class=\"wp-caption-text\">Resize the blue background to fit.<\/figcaption><\/figure>\n<ul>\n<li>Originally it was 745, with the original screen width of 790.\n<ul>\n<li>790-745 = 45.<\/li>\n<li>866-45 = 821 &#8212; our newly resized image.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The web interface went through a few iterations before I had all the options I presently needed. CoovaChilli&#8217;s <em>dnsdomainlocal<\/em> option is problematic &#8211; causing any DNS query that returns an NXDOMAIN error for an A record to cause a redirect to the portal. Unfortunately the portal (from my experience) doesn&#8217;t properly track in this instance if the MAC associated with the request is authenticated &#8211; and redirects the user back to the UAMSERVER with the &#8220;res=notyet&#8221; variable. This means the user is prompted with a login screen unnecessarily.<\/p>\n<p>In other words, visit &#8220;adfasjzc9vdsa0f9jdsaf.com&#8221;, and you&#8217;re presented with a login screen even after you&#8217;re logged in.\u00a0 Adding the option to disable <em>dnsdomainlocal<\/em> fixes this problem.<\/p>\n<figure id=\"attachment_1652\" aria-describedby=\"caption-attachment-1652\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/coovamenu.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1652\" title=\"The CoovaChilli Tab\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/coovamenu-300x240.png\" alt=\"The CoovaChilli Tab\" width=\"300\" height=\"240\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/coovamenu-300x240.png 300w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/coovamenu-1024x819.png 1024w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/coovamenu.png 1280w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1652\" class=\"wp-caption-text\">The CoovaChili tab (with NProbe)<\/figcaption><\/figure>\n<p>By default, I have the &#8220;<em>dhcpradius<\/em>&#8221; option enabled. With this feature, when a DHCP request is received by the CoovaChilli server, it forwards the MAC address to the radius server (as both the username and password) for authentication. If it doesn&#8217;t authenticate, the system redirects the user back to the UAMServer for a captive portal login.<\/p>\n<figure style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.braindeadprojects.com\/img\/Ubiquiti\/IMAG0948.JPG\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"  \" title=\"The North Facing Access Point\" src=\"http:\/\/www.braindeadprojects.com\/img\/Ubiquiti\/IMAG0948.JPG\" alt=\"The North Facing Access Point\" width=\"300\" height=\"240\" \/><\/a><figcaption class=\"wp-caption-text\">Broadcasting throught the stratosphere<\/figcaption><\/figure>\n<p>For the time being, the system is a bit overkill, but the options it presents for the future are many. CoovaChilli can rate-limit individual users based on login or MAC address. This alone opens the door for a pay-for-bandwidth model. If a user is found to be filesharing (legal or not) or otherwise consuming an inordinate amount of bandwidth, they can be easily ratelimited.<\/p>\n<p>I still have a few minor items to add to the firmware (including the ability to pull <a title=\"RSSI\" href=\"http:\/\/en.wikipedia.org\/wiki\/Received_signal_strength_indication\" target=\"_blank\">RSSI<\/a> information per client), but in the meantime it&#8217;s been fun working with the Rocket M2. The access point is now being tested in the neighborhood.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been _extremely_ impressed with the quality of Engenius&#8216; products, most specifically the EOC-2610. For the 2 years that I&#8217;ve had my two units in service, I&#8217;ve had very little issue with them. Recently my workplace ordered a batch of Ubiquiti products from DoubleRadius. Ubiquiti is loved by the WISP world, and (mostly) utilize Atheros &hellip; <a href=\"http:\/\/www.braindeadprojects.com\/blog\/what\/an-upgrade-to-ubiquiti\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">An upgrade to Ubiquiti<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,24,38,1,18],"tags":[],"class_list":["post-1637","post","type-post","status-publish","format-standard","hentry","category-engenius","category-gimp","category-openwrt","category-what","category-wireless"],"_links":{"self":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts\/1637"}],"collection":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/comments?post=1637"}],"version-history":[{"count":87,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts\/1637\/revisions"}],"predecessor-version":[{"id":1809,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts\/1637\/revisions\/1809"}],"wp:attachment":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/media?parent=1637"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/categories?post=1637"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/tags?post=1637"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}