menu

Category: How-To Guides

The How-To Guides category is for posts that explain how to fix an issue, configure a device or a piece of software, or make something work.

Posted on by Arnon Erba in How-To Guides

Let’s Encrypt has steadily improved since its public debut in late 2015. Certbot, the most popular Let’s Encrypt client, is available for a wide variety of Linux distributions, making Let’s Encrypt an easy integration for most common web server configurations. However, because of this broad support, and because Certbot offers many internal options, there are several different ways to integrate Certbot with Nginx.

If you run Certbot with the --nginx flag, it will automatically make whatever changes are necessary to your Nginx configuration to enable SSL/TLS for your website. On the other hand, if you’d prefer to handle the Nginx configuration separately, you can run Certbot with the --webroot flag. In this mode, Certbot will still fetch a certificate, but it’s up to you to integrate it with Nginx.

Once you’ve obtained certificates from Let’s Encrypt, you’ll need to set up a method to automatically renew them, since they expire after just 90 days. On Ubuntu 18.04, the “certbot” package from the Ubuntu repositories includes an automatic renewal framework right out of the box. However, you’ll also need to force your web server to reload its configuration so it can actually serve the renewed certificates (more on this below). The packaged renewal scripts on Ubuntu won’t restart Nginx unless you used the --nginx flag to request certificates in the first place. If you’re using --webroot or some other method, there’s an additional important step to take.

Automatically Restarting Nginx

On Ubuntu 18.04, Certbot comes with two automated methods for renewing certificates: a cron job, located at /etc/cron.d/certbot, and a systemd timer. The cron job is set to run every 12 hours but only takes effect if systemd is not active. Instead, the systemd timer (visible in the output of systemctl list-timers) works in tandem with the certbot systemd service to handle certificate renewals.

Instead of modifying the cron job or the systemd service, we can change Certbot’s renewal behavior by editing a config file. Add the following line to /etc/letsencrypt/cli.ini:

renew-hook = systemctl reload nginx

This will cause Certbot to reload Nginx after it renews a certificate. With the renew-hook option, Certbot will only reload Nginx when a certificate is actually renewed, not every time the Certbot renewal check runs.

A Little Background Information

If you’re new to Let’s Encrypt, and you’re wondering why you need to automatically renew your certificates and restart your web server when you get new ones, it’s a good thing you’re here. While “traditional” SSL/TLS certificates are manually requested and can be valid for up to two years, certificates from Let’s Encrypt are only valid for 90 days. In their blog post, the Let’s Encrypt team explains their reasoning behind such short certificate lifetimes: they limit the time period for damage to be caused by stolen keys or mis-issued certificates, and they heavily encourage automation, which is key to the success of the Let’s Encrypt model.

This means that you’re going to need to automatically renew your certificates in order to take full advantage of Let’s Encrypt. Fortunately, since this is how Let’s Encrypt is designed to work, auto-renewal functionality is built directly into Certbot, the recommended ACME client for Let’s Encrypt.

A slightly less obvious question is why you’d want to automatically restart your web server as well. The answer is simple: web servers, such as Apache or Nginx, don’t read your SSL/TLS certificates directly from disk every time they need them. Instead, they load them into memory along with the rest of the web server configuration. This is great, and perfectly normal, since reading the certificates from disk would be horribly inefficient. However, it means that updating (or renewing) a certificate with Let’s Encrypt won’t directly change the certificate that Apache/Nginx serves when a page is requested. Instead, the web server must be restarted in order to load the new certificate into memory.

Sources

Posted on by Arnon Erba in How-To Guides

Julia, the fast-moving and popular open source programming language for scientific computing, allows for the usage of multiple BLAS implementations. Pre-built Julia binaries ship with OpenBLAS due to licensing restrictions surrounding the Intel Math Kernel Library, but by building Julia from source you can replace OpenBLAS with a free copy of MKL obtained from Intel’s Yum or Apt repositories. As of the time of writing, there are instructions for this process on the Julia GitHub repository.

Determining the BLAS Vendor

