Tuning your Synology NAS for speed

If you own a Synology NAS device at home, you know its an incredible machine for the money. However, it likely has a small amount of RAM (mine has 256MB) and that poses a problem. I have found that if you are not using many of the programs (Disk Station, iTunes server, File Station, etc…), you can free up a great deal of RAM by disabling unused services. This gives precious RAM back to processes that can actually use it, and frees up CPU power.

The first step is to disable services you do not need. For me, this includes all the file indexing and thumbnail services, CUPS printing, USB hotplug, and a few other miscellaneous services. Ensure that SSH access is on (Control Panel – Terminal – Enable SSH Service) and login to the device via SSH.  Then issue the following commands:

/usr/syno/etc/rc.d/S56synoindexd.sh stop
/usr/syno/etc/rc.d/S88synomkflvd.sh stop
/usr/syno/etc/rc.d/S77synomkthumbd.sh stop
/usr/syno/etc/rc.d/S55cupsd.sh stop
/usr/syno/etc/rc.d/S20pgsql.sh stop
/usr/syno/etc/rc.d/S66fileindexd.sh stop
/usr/syno/etc/rc.d/S03hotplugd.sh stop
/usr/syno/etc/rc.d/S03inetd.sh stop
/usr/syno/etc/rc.d/S98findhostd.sh stop

These commands will stop the services from running, but they will restart at the next reboot. To prevent this, simply change the executable status of each service’s start script to be un-executable. This will ensure that disabling these services survives the next reboot. Issue the following commands:

chmod -x /usr/syno/etc/rc.d/S66synoindexd.sh
chmod -x /usr/syno/etc/rc.d/S88synomkflvd.sh
chmod -x /usr/syno/etc/rc.d/S77synomkthumbd.sh
chmod -x /usr/syno/etc/rc.d/S55cupsd.sh
chmod -x /usr/syno/etc/rc.d/S20pgsql.sh
chmod -x /usr/syno/etc/rc.d/S66fileindexd.sh
chmod -x /usr/syno/etc/rc.d/S03hotplugd.sh
chmod -x /usr/syno/etc/rc.d/S03inetd.sh
chmod -x /usr/syno/etc/rc.d/S98findhostd.sh

Note that some of these services might be needed by services you want to run on your DiskStation. You may cherry-pick the services you wish to disable. I only use my DiskStation as a local backup target and have it push to Crashplan, so my requirements are very low. You can reenable a service by using the reverse “chmod +x” command and restarting it.

Next, open the /etc/sysctl.conf file, and add the following network-related settings:

kernel.panic=3
net.core.wmem_max=12582912
net.core.rmem_max=12582912
net.ipv4.tcp_rmem= 10240 87380 12582912
net.ipv4.tcp_wmem= 10240 87380 12582912
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1

This will provide a number of TCP tunings for the Gigabit ethernet card that the DiskStation uses. After making all of these changes, be certain to reboot the box to clear system RAM and caches. You should find that your DiskStation is now more responsive, and tasks should execute much faster.

 

How to sniff your iPhone's outbound traffic.

In the wake of the Path address-book uploading fiasco, I wanted to see what traffic *my* iPhone was sending out. A chatty iPhone app can also be a huge battery drain.

This tutorial assumes that your iPhone is using WiFi to connect to the same network your Mac is connected to. The first tool you will need is the Python-based Mitmproxy (“Man-In-The-Middle”) which is available here.  You will also need Urwid, a console user interface library for Python. Download the current, stable binary versions of both of these programs (0.6 and 1.01 at the time of this writing). Then simply un-tar them to folders on your desktop.

Open a command prompt and change directory into the urwid-1.0.1 directory. Run the install script with the following invocation:

$ sudo python setup.py install
running install
running bdist_egg
running egg_info
creating urwid.egg-info
writing urwid.egg-info/PKG-INFO
...

Note that some of the echoed installation lines are not shown here. Exit from the urwid directory, and change directory into the mitmproxy-0.6.3 directory. From there, run the installation script:

$ sudo python setup.py install
Password:
running install
running build
running build_py
creating build
creating build
...

That’s it! You are now ready to start sniffing your iPhone! Run an “ifconfig” command at the command prompt to obtain the IP address of your Mac. On my Mac, the IP address is 192.168.1.100 on interface en0:

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 50:e5:49:5e:3b:5c
inet6 fe80::52e5:49ff:fe5e:3b5c%en0 prefixlen 64 scopeid 0x4
inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255
media: autoselect (1000baseT <full-duplex>)
status: active

While still in the mitmproxy directory, start mitmproxy by typing “mitmproxy” at the command line. A blank python window will pop-up, ready to receive input.

After that, grab your iPhone and enable WiFi. After it starts running, click the right arrow next to your SSID to access its properties:

Scroll down to the HTTP Proxy section, and enter your desktop’s IP address and port 8080. Here you see my Mac’s IP address of 192.168.1.100

That’s it! Now just wait for an app on your iPhone to initiate outbound traffic. The proxy will capture and record it, like this:

Fixing the "Library not loaded" error with RVM and the MySQL2 Gem

If you are running RVM and have the MySQL Community edition database on your Mac, you will need the MySQL2 gem to access it from Rails. If you install the Gem (gem install mysql2), and then try to start WEBrick, you get this scary error:
[bash]
/Users/cosjef/.rvm/gems/ruby-1.9.2-p290/gems/mysql2-0.3.7/lib/mysql2.rb:9:in `require’: dlopen(/Users/cosjef/.rvm/gems/ruby-1.9.2-p290/gems/mysql2-0.3.7/lib/mysql2/mysql2.bundle, 9): Library not loaded: libmysqlclient.18.dylib (LoadError)[/bash]
To fix this error, run the following command, ensuring that the ~/.rvm path to the MySQL 0.3.7 bundle file listed below is accurate for your system:
[bash]sudo install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.18.dylib ~/.rvm/gems/ruby-1.9.2-p290/gems/mysql2-0.3.7/lib/mysql2/mysql2.bundle[/bash]
Note that this command must be run with the “sudo” prefix (which will require a password) in order to write to the required files. You should then be able to start WEBrick successfully.

Stop User/Password Prompt when Pushing to GitHub

I began using GitHub for Mac to clone my repositories down to my Mac. Then, every time I committed and pushed something up to GitHub, I got prompted for my username and password, like this:

$ git push
Username:
Password:

After a few commits, this got annoying very quickly. I was sure that I had setup my SSH keys correctly, and  retested them to make sure. After some searching, I found the source of the problem: GitHub for Mac clones your repo using HTTPS, which subsequently causes the authentication prompt when performing a push.

Navigate to your cloned directory, and examine the .git/config file. You will see a section entitled [remote “origin”] that looks like this:

[remote "origin"]
	fetch = +refs/heads/*:refs/remotes/origin/*
	url = https://github.com/cosjef/first_app.git

Note the “url” directive pointing to your GitHub repo with the https protocol. This is what we have to change to stop the repeated authentications. From a command prompt inside your local repo directory, issue this command to change the protocol, substituting your login name and repo name where appropriate:

git config remote.origin.url git@github.com:your_username/your_project.git

In the instance of my repo, running the command looks like this:
git config remote.origin.url git@github.com:cosjef/first_app.git

After running the command, reopen your .git/config file, and you now will see that the protocol has changed:

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git@github.com:cosjef/first_app.git

If you now try a push operation, you should not be challenged for a username and password.

Creating a GitHub repository from the command line.

If you’re like me, you hate swapping out of terminal to log into GitHub when creating a new repository.  It an always jarring step that gets you out of coding flow. You can accomplish the very same thing at the command line, and never open a web browser. All you need is the cURL library (found in almost every popular flavor of Linux and OSX today), and your personal GitHub API token.

This technique calls on GitHub’s API to work its magic. You will therefore need to login to GitHub, browse to the “Your Account – Account Admin” section and find your unique API token listed there. Copy the token down for reference purposes.

When you are ready to create a new GitHub repository for your code (ie: just before “git remote add origin” step), issue the following command using the cURL URL transfer tool:

$ curl -F 'login=<your_login_name>' -F 'token=<your_API_token>' https://github.com/api/v2/json/repos/create -F 'name=<your_repo_name>' -F 'description=<your_repo_summary>'

GitHub will reply to your API call with a flurry of JSON, while it creates your new repo in the background:

Your repo will now be ready to push code into. Login into GitHub to validate that it is indeed there. That’s it!

UPDATE 1/10/2013: Github terminated its API on June 1, 2012, which negates the ability to create the repo. More detail can be found here.

 

Create a wireless bridge with a cheap TP-Link router

The TL-WR1043 router from Chinese manufacturer TP-Link is one of the most capable AND inexpensive routers on the market today.  With four Gigabit Ethernet LAN ports, Wireless-N, and a cost of only $54 (at the time of this writing), you cannot find a better value. And it efficiently solves a problem many people have: insufficient wireless coverage.

If your home is large or prone to Wi-Fi “dead spots” where the signal is weak, you can use a wireless bridge to help overcome these problems.  A bridge does exactly what it sounds like: it connects two Wi-Fi networks without the need for cabling. The bridge is nothing more than a second router that joins to your existing network, and extends its range. A bridge also increases the number of wired devices you can connect to your home network via the wired Ethernet ports on the back of it.  Anything you connect there is also connected to your home network,  enabling you to connect devices without onboard Wi-Fi, such as DVD players or game consoles.

To do this, you need two routers, a laptop, and an Ethernet cable. This article assumes one of those two routers is already setup and functioning as your primary Wi-Fi router, and the other is out-of-the-box, unconfigured TP-Link TL-WR1043 router . It will be referred to as the “bridge router” in this article. It is also recommended that you update the router to the latest firmware version from TP-Link before proceeding (3.13.4 Build 110429 Rel.36959n as of this writing)

Here is how you build the bridge:

1) Write down your existing wireless settings
Open up the web-based management console on your existing, primary router. Browse to the Wireless/Wireless Settings section and write down the values for channel, SSID, transmission mode, and the wireless security method and password in use. You will need these value later when you configure the bridge router.

2) Connect the bridge router
Connect the bridge router directly to your laptop with an ethernet cable plugged into any of its four LAN ports. Disable the laptop’s wifi connection, which will ensure your laptop is only talking only to the router. Power the router on, and your laptop should obtain an IP address from it.

3) Open the Administration console
Open a web browser and go to the bridge router’s administration page at 192.168.1.1; you will be prompted for the default password of admin/admin

4) Select the Wireless/Wireless Settings section.
In this section, set a different Wireless Network Name (SSID) from the one used by your primary router. Then set all of the other settings on this page to match your primary router. After making these changes, you will be prompted to reboot the router, which you must do to ensure these changes take effect. After the reboot, move on to the next step.

5) Give the bridge router a different IP.
Open the router management console once again, and select the Network/LAN section. In this section, you will see that the router has a default IP address of 192.168.1.1, which is the same IP address as your primary router. In order to avoid an IP address conflict, change the IP address of the bridge router to 192.168.1.2.  You will need to reboot the router after making this change.

6) Setup the bridge
In the router management console, browse again to the Wireless/Wireless Settings section. This time, tick the checkbox entitled “Enable WDS Bridging.”  This will open a drop-down section with a number of new settings.  You will need to fill in the “SSID(to be bridged”) and the “BSSID(to be bridged)” sections. The fastest way to do this is click the “Survey” button. This will open a new window called “AP List” which shows you all the Wi-Fi networks in range. Look for your primary router in the list by its name (SSID), and click the “Connect” link on the right.

You will notice that the SSID and BSSID sections are now filled out properly. Now simply enter the wireless security values you copied from your primary router. It should look something like this, with the sections with red arrows filled in. Save the settings, and your router will reboot and join your existing Wi-Fi network.

7) Disable DHCP
Since your primary router will be handing out IP addresses on your network, you do not want the bridged router also trying to assume this role. Select the DHCP/DHCP Settings section, and disable the DHCP server.

Then choose the System Tools/Reboot section, and reboot the router for the last time.

8) Reconnect to your primary router.
Disconnect the Ethernet cable from the bridge router and reenable your Wi-Fi. You should now see two possible SSID’s for you to connect to: the primary router and the new bridge router. Connect to the primary router, as you would normally do.

9) Validate the bridge setup.
You can perform a few tests to ensure your setup is configured correctly:
a) Browse to the administration page on the primary router. Select the Wireless/Wireless Statistics section. In this section, you should see the MAC Address of your bridge router, and some values in the Received and Sent Packets counters, indicating the connection is working. It should look like this:

Note that the MAC address of your bridge router should be printed on the bottom of the device.

b) Browse to the 192.168.1.2 address, which is the management console of the bridge router. You should be able to resolve this address and login to the adminstration page on the bridge router without issue.

If both of these test pass, you should be reasonably certain your bridge is configured correctly and running.

10) Connect to the bridge
Now reset your Wi-Fi connection to the SSID of the bridge router.  You should be able to connect successfully, get an IP address through the primary router, and be able to connect to the Internet. You should also be able to connect a wired device to any of the LAN ports on the router and get to the Internet as well.

A quick RDoc primer

I was working through Exercise 35 of  Zed Shaw’s excellent tutorial Learn Ruby the Hard Way when I hit question three in the Extra Credit section.  There he instructs you to “Write comments for the functions you do not understand. Remember RDoc comments?”  And when I Googled for how to use RDoc, nothing really jumped out. Here’s how difficult it is:

In the directory containing your Ruby file, type:

"rdoc <name_of_ruby_file"

That’s it.

That command kicks off a small set of actions, including a scan of your code. Note that it found only a single class, and lists many items as “undocumented.”

The command also creates a “doc” directory containing HTLM, CSS, and Javascript files for presenting documentation of your code.

Opening the index.html file you find in that directory will reveal your documented code:

RDoc has cleanly listed out the objects it found in your file, as well as the methods it discovered. Clicking on any of the method names drills down into more detail, including showing the method code itself:

All this was generated with one simple command.  To truly unlock the power of RDoc, you need to add a few more detailed comments to your code. Such comments allow RDoc to provide much greater detail on the code itself, and remove the “undocumented” response when you build your RDoc documentation.

It will also help anyone in the future who wants to implement your code-which is the whole point of RDoc.

How to Disable IPv6 On a Mac

Open a Terminal session and run the “ifconfig -en1” command to obtain the network configuration of your wireless network. It should look something like this:

en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 60:33:4b:25:24:d0
inet6 fe80::6233:4bff:fe25:24d0%en1 prefixlen 64 scopeid 0x4
inet 192.168.1.101 netmask 0xffffff00 broadcast 192.168.1.255
media: autoselect
status: active

Note the “inet6” section that assigns an IPv6 address to the en1 interface. If you want to disable IPv6 on all interfaces (except loopback), issue the following command:

$ sudo ip6 -x

Now rerun the “ifconfig -en1” command, and you should no longer see IPv6 entries. This change will survive a reboot.

$ ifconfig en1
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 9000
ether 00:1c:c0:a0:5b:94
inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255
media: 1000baseT <full-duplex>
status: active

Install Ruby Version Manager (RVM) on CentOS 6

CentOS 6 ships with updated version of Ruby (version 1.8.7), but does not include the flexibility provided by the Ruby Version Manager (RVM). You will definitely want to use RVM, as it lets you easily manage the roll-forward and roll-back of Ruby and associated Gemsets. Assuming you begin with a Minimal installation of CentOS 6, here is how you install RVM:

1) Install the base packages Ruby needs (all 115 of them)

yum groupinstall "Development Tools"

2) Install NTP and force a time update.

yum install ntp
ntpdate tick.gatech.edu

3) Install zlib and sqlite3

yum install zlib zlib-devel sqlite-devel

4) Download and install RVM

bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

UPDATE:
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

Once installed, log out of your SSH session, then log back in.
5) Verify your RVM installation. You should see “RVM is a function” echoed back.

type rvm | head -1

6) Install Ruby version 1.9.2

rvm install 1.9.2

7) Set version 1.9.2 to be the default Ruby version.

rvm use 1.9.2 --default

8) Verify your version of Ruby is 1.9.2

ruby -v

9) Install Rake gem

gem install rake

10) Install Rails gem

gem install rails

11) Verify Rails install

rails -v

12) Install SQLite gem

gem install sqlite3

You should now have a fully functioning Ruby development environment for your CentOS Linux server.

Debugging IPTABLES rules with pkts and bytes

One of the most common problems with IPTABLES is misconfiguration of its rule sets. You can easily block “good” traffic that should be hitting your server. This typically manifests itself when a dependent service cannot talk to your server with IPTABLES running, but communicates just fine with IPTABLES disabled.

So how do you determine if one of your IPTABLES ACCEPT rules is causing the problem?  If you instruct IPTABLES to list its rules with the “iptables -nvL” command, you should be able to find your answer.  This command returns a list of all chains, but also includes two important columns: “pkts” and “bytes.”  The pkts, or packets, column indicates how many packets have passed through the chain, while the bytes column reveals the total number of bytes that have traversed it.

Here’s how it works in practice:

We recently enabled IPTABLES on two nodes of an Oracle RAC cluster.  As soon as IPTABLES was enabled, the second node would be evicted from the cluster, as the first node could no longer see it.  We surmised that IPTABLES was blocking the traffic, thereby cutting the server off.

To validate this, we ran the “iptables -nvL” command, and looked at the last line returned – the REJECT chain. This showed us a huge number of packets and bytes being rejected by IPTABLES.

pkts bytes target     prot opt in     out     source               destination
311M 571M REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

We also saw no mention of interface bond2 in the listing, which is the private interconnect interface for each RAC node. We therefore added an ACCEPT rule for that interface:

-A RH-Firewall-1-INPUT -i bond2 -j ACCEPT

We then restarted the IPTABLES service to pick up the change, and ran the “iptables -nvL |grep bond2” command to view the traffic:

pkts bytes target     prot opt in     out     source               destination
1032  217K ACCEPT     all  --  bond2  *       0.0.0.0/0            0.0.0.0/0

As you can see, IPTABLES was now processing traffic on the interface, as the pkts and bytes totals had advanced from initial zero values.  After two minutes, we re-ran the command:

pkts bytes target     prot opt in     out     source               destination
5373 9541K ACCEPT     all  --  bond2  *       0.0.0.0/0            0.0.0.0/0

Note the substantial increase in packets and bytes, indicating that our rule was, in fact, working. This was later validate up the application stack, as the RAC clusters could now see each other.  By simply looking at the traffic hitting each IPTABLES rule, we could clearly see where our problem was.