IPv6 Things

(Redirected from Nginx-40e)

IPv6 Things start page.

IPv6 Things is a simple proof-of-concept that illustrates how it is possible to give a variety of things their own IPv6 address. Originally extending from the IPv6 Bible and also a small part of my custom IPAM software, the IPv6 Things project attempts to give as many things as possible their own IPv6 address in a way that simply cannot be done in IPv4.

There are two main parts to IPv6 Things:

  • The IP address management software, which assigns a name (symbolic of an object) to each of the IP addresses and generates forward and reverse DNS records.
  • The server-side component, which reads the server's IP address to deliver an individualized webpage.

The web app was written using Node.js and Express. Internally, all these websites are handled by one server with a static /64 route and the AnyIP trick. The server will respond on any IP address within that /64, and we can read that IP address (hereinafter the "server IP address") by calling getsockname() on a connection socket returned by accept() (nginx exposes this via the "$server_addr" variable). The server can change its behavior depending on what IP address it was referred to; specifically, there is a function that takes in the server's IP address and displays the "content" associated with that IP address. For example, if the server IP address is 2602:806:a003:40e::3000:7f, then the contents of "sebastian.aliases.peterjin.org" is shown. If the server IP address is 2602:806:a003:40e::5c50:49, then "SCP-049" is shown. Tradition tells us that different IP addresses correspond to different servers, so from the perspective of anyone else on the Internet, each one of those websites is its own little server, with the "You are connected to (domain/IP)" page shown as the "default" site.

Live demos

World IPv6 launch logo.svg No-ipv4.svg The services described here are IPv6-only, without any IPv4 addressing. If you have trouble viewing these pages, then you do not have IPv6 connectivity. This is usually not due to an issue with the firewall or web filter (if present in your network). If you have a cell phone, you may need to turn off your Wi-Fi or VPN and use cellular data instead.
Excellent! Your ISP appears to support IPv6! You shouldn't have any problem viewing these webpages.
Checking your internet connection for IPv6 support. If this text does not change, then it looks like your ISP does not support IPv6. Please disable or enable any proxies or VPNs, switch to mobile data, or simply just find another ISP.

Came here from ungleich.ch? Start here: https://ipv6-things.srv.peterjin.org

For a complete list of subdomains, see List of IPv6 Things subdomains.

The canonical version of IPv6 Things uses the 2602:806:a003:40e::/64 subnet.

