How to Host a .bit Website with HTTPS

Complete guide to hosting a website on a Namecoin .bit domain with HTTPS: name registration (Namecoin Core or Electrum-NMC), self-issued TLS certificates pinned on-chain, web server setup (Caddy/Nginx), and the TLS + Namecoin Resolver browser extension. No ICANN, no CA, no registrar — the blockchain is the registry and you are the certificate authority.

How to Host a .bit Website with HTTPS

A Complete Guide: Namecoin Registration → Web Server → TLS → Browser Extension

Last updated: 2026-04-14


What You’re Building

By the end of this guide you’ll have:

  • A .bit domain name registered on the Namecoin blockchain
  • A web server reachable at that domain
  • A valid TLS certificate for it (no CA needed — you are the CA)
  • The TLS + Namecoin Resolver extension configured to view it in your browser

The whole stack is decentralised. No ICANN. No Let’s Encrypt. No registrar. The blockchain is the registry. You are the certificate authority.


How It Works (Quick Overview)

Standard web: Browser → ICANN DNS → CA-signed cert → Server

.bit web: Browser → Namecoin blockchain → self-issued cert (pinned on-chain) → Server ↑ (extension handles this step)

The Namecoin blockchain stores two things for your domain:

  1. The IP address of your server (like a DNS A record)
  2. The public key of your CA certificate (like a TLSA/DANE record)

Visitors using the extension resolve both from the blockchain directly — no third-party DNS, no certificate authority needed.


Prerequisites

  • A machine running Linux (Ubuntu/Debian used in examples) to act as your web server
  • Some NMC (Namecoin coins) to pay for name registration → Buy at an exchange: https://www.namecoin.org/exchanges/
  • Node.js ≥ 18 (for the browser extension)
  • Chrome, Brave, or Firefox

Part 1: Install Namecoin Core and Sync

Namecoin Core is the full node. It syncs the blockchain, holds your wallet, and exposes the JSON-RPC interface the extension uses to resolve names.

1.1 Download

Go to: https://www.namecoin.org/download/

Current stable release: v28.0

Linux (x86 64-bit): wget https://www.namecoin.org/files/namecoin-core/namecoin-core-28.0/namecoin-28.0-x86_64-linux-gnu.tar.gz tar xzf namecoin-28.0-x86_64-linux-gnu.tar.gz sudo cp namecoin-28.0/bin/* /usr/local/bin/

macOS (ARM): Download namecoin-28.0-arm64-apple-darwin.tar.gz from the downloads page.

1.2 Configure

Create ~/.namecoin/namecoin.conf:

server=1 rpcuser=yourusername CHANGE THIS rpcpassword=yourpassword CHANGE THIS rpcallowip=127.0.0.1 rpcport=8336 daemon=1

Optional: prune to save disk space (can’t mine when pruned)

prune=550

Keep these credentials safe — you’ll need them later.

1.3 Start and sync

namecoind -daemon

First sync takes an hour or 2 on tor. The Namecoin blockchain is ~8 GB.

Check progress: namecoin-cli getblockchaininfo

Wait until “blocks” equals “headers” before registering names.


Part 2: Register Your .bit Name

.bit names are stored in the Namecoin blockchain under the “d/” namespace. “example.bit” is registered as the key “d/example”.

2.1 Get NMC into your wallet

Get your wallet address

namecoin-cli getnewaddress

Send NMC to that address from an exchange. Check balance: namecoin-cli getbalance

2.2 Register the name (two-step process)

Namecoin name registration is intentionally two steps to prevent front-running.

Step 1 — Reserve (doesn’t reveal the name publicly yet): namecoin-cli name_new “d/yourname”

This returns two values: [txid, rand] Save BOTH values. You need rand in step 2.

Example output:

[“abc123…txid…”, “deadbeef…rand…”]

Wait for at least 12 confirmations (~2 hours): namecoin-cli gettransaction “abc123…txid…”

Look for “confirmations” ≥ 12.

Step 2 — Activate (reveals the name with its value): namecoin-cli name_firstupdate “d/yourname” “rand_from_step1” ‘{“ip”:“YOUR.SERVER.IP”}’

Replace YOUR.SERVER.IP with your web server’s public IP address.

Minimal valid value (just an IP address): ‘{“ip”:“203.0.113.10”}’

