IPv6 ULAs are private IP addresses, similar to IPv4 private addresses which you might recognize, such as 192.168.1.1. The biggest conceptual difference is that IPv6 addresses are designed to be unique.
Local network addresses are used to make specific services readily available for people and computers within your private network, but not (readily) available to people off-network such as attackers. The actual security level this provides is contested.
There may also be more niche usecases, such as multi-WAN configurations at home, since in the current ISP climate (at least in the United States) you are almost certainly unable to announce your own IPv6 addresses.
Sometimes you want to join two or more private networks. A common example is when you connect your PC from your home network to your office network using a VPN, or when an enterprise is joining multiple office networks together. When both networks use the same private address range (ex. 192.168.1.0/24), this creates IP address conflicts, and can disrupt or entirely prevent communication.
+--------+-+------------+-----------+----------------------------+ | 7 bits |1| 40 bits | 16 bits | 64 bits | +--------+-+------------+-----------+----------------------------+ | Prefix |L| Global ID | Subnet ID | Interface ID | +--------+-+------------+-----------+----------------------------+
The prefix allocated by RFC 4193 for private addressing is fc00::/7, but the 8th bit ("Local" or L) must be set to 1, which makes the prefix that we can actually use start with "fd00."
bit position: 12345678 hex: fc | binary: 11111100 hex: fd | binary: 11111101
Don't quite get it? Try the Simple English Wikipedia entry on hexadecimal - should help!
This also halves the address block's size, as one additional bit has been reserved, hence why it's fd00::/8 and not fd00::/7.
After the Global ID you have 16 bits for your subnetting, which you can use however you like. If you don't have any subnetting plans right now, it's probably best to just start with what's shown on the "first subnet" on the generator, which is a /64 subnet using 0000 as the Subnet ID. You could use a bigger subnet if needed, such as to match the size of the public IPv6 address block delegated to your network by your ISP.
If you want to use a unique local network for your personal use or for testing only, no one bars you from using fd00::/48, fd00:abba::/48 or fd00:1234::/48. That said, frequent and frustrating conflicts in IPv4 networks are why IPv6 private networking has an element of uniqueness in the first place - this wasn't an arbitrary decision in IPv6's design. There's no good reason not to use a randomly generated address - how about the ones you've already generated?
The Global ID part of unique local addresses is a pseudo-randomly generated 40-bit integer. There is the possibility that multiple IPv6 sites will use the same Global ID and result in a conflict, however this should be unlikely. Just how likely?:
Connecting more than that, it'd be a wonder you're not already on the internet. These calculations are from RFC 4193 section 3.2.3, for reference.
The original, circa-2013 site generated ULAs server-side, so we can't know for sure. When the site was rewritten in 2014, it began to use Math.random() to generate the Global ID. As IPv6 ULAs are not a security sensitive context, this is sufficient and I have not rewritten this to use the Web Crypto API.
No. RFC 4193 section 3.2.2 defines a process to obtain a global ID by:
If you really want to follow the spec, use cd34's ULA generator. I find the simple promise of "approximately uniform PRNG" provided by Math.random() more convenient, but while unlikely, it's possible that poor seeding practices for Math.random() by your browser could produce identical ULAs.
This is why RFC definitions are not really as simple as "use a correctly seeded PRNG."
The Internet Society has curated a list of learning resources for IPv6. To dive deeper on IPv6 private addressing, always be sure to reference the RFC.