nathandemick.com

Bare-bones SSH Tunneling

This year, I wanted to work remotely for a day or two in the week leading up to Christmas. I went through the trouble of getting an RSA dongle and setting up the terrible VPN software on my machine, only to discover that I couldn’t access some resources that were within my company’s DMZ. When I asked about this, the “official” response was that it was expected for users to connect to an intermediary machine first, then connect to the desired (restricted access) resource. Whiskey Tango Foxtrot! The problem here is that I don’t have an intermediary machine.

This situation can be (mostly) solved by using SSH tunneling, which can take network traffic directed at a local port, and send it to a remote port via a man-in-the-middle server. In my case, I have access to an internal-only webserver, which itself has access to the DMZ. The two tasks that I needed to do on restricted server were HTTPS access (port 443) and SFTP access (port 22).

HTTPS


ssh -L 3000:<inaccessible_server>:443 <your_username>@<accessible_server> -N

The -L option means we want to do local port forwarding, and -N specifies that no command should be executed on the remote server. You could also add -f if you want to put the ssh process in the background. Run this command, and load localhost:3000 in your browser. Unfortunately, you’ll see a “certificate mismatch” error message, because the SSL certificate doesn’t match the URL. A hacky way to fix this is to modify your /etc/hosts file, and add an alias (on a new line):


127.0.0.1 <inaccessible_server_url>

Then you can hit <inaccessible_server_url> as (almost) normal, the only difference being that you have to specify port 3000 instead of the normal HTTPS port 443.

SFTP

Basically do the same thing as with the HTTPS setup, except change the remote port to be 22:


ssh -L 3000:<inaccessible_server>:22 <your_username>@<accessible_server> -N

Add your hosts alias, then modify your SFTP connection to hit port 3000, and connect as normal.

(Note that adding the DNS alias only matters if you’re accessing the server via URL; if you’re connecting via IP, you’ll have to change the server to localhost.)

References

· 0 comments

PM2: The Swiss Army knife for your Node.js app

I recently discovered PM2. It is great. Tell your friends. I can’t believe that one app does so many (necessary) things:

(Re)starts your app

A naive approach to running a Node application would be to start the process and put it in the background. But what happens when it (inevitably) crashes? Give PM2 your application configuration, and it will start the app and ensure it respawns after a crash.

Monitor memory/CPU usage

App got a memory leak? Churning CPU? Watch your usage levels in real time.

Run app in fork/cluster mode

Normally you’d have to write your app specifically to take advantage of clustering, but with PM2, you can just specify whether you want a single process or multiple processes. By default, it’ll spin up as many workers as your CPU has cores.

Log output from stdin/stderr

While there are a number of sophisticated logging solutions for Node, at this point in my usage of it I really only care about getting console.log statements and stack traces written out to external files. By default, Node outputs these messages to stdout/stderr, which PM2 will watch and write off to log files. You can easily get a stream of logs using pm2 logs, or limit to one application using pm2 logs <appname>.

Easily set up log rotation

As with any web application that generates log files, after a while the files get too large and unwieldy. PM2 has a command that will automatically generate a logrotate config file that targets the default PM2 log location.

Auto-restart app during development

When developing, you have to restart your Node server in order to see changes. Frameworks like Rails have a “development” mode they can use to re-load code before each request, but with Node you’ll probably rely on something like supervisor, which watches the filesystem of your project for changes, then kills/respawns your Node process. Or you can just use PM2, which does the same thing.

Start app after server reboot

This is a necessary evil that I’d wager many developers don’t think about, similar to log rotation. Unless you create a custom init script, if your server ever reboots, you will have to log in and restart the PM2 daemon. PM2 can generate a startup script for you!

Deployment

I haven’t used this aspect of PM2, but am hoping to soon. Instead of manually SSH’ing to your server in order to do deploys, just use the functionality built in to PM2, which will check out code from your VCS and (re)start the Node process. It supports multiple server targets, as well as rollbacks.

· 0 comments

Refactoring