CIDR range[1] Usage Number of objects/IP addresses used Example Notes
2602:806:a003:40e::1 introduction page 1 https://ipv6-things.srv.peterjin.org Used primarily only as a start page, to introduce this website to anyone who looks at this from an external source.
2602:806:a003:40e::3000:0/100 Aliases 3000 about 250 https://sebastian.aliases.peterjin.org (2602:806:a003:40e::3000:7f) Unlike other name lists used in Aliases 3000, the names listed here is an exhaustive list. This means that even names that I would never use to refer to myself are listed here, in order to fulfill the overall goal of assigning as many things as possible their own IPv6 address. The presence or absence of a name does not necessarily imply that I will necessarily be referred to by that name in the future.
2602:806:a003:40e::5c50:0/108[2] SCP Foundation/Wiki objects 10,000 (including possible unassigned SCP numbers) I am a toaster[3] accessible under the IP address 2602:806:a003:40e::5c50:426 (https://scp-426.scp.rdns.peterjin.org) that can only be referred to in the first person.
2602:806:a003:40e:0:2::/96 Miscellaneous random things about 10 https://in-honor-of-george-floyd.misc.peterjin.org (2602:806:a003:40e:0:2:2020:525) George Floyd died on 2020-05-25.
2602:806:a003:40e:0:3::/96 CSS/SVG colors about 150 https://blue.colors.misc.peterjin.org (2602:806:a003:40e:0:3:ff00:ff), https://khaki.colors.misc.peterjin.org (2602:806:a003:40e:0:3:fff0:e68c) Last 24 bits of IP address represent the RGB value of the color.
2602:806:a003:40e:4000::/66 Astronomical objects about 100 not yet operational Inspired because of claims that you can give entire internets to stars.
2602:806:a003:40e:b1be::/80 IPv6 Bible 31,000 https://1-1.genesis.ipv6.bible (2602:806:a003:40e:b1be:7700:1:1)


Screenshot of https://ipv6-things.srv.peterjin.org. If no caption is provided, then only the domain name is shown.
http://[2602:806:a003:40e::2]. If an IP address is not associated with a domain name, then only the IP address is shown.

What is this?

Extending from the IPv6 Bible, this project serves as a simple demonstration as to how the AnyIP trick may be useful. The system is designed such that it may appear that the IP addresses all map to separate hosts (with characteristics to strengthen that illusion such as reverse DNS and not requiring SNI), even though everything happens on a single server.

Fun fact: Because the SSL certificate to serve is determined entirely by the server IP address, if you test any of the hostnames here on the Qualys SSL test, then it will not say anything about requiring browser SNI support.

How does it work?

Most of the magic comes from using the $server_addr variable. By subjecting the value of this variable to a number of lookups, we can change the server's behavior just based on the IP address, a variable already supported by DNS lookups.

In addition, the mapping of objects/domain names to IP addresses is a bijection or a one-to-one function; every domain name involved is mapped to exactly one IP address (via an AAAA record), and that IP address maps back to that domain name (via a PTR record). Every IP address involved is mapped to exactly one domain name, and that domain name maps back to that IP address. It's not a perfect bijection, since some of the colors map to the same IP address, but otherwise, it's a bijection. This means that "charles.aliases.peterjin.org" is equivalent to "2602:806:a003:40e::3000:17", and specifying either one of these two identifiers is enough information to imply the other.

Where did you get the idea?

As I always say, IP addresses define services, not hosts. By exploiting the fact that IPv6 has a much larger address space and that servers are already identified by IP addresses, we can encode up to 64 bits of discretionary information in the bottom half of the IPv6 address, as sort of specifying additional information to existing services transparently without any client support. In terms of the TCP/IP and OSI models, we have basically moved the parsing of the bottom 64 bits of the IP address from the network layer to the application layer.

Another factor was because of how I intended to operate Aliases 3000. For normal people with only a single, canonical name (akin to a single IP address), their behavior is mostly the same regardless of who talks to them, but with Aliases 3000, I can sort of modify my behavior based on what name they call me, and this makes it appear that I'm more than one person, even though I'm actually only one person. This project is the same, but with connection 4-tuples instead of names.

I also remember reading somewhere about a certain DNS service where if you accessed it via IPv4, you would have to put in your own IP address so that it can identify you, but if you accessed it via IPv6, they would give you a dedicated IPv6 address to use as your nameserver, since they can just use parts of the server IPv6 address to identify the customer.

Does this exist elsewhere?

Even after searching lists of IPv6-only websites, I think this is the only similar thing that exists on the Internet in terms of its network structure.

The 42.be demo also involves giving "squares" their own IPv6 address to form a Nyan Cat mosaic, however, each one of the squares is specified by the path in the URL, not the IP address, which would be contrary to the central idea of IPv6 Things.

Is there a complete list of available subdomains?

See List of IPv6 Things subdomains.

How do I know that name-based virtual hosting is not used?

Put the following into your /etc/hosts file:

2602:806:a003:40e:b1be:7700:1:3 no-sni.test

If you then browse to no-sni.test, you should see the contents of Genesis 1:3. You can replace the 7700:1:3 part to obtain a different Bible verse.

Similarly, you can telnet 2602:806:a003:40e:b1be:7700:1:3 80, then type GET /, and the HTML code of the Bible verse should appear. Because you did not type a Host header, this server does not use name-based virtual hosting.

Wouldn't this overload the neighbor table?

We use static routing without neighbor discovery. In general, static routing is available anywhere where BGP sessions are offered.

Some of the stuff just sounds like total nonsense!

You have to use your imagination, especially with the aliases and SCPs :).