Regardless of which BLAS implementation you choose, it is nice to check that Julia is actually using the one you want, especially if you are building Julia from source. In recent versions of Julia, you can run the following two commands in the Julia REPL to find your BLAS vendor:

julia> using LinearAlgebra
julia> LinearAlgebra.BLAS.vendor()

The second command should output a string indicating which BLAS implementation your Julia installation is currently built with.

Posted on by Arnon Erba in How-To Guides

As a blogger, getting your content in front of as many people as possible is crucial to growing your reader base. One way to broaden your reach is to take advantage of Apple News as a publishing platform so that iOS users can easily discover your content. Fortunately, getting an established blog on Apple News takes nothing but an Apple ID and a little patience.

Two Ways to Publish

Apple News offers two different formats for displaying your content in the News app. If you have some extra time, you can publish your articles in Apple News Format, which allows you to create a custom visual theme and gives you access to more advanced features like analytics. There are third-party Apple News Format plugins available for popular content management systems such as WordPress and Drupal, and you can find the instructions for setting up Apple News Format in the News Publisher documentation.

However, if you’re in a hurry, you can simply add an RSS or Atom feed to your Apple News account. We’ll be covering that method in this post. If you’re using WordPress, you can take advantage of its built-in RSS and Atom feeds for this tutorial.

Publishing Using an RSS/Atom Feed

Adding a blog to Apple News with just an RSS or Atom feed can be accomplished in a few quick steps:

  1. First, head to the Apple News sign-up portal. The sign-up process for a News Publisher account is handled through iCloud, so you’ll need an Apple ID for this step.
  2. Next, enter your publisher information. Apple News requires a name, email address, and mailing address to proceed.
  3. After setting up your personal News Publisher account, you’ll be able set up a “channel” for your blog. This is separated from the previous step, and requires you to provide a phone number.
  4. Next, you can break off and set up Apple News Format, or you can skip directly to adding an RSS/Atom feed. You can even add multiple feeds if you have different streams of content.
  5. Once you add your feed, Apple News will ask if you want to upload branding for your channel. Apple has clear guidelines for this optional branding in the News Publisher documentation, but you can skip this step too if you’re short on time.

Finally, your new News channel containing your blog’s feed will be submitted to Apple for review. The waiting period can vary, and it took about three weeks for Apple to approve the Atom feed for my blog. You’ll get an email from Apple if your submission is approved, and you should be able to find your channel in the News app immediately.

Posted on by Arnon Erba in How-To Guides

The Fibonacci sequence (or series) is a classic example of a problem that can be solved by using recursion. As such, it’s often used to teach the concept of recursion in introductory programming courses. In this post, I’m going to explain how to write a simple recursive Fibonacci sequence calculator in C++ and how to optimize it so that it is capable of computing large Fibonacci numbers more efficiently.

Some Background: What is Recursion?

If you’re already familiar with the concept of recursion, you’re welcome to skip to the next section, where I’ll jump right into the code. Otherwise, you may want to review this section before continuing.

An Informal Definition

Put most simply, a recursive problem is one that is defined in terms of itself. In computer science, recursive procedures (functions) are used to break these kinds of problems down into simpler, easier-to-solve versions of themselves. Recursive functions, like the problems they solve, are also defined in terms of themselves.

Recursion in Code

In practice, this means a recursively defined function must call itself when it runs. To prevent an infinite loop, a correctly written recursive function will stop calling itself once it reaches a base case, which is a problem it can solve without having to call itself again. This is the idea behind recursion: A complex problem is eventually reduced to an easy-to-solve base case with a known solution. Recursive functions achieve this goal by re-using the same logic with different parameters every time the function is recursively called.

Recursion and the Fibonacci Sequence

With this in mind, it’s easy to see why the Fibonacci sequence is a good example of recursion. In the Fibonacci sequence, each number is recursively defined as the sum of the two previous numbers. For example, to find the fifth Fibonacci number, you first have to find the third and fourth numbers. However, you can’t find the fourth number without finding the second and third numbers, and so on. In fact, the whole sequence is constructed from the first two numbers, 0 and 1, which are the base cases. Some recursive problems only have one base case, but the Fibonacci sequence has two.