When learning the code base of a new project, there are always places where you look at what’s been written, and have a “WTF” moment. Normally, it’s best to leave written code in place – if it ain’t broke, don’t fix it. However, I let myself get a bit carried away with a recent project, and rewrote the bulk of the server-side component. I thought I’d pull out a small example of how you can take some verbose code, and condense it down to something more readable.

In this example, we have an array of email addresses, some of which may be prepended with the string "coordinator-". Why the original developer didn’t just create two database columns, user_emails and coordinator_emails, I can’t imagine. In any case, we want to send a message to the “non-coordinator” email addresses.

Here was the original code:


var to = "";
for(var i=0; i<emails.length; i++) {
    var email = emails[i];
    if(email.indexOf('coordinator') == -1) {
        to += email;
        if(i != emails.length-1) to += ",";
    }
}
to = to.slice(0, -1);

Straightforward enough, right? Create an empty string, and concatenate the appropriate email addresses (include a separating comma), then remove the final comma. So, if the emails array looks like ['bob@gmail.com', 'larry@gmail.com', 'coordinator-joe@gmail.com'], the final output is the string "bob@gmail.com, larry@gmail.com".

But there’s an easier way to do this, and it involves being knowledgeable about common Array manipulation methods. The first thing we want to do is remove any email addresses that contain "coordinator-". Filter them out, if you will. By Jove, there just happens to be an Array method named filter that we can use! Next, we want to join the resulting email addresses together, with a comma between them. What do you know? join is an Array method as well!

The whole thing boils down to one (long) line (pardon the ES6 syntax):


let recipients = emails.filter(email => { return email.indexOf('coordinator-') === -1; }).join(',');

Which do you prefer?

· 0 comments

Review: Happy Hacking Keyboard Professional 2

Recently I took the plunge and purchased a Happy Hacking Keyboard Professional 2.

Design

The first thing you notice about the HHKP is its small footprint. It is approximately the size of a laptop keyboard, but the keys are full size. I purchased the black version, which uses a dark grey plasic for the board/keys, with black lettering on the key tops. Taken as a whole, it looks very attractive and minimalistic. One thing to note is that the contrast between the keys and labels is very slight, which might make it difficult to see in a darkened room. The textured plastic also seems to attract lint, which mars the overall appearance.

Feel

The keys feel great; if you’re used to typing on modern Apple keyboards, the key travel will feel almost excessive at first. I wasn’t sure what I would think about Topre switches, but I think that I like them; they aren’t really noisy, but have a deep, satisfying “thunk” when they bottom out. The keycaps have a textured plastic on the top which is also very pleasant to feel. I think that overall, the switches fulfill the requirement I had for them, which was to provide moderately deep travel and not be too loud for a cramped office space.

Compromises

Of course, the reason why the HHKP is so polarizing is that the designers made some choices that not everyone will agree with. Probably the most obvious is that there are no dedicated arrow keys; you have to press a modifier key plus one of the [, ;, ' or / keys. If you’re a visual text editor power user, this may very well be a dealbreaker for you. The only other real annoyance I’ve found is the placement of the tilde (~) key, which is on the upper right side of the board, above the Delete key. It’s very commonly used in Unix-flavored systems (e.g. cd ~ will take you to your home directory), and I have not gotten used to its placement yet.

Conclusion

Although it will only appeal to a subset of keyboard enthusiasts, I have enjoyed using the HHKP. If you use a computer professionally, it’s definitely worth your time to investigate other keyboards besides the one baked into your laptop.

Happy Hacking Keyboard Professional 2 on Amazon.com (referral link)

· 0 comments

Let's Build Bridges!

Finally getting around to making note of this here: I finished another simple puzzle game a few weeks ago. It’s a hashi wo kakero implementation, called “Let’s Build Bridges.” Check it out on the Ganbaru Games site. It works great on mobile (Chrome/Safari) as well, so you can save it to your device’s homescreen for fast access. Alternately, I put an IAP-enabled version on iTunes, so plz give me pennies.

Also, since trashing the Ganbaru Games dev blog, I needed something to put there, so ended up making a faux smartphone-type interface. It’s a bit spartan now, but will be fleshed out a bit as I slowly convert some of my Javascript games over to using Arcadia.

· 0 comments