I want to host this myself. Where do I start?

You will need:

  • a /64 static route from your hosting provider, or a BGP session
  • Delegation of the reverse DNS zone corresponding to that /64 (optional). If you use PI space from ARIN/APNIC/RIPE/whatever and BGP sessions, you will do this through the ARIN/APNIC/RIPE portal. Most of us won't have the luxury to have over 300 PTR entries (I use custom nameservers to support this). If you don't have access to reverse DNS, that's OK; it's mostly for vanity purposes and the web app will work fine without it.
  • Delegation of a subdomain (NS records) of a domain name you have DNS access to.

Use the 'ip route add local' trick described below to bind the entire /64 to your server.

Use the example nginx config below as part of the frontend. The Node.js program in https://gitlab.peterjin.org/_/ipv6-things is the backend.

Unfortunately, there are so many parts to this web app that it's impossible to have a clear view of all of the source code involved in the making. If you would like to host this anyway, contact me for information.

Permitted things

  • Any set of objects, physical or virtual, may be used.
  • Preference may be given to objects with numerical cataloguing systems.
  • Sets of names that are more likely to be used as hostnames, such as gods and goddesses or arbitrary words are usually not permitted, because other people may perceive it as the name of a full computer host, which may deserve more than one IP address.
  • Stuff from popular culture is usually not permitted due to licensing reasons.
  • Concrete objects or symbols thereof are preferred over abstract objects.


SSL Certificate

The SSL certificate for this site, was, unfortunately, a bit tricky. First, the facts:

  • SSL certificates protect domain names, not IP addresses.
  • Most forms of virtual hosting are name-based, not IP-based.
  • We wanted web browsers to be able to access the pages without server name indication (SNI), since SNI was created mainly due to the IPv4 shortage.
  • We may possibly need multiple or wildcard SSL certificates due to the number of domain names involved.

As a result, we relied on the fact that IP addresses can be used to encode information and came up with the "geo $server_addr" hack, as shown below.

However, since the SSL certificate is still shared between all "hosts", the model reduces down to a series of separate web server hosts all sharing the same wildcard certificate, as may be found in an enterprise.

In that case, we recognize that in such a circumstance, traffic to one server could be maliciously redirected to another, and it would not be noticed because the other host's SSL certificate is still valid for the original domain name. The common way to fix this is by checking the Host header on all trusted systems; however, this is not yet implemented here.

IPv6 Things vs 42.be / 42.dnslabs.nl

It's noteworthy to point out that unlike https://42.be and https://42.dnslabs.nl, the server IP address is actually being used as a primary key. 42.be, on the other hand, appears to rely on the file path after the domain to retrieve the correct image, and specifying a different file path would result in a different image, even on the same domain. In our opinion, such a setup could just be a virtual or alias host of the same server, which would effectively nullify the overall intent of those sites.

Aliases 3000 and the jealousy of the Cloudflare nameservers

The i6t-cf-poc-nnn DNS records, exactly as they appear in my Cloudflare dashboard

After thinking about this a bit, I sort of realized that one factor as to why Aliases 3000 was included here was due to the Cloudflare nameservers. For those who don't know about this, when you sign up for Cloudflare and add your domain, you are given random nameservers of the form <some given name>.ns.cloudflare.com. Examples here. Each nameserver has its own IPv4 address. I guess they just wanted to express their riches through assigning give IPv4 addresses "names". But of course, to me, IPv4 is overrated, so I guess I should probably just be doing this entirely on IPv6.

Speaking of Cloudflare, if your SSL mode is "flexible" or "full" (but not "full (strict)"), then you can actually create an orange cloud CNAME or AAAA record pointing to any one of the subdomains and it should still show the correct site.

("poc" means "proof of concept")

Note: Since my SSL mode is on "full (strict)", I had to add the following block to my http section. The only thing this does is serve the Cloudflare origin SSL certificate whenever Cloudflare connects to the server since Cloudflare always uses SNI to connect to the origin server. No other changes were made.

