Setting up and testing two bridged wifi routers

The walls and microwaves of my house have always conspired to cripple the wifi signal in some rooms, especially the ones downstairs and the backyard. I recently got another wifi router to expand the range. They are daisy-chained from the modem with ethernet cables. My servers and printers are connected to the router in the middle, so it takes responsibility for forwarding ports for virtual services and static IP/MAC bindings. The router at the end of the chain is just there for range. I’m just going to quickly document how I set this up and tested it.

I set up the routers through their web interfaces over ethernet on my laptop. Here are some things to double check before you hook up the devices:

  1. The secondary router is set to receive its WAN configuration from DHCP. I tried a static configuration, but it refused to connect for reasons unknown.
  2. If you need to migrate settings (especially between routers of different models/brands), take down all the configuration settings beforehand, including forwarded services, IP/MAC bindings, DHCP and subnet ranges, QoS, static routing, if you’re using them, etc.

After the devices are set up and hooked up in their proper positions, perform a quick AP scan with your wireless card:

$ sudo iwlist wlan0 scan
wlan0   Scan completed:
        Cell 01 - Address:  XX:XX:XX....
                  Channel:  ...

There should be 2 (or more) access point results that correspond to each of your routers. Configure your local wireless card to connect to each router in turn by specifying its MAC address in your OS’s configuration. Run diagnostics and make sure the connection is operational:

$ ip addr
... (an assigned address on the correct subnet) ..
$ curl
... (your public IP) ..

That’s it. Now breathe easier knowing you can watch Netflix in the yard without suffering degraded streams. Hoorah.

Signing your own wildcard SSL/HTTPS certificates

There has been a lot of concern about online privacy in the past few weeks, and lots of people people are looking for ways to better protect themselves on the Internet. One thing you can do is to create your own HTTPS/SSL Certificate Authority. I have a bunch of websites on RogerHub that I want to protect, but I am the only person who needs HTTPS access, since I manage all of my own websites. So, I’ve been using a self-signed wildcard certificate that’s built into my web browser to access my websites securely. You can do this too with a few simple steps:

First, you will need to generate a cryptographic private key for your certificate authority (CA):

$ openssl genrsa -out rootCA.key 2048

Certificate authorities in HTTPS have a private key and a matching public CA certificate. You should store this private key in encrypted storage, because you will need it again if you ever want to generate more certificates. Next, you will need to create a public CA certificate and provide some information about your new CA. If you are the sole user of your new CA, then this information can be set to whatever you want:

$ openssl req -x509 -new -nodes -key rootCA.key -days 9999 -out rootCA.pem

Let me explain a bit about these two commands. The openssl command line utility takes a subcommand as its first argument. The subcommands genrsa and req are used to create RSA keys and to manipulate certificate signing requests, respectively. Normally when you go out and purchase an expensive SSL certificate, you will generate a key yourself and create a Certificate Signing Request (CSR), which is given to your certificate authority to approve. The CA then sends back an public SSL certificate that is presented to website clients. Generating the key yourself means that the private key never passes through the hands of your CA, so only you have the ability to authenticate using your SSL certificate.

The x509 switch in the argument above signifies that you are trying to create a new Certificate Authority, not a Certificate Signing Request. The nodes switch actually means no DES, which means that the resulting certificate will not be encrypted. In this case, DES encryption of the certificate is not necessary if you are the only party involved.

You have just created a new Certificate Authority key and certificate pair. At this point, you can import the rootCA.pem certificate into your web browser and instruct it to trust it for identifying websites. From then on, your browser will accept any website certificate that is signed by your new CA. Now you’re ready to make some website certificates. Create a private key and Certificate Signing Request for your new website as follows:

$ openssl genrsa -out SITE.key 2048


$ openssl req -new -key SITE.key -out SITE.csr


> Common Name ... : (put the name of your domain here)

Remember to put the domain name of your website as the common name when it asks you for it. Once you’ve completed the certificate signing request, you need to use your new Certificate Authority to issue a certificate for this new key:

$ openssl x509 -req -days 9999 -in SITE.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out SITE.crt

