Terminal.app’s password icon

The other day was the first I had noticed this:Screen Shot 2015-12-12 at 10.49.46 AM

Now, whenever you authenticate (at least on your localhost), Terminal.app has replaced the usual asterisk character for the inverted key symbol while awaiting your password entry.

It’s a very nice touch, though I’m not sure how long it’s been there. Regardless, kudos to the Terminal.app team. Elegant AF. Now, to see if I can dig through the frameworks to figure out how to call up the same functionality for other situations…

Dear Technology Job Recruiters

I’m currently kind-of sort-of looking for jobs. While I’ll admit I’m being pretty selective in the specific industries I’m looking, I’m also being bombarded by contact from recruiters, looking to fill jobs for their client companies, and take home a healthy (I presume) commission. With the frequency of uninitiated contact, I’m noticing some troubling habits and trends amongst recruiters. These are a few of those habits and trends.

Reading is fundamental. Often times, I will get an email out of the blue from someone I’ve never met, telling me that they came across my resume on Dice or some other place, and that they thought I might be interested in a job at $companyX, located in $locationY. Frequently, $locationY is someplace I can’t easily get to from where I live, requiring a 2+ hour commute, each way, or, worse yet, it’s in some area that I have no interest in relocating to. I have indicated on my profile where I live, and I have indicated the three places I’d be willing to relocate. Far too often, it seems the recruiters either have no knowledge of geography, or they are unable to read. And that’s just with the location.

Then there’s the issue of them sending jobs for which I am decidedly the wrong candidate. They see one or two skills listed that match the description of the position they’re trying to fill, so they send me the position, which I then read, and wonder why on earth they thought I’d be a good candidate for a Windows administrator position, since I do not list any Windows experience on my resume at all. I’m a UNIX admin. I have been for almost two decades. It’s not even that I have anything against working in a Windows environment; I’m not a platform zealot at this age. I’m just not the right guy for that job. And you’d know that if you’d actually read my resume, rather than scanning it for keywords. While reading takes time, and you probably eventually get some results with your “no reading, shotgun the position to everyone” method, you might be surprised what you could achieve if you focused your munitions on specific, appropriate targets.

Email first, call second. You’d be surprised how often I get a phone call from some random, unknown number, which then turns out to be a recruiter, asking if I’d received their email about a job they’re trying to fill. The problem is, they don’t send the email out until after they talk to me on the phone. So, no, I haven’t seen the position you sent me, because you haven’t actually sent it to me. Here’s how this should work, ideally: you read my resume, it matches the job you’re trying to fill, then you send me an email about that job. You provide a contact number in your email, so I can contact you, either by email or by phone, at my leisure. If you must call me, you absolutely, positively need to send the job description to me in email first, and you have to give me a reasonable amount of time to have read your email. Believe me, if you haven’t sent me spam, I’ll read it. I’ll probably look you up online, too, and see if anyone thinks you’re a twit, and I’ll look up the company you’re working for, and the client, and make my decision accordingly. But if you call me first, then expect that I’m going to drop what I’m doing to go read your email while you’re still on the phone with me, and then I’m going to immediate let you know how to proceed, you’re in for a surprise.

Don’t try to intimidate me. This hasn’t happened often, but it has happened. I get a call-first, send email later guy, who calls and tells me he’s going to email the job description to me. I ask him who the client is, he tells me it’s $companyX. I tell him I’m not going to be interested in working for $companyX. He tells me I should read the job description, which he still hasn’t sent, first, then tells me I should call him back and let him know how I would like to proceed. I tell him, “Sure, I’ll read your email, just send it. If I feel like it’s something I’m interested in, I’ll let you know.” He insists I should let him know, even if I’m not interested. I point out that I’m wasting both of our time if I make a phone call to tell him I’m not interested. He asks what sort of time frame I can get back to him in, I tell him 24 hours. “Two to four hours?”, he asks. “No, twenty four hours,” I reply. He tells me he really needs me to get back to him much sooner than that. I tell him “alright, now it’s forty-eight hours.” He tells me that 48 hours is even worse than 24 hours. I tell him I’m moving the time frame to 72 hours, and if he keeps it up, I’ll keep moving the time frame back. He’s angry, and hangs up on me. Sweet, I’m free of this jerk!

Naturally, this would be too good to be true. He calls back, and claims he got disconnected. He asks, again, if I could read his email, which he still hasn’t sent, and get back to him as soon as possible. I tell him I’ll do what I can. He hangs up, frustrated at not getting his way. He then sends the email. I wait three days, and send him an email back telling him, as expected, that I’m not interested. I also add his number to my blocked caller list. We’re done here.