server {
        server_name "~^i6t-cf-poc-[0-9]+\.peterjin\.org$";
        listen [::]:443 ssl http2;
        ssl_certificate "/containers/nginx-40e/ssl/i6t-poc.crt";
        ssl_certificate_key "/containers/nginx-40e/ssl/i6t-poc.key";
        include /containers/nginx-40e/conf/normal-ipv6.conf;


The reason why it's https://bonnie1.aliases.peterjin.org and not "bonnie.aliases.peterjin.org" is because, internally, this domain is used as an NSEC/NXDOMAIN test. https://dnsviz.net/d/bonnie.aliases.peterjin.org/dnssec/

Note: Despite the my-bonnie-lies-over-the-ocean domains, there will never be a "bonnie2".

To do

  • The "aliases" group should be replaced with something else, distinct from Aliases 3000, since I have no intention of using most of the names in that zone in the current form of Aliases 3000. The current "Peter Jin a.k.a. (name)" format is inaccurate since it was mostly based on a simple formula that simply made the first letter of the name uppercase, and with an intended connection to an "expanded" version of Aliases 3000 instead of merely the names by themselves. Use subdomains of "names.misc.peterjin.org"
  • Remove the my-bonnie-lies-over-the-ocean-nn subdomains?
  • Should the IPv6 Bible be separated from this project? I think that it should be kept here, and just declare 2602:806:a003:40e:8000::/65 be reserved for major subprojects like for ones the scale of the IPv6 Bible.
  • Add elements of the periodic table

Source code

ip route add local 2602:806:a003:40e::/64 dev lo
# nginx.conf snippet
http {
	# other configuration parameters not shown
	geo "$server_addr" $proxy_socket {
		default unix:/dev/null:;
		2602:806:a003:40e:b1be::/80 unix:/containers/nginx-40e/sockets/ipv6bible.sock:;
		2602:806:a003:40e::3000:0/100 unix:/containers/nginx-40e/sockets/aliases3k.sock:;
	geo "$server_addr" $ssl_cert_match {
		default things;
		2602:806:a003:40e:b1be::/80 ipv6bible;
	geo "$server_addr" $no_website {
		default 1;
		2602:806:a003:40e:b1be::/80 0;
	map "$time_iso8601" $my_time_simple_iso8601 {
		default "unknown";
		"~([0-9-]+)T([0-9:]+)\+00:00" "$1 $2";
	server {
		listen [::]:80 ipv6only=on;
		server_name .ipv6.bible .aliases.peterjin.org .rdns.peterjin.org;
		location / {
			return 301 https://$host$request_uri;
	server {
		listen [::]:80 default_server;
		include normal-ipv6.conf;
	server {
		listen [::]:443 ssl http2 default_server ipv6only=on;
		ssl_certificate "$ssl_cert_match.crt";
		ssl_certificate_key "$ssl_cert_match.key";
		include normal-ipv6.conf;
# normal-ipv6.conf
location = / {
	types { }
	default_type text/plain;
	if ($no_website) {
		return 200 "Host: $host\nCurrent date/time: $my_time_simple_iso8601 (UTC)\nYour IP address: $remote_addr\nServer IP address: $server_addr\n";
	proxy_pass http://$proxy_socket;
	proxy_set_header X-Server-IP "$server_addr";
	proxy_set_header Host "$host";
location / {
	if ($no_website) {
		return 404;
	proxy_pass http://$proxy_socket;
	proxy_set_header X-Server-IP "$server_addr";
	proxy_set_header Host "$host";
  1. These are not "subnets" as would be described in traditional computer networking; these are merely to describe the overall organization of IP addresses within 2602:806:a003:40e::/64.
  2. You might have heard people on YouTube "calling the SCP Foundation" with a number of 951-███-2602, and thinking that this IP address could be related to it since it also begins with 2602. This is a coincidence and I had no control over the first ten digits of my ARIN-assigned range. Neither was it the case that the IP addresses used to be a library or a film projector.
  3. Technically, if it were truly possible that a toaster (or other object) could only be referred to by the first person, then it wouldn't have a name.