The Simple Function (And Why It’s So Slow)

All of this can be expressed more clearly with code:

 1 int fibonacci(int n) {
 2     if (n == 0) {
 3         return 0;
 4     } else if (n == 1) {
 5         return 1;
 6     } else {
 7         return fibonacci(n-1) + fibonacci(n-2);
 8     }
 9 }

This basic fibonacci function takes a single integer n as a parameter. This integer is the index value of the desired Fibonacci number. The first two if statements (lines 2 and 4) are simple: If the 0th Fibonacci number is requested, return 0. If the 1st Fibonacci number is requested, return 1.

However, if anything beyond the 1st Fibonacci number is requested, the function jumps to the statement in the last else block (line 7):

return fibonacci(n-1) + fibonacci(n-2);

In this case, the function will first compute the previous two values of the sequence, and then add them together and return the answer. This is because the value of fibonacci(2) depends on the values of fibonacci(1) and fibonacci(0), and so on.

This quickly becomes complex. Calling fibonacci(5) results in calls to fibonacci(4) and fibonacci(3). However, calling fibonacci(4) results in a second call to fibonacci(3), since we need to know the value of the 3rd number in the sequence before we can find the value of the 4th. Likewise, both calls to fibonacci(3) will result in duplicate calls to fibonacci(2) (and eventually fibonacci(1) and fibonacci(0)).

Re-computing values we’ve already calculated is a big performance drain, and it only gets worse as we go farther into the sequence. Wouldn’t it be great if we could store the value of fibonacci(3) somewhere so we didn’t have to re-compute it later?

The Optimized Function

 1 unsigned long fibonacci(unsigned long n) {
 2         static std::vector<unsigned long> fibovector = {0, 1};
 3         unsigned long temp;
 4         if (n < fibovector.size()) {
 5                 return fibovector[n]; 
 6         } else {
 7                 temp = fibonacci(n-1) + fibonacci(n-2);
 8                 fibovector.push_back(temp);
 9                 return temp;
10         } 
11 }               

In this optimized version of the fibonacci function, I’ve added a vector (called fibovector) that caches the computed values. I’ve also changed the base case: The function no longer checks to see if the requested value is 0 or 1 but instead checks to see if the value is cached in the vector (line 4). If the requested value is already stored in the vector, the function uses the cached value and skips having to re-compute it. If it’s not already cached, the function recursively computes it (line 7) and then adds it to the vector for later use.

The Vector

There’s a few important points worth noting regarding the vector. The vector is declared with the static keyword so that its contents can persist between function calls. To get the program started, the vector is “preloaded” with the first two values in the Fibonacci sequence, 0 and 1. These are the initial base cases for the function.

Because the vector gets populated in order, there’s an easy way to check if the desired value is already cached or not. Since the index values of the numbers in the vector correspond to the actual index values of the numbers in the Fibonacci sequence, you can simply compare the desired index value with the size of the vector. If the requested index value is less than the size of the vector (line 4), the function has already cached that value. It’s important to keep in mind that this works because the largest index value in a vector is always one less than the total number of elements it contains (the size) since index values start at 0.

Why unsigned long?

Fibonacci numbers get very large very quickly, and due to the nature of how computers store numerical data it’s easy to overflow your chosen data type before getting very far. There’s a section about integer overflow at the end of this article about email servers, but the bottom line is that the 46th number in the Fibonacci sequence is the largest Fibonacci number that can be stored in a 32-bit integer. With unsigned long as the data type, we’re able to store up to the 93rd Fibonacci number before overflowing that data type as well. To keep the function simple, I’ve opted to use native C++ data types instead of writing or importing a custom “big integer” class that would allow for the storage of even larger Fibonacci numbers.

Checking Your Work

To test if your program is working correctly, you can compare its output to the list of the first 2000 Fibonacci numbers published by the On-Line Encyclopedia of Integer Sequences (OEIS).

Then, try timing each program and comparing how long they both take to reach the 46th Fibonacci number. The results might surprise you.

