A few months back I wound up concluding, based on conversations with Ofcom, that aphyr.com might be illegal in the UK due to the UK Online Safety Act. I wrote a short tutorial on geoblocking a single country using Nginx on Debian.

Now Mississippi’s 2024 HB 1126 has made it illegal for essentially any web site to know a user’s e-mail address, or other “personal identifying information”, unless that site also takes steps to "verify the age of the person creating an account”. Bluesky wound up geoblocking Mississippi. Over on a small forum I help run, we paid our lawyers to look into HB 1126, and the conclusion was that we were likely in the same boat. Collecting email addresses put us in scope of the bill, and it wasn’t clear whether the LLC would shield officers (hi) from personal liability.

This blog has the same problem: people use email addresses to post and confirm their comments. I think my personal blog is probably at low risk, but a.) I’d like to draw attention to this legislation, and b.) my risk is elevated by being gay online, and having written and called a whole bunch of Mississippi legislators about HB 1126. Long story short, I’d like to block both a country and an individual state. Here’s how:

First, set up geoipupdate as before. Then, in /etc/nginx/conf.d.geoblock.conf, pull in the country and city databases, and map the countries and states you’d like to block to short strings explaining the applicable law. This creates variables $geoblock_country_law and $geoblock_state_law.

geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
  $geoip2_data_country_iso_code country iso_code;
}

geoip2 /var/lib/GeoIP/GeoLite2-City.mmdb {
  $geoip2_data_state_name subdivisions 0 names en;
}

map $geoip2_data_country_iso_code $geoblock_country_law {
  GB      "the UK Online Safety Act";
  default "";
}

map $geoip2_data_state_name $geoblock_state_law {
  Mississippi "Mississippi HB 1126";
  default     "";
}

Create an HTML page to show to geoblocked IPs. I’ve put mine in /var/www/custom_errors/451.html. The special comments here are Server-Side Include (SSI) directives; they’ll insert the contents of the $geoblock_law variable from nginx, which we’ll set shortly.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Unavailable Due to
      <!--# echo var="geoblock_law" default=""-->
    </title>
  </head>
  <body>
    <h1>Unavailable Due to
      <!--# echo var="geoblock_law" default=""-->
    </h1>
</body>
</html>

Then, in /etc/nginx/sites-enabled/whatever.conf, add an error page for status code 451 (unavailable for legal reasons). In the main location block, check the $geoblock_country_law and $geoblock_state_law variables, and use them to return status 451, and set the $geoblock_law variable for the SSI template:

server {
  ...
  # Status 451 renders this page
  error_page 451 /451.html;
  location /451.html {
    ssi on;
    internal;
    root /var/www/custom_errors/;
  }

  location / {
    # If either geoblock variable is set, return status 451
    if ($geoblock_state_law != "") {
      set $geoblock_law $geoblock_state_law;
      return 451;
    }
    if ($geoblock_country_law != "") {
      set $geoblock_law $geoblock_country_law;
      return 451;
    }
  }
}

Test with nginx -t, and reload with service nginx reload, as usual.

Geoblocking is a bad experience in general. In Amsterdam and Frankfurt, I’ve seen my cell phone’s 5G connection and hotel WiFi improperly identified as being in the UK. I’m certain this is going to block people who aren’t in Mississippi. If you don’t want to live in this world either, start calling your representatives to demand better legislation.

Post a Comment

Comments are manually approved. Links have nofollow. Seriously, spammers, give it a rest.

Please avoid writing anything here unless you're a computer. This is also a trap:

Supports Github-flavored Markdown, including [links](http://foo.com/), *emphasis*, _underline_, `code`, and > blockquotes. Use ```clj on its own line to start an (e.g.) Clojure code block, and ``` to end the block.