Wait ~10 more minutes for this transaction to confirm. Verify registration: namecoin-cli name_show “d/yourname”

You should see your name and its value. You’re on the blockchain.

2.3 Name lifecycle

Names expire after 35,999 blocks (~200 days). Renew before they expire: namecoin-cli name_update “d/yourname” ‘{“ip”:“YOUR.SERVER.IP”}’

Recommended: renew every ~150 days to stay well ahead of expiry.


Alternative: Register with Electrum-NMC (Lightweight)

If you don’t want to run a full Namecoin Core node (~8 GB blockchain), Electrum-NMC is a lightweight SPV wallet that can register and manage .bit names without syncing the full chain. It connects to ElectrumX servers instead.

Trade-off: faster setup, less disk, but you trust ElectrumX servers more than a local full node. For maximum sovereignty, use Namecoin Core.

Install Electrum-NMC

Download from: https://www.namecoin.org/download/betas/ Source: https://github.com/namecoin/electrum-nmc

Or install from source (Linux):

sudo apt-get install libsecp256k1-0 python3-pyqt5 python3-cryptography git clone https://github.com/namecoin/electrum-nmc.git cd electrum-nmc git submodule update –init python3 -m pip install –user -e . ./run_electrum_nmc

Register a name with Electrum-NMC

Electrum-NMC has a built-in “Names” tab for managing Namecoin names.

  1. Open Electrum-NMC and let it sync (takes seconds, not hours)
  2. Send NMC to your Electrum-NMC wallet address (Receive tab)
  3. Go to the Names tab
  4. Click “Register Name”
  5. Enter the name to register: d/yourname
  6. Enter the value (your JSON record): {“ip”:“YOUR.SERVER.IP”}
  7. Confirm and pay the transaction

Electrum-NMC handles the two-step name_new → name_firstupdate process automatically behind the scenes. You don’t need to manually save the rand value or wait and run a second command.

Update / renew names

In the Names tab, select your name and click “Renew” or “Update”. To update the value (e.g. add TLS records later), edit the value field and confirm the transaction.

Remember: names expire after ~200 days. Renew before they expire.

Using Electrum-NMC from the command line

Electrum-NMC also has a CLI interface:

List your names

./run_electrum_nmc name_list

Register a name (two-step handled automatically in GUI;

CLI requires manual name_new + name_firstupdate)

./run_electrum_nmc name_new “d/yourname”

Wait for 12 confirmations, then:

./run_electrum_nmc name_firstupdate “d/yourname” “rand” ‘{“ip”:“YOUR.SERVER.IP”}’

Update a name

./run_electrum_nmc name_update “d/yourname” ‘{“ip”:“YOUR.SERVER.IP”}’

Check a name

./run_electrum_nmc name_show “d/yourname”

When to use which

Namecoin Core Electrum-NMC ────────────── ───────────────── Full node (8 GB) SPV client (~50 MB) Hours to sync Seconds to sync Maximum privacy Trusts ElectrumX servers Full RPC interface GUI + limited CLI Required for the Can register names but browser extension extension still needs (name resolution) Core or ElectrumX for name resolution

Note: Even if you use Electrum-NMC to register names, you’ll still need either Namecoin Core or the ElectrumX fallback in the browser extension (Part 5) for visitors to resolve your .bit domain.


Part 3: Generate Your TLS Certificate

Namecoin uses a self-issued CA model. You generate your own CA certificate, pin its public key in the blockchain, and issue TLS certificates from it. No external CA involved.

3.1 Download generate_nmc_cert

Linux (x86 64-bit)

wget https://api.cirrus-ci.com/v1/artifact/github/namecoin/generate_nmc_cert/Cross-Compile%20Go%20latest/binaries/dist/generate_nmc_cert--linux_amd64.tar.gz tar xzf generate_nmc_cert–linux_amd64.tar.gz chmod +x generate_nmc_cert sudo mv generate_nmc_cert /usr/local/bin/

macOS/Windows binaries are also available from the same base URL — swap “linux_amd64” for “darwin_amd64” or “windows_amd64”.

3.2 Create your CA certificate

mkdir ~/yourname.bit-ca cd ~/yourname.bit-ca generate_nmc_cert -use-ca -use-aia -host yourname.bit