Posted on by Arnon Erba in How-To Guides

Several months ago, I was handed a sheet of paper with a strange error printed on it. One of our HP M602’s had spit it out, it seemed, while working on a real print job for one of our users. On further inspection, the printer had printed several identical pages with the same error, smiley face and all:

☺@EJL 1284.4
            @EJL
                @EJL

My first guess was a corrupted driver, so I re-installed the printer for the user who had reported the issue and waited for the error to come back.

It didn’t stop there. It wasn’t long before several users started reporting the error, all from different computers running different operating systems, and then the error pages started printing in the middle of the night when no one was using the printer.

We maintain a small fleet of HP M602’s and M605’s, but until this point the error had only been appearing on one of them. Updating the firmware on that printer didn’t help: instead, by the second week, all of our printers were randomly printing the @EJL 1284.4 pages.

Tracking Down the Issue

At this point, we inspected the print logs on the printers themselves and realized that every time an error page printed a “Guest print” event was added to the job log. Unfortunately, the M602/M605’s don’t log the source IP of the jobs they receive, but they do log the time and date when the job was processed. Now that we knew a network device was responsible for the mysterious print jobs, it was just a matter of finding the device on our network. After overcoming a minor setback caused by incorrect time and date settings on most of the printers, we were able to log traffic on the network and correlate it with the timing of the mysterious “Guest print” jobs to find the source IP of the offending device.

To figure out which computers were communicating with the printer, we shut down the printer and set up a Linux box in its place with its IP address. The, we gave the printer a new IP address, and configured the Linux box to forward all the traffic it received to the new IP address of the printer. Since the Linux box was now in a position to receive all traffic intended for the printer, a simple tcpdump session quickly revealed the source IP addresses of all the computers trying to send jobs to the printer. At this point, it was simply a matter of waiting for another error page to print, and the printer happily obliged.

Thanks, Epson (Fixing the Problem)

With the source IP address of the offending computer in hand, we tracked down the physical source of the rogue print jobs. It turned out to be a MacBook Pro, running a full Epson software/driver suite, that had joined our network at the same time that the error pages started printing. Some extensive Googling from the past week had led to the conclusion that “EJL” stood for “Epson Job Language”, so I formed a quick hypothesis that the Epson drivers were doing something that our HP printers weren’t very happy about. I uninstalled the Epson drivers from the MacBook, and sure enough, the @EJL 1284.4 pages stopped instantly.

Whatever the exact cause, the issue was clearly caused by a conflict between the Epson software suite and our HP network printers. If you encounter this error and you’re not on a large network like we are, it might be worth checking your computer for Epson software.

Epson, if you’re out there reading this, you owe me 3 reams of paper and a black toner cartridge for an HP M602.

A Little More About @EJL 1284.4

According to the Undocumented Printing Wiki’s page on Epson Job Language, the @EJL 1284.4 command:

takes the printer out of the Epson packet mode communication protocol (whatever that is) and enables IEEE 1284.4 communications mode

On top of this, the HP/Epson conflict has been well documented on HP’s support forums over the past year:

Posted on by Arnon Erba in How-To Guides

For lack of better introduction, this post is about diagnosing and fixing the “Value Too Large for Defined Data Type” error in Postfix on Linux. A few weeks ago, shortly after deploying a new email server, I got a bounce notification with the following error:

Diagnostic-Code: X-Postfix; cannot update mailbox /var/spool/mail/username for user username. cannot open file: Value too large for defined data type

Checking the mail log revealed the following, more informative lines:

postfix/local[8354]: warning: this program was built for 32-bit file handles, but some number does not fit in 32 bits

postfix/local[8354]: warning: possible solution: recompile in 64-bit mode, or recompile in 32-bit mode with 'large file' support

postfix/local[8354]: E8FAA86251F: to=username, relay=local, delay=0.01, delays=0/0/0/0.01, dsn=5.2.0, status=bounced (cannot update mailbox /var/spool/mail/username for user username. cannot open file: Value too large for defined data type)

Diagnosing the Problem