You’ve created a functional SSL certificate and keypair for your website! You can configure your web server to use your new site key and certificate, and it will begin serving resources over HTTPS. However, this certificate will only work for the domain that you specified before in your CSR. If you want to create a single certificate that will work for multiple domains (called a wildcard certificate or a multi-domain certificate), you will need some more steps. Create a file named SITE.cnf, and put the following inside:

countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name (full name)
localityName = Locality Name (eg, city)
organizationalUnitName	= Organizational Unit Name (eg, section)
commonName = Common Name (eg, YOUR name)
commonName_max	= 64
emailAddress = Email Address
emailAddress_max = 40

distinguished_name = req_distinguished_name
req_extensions = v3_req

keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

DNS.1 =
DNS.2 = *

Under the last block, you can insert as many domains with wildcards as you want. To do this, use the following command to generate your CSR:

$ openssl req -new -key SITE.key -out SITE.csr -config SITE.cnf

Now, run the following to generate your wildcard HTTPS certificate, instead of the last command above:

$ openssl x509 -req -days 9999 -in SITE.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -extensions v3_req -out SITE.crt -extfile SITE.cnf

The v3_req block above is a HTTPS extension that allows certificates to work for more than one website. One of the flags in the certificate creation command is CAcreateserial. It will create a new file named whose contents are updated every time you sign a certificate. You can use CAcreateserial the first time you sign a website certificate, but thereafter, you will need to provide that serial file when you sign more certificates. Do this by replacing -CAcreateserial with -CAserial in the final command. A lot of the concepts here only hint at the greater complexity of HTTPS, openssl, and cryptography in general. You can learn more by reading the relevant RFCs and the openssl man pages.

7 tips for writing better CSS

CSS stylesheets are a fundamental part of the web, but they are also one of the most neglected parts of modern web applications. Traditional programming languages give you a ton of organizational features: namespaces, classes, scope, blocks, etc. CSS has none of these constructs.

I recently released the WordPress theme that runs this blog on the free public WordPress Theme Repository. The theme repository has very high quality-assurance standards and a team of theme reviewers, who run test suites on each newly submitted theme as well as updates to approved themes. While I was preparing my theme for public release, I picked up on a lot of good CSS tips that helped me improve the maintainability of my theme’s CSS. I hope they will help you too:

0. Use a CSS Preprocessor

Before you continue reading, the first thing you should do is make sure you’re using a CSS preprocessor like SASS. CSS preprocessors are tools that let you write your CSS in a special stylesheet language, and then translate your code into actual CSS before it goes into production. They add programming language features to CSS like variables, nested blocks, mixins (CSS functions), inheritance, and single-line comments.

I choose SASS over other options like LESS or SASS+Compass because:

  • SASS is highly stable (it’s built in Ruby) and contains zero bullshit.
  • SASS supports an indentation-based syntax similar to python and yaml. LESS does not.
  • SASS requires zero configuration, as it should.

It’s easy to set up a loop that re-compiles your SASS when you save changes to it, using the tools I wrote about in my continuous integration post.

1. Stop nesting. Use classes.

When you write CSS, always remember to separate structure and presentation. You should not be adding extraneous elements to your HTML for presentation purposes. This also means that you should disentangle your CSS rules from the structure of your HTML. This is not okay:

      <h1>Welcome to my site!</h1>


// Don't do this!!
body > header
  display: fixed
  top: 0
      color: white
      font: 700 2.25em/1.5 $serif

As a rule of thumb, you should only nest blocks like this when you mean it. A long selector like body > header div h1 is hardly ever what you want. This CSS will break if you ever move your HTML elements around or add/remove a wrapper anywhere.

Use classes liberally. Your CSS should not look like just an outline of your HTML.

In the long run, classes go a long way towards maintainable CSS. You can always do a recursive search through CSS files to look for class names, but you will have a hard time locating a CSS block like the one above if all you have is the resulting 4-part CSS selector. The above example could be better written like with classes like this:

  <header class="site-header">
      <h1 class="site-name">...</h1>

  display: fixed
  top: 0
  color: white
  font: 700 2.25em/1.5 $serif

On that note, you should also stop leaving <div class="clear-fix"></div> around in your HTML. I’ll show you how to work around this with CSS Inheritance:

2. Selector inheritance is awesome

Inheritance is a very powerful, underrated feature in SASS. (LESS doesn’t support it in the way that SASS does.) Selector inheritance allows you to make classes that “extend” other classes, like parent and child classes do in OOP. It doesn’t do this by stupidly copying their CSS rules, but by adding extra selectors to the parent class’s CSS blocks. Let me show you an example:

  margin: 1em 0 1.5em
    color: white
    margin-bottom: 1.5em
  @extend .content
  margin-bottom: 2em


// Would compile to...
.content, .summary {
  margin: 1em 0 1.5em;
.content p, .summary p {
  color: white;
  margin-bottom: 1.5em;
.summary {
  margin-bottom: 2em;

Any rule and child-rule applied to the parent selector will also be applied to the child. Child classes can also have their own properties that override the parent’s. Here’s a more realistic example of what you can do with selector inheritance:

You’ve probably run into the clearing float CSS problem before. If you’re not familiar with it, take a look at this sample code:

<div class="container">
  <div class="left">
  <div class="right">

  border: 1px solid black

  float: left
  float: right

The intended effect is that the container’s 1px black border surrounds both .left and .right, but it appears that only the top border is displayed. The problem arises because floated elements are taken out of flow and now, .container has no height. There are several solutions to this problem, but the most common one involves adding an extra element after both floated div’s and giving it clear: both. Instead of adding extraneous presentation elements to the HTML, you can use selector inheritance:

<div class="container">

  // "&" refers to the current selector
    clear: both
    content: '.'
    display: block
    height: 0
    visibility: hidden

  @extend .after-clear-fix

If you apply @extend .after-clear-fix to several elements, it will compile to a single long CSS selector whose body contains the clearfix rules, thus reducing redundancy in the final stylesheet:

.search-area:after {

SASS also supports a custom syntax that prevents the original class from being printed. Another powerful SASS feature is the @import directive, which works just like CSS’s import directive, but actually brings in the content of the target stylesheet if it is available locally.

3. Organizing your sass/ directory

Most WordPress themes have just 1 stylesheet that’s located at the theme root. When using SASS, my theme stylesheet is usually generated with SASS, while the SASS source files are located in a separate directory. SASS supports the idea of CSS partials. Partials are SASS files whose names begin with an underscore. They are meant to be imported into other stylesheets, and not compiled directly by themselves (although you can do that if you want).

The @import directive is also partial-aware and will match @import "reset" with a file named _reset.sass.

For larger projects, you should split your CSS into files that reflect the semantic role of the parts of the page they style. Additionally, you will usually have a few extra SASS source files for a CSS reset, JavaScript plugins, color/font variables, and mixins. Here’s my theme’s sass directory as an example:

  • style.sass — The target of the SASS compiler. WordPress theme metadata is stored in CSS comments, so I put my metadata at the top of this file. This source file also imports the rest of your source files.
  • _reset.sass — I use Eric Meyer’s CSS reset. It’s available in SASS form on Google.
  • _variables.sass — It’s useful to store all of your colors and fonts in one place and refer to them by variable names. In a monochrome theme like this one, I used color variables named $blue1 to $blue15 in order of increasing lightness.
  • _cobalt-global.sass — Buttons, input elements, and WordPress core classes
  • _cobalt-grid.sass — Grid for desktop and mobile layout
  • _cobalt-header.sass
  • _cobalt-primary.sass — The primary content area
  • _cobalt-secondary.sass  — Secondary content like sidebars
  • _cobalt-footer.sass

You can see that this naming scheme reflects traditional source code a lot more than CSS usually does, and because of the import directive, you don’t sacrifice any performance by splitting your CSS into files like this. One mistake that beginner CSS programmers sometimes make is separating the rules for a single selector into different files. They organize their stylesheets by the semantics of the CSS properties, rather than the semantics of their selectors.

// Don't do this!!
  color: black
  color: #CCCCCC

  font: 700 2.25em/1.5 $serif
  font: 400 1em/1.68 $sans-serif

When you split up your stylesheets like this, you end up having to edit 5 or 6 files even if you’re just working on one part of the site design. Usually there’s also a _mobile.sass thrown into the mix, which is also a bad idea. On the other hand, you don’t want to be writing @media only screen and (max-width: 767px) more than once. You can avoid both of these problems by using SASS mixins:

4. Essential mixins for any project

One of the reasons I don’t like SASS+Compass is that there is too much hand-holding and mixins that you’d never use. Most useful mixins are ones that you can program yourself in a few lines. Here are the essential ones that you might actually find useful:

Mobile Layout Mixin

$mobile1: 767px
$mobile2: 479px

= mobile1
  @media only screen and (max-width: $mobile1)

= mobile2
  @media only screen and (max-width: $mobile2)

This is the solution to the mobile layout problem I mentioned in the previous section. Mixins in SASS, as you can see, are defined with the equal sign. The SASS content directive is similar to the Ruby yield directive. Instead of typing out the mobile media query every time you need to use it (or even a lengthy variable interpolating selector), you can use the content directive in SASS 3.2+ to define your responsive mobile styles. Here’s an example of it in action:

  float: right
    float: none
    display: inline-block
      display: block

You should never make a separate SASS source file just for mobile CSS. Instead, mobile styles should be kept with the original non-mobile CSS so that you can see both the original and the overriding properties in a single place.

Vendor Prefix Mixin

= vendor-prefix($name, $argument)
  #{$name}: $argument
  -webkit-#{$name}: $argument
  -moz-#{$name}: $argument
  -ms-#{$name}: $argument
  -o-#{$name}: $argument

A vendor prefix mixin is always useful when when using CSS3 properties like border radius and transitions. However, remember not to depend on CSS3 properties for critical parts of the page. Occasionally, you will need to specify the argument on a separate line if it contains commas:

  $transition: background 0.3s, color 0.1s
  +vendor-prefix(transition, $transition)

That’s it. These two are really the only mixins that you may ever need, and you could have written them yourself in a minute. As a rule of thumb, you should only turn a rule into a mixin if you’re using it at least 3 times, and if a mixin only has 1 property, you might as well use a variable.

5. Prefixes for your classes

Anyone who has worked on a large project has come across an HTML element with a class whose purpose was completely unknown. You want to remove it, but you’re hesitant because it may have some purpose that you’re not aware of. As this happens again and again, over time, your HTML become filled with classes that serve no purpose just because team members are afraid to delete them. The problem is that classes are generally given too many responsibilities in front-end web development. They style HTML elements, they act as JavaScript hooks, they’re added to the HTML for feature detections, they’re used in automated tests, etc.


This quote is from an article about CSS architecture by Philip Walton. He recommends that you prefix classes used by JavaScript hooks with .js- and so on, so that you can change CSS class names without breaking anything. I think it’s a great idea, and I’ve been using these other class prefixes as well: (most of these are for WordPress)

  • .site- — For classes that apply site-wide like site headers and footers.
  • .entry- — For classes that apply to a single element, of which there are many.
  • .nav- — For classes on navigation elements that apply to many entry elements.
  • .var- — For variants of classes (e.g. var-blue or var-small)

Intent-based class prefixes like these are advantageous over colloquial class names like .next-button or position-based class prefixes .bottom-navigation.  They let you form a natural class hierarchy using dashes so you can be sure that class names you create are unique. Above all, you don’t want to use generic class names like .container or .header without prefixes. They don’t convey much information about their intent, and they are easy to reuse accidentally, especially if you plan on using messy nested selectors.

6. Know your CSS shorthands

CSS is a vertical language. Lines are rarely more than 75 characters long, but blocks can span 20 or 30 lines easily. To conserve space on your screen (and the screens of those who are reviewing/maintaining your code), use CSS shorthands liberally. Here are a few essential shorthands forms that you should know by heart:

Box Model Shorthand

Numeric box-model properties like margin, padding, and border offer a shorthand notation. The order is clockwise from top, as demonstrated below:

  padding-top: 2px
  padding-right: 3px
  padding-bottom: 4px
  padding-left: 5px

// Equivalent to:
  padding: 2px 3px 4px 5px

You can also specify just 2 or 3 values instead of all 4. In this case, the missing sides will have the same value as their opposite side:

  margin: 4px 3px
  border-width: 1px 2px 0

  // Equvalent to:
  margin-top: 4px
  margin-bottom: 4px
  margin-right: 3px
  margin-left: 3px

  border-width-top: 1px
  border-width-right: 2px
  border-width-left: 2px
  border-width-bottom: 0

Border Shorthand

Borders have 3 properties that are easily distinguishable. They also offer a shorthand form to write all three in one property. Note that you can’t combine the box-model shorthand with this one:

  border-width: 1px
  border-style: solid
  border-color: #00477D

// Equivalent to:
  border: 1px solid #00477D

Font Shorthand

The font property shorthand is the least-commonly used of these shorthands. It’s a hard one to remember, but it will knock out 3 or 4 lines of CSS every time you use it:

$serif: Georgia, Times, serif

  font: 2.25em $serif
  font: 2.25em/1.6 $serif
  font: bold 2.25em/1.6 $serif
  font: 700 italic 2.25em/1.6 $serif

  // Final form is equivalent to:
  font-weight: 700
  font-style: italic
  font-size: 2.25em
  line-height: 1.6
  font-family: $serif

You can omit properties from the font shorthand as shown above. However, it must have at least the font size and the font family declarations in order to work at all. If you’re not familiar with numeric font weights, 700 means bold.


The background shorthand is also rarely used because it is hard to remember. Backgrounds have just 4 properties: color, image, repeat, and position. Specify them in that order:

  background: blue url(...) repeat-x center center

  // Equivalent to:
  background-color: blue
  background-image: url(...)
  background-repeat: repeat-x
  background-position: center center

That being said, you should not use these shorthands if you only want to specify the top margin or the font size. CSS shorthands are most effective when most of their properties are utilized.

7. Alphabetize for easy comprehension

People have all sorts of different methods they use to order CSS properties. I tend to favor alphabetical order by property name, even if related properties like top and left are separated. You can take a look and pick which one you like yourself:

// Alphabetical order
  @extend .button
  background-color: $blue
  border: none
  color: $white
  cursor: pointer
  font: 300 1em/1.25 $sans-serif
  left: 1em
  padding: 4px 9px
  position: relative
  text-align: center
  text-decoration: none
  top: 0.25em
  +vendor-prefix(border-radius, 0.25em)
  vertical-align: middle

Others prefer to order properties by theme:

// Thematic order
  @extend .button

  // Box model
  border: none
  padding: 4px 9px
  +vendor-prefix(border-radius, 0.25em)

  // Positioning
  position: relative
  left: 1em
  top: 0.25em

  // Internal styles
  color: $white
  cursor: pointer
  font: 300 1em/1.25 $sans-serif
  text-align: center
  text-decoration: none
  vertical-align: middle

However you decide to order your CSS properties, the effect is the same. All of the tips listed here are purely for the programmer’s convenience. Presentation can always be achieved without CSS preprocessors or shorthands, but using these tools will make your CSS much more readable and maintainable.

Backing up my data as a linux user

It’s a good habit to routinely back up your important data, and over the past few years, dozens of cloud storage/backup solutions have sprung up, many of which offer a good deal of free space. Before you even start looking for a backup solution, you need to sit down and think about what kind of data you’re looking to back up. Specifically, how much data you have, how often it is changed, and how desperately do you need to keep it safe?

I have a few kinds of data that I actively backup and check for integrity. (Don’t forget to verify your backups, or there isn’t any point in backing them up at all.) Here are all the kinds of data that might be on your computer:

  • Program code – irreplaceable, small size (~100MB), frequently updated
  • Documents, and personal configuration files – irreplaceable, small size (~100MB), regularly updated
  • Personal photos – mostly irreplaceable, large size (more than 10GB), append only
  • Server configuration and data – mostly irreplaceable, medium size (~1GB), regularly updated
  • Collected Media – replaceable if needed, medium size (~1GB), append only
  • System files – easily replaceable, medium size (~1GB), sometimes updated

Several backup solutions try to backup everything. This is not a good idea. First, there are a lot of files on your computer that are easily replaceable (system files) and others that you’d rather not keep in your backup archives (program files). Second, those solutions have no way of giving extra redundancy to the things that matter most, and less redundancy to things that matter less.

In addition to these files, here are some types of data that you might not usually think about backing up:

  • Email
  • RSS and Calendar data
  • Blog content
  • Social networking content

My backup solution is a mix consisting of free online version control sites, Google, Dropbox, and a personal file server. My code, documents (essays, forms, receipts), and configuration (bash, vim, keys, personal CA, wiki, profile pictures, etc..) are the most important part of my backup. I sync these with Insync to my Google Drive, where I’ve rented 100GB of cloud storage. My Google Drive is regularly backed up to my personal file server, with about 2 weeks of retention.

Disks and old computers are cheap. Get a high-availability file server set up in your home, and you can happily offload intensive tasks to it like virtual machines, backup services, and archival storage. Mine is configured with:

  • Two 1TB hard drives configured in RAID-1 mirroring
  • Excessive amounts of ram and processing power, for a headless server
  • Ubuntu Server installed with SMART monitoring, nagios, nginx (for some web services), a torrent client
  • Wake-on-lan capabilities

Backing up your Google Drive might sound funny to you, but it is a good precaution in case anything ever happens to your Google Account. Additionally, most of my program code is in either a public GitHub repository or a private BitBucket repository. Version control and social coding features like issues/pull requests give you additional benefits than simply backing up your code, and you should definitely be using some kind of VCS for any code you write.

For many of the projects that I am actively developing, I only use VCS and my file server. Git object data should not be backed up to cloud storage services like Google Drive because they change too often. My vim configuration is also stored on GitHub, to take advantage of git submodules for my vim plugins.

My personal photos are stored in Google+ Photos, formerly known as Picasa. They give you 15GB of shared storage for free, and if that’s not enough, additional space is cheap as dirt. My photos don’t have another level of redundancy like my code and configuration files do. They are less important to me, and Google can be trusted to sustain itself longer than any backup solution you create yourself.

I host a single VPS with Linode (that’s an affiliate link) that contains a good amount of irreplaceable data from my blogs and other services I host on it. Linode itself offers cheap and easy full-disk backups ($5/mo.) that I signed up for. Those backups aren’t intended for hardware failures so much as human error, because Linode already maintains high-availability redundant disk storage for all of its VPS nodes. Additionally, I backup the important parts of the server to my personal file server (/etc, /home, /srv, /var/log), for an extra level of redundancy.

Any pictures I collect from online news aggregators is dumped in my Google Drive and shares the same extra redundancy as my documents and personal configuration files. Larger media like videos are stored in one of my USB 3.0 flash drives, since they are regularly created and deleted.

I don’t back up system files, since Xubuntu is free and programs are only 1 package-manager command away. I don’t maintain extra redundancy for email for the same reason I don’t for photos.

A final thing to consider is the confidentiality of your backups. Whenever you upload data to a free public cloud storage service, you should treat the data as if it were being anonymously released to the public. In other words, personal data, cryptographic keys, and passwords should never be uploaded unencrypted to a public backup service. Things like PGP can help in this regard.

Online advertising and why adblock is not the solution

There has been some pretty shocking stuff happening in the realm of online advertising recently. By recently, I mean anywhere from just this week to a year and a half ago. Let’s revisit some of them:

A brief recap of this year in advertising

We saw the introduction of the Do Not Track HTTP Header, which at the time of writing hasn’t yet moved from its initial draft state. The draft proposes a new header, sent with every request, that would enable a user to opt-out of all Internet tracking. If adopted, it would greatly hinder the effectiveness of targeted ads. Not long after the draft was announced, Microsoft announced that Internet Explorer 10 would send the DNT header by default as part of their privacy-oriented image. This led to a two week ad-tracking arms race between IE 10 and various websites and website software, most notably apache’s web server, who chose to specifically ignore the header when it came from from IE 10 clients. The draft was soon revised to make this behavior nonconforming.

In an effort to encourage responsible advertising, Adblock Plus 2.0 introduced the Acceptable Ads system that allowed certain non-obtrusive advertising through its filter. The list started with a motion to whitelist ads on reddit. A minority of users are concerned about commercial influence within the project.

Then, Mozilla announced that Firefox 22+ would block third-party cookies by default, another strike against advertisers. More specifically, the ban applies to domains that haven’t already established cookies (instead of a ban blocking all third-party cookies). The cookie ban would cripple many ad-targeting techniques that rely on third-party tracking of user behavior.

Finally, it was revealed just last week that Google allegedly sponsors Adblock Plus’s acceptable ads program in order to get some of their own text ads whitelisted, raising concern about market monopolization.

The controversy

Advertising has always been a controversial part of the Internet. Modern internet architects are mostly science and engineering geeks and harbor a innate predisposition against commercial uses for the world wide web, in very much the same way the astronomers of the 1960’s were disgusted by the thought of a militarized space program.

The reverse is also true: corporate executives and run-of-the-mill internet users today have no idea how much insane power their server administrators hold. Essentially, a lot of miscommunication happens between those who have the power to make decisions and those who have the power to carry them out.

A quick note about adblock and ads

I will use the term adblock in the rest of this post to refer to any one of the several advertisement-blocking browser plugins available. I will use ads and advertising to refer to graphical and text ads (banner ads, skyscrapers, rectangles) as well as video ads, and by extension, certain kinds of advertising on physical media.

Adblock illustrates the tragedy of the commons. Most people are aware that if everybody used adblock, parts of the internet would die off from lack of funding. Nonetheless, many people block ads anyway. The option is tempting, and a single extra user with adblock will likely not make a difference.

I’d like a chance to convince you not to use adblock.

I won’t make any pleas about content publishers deserving money or anything, because those are honestly not good arguments. I want to tell you about a few reasons why ads are not all bad and why you might not want to block ads.

1. Ads pay for the Internet

Everybody loves free online websites, but if Google didn’t make hundreds of billions a year in online advertising revenue, it would have no way to run its services, pay its employees, and support all of its public projects. Sure, you might agree to a $10/month fee to help out some of your favorite sites, but there are a few reasons why this wouldn’t work long-run:

Zero-cost websites provide a ton of social, business, and infrastructural tools that a majority of the population in developed nations have learned to use. Free internet services like those provided by Google are responsible for an enormous part of our country’s productivity and GDP (as well as those of other countries, both developed and undeveloped), and it is because they are free.

The free-to-use nature of these services encourages adoption, which is far more important than immediate profit because suddenly, your average workforce employee knows how to use corporate-grade calendar, email, and spreadsheet software and depend on them as basic communication and organizational tools. These tools not only augment their own human capital, but also created the demand for internet access that fueled the construction of the global internet infrastructure we have today.

Simply put, advertisements are where the internet draws the money to sustain itself and perpetuate this whole cycle of economic development. And because this free-with-ads online publishing model has proven itself to work so well, we now have free photo-sharing sites, news sites that publish exclusively online, and free blogging platforms. Every time you block ads, these are the guys you’re hurting.

You aren’t, of course, obligated to look at ads in order to support these websites, but it’s a small price to pay for all the free stuff you get in return. If you value a free service, you should not block their ads. If you want to support a content publisher, whether it’s a YouTube vlogger or the admins of your regular news aggregator, you should not block ads.

2. Servers aren’t cheap

One thing people usually cite when asked about why they support adblock is the greediness of publishers and advertisers. Most people don’t understand why websites, which are virtual and intangible, cost so much to run in comparison to tangible goods. A large part of this misconception is due to the relative inexpensiveness of commodity consumer hardware.

The hardware that powers your $600 Costco desktop computer is not the same stuff that runs in most datacenters. You might have an exorbitant 16 gigabytes of RAM and a terabyte of disk space, but these devices are consumer-grade devices and would, in most cases, be inappropriate for a server (not counting those who believe in cheap commodity hardware servers). Server hardware often contains extra features to improve their reliability and longevity that aren’t present in consumer hardware. These include error correcting codes that can automatically fix memory corruption, redundant file systems that require several independent hard disks, and specialized CPUs with support for multi-CPU configurations and 24/7 continuous usage.

A server with numerically equal capacity as your home desktop might cost $600 a month to operate, including the massive network infrastructure, housing, HVAC, redundant power, and maintenance staff. Your household computer, on the other hand, doesn’t have to run continuously day-and-night, and it isn’t important if a few bits of memory get flipped accidentally or if it breaks down after two years.

Some websites that provide online services are big enough that they have to rent out enterprise-class equipment, but not large or important enough that they can start billing their customers. These guys who get stuck in the middle often have no other choice but to sell ad space to pay the bills. Websites aren’t exactly cash cows either. In fact, most big websites spend their first couple years in the red. (Tumblr reportedly only made $14 million in revenue in 2012 while spending $25 million in operating costs.)

3. Some advertisements are actually useful

If you can honestly say that online advertising has never ever contributed any value to your life, then:

  1. You probably don’t buy things on the Internet, and
  2. You’re probably not worth very much to advertisers anyway.

That’s totally fine, but you should understand that a majority of internet users do buy things regularly, whether it’s online at or in person at Safeway. Advertisers run ads for them, not for you.

Ads themselves do a few different things in a few different ways. Some ads are political in nature, but the vast majority are commercial advertisements designed to get you to buy or donate. Ads cost a lot of money, so they need to earn money in return. That’s just how it works. There are a few ways that advertisers go about this:

  • Some ads try to promote brand awareness. Companies sponsor these ads to convince you to choose them over their competition—imagine an advertisement for Coke.
  • Some ads announce reasons why you should buy something immediately (seasonal sales, special offers, advantages, testimony, etc.).

These are generic ads that usually don’t provide much value to the consumer (that’s you), but make up the majority of ads shown anyway. This is usually because they apply equally well to everybody. (Generic ads also encompass the pop-up and pop-under ads that are just plain annoying.) You may have also seen:

  • Ads for online education websites or study tools placed on Sparknotes, or
  • Ads for public cloud solutions or VPS services placed on a blog for system administrators, or
  • Ads for sword replicas or a fantasy RPG placed on a fan wiki for your favorite fantasy novel series.

These are known as contextual ads and are shown because they’re related to the content on whatever page you’re visiting. (The examples were taken from my open browser tabs..) They are slightly more valuable than generic ads, because they fit in with the content on the page. And finally, you may have before encountered this special kind of ad:

  • An advertisement for motherboards and microcontrollers you might buy, because you looked at a few on Amazon last week.

Ads like this one are targeted ads. They range from a subtle “hey these gadgets could be cool to have” to a more pronounced “you put these earbuds in your shopping cart, do you still want them??”, depending on how they were targeted. Targeted ads provide excellent value, because most of the time, they’re shown after you have already demonstrated a commercial interest in some sort of product or service, like a music album or a haircut. Once you’re interested, most companies believe you only need a little nudging before you’ll buy something.

(It’s true that targeted ads might lead you to spend more money, but if you’re having problems being frugal, blame your lack of self-control, not the advertisers.)

The ad industry today is pushing every which way they can to adopt ad targeting in all channels, and for a good reason too: the more value an ad has to you, the more value it has to the advertiser. However, a lot of people are afraid of targeted ads because suddenly, advertisers are tracking everything you buy, everything you search online, and every website you visit in an attempt to figure out what you’re interested in buying.

The truth is that most everything you do online is already being tracked. However, the data recorded is usually scattered in a bunch of different places and is never analyzed for trends. Websites maintain logs of their visitors. Department stores keep databases of purchase history (especially if you’ve got their loyalty rewards card). The means to analyze your habits already exist and have existed for a long time. It’s ultimately up to you to use incognito browsing if you don’t want certain searches or websites to be used for targeting.

The fewer generic ads and the more targeted ads we have, the fewer gimmicks are needed to get your attention and the better our advertisement experience gets (we’ve already come a long way from pop-ups). In an ideal world, we wouldn’t need ads at all. However, reality doesn’t work like that, and most people agree that pure HTML Amazon ads are much better than flashing pop-up ads with auto-playing audio.

Still not convinced?

Like I said before, it’s up to you whether you want to use ad blocking software or not, but hopefully you now at least see why advertising is not entirely bad and why it is important to have. If you’re a computer security enthusiast like me, you’ll ditch ad blockers exclusively because of the fact that they hook onto every web page. If not, just stop complaining about advertisements, because things would be a lot worse without them.