I’m not sure if he ever gets results with his strategy, but that sort of thing doesn’t work with me. I’m not desperate for work. I probably don’t want your job. You need me to help fill a position for your client, so if you want my cooperation, it behooves you to not be a dick. And with me, in particular, if you decide to be a dick, you will soon find out that I love the “who can be a bigger dick” game. You won’t win. I’m actually fairly adept at the game.

Pay attention. I had a recruiter call me (again, without sending the email first) to see if I was interested in a position with their client. I told them, overtly, I was not interested in working for that client. They asked if I could please just look at the job description, and let them know. The problem was that I was headed out of town for a 5-day event, during which I would be offline, entirely. No phone, no internet, nothing. I tell him I’ll take a look after I get back online, in five days. I get on a plane, fly to my destination, and while I’m waiting for my baggage, I get another call from someone else at the same recruiting firm. This one wants to know if I would be available for a brief phone chat once I get back online. I said, “Maybe, it will depend on the job description,” which, at that point, still hadn’t been sent. I remind the individual that in mere minutes, I would be offline, and unreachable, and that I would read what they sent me once I got back.

I leave cellular coverage area. I am entirely off the grid. Five days later, I’m headed back to the airport, and find six emails, four text messages, and three voicemails from the recruiter. Each one is increasingly desperate in tone. The recruiter somehow managed to take what I said, and turn it into me agreeing to do a phone interview with the client, which he then went ahead and scheduled for 2 pm on the day I was to be back online. He then just wanted to have a “brief conversation” to go over the plan for the interview which would “only take a couple of minutes”. After receiving no response from me to that email, he began calling, texting, and emailing, insisting that I should call him back right away, so we could “best prepare” for the interview he’d scheduled for me.

Once I sat down at my gate, waiting for my boarding time, I composed a brief email telling him I’d never agreed to do a phone interview with the client, much less agreed to a specified time for that interview, and that when I said I was going to be offline, I meant entirely, literally off-line. I pointed out that he had made a series of mistakes in interpreting the very simple things I had said, and that I had no interest in either doing a phone interview with the client, or, for that matter, ever doing business with his recruiting company, based on the ineptitude they had already displayed in this encounter. And I added both individuals I had spoken with, and their company, to my black list. Done.

SSH Key Generation Boot Camp

The target audience for this entry is “people using OS X who don’t have a lot of UNIX shell experience”, though it might also be applicable for people learning the basics of any UNIX-based or UNIX-flavored operating system, barring some minor differences in where binaries, configuration files, etc., are located in the particular file system. What we’re going to describe is the basic process for creating public and private key pairs for use with SSH, or “Secure SHell”. But first, let’s talk a little bit about what SSH is.

SSH is a client/server protocol which allows a user on a “client” system, to securely log in to a “server” system. In this context, the “client” system would be the system you’re reading this article on, and the “server” system would be the (most likely) remote system you want to login to. Keep in mind, the “client” and “server” can actually even be the same system, as “client” in the context of SSH just means the machine you launch the ssh process from, and “server” means the system running “sshd“, the server piece of SSH, which allows encrypted remote login.

Client (ssh) ->  Server (sshd)

Basic use of ssh/sshd requires that an account exist on the server you want to login to, and that you know the user name and the password for that account. It also requires that SSHD be running on the server, and that the particular port SSH is configured to use be open to the segment of any given network you’re on.

First, your account has to exist in both places (client and server). For the purpose of this instructional entry, we’re using an example user name of “username“, the details of which look like this:

Login: username Name: username
Directory: /Users/username Shell: /bin/bash
Never logged in.
No Mail.
No Plan.

In order to keep this basic, we’re going to assume you have two systems; a MacBook Air (macbookair.local), and a Mac Mini (macmini.local), both sitting on your home network. Provided you’ve created accounts for yourself (in this example, each has a “username” account), and you want to login from your MacBook Air to the Mac Mini, what you’ll want to do next is make sure SSHD is running on the Mac Mini. You can do that through the GUI (go to System Preferences::Sharing and select the Remote Login option, turn it on, and select that it allow “All users” to login remotely):

Screen Shot 2015-11-02 at 9.00.51 AM

Or you can turn it on from the command line, by issuing the following command in a terminal window on the Mac Mini, from an account with “Administrator” privileges (because it turns on a system service, it will require an administrator password be entered):

sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

At this point, you should be able to use ssh (/usr/bin/ssh) to login from the MacBook Air by simply typing “ssh macmini.local” or whatever the host name is for the server.

macbookair:~ username$ ssh macmini.local
The authenticity of host 'macmini.local (192.168.11.35)' can't be established.
RSA key fingerprint is SHA256:A+aZMhz8Sk+tteMTOYevHEJVthI4B0fXzQ5tUr9+cbw.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'macmini.local,192.168.11.35' (RSA) to the list of known hosts.
Password: [username's password]
macmini:~ username$

And boom, you’re in. Simple, right? Well, typing a password once isn’t too bad, but if you do this a lot, you’ll want to avoid having to type that same password all the time. SSH Keys allow you to circumvent the need for typing the password, as it enables the use of a public/private key pair to authenticate that 1) you are who you say you are, and 2) you should have access to where you’re trying to login.

