Sharing a LetsEncrypt certificate with Apache and OpenVPN

You may want to share your LetsEncrypt certificate with Apache and OpenVPN. Once you have the certificate configured in Apache, and (any) custom certificate configured in OpenVPN, updating it alongside your Apache cert is as simple as:

letsencrypt-auto -d [domain] certonly
cp -L /etc/letsencrypt/live/[domain]/cert.pem /usr/local/openvpn_as/etc/web-ssl/server.crt
cp -L /etc/letsencrypt/live/[domain]/privkey.pem /usr/local/openvpn_as/etc/web-ssl/server.key
cp -L /etc/letsencrypt/live/[domain]/chain.pem /usr/local/openvpn_as/etc/web-ssl/ca.crt
service openvpnas restart

Blank Black Page for Cards Against Humanity

Sometime over New Years, a few of us decided to print up a set of Cards Against Humanity. The cards are freely downloadable under the Creative Commons BY-NC-SA 2.0 license.

For a nice set of cards, they recommend that you print them on card stock, and for a really nice set, print black on the backside of the black cards…. which would be a great idea, if only they made a black page for that purpose.

Here is the missing Blank Black Page for the backside of the black cards. Enjoy. 🙂

CAH Black Page Download

Repairing your developer profile in Xcode 4.6

If you’re not particularly familiar with Xcode’s signing mechanisms, you might forget (like I did) to back up your Developer Profile. Oops. Now there is a whole mess of certificates that have to be cleaned up and fixed.

Since there are a whole bunch of questions over on Stack Overflow about various errors related to a broken developer profile, and no clear answers, and since it took me a long time to figure out how to fix it, I’m writing this guide, in hopes it can help you:

First, a bit of terminology:

Your “Developer Profile” is really a bunch of certificates. This is so that Apple (and the people using your software) have at least some guarantee that the software came from you… really, that’s the whole point of code signing.

The “Organizer” in Xcode is a fancy front-end to Apple’s developer site and your Keychain that ties everything together in an easy-to use way (until something gets broken)… If you’re not familiar with the Keychain, it’s the secure certificate/password store built into Mac OS X.

You need five certificates to sign and distribute your apps. I don’t really care if another how-to says you can get by with fewer (they’re right, by the way), because it is easier to get everything set up right, and just forget about it. If you went down the path of figuring out which two or three of the five you needed, you might end up needing the rest later – why bother with the trouble?

Those five certificates are:

* 3rd Party Mac Developer Application: Name (ID)
* 3rd Party Mac Developer Installer: Name (ID)
* Developer ID Installer: Name (ID)
* Developer ID Application: Name (ID)
* Mac Developer: Name (ID)

The first two “3rd Party Mac Developer” certificates are used to sign your app for submission to the app store. The two “Developer ID” certificates are used to sign your app for distribution outside of the app store. And lastly, the “Mac Developer” certificate is used for code signing.

There can also be more certificates needed if your app uses push notifications, iCloud, etc. The ramifications are also more serious if you lost your Developer Profile with those certificates, so I don’t cover that in this how-to.

Lastly, fair warning – I don’t work for Apple, so they haven’t endorsed what is below. If you don’t understand what you’re doing, your profile can become even more fubar’ed than it already might be…

Now down to business:

So, the first step to repairing your Developer Profile is to open up Keychain, go into “My Certificates”, and delete every certificate that matches one of the above names. Make sure you delete the keys that go along with those certificates. Then open up Xcode (it should already have been closed before), and check to make sure there is no one left under “Teams” in the Organizer.

Next, go to the Certificates, Identifiers, & Profiles in Apple’s Member Center. Once there, revoke every certificate that you can under the “Certificates -> All” section. Odds are good that you will have one or two “Developer ID” certificates that you can’t revoke. They can be safely ignored, and you can ask Apple to clean them up later.

Still in Apple’s web tool, start re-creating the certificates necessary to rebuild your developer profile. Remember, you need five certificates (from above). In the web tool, those are:

* Mac Development
* Mac App Store (you’ll need to do this twice, for App and Installer)
* Developer ID (you’ll need to do this twice as well, again for App and Installer)

Once you have re-issued those five certificates, import them into your keychain (they should automatically associate with the keys that you generated earlier). Your keychain should look something like the following:

Developer Profile in Keychain

… and finally, open up the Xcode organizer; it should now look something like this. In particular, notice the little green checkmark next to each identity – that checkmark means you have the private key for each cert… the loss of which caused a great deal of headache, and probably the reason you’re reading this now.