This is not a pretty error, and it stems from the fact that 32-bit binary numbers have a fixed maximum value that they can hold. If you overflow this maximum value, bad things will happen (such as mail bouncing from your email server). In modern 64-bit programs, we don’t run into these constraints as much, because 64-bit binary numbers can hold much larger values than 32-bit ones. However, it turned out that the affected email server was running a 32-bit version of Postfix, which meant it was stuck with the limitations of 32-bit binary numbers.

When a program (e.g. Postfix) opens a file (e.g. a user’s inbox) in Linux, some information about the file is passed to the program. The program must store the information in some sort of data structure. In this case, one of the pieces of information is the size of the file, which the 32-bit version of Postfix stores in a 32-bit signed integer. The maximum value that can be stored in a 32-bit signed integer happens to be 2,147,483,647, which is 2 GB expressed in bytes. (Check out the last section of this post for how that number is derived). This means that the largest file size that can be “understood” by the 32-bit version of Postfix is 2 GB.

This works fine until Postfix encounters a file larger than 2 GB. For example, if you have a 3 GB file, the file size expressed in bytes is 3,221,225,472. It is not physically possible to express that value in the 32-bit signed integer that Postfix uses, so the file cannot be opened because its size cannot be understood. This is the root cause of the this program was built for 32-bit file handles error in the mail log.

The GNU Core Utilities FAQ has a paragraph that confirms what the “value too large for defined data type” means:

The message “Value too large for defined data type” is a system error message reported when an operation on a large file is attempted using a non-large file data type. Large files are defined as anything larger than a signed 32-bit integer, or stated differently, larger than 2GB.

Confirming the Issue

I verified that the issue was caused by a 32-bit version of Postfix with the following two steps:

  1. By running the file command on the main Postfix binary, which yielded the following output: ELF 32-bit LSB executable, Intel 80386.
  2. By verifying that the size of the mail spool file that caused the error was larger than 2 GB.

Additionally, the problem affected a few other users, all of whom had mail spool files larger than 2 GB.

Fixing Postfix

Unfortunately, there’s no configuration parameter that you can change or set that will allow a 32-bit installation of Postfix to overcome the innate 32-bit size limit for files. There is an option — mailbox_size_limit — that controls the maximum mailbox size that Postfix will allow, but that is unrelated to the file size limitation imposed by running a 32-bit application.

Given that the issue is caused by running a 32-bit version of Postfix, fixing the problem means recompiling a 64-bit version of Postfix or installing a 64-bit version directly. In my case, the 32-bit version had been installed by a piece of proprietary software, and I had to switch to a different installation of Postfix entirely.

Running file on the fresh installation of Postfix returned ELF 64-bit LSB shared object, x86-64.

Bonus Section: What Determines the Max Size of a 32-bit Signed Integer?

Traditional 32-bit programs are unable to open files larger than 2 GB due to a limitation imposed by the nature of 32-bit signed integers. For reference, a signed integer is a binary number that is stored using a method that indicates whether the number is positive or negative. The opposite of a signed integer is an unsigned integer. Unsigned integers contain no information about the sign of the number and therefore can only be positive.

There are a few different methods that can be used to store signed integers, but the most common method is two’s complement because of the various benefits it provides. Using two’s complement limits the maximum possible value of an integer, as we can see in the following example:

A 32-bit integer gives us 32 binary bits to use for storing data. If you store the number “zero” in a 32-bit unsigned integer, you would get something like this:

00000000 00000000 00000000 00000000

If we set all the binary digits to 1, we get the following number:

11111111 11111111 11111111 11111111

Converted to decimal, this number is 232-1, or 4,294,967,295. The value is 232-1 instead of 232 because binary numbers start at zero. The maximum number of values is 232, but the maximum value is 232-1. This happens to be the maximum size of an unsigned 32-bit integer.

However, we are concerned with the maximum value of a signed integer. If we’re using two’s complement to store the integer, the first bit is reserved to indicate the sign:

10000000 00000000 00000000 00000000

Because we lose the farthest bit to the left, the maximum value is reduced to 231-1, or 2,147,483,647.