This creates: caChain.pem — CA certificate chain (used to issue TLS certs) caKey.pem — CA private key (keep offline/secure!) chain.pem — TLS certificate chain (deploy to your server) key.pem — TLS private key (deploy to your server) namecoin.json — TLSA record to publish in the blockchain

Keep caKey.pem somewhere secure and preferably offline. If it’s stolen, someone can forge certificates for your domain.

3.3 Publish the TLS record in the blockchain

Read the content of namecoin.json: cat ~/yourname.bit-ca/namecoin.json

It looks like: [2, 1, 0, “MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAD…base64pubkey…”]

Now update your name’s blockchain value to include this TLS record:

namecoin-cli name_update “d/yourname” ‘{ “ip”: “YOUR.SERVER.IP”, “map”: { “*”: { “tls”: [ [2, 1, 0, “MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAD…”] ] } } }’

The “map”: {“*“: {“tls”: […]}} structure publishes the CA public key for yourname.bit and all subdomains.

Verify it’s on-chain: namecoin-cli name_show “d/yourname”


Part 4: Set Up Your Web Server

This guide covers Caddy, Nginx, and Apache. The key step is the same for all three: load your Namecoin-issued chain.pem and key.pem instead of a Let’s Encrypt certificate.

4.1 Install Caddy

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/gpg.key’ | sudo gpg –dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt’ | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update && sudo apt install caddy

4.2 Copy your TLS files to the server

sudo mkdir -p /etc/caddy/namecoin sudo cp ~/yourname.bit-ca/chain.pem /etc/caddy/namecoin/chain.pem sudo cp ~/yourname.bit-ca/key.pem /etc/caddy/namecoin/key.pem sudo chmod 600 /etc/caddy/namecoin/key.pem

4.3 Configure Caddy

Edit /etc/caddy/Caddyfile:

yourname.bit { tls /etc/caddy/namecoin/chain.pem /etc/caddy/namecoin/key.pem root * /var/www/yourname.bit file_server }

Create your site: sudo mkdir -p /var/www/yourname.bit echo “

Hello from yourname.bit

” | sudo tee /var/www/yourname.bit/index.html

Restart Caddy: sudo systemctl restart caddy sudo systemctl enable caddy

For Nginx users

In your server block: server { listen 443 ssl; server_name yourname.bit; ssl_certificate /etc/nginx/namecoin/chain.pem; ssl_certificate_key /etc/nginx/namecoin/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305; root /var/www/yourname.bit; index index.html; }

For Apache users

Enable the required modules: sudo a2enmod ssl sudo a2enmod headers

Copy your TLS files: sudo mkdir -p /etc/apache2/namecoin sudo cp ~/yourname.bit-ca/chain.pem /etc/apache2/namecoin/chain.pem sudo cp ~/yourname.bit-ca/key.pem /etc/apache2/namecoin/key.pem sudo chmod 600 /etc/apache2/namecoin/key.pem

Create /etc/apache2/sites-available/yourname.bit.conf:

<VirtualHost *:443> ServerName yourname.bit

  SSLEngine on
  SSLCertificateFile    /etc/apache2/namecoin/chain.pem
  SSLCertificateKeyFile /etc/apache2/namecoin/key.pem

  SSLProtocol           all -SSLv3 -TLSv1 -TLSv1.1
  SSLCipherSuite        ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384
  SSLHonorCipherOrder   on

  Header always set Strict-Transport-Security "max-age=63072000"

  DocumentRoot /var/www/yourname.bit
  <Directory /var/www/yourname.bit>
      AllowOverride None
      Require all granted
  </Directory>

Enable the site and restart: sudo a2ensite yourname.bit sudo systemctl restart apache2 sudo systemctl enable apache2

For Lighttpd users

Lighttpd is a lightweight alternative suited to Raspberry Pis, VPS boxes, and embedded devices.

Install: sudo apt install lighttpd

Combine chain.pem and key.pem into one file (Lighttpd requires this): sudo mkdir -p /etc/lighttpd/namecoin cat ~/yourname.bit-ca/chain.pem ~/yourname.bit-ca/key.pem | sudo tee /etc/lighttpd/namecoin/combined.pem > /dev/null sudo chmod 600 /etc/lighttpd/namecoin/combined.pem

Enable the SSL module: sudo lighttpd-enable-mod ssl