At this point, you should be back up and running. Oh, by the way, if it is working, the very next thing you’ll want to do is click that little “Export” button, and save the resulting file somewhere nice and safe so that you’ll never need to do this again. Good luck!

Creating your own Facebook share button

I recently found out that Facebook no longer offers a “share” button. I think in some cases, the “share” button can give you a better return on your social traffic than a “like” button. I went ahead and wrote up a very short tutorial while I created my button so that you can have your own “share” button too:

Step 1: Create the button:


<div class="f_btn"><a href="#" target="_blank">Share</a></div>


.f_btn {
font-family: 'Helvetica Neue', Arial, sans-serif;
font-weight: normal;
font-size: 11px;
line-height: 18px;
.f_btn a {
position: relative;
display: inline-block;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
color: #222;
overflow: hidden;
height: 20px;
outline: none;
text-decoration: none;
background-color: #f8f8f8;
background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#dedede));
background-image: -moz-linear-gradient(top,#fff,#dedede);
background-image: -o-linear-gradient(top,#fff,#dedede);
background-image: -ms-linear-gradient(top,#fff,#dedede);
background-image: linear-gradient(top,#fff,#dedede);
border: #ccc solid 1px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;

It should look something like this:


Step 2: Clean up the button


<div class="f_btn"><a href="share.php" target="_blank"><span>Share</span></a></div>


.f_btn span {
position: relative;
display: inline-block;
padding: 0 4px 0 19px;

.f_btn a:focus, .f_btn a:hover {
border-color: #bbbbbb;
background-color: #f8f8f8;
background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#d9d9d9));
background-image: -moz-linear-gradient(top,#f8f8f8,#d9d9d9);
background-image: -o-linear-gradient(top,#f8f8f8,#d9d9d9);
background-image: -ms-linear-gradient(top,#f8f8f8,#d9d9d9);
background-image: linear-gradient(top,#f8f8f8,#d9d9d9);

.f_btn a:active {
background-color: #efefef;
-webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,0.1);
-moz-box-shadow: inset 0 3px 5px rgba(0,0,0,0.1);
box-shadow: inset 0 3px 5px rgba(0,0,0,0.1);

It should look something like this:


Step 3: Add a nice logo


<div class="f_btn"><a href="share.php" target="_blank"><i></i><span>Share</span></a></div>


.f_btn i {
position: absolute;
top: 50%;
left: 3px;
margin-top: -6px;
width: 12px;
height: 12px;
background: rgba(0, 0, 0, 255) url('../img/f_tiny.png');

It should look something like this:


Step 4: Add the share count


<div class="f_btn"><a href="share.php" target="_blank"><i></i><span>Share</span></a><div class="f_count">2450</div></div>


.f_count {
position: relative;
display: inline-block;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
vertical-align: top;
background: #F7F7F7;
border: 1px solid #BBBBBB;
margin-left: 4px;
padding: 0 3px 0 2px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
height: 20px;
.f_count:after, .f_count:before {
right: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
.f_count:after {
border-color: rgba(247, 247, 247, 0);
border-right-color: #F7F7F7;
border-width: 3px;
top: 50%;
margin-top: -3px;
.f_count:before {
border-color: rgba(187, 187, 187, 0);
border-right-color: #BBBBBB;
border-width: 4px;
top: 50%;
margin-top: -4px;

It should look something like this:


If you want the share count to be dynamic, you can use Facebook SQL, and load the value using an AJAX request like this:

Intuitive user interface design failure… when a doorknob isn’t.

Sometimes, designing an intuitive user interface takes only stepping away from the project, and trying to think about how someone else might try to use an object. Most of the time though, you really need to see how the interface is used in the real world. The very best example I can think of this involved a so-called “inactive” doorknob. It was the door to a closet in an apartment that I rented.

For nearly two months, I was unable to open the door, instead thinking that perhaps management had located a hot water heater or some similar utility behind the door, locking it away from tenants. Inactive Doorknob

It looked like a doorknob, but it didn’t act like one. It didn’t turn, and it didn’t latch. Instead, I found the doorknob worked like a handle on a cabinet rather than the usual doorknob. One needed only to give the knob a firm tug and the door would open.

On paper, and to those that installed the knob, it probably made perfect sense. But to me, who had never seen that kind of doorknob, it was not an intuitive interface.

These are the kinds of things that can be easily worked out through user testing.