The next thing to do is generate a pair of keys, using “ssh-keygen“. From the MacBook Air, issue the following command:

macbookair:~ username$ ssh-keygen -t rsa -b 4096

ssh-keygen can actually be run without the command line arguments shown, but since anything worth doing is worth doing right the first time, I’ve added each argument for the following reasons:

-t rsa‘ tells ssh-keygen to generate a key using the RSA-specific algorithm. I prefer this algorithm for my own personal reasons, which I’ll discuss some other time. For now, you can either use it, or you can use the default algorithm, or any of the other options.
-b 4096‘ tells it to make the key-pair with a bit length of 4096, rather than the default of 2048. With public/private keys, the longer the bit length, the more difficult it is to decrypt the data.

Issuing the command will result in the following:

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa):
Created directory '/Users/username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/username/.ssh/id_rsa.
Your public key has been saved in /Users/username/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:IwY34/EZ+AAwo2d5K78mmy6M95WLQVf8j4BTnd3zSw0 username@macbookair.local
The key's randomart image is:
+---[RSA 4096]----+
| +.. |
| . + . o . o . |
|. + o B = o . E |
| o . = @ + +.|
| . o B S . .o|
| + o + o o . .|
|o o o . . . |
|o.o..= . |
| ++=+ . |
+----[SHA256]-----+

You’ve now successfully generated an SSH key pair. The key pair has two elements; the private key (id_rsa), and the public key (id_rsa.pub). They’re both located inside the .ssh directory inside your home directory (unless you specified that it place the keys somewhere else when you were generating the key pair). The .ssh directory is accessible from the command line (cd ~/.ssh/ will place you there), but should be “invisible” from a Finder window, as Finder hides, by default, any directory that begins with a ‘.’ character. So the two files we just created are here:

~/.ssh/id_rsa = PRIVATE KEY
~/.ssh/id_rsa.pub = PUBLIC KEY

Now, I’m going to over-simplify the description of how key pairs work, because the reality is a little math-heavy, and you don’t necessarily have to understand it in order to benefit from their use, but basically, the id_rsa.pub file contains information that allows data to be encrypted that should only be decrypted by people with access to the contents of “id_rsa“.

What you DO need to remember is this: KEEP id_rsa TO YOURSELF. Never transfer the contents of id_rsa to another user, another system, or anywhere you don’t plan on keeping entirely secure. id_rsa.pub is distributable to systems where you want to login in order to access them remotely, but id_rsa is not to leave your system. Defend it with your life, because if someone else gets a hold of id_rsa, they will then have password-less access to everything you have access to, and that can be bad. Very, very bad.

Now, let’s take a look at the public key (id_rsa.pub) we just generated:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzSwBZ6AT9gQYV3m1OAKRJpoktxn8RuoubIp1mkaJvSBYw/zS7UCGFyKVwlbzr88HU9ddlFRd0EZKRqUFbbMBoqwt0G/EPhp4Rs4L2wkDbOZkUJLaGHlEflwn4iVHK6Y3BXOppIRWu0u8aTWKsOyxmv3DCKhAr6HDfxhYQJ+egkWN9Qhz1em1PSqPV/d6bujgrD0SUZpP7Kz2V4nSvc9jGUhtOaCMwAxuDc66j5xpT8j+nEiGx8KdzJHBDwQm/aBqDmVj+G/Lchq8C1147iAw1W8RYoQXfDJyFK/CNIgz0uPi2UdUumNOxsASH0C76kXQAC3Lrjsdf6b+MJ1LJQIQ28msRTiRxc+b1O10SylEb/SEikRnngqbhwiFQU0f95RLWBrSpfw1RRWCOZxovH12+/R4CmeDm3D3fajU9Gapi6EnPlNl3mrEK1GlaE/8TS0BMa4jHGWx1sppxD8e11yyaFyEeYPF5VePnV7pO7bDrreZQJVWP0ldp5suVMDLm2Ggx8SEWD3+JTWwwhRaZyDNh9BxQaD34AHdsb326q1+N3vU7UxugXFdtejU8aGZCKI40VQhLij2lZbPiPQzBwAvBoyfFjo3CYRVhGN0CxvKqhA2Sz4F6/N/eHt5UPJsf0eyiJKvc75g3nNqOUKDeImpm3sSdldghTXhDpbObg7mpeQ== username@macbookair.local

The first seven characters establish that this is an ssh key, generated with the RSA algorithm, then there is a long sequence of characters that do not appear to be human-readable, followed by “username@macbookair.local” at the very end, which means that this is the user who generated the key, and the hostname it was generated on was “macbookair.local“.

What we need to do next, is copy this key over to the Mac Mini, and put it in “username”‘s ~/.ssh/ directory, in a file called “authorized_keys”. The simplest way to do this from the MacBook Air is going to be by using “scp” to send it there.

scp .ssh/id_rsa.pub macmini.local:~/.ssh/authorized_keys

What this command does is tell the “scp” (secure copy) process to send file “.ssh/id_rsa.pub” to the host “macmini.local”, where it should save the file as “.ssh/authorized_keys” on that host. Issuing the command will result in you being asked for username’s password on MacMini (one last time!), to authenticate that you have access and privileges to write files as username on the Mac Mini, then it will copy the file, and save it on Mac Mini with the filename “authorized_keys” in the .ssh directory.

Now, what you can do is try to login from your MacBook Air to your Mac Mini again, using ssh.

macbookair:~ username$ ssh macmini.local
macmini:~ username$

Provided it worked (and why wouldn’t it have?), it should have just logged you right in without pestering you for that pesky password. And now you’re cooking with gas!

In future articles about SSH and scp, we’ll get into some more depth of what is possible, including using scp to copy entire directories from one machine to another, using ssh-agent to allow forwarding of credentials from one host, to another host, to another host, and securing access to SSH to specific groups of users, as well as using non-standard ports to confuse potential attackers. There is a lot that can be done with this family of tools. For now, pat yourself on the back for what you’ve accomplished, and go get some coffee!

OS X “Spotlight” from a shell

Ever lost something on your Macintosh that you’re sure you saved someplace? Can’t find a particular email on a subject, but you remember a keyword that might help locate that email? Spotlight is OS X’s built-in operating system function that allows you to search an index of the contents of your computer, and quickly find that old email, or a file, based on a keyword search. To invoke the GUI version, you need only hit the Command-Space Bar combination, and up pops the dialog box waiting for your keyword.

But you can also do this from a shell, from within Terminal.app. While the usefulness of that feature on a computer you’re currently using might not be that great, it does come in handy if you have multiple Macintosh machines, and you’re sure the file is on your other computer, but you really don’t feel like getting up and walking over to it to check. Simple ssh over to that machine, and issue the following command:

mdfind -name <whateverYou’reSearchingFor>

An example; I wanted to look at my rsync script that I use to make sure my entire music library gets copied to multiple hosts inside my network, but that would have required walking to the office to use Spotlight there in order to search for “rsync.functional”, since I knew that was the name of the script. Instead, I did the following:

tritium:~ mns$ ssh radium.local

Last login: Fri Oct 30 14:29:28 2015 from [tritium.local]

radium:~ mns$ mdfind -name rsync.functional

/Users/mns/Documents/rsync.functional

Now, if I had only known that the file had “rsync” in the title, but didn’t know the whole title, I could have used ‘mdfind -name rsync‘, and it would have returned a larger list of files containing “rsync” in their filenames. There are also a host of other command line options for the mdfind utility, which, if you’re curious, can be seen by taking a look at the man page for it. Issue “man mdfind“, and it will explain a great deal more.

Introducing a new category for this “blog” thing: Nerdery

I’ve generally hesitated to write up technical tips or how-to entries, largely as the result of being restricted from writing about certain technologies for NDA reasons for a number of years. That said, I’ve still been asked countless times to help friends or family with technical issues, and as a result, I’ve written plenty of how-to documents or handed out quick lessons in technical subjects for the benefit of people who know me, and largely because while it’s simple enough to fix one person’s particular problem, it’s even more rewarding to teach them how to solve those problems for themselves.

Given my work experience as a UNIX system administrator for almost 20 years, I’ve acquired a certain body of technical knowledge that I am no longer restricted from writing about. Further, my extensive experience with Mac OS X Server and Mac OS X, running the entire duration of the existence of those operating systems, puts me in a rare category of UNIX admins. Because of this experience, I’m going to start writing more technical things here, on top of the usual expository dreck on subjects I’ve found interesting for years.

Some of these tech-oriented pieces will be geared towards newbies or would-be “power users”, some will end up being more complex, and better-suited for experienced systems administrators. I’m not going to try to define (and subsequently restrict) the content at this point; I’m just going to start knocking entries out, and we’ll see where it goes. Fortunately for all of us, you, the reader, still retain the ability to skip reading articles you don’t want or need to read. I encourage you to exercise that discretion accordingly, and if you happen to find some of this useful, well, huzzah! If nothing else, it will serve as a repository of material from which I can send links to the same said friends and families, so that I don’t have to re-write the same how-to articles tailored to each individual problem.

And I promise that this article will be the least useful of all of them, since it is of an administrative (in the non-system administration sense) nature, and therefore provides no actual technical knowledge, whatsoever.