Edit /etc/lighttpd/conf-enabled/10-ssl.conf (or add to lighttpd.conf):

server.modules += ( “mod_openssl” )

$SERVER[“socket”] == “:443” { ssl.engine = “enable” ssl.pemfile = “/etc/lighttpd/namecoin/combined.pem”

  ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2")
  ssl.cipher-list = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384"
  ssl.honor-cipher-order = "enable"

}

Set the document root in lighttpd.conf: server.document-root = “/var/www/yourname.bit”

Create your site and restart: sudo mkdir -p /var/www/yourname.bit echo “

Hello from yourname.bit

” | sudo tee /var/www/yourname.bit/index.html sudo systemctl restart lighttpd sudo systemctl enable lighttpd

Note: Lighttpd requires the certificate and private key concatenated into a single PEM file (ssl.pemfile). This is different from Caddy, Nginx, and Apache which take them as separate files.

The certificate chain.pem and key.pem are exactly what your TLS server loads — same as any other cert, just self-issued via generate_nmc_cert.

4.4 Open firewall ports

sudo ufw allow 80/tcp sudo ufw allow 443/tcp


Part 5: Configure the Browser Extension

The TLS + Namecoin Resolver extension resolves .bit names and inspects TLS headers. With a local Namecoin Core node running, it queries your node directly — no third party involved.

5.1 Install the extension

Clone and build from source: git clone https://github.com/mstrofnone/tls-namecoin-ext cd tls-namecoin-ext npm install node esbuild.config.mjs

Load in Chrome/Brave:

  1. Go to chrome://extensions
  2. Enable Developer mode (top right)
  3. Click “Load unpacked”
  4. Select the tls-namecoin-ext/ directory

Load in Firefox:

  1. Go to about:debugging#/runtime/this-firefox
  2. Click “Load Temporary Add-on”
  3. Select manifest.firefox.json

5.2 Configure the extension options

