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

Moving beyond the App Store

I got a nice e-mail from Rogue Amoeba this morning about their release of Airfoil 5, and it indirectly highlighted nearly every single thing that is wrong with the App Store. Here they are, in the order that they appeared in the e-mail:

  • A lack of direct customer interaction
    Rogue Amoeba was able to reach out to me directly as a customer to let me know about their release
  • Poor discoverability and weak cross-promotion
    The e-mail’s header included the icons and titles (each as a link) for all six of Rogue Amoeba’s major products.
  • A lack of free trial versions
    The e-mail included a prominent link to download a trial version of Airfoil
  • A lack of paid upgrades
    As an existing customer of Airfoil, I was offered a discount of $14 (nearly 50% off the full price)

Most of these things are key to an indie software development business (and frankly, pretty important in non-indie shops as well). The inability to implement sustainable business models is, I think preventing many otherwise reputable side-projects from pivoting into real businesses. Some have argued (can’t find the link at the moment), that we developers need to get with the times, and that in-app purchases are the future, etc.

I don’t agree. Sure, you can prompt users for their e-mail address at startup, you can cross promote apps or “upgrades” with in-app notifications (and many of the more successful developers are doing just that), but I think that these kinds of tactics are simply hacks to work around a broken system.

Dan Counsell of Realmac Software wrote last year about how the Mac App Store still needs paid upgrades, and we are now three months into Phil Schiller’s promotion that put him in charge of the App Store. Unfortunately, it looks like things aren’t going to change anytime soon.

I don’t know the internal’s of Rogue Amoeba’s business, but they seem to be doing pretty well, and they’ve been around for a long time. The nature of their software forced their hand in staying out of the App Store, but in retrospect in might have been a blessing in disguise.

It’s time to move beyond the App Store…

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: