Ylan Segal

Renewing a Let's Encrypt Certificate

I previously wrote about changing my certificate authority to Let’s Encrypt. About the only downside I found about using it with my hosting service, Nearly Free Speach, is the need to manually renew every 3 months. Today, I went through the process and found it to be relatively simple.

To renew the certificate, I ran certbot like this on my machine:

1
$ sudo certbot certonly --manual

This initiated the in-terminal process, with instructions on adding some specific content to the domain to ensure you control it. After the verification the certificates where issued and placed in /etc/letsencrypt/live/ylan.segal-family.com/.

The generated certificate contents looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
$ openssl x509 -in cert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            03:b3:26:9f:ed:b0:58:d7:57:6f:ba:0d:0c:8e:85:cb:f0:d8
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3
        Validity
            Not Before: Dec  7 20:42:00 2016 GMT
            Not After : Mar  7 20:42:00 2017 GMT
        Subject: CN=ylan.segal-family.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:b2:3c:2d:4e:2b:cc:ae:c2:75:08:43:08:f7:2d:
                    cc:fa:05:06:36:e6:06:9f:48:1a:71:a2:aa:c0:4f:
                    01:9d:e7:b2:a0:1b:18:ec:48:ef:59:ec:98:93:89:
                    e5:7a:a7:e4:62:b1:32:85:cf:60:72:40:81:46:71:
                    b8:6f:8d:d1:bb:5d:7d:d4:cd:9c:49:ad:94:8d:ba:
                    98:ad:01:db:d1:7f:f9:98:e3:c2:50:43:97:50:f0:
                    b0:a8:58:8a:e9:5d:f3:d9:88:4a:63:77:4a:06:b2:
                    5d:16:a2:66:6d:1d:b7:2b:c2:90:8f:30:90:18:3d:
                    23:09:8d:fb:07:4c:32:c5:bf:3b:3a:3b:fd:f5:49:
                    7e:e9:2e:82:e5:31:59:3c:b7:c3:e8:07:b9:a8:b6:
                    c7:11:f0:53:36:0a:d9:58:a5:26:09:42:51:b7:9c:
                    78:8c:c0:01:e8:0d:44:7c:eb:66:c8:b4:49:09:22:
                    69:48:94:68:9c:d5:ce:c1:9d:bf:e1:b1:4c:b3:ff:
                    f2:eb:c0:66:e4:7b:1a:1c:4e:24:71:bf:f5:e9:8a:
                    bb:8d:e7:50:5c:f6:01:32:09:53:fd:fe:2f:96:eb:
                    f2:6a:44:7f:dc:5e:f6:c6:18:1a:02:99:b2:0b:45:
                    53:25:b2:97:1c:c4:67:61:99:2b:d7:2a:d6:52:e0:
                    90:2b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                17:5A:1E:01:42:05:20:F2:CA:AE:CB:BA:84:49:DB:53:02:7D:76:3E
            X509v3 Authority Key Identifier:
                keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1

            Authority Information Access:
                OCSP - URI:http://ocsp.int-x3.letsencrypt.org/
                CA Issuers - URI:http://cert.int-x3.letsencrypt.org/

            X509v3 Subject Alternative Name:
                DNS:ylan.segal-family.com
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org
                  User Notice:
                    Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/repository/

    Signature Algorithm: sha256WithRSAEncryption
        35:98:2b:c4:ed:e3:93:5b:2a:61:f0:cb:1d:23:3f:d8:15:79:
        eb:92:f4:79:e9:a2:31:2b:d1:35:bc:0c:5d:89:ad:ec:ed:56:
        2c:d2:77:bc:f0:19:64:7c:04:9b:76:6c:16:84:23:b5:94:9a:
        74:2e:2e:3c:18:47:ee:73:6e:d9:b5:2c:dd:89:c5:1e:ec:a4:
        c0:c4:e7:8c:35:9f:a0:af:ec:87:ea:78:81:45:6b:e5:db:b3:
        60:0a:02:08:4e:92:5a:da:5c:d8:95:d3:45:7d:d7:3f:07:2e:
        0c:a3:dc:a8:4f:1a:e8:e7:9b:d7:09:2e:d7:f3:2c:c2:c0:ba:
        78:70:11:12:62:37:80:e6:e3:cb:a0:04:e6:19:f3:0a:eb:74:
        64:50:e6:90:e5:60:32:f6:f6:d4:e8:db:94:6a:47:76:25:34:
        23:e0:13:2b:19:a0:de:33:7c:33:a2:fb:7e:03:79:d6:30:ab:
        f8:85:3d:27:3c:d4:69:9a:f9:da:b4:5c:88:b5:1c:95:5d:64:
        8f:2c:26:eb:73:f9:08:4c:ec:30:d8:91:82:a7:0a:ed:9c:82:
        b5:24:b7:54:38:04:61:47:5e:ac:02:83:81:cf:d7:29:d6:74:
        b2:90:3d:0c:75:2a:e3:12:f2:3d:53:96:9d:ca:48:c4:bc:b3:
        a8:94:5a:d2

As was the case when first installing the certificates, Nearly Free Speach requires them to be concatanated and pasted into their form:

1
$ cat fullchain.pem privkey.pem | pbcopy

The changes take place immeditely. I now have 3 more months of a valid TLS certificate for this web-site.

The REPL: Issue 28 - November 2016

Open-Sourcing Yelp’s Data Pipeline

The Yelp Engineering team has been posting regularly about they structure data consumption between different teams. The backbone of their system is Apache Kafka, but they have created a lot of tooling around it. In this announcement, they have open sourced (Apache License 2.0) many of these tools. MySQL Streamer pipes data from MySQL to Kafka. Schematizer stores and tracks the various data schemas used throughout their pipeline. There is a lot to learn in this projects and the blog itself, which provides an overview of how they approach dealing with data.

Offshoring roulette: lessons from outsourcing to India, China and the Philippines

Troy Hunt writes a lengthy post about his experience offshoring development work to teams in India, China and the Philippines. He goes through the motivation for offshoring in the first place, the challanges and rewards, and the differences he encountered in different countries. His conclusion:

if you’re looking at hourly rate as a metric for outsourcing success, you’re doing it very, very wrong!

NIST’s new password rules – what you need to know

The United States National Institute for Standards and Technology has come up with new guidelines for password policies. If you are wondering which password rules to follow in your product, these are a great baseline. Note that the NIST policies contradict the FBI’s. While you are at it, consider if you actually need to store a password at all. Medium, for example, emails you a link to log in. Because of “forgot your password” functionality in most sites, access to your email is essentially equal to access to the site. Medium just made it explicit and removed the need for them to store users passwords. Those passwords are probably re-used elsewhere. If you don’t store them, you can’t loose them. Right?

Benchamarking With Abprof & Abcompare

This week at RubyConf I learned about two new tools.

ripgrep (rg) combines the usability of The Silver Searcher (an ack clone) with the raw speed of grep.

And abcompare:

Determine which of two programs is faster, statistically.

Let’s use abcompare to check the speed of ag against rg.

1
2
3
4
5
6
7
8
9
10
11
12
$ abcompare "ag 'protected$'" "rg 'protected$'"
...
Based on measured P value 1.938532867962195e-05, we believe there is a speed difference.
As of end of run, p value is 1.938532867962195e-05. Now run more times to check, or with lower p.
Lower (faster?) process is 2, command line: "rg 'protected$'"
Lower command is (very) roughly 2.804074569852101 times lower (faster?) -- assuming linear sampling, checking at median.
         Checking at mean, it would be 2.794296598639456 lower (faster?).

Process 1 mean result: 0.08557533333333334
Process 1 median result: 0.085886
Process 2 mean result: 0.030625
Process 2 median result: 0.030629

And:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ abcompare "ag '< ApiController'" "rg '< ApiController'"
...
Trial 3, Welch's T-test p value: 0.00019649943055588537   (Guessed smaller: 2)
Based on measured P value 0.00019649943055588537, we believe there is a speed difference.
As of end of run, p value is 0.00019649943055588537. Now run more times to check, or with lower p.
Lower (faster?) process is 2, command line: "rg '< ApiController'"
Lower command is (very) roughly 2.3338791691803844 times lower (faster?) -- assuming linear sampling, checking at median.
         Checking at mean, it would be 2.408501905599531 lower (faster?).

Process 1 mean result: 0.082154
Process 1 median result: 0.08124
Process 2 mean result: 0.03411
Process 2 median result: 0.034809

The above was tried on my largest project, with ~3,000 Ruby files in it:

1
2
$ find . -name '*\.rb' | wc -l
  2757

Conclusion

For my use case, it seems clear that rg performs faster than ag. Don’t take my word for it, though. Run a benchamrk yourself!

The REPL: Issue 27 - October 2016

Karafka

Karafka is a framework used to simplify Apache Kafka based Ruby applications development. It looks like a Rails-like abstraction to remove some of the boilerplate and decisions around how to structure a Kafka application. I don’t know if it’s ready for production, but worth keeping an eye on it.

MiniTest is not “Just Ruby”, it is “Just Rails”

Victor Shepelev writes his opinion about RSpec and MiniTest and how the differ. I don’t subscribe to all the author’s opinions or conclusions, but I do prefer RSpec and I have never found the “It’s just Ruby” argument for MiniTest very convincing. If anything, I find that having a distinct shape, structure and feel for test is a net positive. It promotes shifting from “This is the part that specifies behavior” to “This is the part that implements behavior” in a cleaner way.

Be Kind

Being a good and kind person pays dividends. I love this story. You should read it.

Subtleties of Xargs on Mac and Linux

xargs is one of my go-to tools in Unix. It reads lines from stdin and executes another command with each line as an argument. It’s very useful to glue commands together.

It’s default behavior is slightly different in Mac (or BSD) and Linux, in a subtle way. On the Mac, if there is no input from stdin, it will not execute the command. On Linux, it will execute it without any argument.

As an example, let’s say that we want to use rubocop (a ruby syntax checker and linter) to check only RSpec files in a project. We can write something like this:

1
$ find . -name '*_spec.rb' | xargs rubocop

On a project that has a two spec files, expanding the above example:

1
2
3
$ find . -name '*_spec.rb'
./spec/one_spec.rb
./spec/two_spec.rb

xargs will execute the equivalent of:

 $ rubocop ./spec/one_spec.rb ./spec/two_spec.rb

The subtlety in behavior cames in when no files are found. To illustrate, let’s see the difference in a trivial example:

1
2
3
4
$ uname
Linux
$ echo "" | xargs echo "Hello"
Hello
1
2
3
4
$ uname
Darwin
$ echo "" | xargs echo "Hello"
$

On Linux, xargs will execute the utility, on a Mac it will not. The Linux version can be configured to have the same behavior as the Mac:

1
2
3
4
$ uname
Linux
$ echo "" | xargs --no-run-if-empty echo "Hello"
$

Unfortunetly, the --no-run-if-empty option is not recognizable by the Mac:

1
2
3
4
5
6
7
$ uname
Darwin
$ echo "" | xargs --no-run-if-empty echo "Hello"
xargs: illegal option
usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
             [-L number] [-n number [-x]] [-P maxprocs] [-s size]
             [utility [argument ...]]

Why is this important? In the original example, if no files are found, rubocop will not be invoked at all on the Mac, but will be invoked with no arguments on Linux. In my case, that is unwanted behavior because rubocop will then check all files in the project.

Conclusion

When writing bash scripts that are intended to run on different Unix version, be careful that you understand and test the behavior of the Unix commands used, sometimes they have subtle differences in behavior.