Right-click the extension icon → Options (or chrome://extensions → Details → Extension options)

Fill in your Namecoin Core RPC credentials: RPC Host: 127.0.0.1 RPC Port: 8336 RPC Username: yourusername (from namecoin.conf) RPC Password: yourpassword (from namecoin.conf)

Click “Test Connection” — you should see a success message.

If using the ElectrumX fallback (no local node): Leave RPC credentials empty. The extension will use the default ElectrumX server: ws://electrumx.testls.space:50003

Note: ElectrumX is a lighter option but the server operator can see your .bit queries. For maximum privacy, run a local Namecoin Core node.

5.3 Visit your .bit site

Navigate to https://yourname.bit in your browser.

What you’ll see with the extension:

  • The extension popup shows the resolved IP and TLS record from the blockchain
  • The TLS certificate info shows your chain.pem is in use
  • If your server is configured correctly, the page loads over HTTPS

⚠️ Note: Standard browsers will show a “connection not secure” warning even with the extension, because the browser’s built-in TLS validator doesn’t know about Namecoin CA certificates. Full browser TLS validation for .bit requires additional setup (see Part 6). The extension currently surfaces the TLS record data for inspection — it’s informational until full DANE validation lands.


Part 6: Optional — Full TLS Validation in the Browser

The extension resolves names and shows TLS records. To get the browser itself to trust your Namecoin certificate (green padlock, no warnings), you need extra tooling. This is optional but worth doing for a clean experience.

Windows (easiest path)

Install the ncdns Windows installer — it handles everything: https://www.namecoin.org/files/ncdns/ncdns-0.3.1/ncdns-0.3.1-x86_64-install-fb9d49.exe

The installer:

  • Configures Namecoin name resolution system-wide
  • Sets up TLS certificate validation for Chrome and Edge (via CryptoAPI)
  • Configures Firefox separately
  • Installs Dnssec-Trigger for DNS

After the installer runs, Chrome and Edge will trust .bit certificates issued by your Namecoin CA without any warnings.

Linux (Chrome/Chromium)

Install ncdns plain binaries and configure it to connect to your local Namecoin Core node. Then run tlsrestrict_chromium_tool to prevent regular CAs from signing .bit certificates: https://www.namecoin.org/docs/tls-client/chromium/gnu-linux/

Linux (Firefox)

Install ncdns and use the ncp11 PKCS#11 module to inject Namecoin certificate trust into Firefox’s certificate store: https://www.namecoin.org/docs/tls-client/firefox/gnu-linux/


Part 7: Renewing Your TLS Certificate

Your TLS certificate (chain.pem / key.pem) expires after 365 days by default. The CA certificate (caChain.pem / caKey.pem) also expires but can be renewed.

Renewing the TLS certificate (annual)

You do NOT need a new blockchain transaction for this — just re-issue from the same CA:

mkdir ~/yourname.bit-tls-2026 cd ~/yourname.bit-tls-2026 generate_nmc_cert -use-ca -host yourname.bit
-parent-chain ~/yourname.bit-ca/caChain.pem
-parent-key ~/yourname.bit-ca/caKey.pem

Copy new chain.pem and key.pem to your server: sudo cp chain.pem /etc/caddy/namecoin/chain.pem sudo cp key.pem /etc/caddy/namecoin/key.pem sudo systemctl restart caddy

No blockchain fees. No wallet transaction. The CA public key in the blockchain is still valid — you’re just issuing a new cert from the same CA.

Renewing the CA certificate (when needed)

If your CA certificate is nearing expiry, renew it without rotating the key:

mkdir ~/yourname.bit-renew-ca cd ~/yourname.bit-renew-ca generate_nmc_cert -use-ca -use-aia -host yourname.bit
-grandparent-key ~/yourname.bit-ca/caAIAKey.pem
-parent-key ~/yourname.bit-ca/caKey.pem

The CA public key stays the same, so no blockchain update is needed. Add the new caChain.pem to any existing chain.pem files on your server.

Rotating the CA key (emergency only)

If you believe your CA private key was compromised:

  1. Generate a completely new CA: mkdir ~/yourname.bit-ca-new generate_nmc_cert -use-ca -use-aia -host yourname.bit

  2. Update the blockchain with the new CA public key from namecoin.json (this requires a transaction and a fee)

  3. Issue new TLS certificates from the new CA

  4. Destroy the old caKey.pem


Quick Reference: Full Name Record Format

A complete name value with IP, IPv6, subdomains, and TLS:

{ “ip”: “203.0.113.10”, “ip6”: “2001:db8::1”, “map”: { “www”: { “ip”: “203.0.113.10” }, “*”: { “tls”: [ [2, 1, 0, “MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAD…”] ] } } }

Field Meaning
ip IPv4 address (A record)
ip6 IPv6 address (AAAA record)
ns Nameservers (NS record) — suppresses tls if used
map Subdomain records
map.* Wildcard — applies to all subdomains
tls TLSA-like record: [usage, selector, type, data]

TLS record fields: [2, 1, 0, “base64pubkey”] ↑ ↑ ↑ | | └─ 0 = exact match, 1 = SHA-256 | └──── 0 = full cert, 1 = SubjectPublicKeyInfo └─────── 2 = trust anchor (your CA)


Troubleshooting

“name not found” in the extension

  • Check that Namecoin Core is fully synced: namecoin-cli getblockchaininfo
  • Verify the name is registered: namecoin-cli name_show “d/yourname”
  • Check that RPC credentials in the extension options match namecoin.conf
  • If using ElectrumX fallback, check the server URL in options

Page doesn’t load at yourname.bit

  • The browser itself can’t resolve .bit via normal DNS — it needs ncdns (system-level) or the extension to redirect the request. With the extension alone, you may need to navigate to the IP directly until full redirect support is added.
  • Check your server is reachable: curl -k https://YOUR.SERVER.IP
  • Check firewall: sudo ufw status

TLS certificate warning in browser

  • Expected without ncdns + certificate injection (Part 6). The extension surfaces the TLS record; the browser’s validator still sees an unknown CA. Install ncdns for full browser trust.

name_firstupdate returns “too early”

  • You need ≥ 12 confirmations on the name_new transaction first. Run: namecoin-cli gettransaction “your_txid” | grep confirmations Wait until confirmations ≥ 12.

Name expired / “name not in db”

  • Namecoin names expire after ~200 days. Renew with name_update: namecoin-cli name_update “d/yourname” ‘{“ip”:“YOUR.SERVER.IP”,“map”:{“*“:{“tls”:[[2,1,0,“…“]]}}}’

Resources


No comments yet.