Enabled IPv6 for my current blog using FreeBSD and Nginx

9 min

language: ja bn en es hi pt ru zh-cn zh-tw

Hello, I am incompetent.

When I sent a request to my site from my home smartphone environment, the response speed was slow, and I thought it might be my imagination. However, when I switched to au's mobile network and accessed it, it became faster instead. I realized it wasn't my imagination, and the culprit was probably the lack of IPv6 support.

Work

AAAA Record Registration

It's a bit confusing because I'm tinkering with it right now, but I will register the AAAA record.

$ dig www.soulminingrig.com AAAA

; <<>> DiG 9.20.16 <<>> www.soulminingrig.com AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20103
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.soulminingrig.com.         IN      AAAA

;; ANSWER SECTION:
www.soulminingrig.com.  300     IN      CNAME   edge.soulminingrig.com.
edge.soulminingrig.com. 300     IN      CNAME   pool.soulminingrig.com.
pool.soulminingrig.com. 300     IN      AAAA    2400:8500:2002:3317:163:44:113:145

;; Query time: 50 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Tue Apr 07 20:38:20 JST 2026
;; MSG SIZE  rcvd: 116

Nginx

As it is, Nginx is not listening on IPv6, so I will change the settings.

# git diff
diff --git a/site/soulminingrig.com.conf b/site/soulminingrig.com.conf
index 35f96e0..10c99d6 100644
--- a/site/soulminingrig.com.conf
+++ b/site/soulminingrig.com.conf
@@ -12,12 +12,14 @@ map $uri $static_cache {
 
 server {
     listen 80;
+    listen [::]:80;
     server_name soulminingrig.com www.soulminingrig.com;
     return 301 https://$host$request_uri;
 }
 
 server {
     listen 443 ssl;
+    listen [::]:443 ssl;
     listen 443 quic reuseport;
     listen [::]:443 quic reuseport;
     http2 on;

I hadn't noticed at all, but QUICK alone supports IPv6 unnecessarily... Well, it was blocked upstream, so it was meaningless...

pf

Editing FreeBSD's PacketFilter settings.

set skip on lo
set block-policy drop
set optimization conservative

wanint="vtnet0"

exsrv1 = 163.44.113.145

wg_net = "10.1.0.0/24"
wg_clients="{ 10.1.0.4, 10.1.0.2, 10.1.0.22 }"
wg_ports="{51820}"

scrub in on $wanint all random-id max-mss 1360
scrub out on $wanint all random-id max-mss 1360
scrub in all
scrub out all

nat on $wanint inet from $wg_clients to any -> $wanint

pass in on $wanint proto udp from any to ($wanint) port $wg_ports

block all
pass out quick keep state

~~~

pass in on $wanint proto udp to ($wanint) port 443 keep state
pass in on $wanint proto tcp to ($wanint) port {80, 443} keep state

I'm currently reviewing the pf settings, so there might be some incorrect descriptions, but I'm using dynamic routing as ($wanint). This means if traffic comes from IPv6, the rule applies directly to IPv6; if from IPv4, it applies directly to IPv4. This eliminates unnecessary NAT conversions.

However, this time, I only changed the settings for HTTP-related traffic. While there are also mail server settings that only I use, there isn't much point in enabling IPv6 for a mail server that I use almost exclusively for receiving mail, so I won't address it this time.

Verification

$ curl -vvv -so /dev/null https://www.soulminingrig.com 2>&1 | head
20:59:59.614252 [0-x] * [READ] client_reset, clear readers
20:59:59.680564 [0-0] * Host www.soulminingrig.com:443 was resolved.
20:59:59.680678 [0-0] * IPv6: 2400:8500:2002:3317:163:44:113:145
20:59:59.680806 [0-0] * IPv4: 163.44.113.145, 91.98.169.80
20:59:59.680958 [0-0] * [HTTPS-CONNECT] adding wanted h2
20:59:59.681086 [0-0] * [HTTPS-CONNECT] added
20:59:59.681188 [0-0] * [HTTPS-CONNECT] connect, init
20:59:59.681324 [0-0] *   Trying [2400:8500:2002:3317:163:44:113:145]:443...
20:59:59.681605 [0-0] * [HTTPS-CONNECT] connect -> 0, done=0
20:59:59.681721 [0-0] * [HTTPS-CONNECT] Curl_conn_connect(block=0) -> 0, done=0

Done!

By the way, last time, when there were multiple A records in ConoHa's DNS records and one of the servers pointed to by an A record died, it was automatically routed to the A record of a live server, even though it was just round-robin. It seems that the HTTP client side was just handling it well with retries or similar.

Thus, even from Starlink IP, where the egress IP is basically a global IPv6 IP, the costs of NAT conversion and similar processes have been eliminated, and phenomena like response delays have successfully disappeared. Oh, that's a relief.

Looking Ahead

In reality, 'remembering IPv6' feels quite difficult for humans to memorize or manage, but it also seems like it will be increasingly used for malicious purposes.

At the same time, with this change, I re-checked the fail2ban settings to ensure there are no issues with IPv6.

Currently, we live in an era where coexistence is possible with NAT conversion and so on. However, in reality, CGNAT, as an open internet and as the WWW, feels like it creates a closed internet, and perhaps IPv6 is now a better fit for the form of a free internet. That said, if you ask if I specifically want to consciously use IPv6, it's a bit of a 'hmm' feeling.

As far as I can see from my server's log files, about 90% of clients still seem to be IPv4, but this is also because a large number of bots are coming in. So, if you consider actual user requests, IPv6 might indeed be quite widespread.

However, when it comes to whether to support it or not, for HTTP alone, I feel it's better to support it. But the risk is security vulnerabilities. Also known as human laziness. There's a non-zero chance that dynamic WAFs and similar systems might only be configured for IPv4, and if it's an introduction on a considerable scale, I think it might be better to start by organizing WAFs and network rules.

Related Posts