Fix BIND9 Open Resolver Issue on Virtualmin Server

(Recursion Not Available / REFUSED)

BIND9 was unintentionally acting as a public recursive DNS resolver, creating a security risk. This guide shows how to safely disable recursion without breaking hosted domains.

Table of Contents

One of my production hosting servers (running Virtualmin) looked perfectly fine on the surface — domains were resolving, clients weren’t complaining, and everything seemed stable.

But during a routine check, something didn’t feel right.

The server had BIND9 installed (as expected with Virtualmin), but deeper inspection showed it was behaving as a public recursive DNS resolver. That’s not just inefficient — it’s a serious security issue.

This kind of problem is common on VPS setups where:

If left unfixed, your server can be abused for DNS amplification attacks or even get blacklisted.

This is a classic case under SSL & DNS Problems.

Problem Summary

Here’s what I observed:

				
					192.0.x.x:53
				
			

Key symptom

From an external server:

				
					dig @192.0.x.x google.com
				
			

Initial behavior (before fix):

At this point, it was clear:

BIND was doing both authoritative DNS + recursion, which is dangerous in production.

Since Unbound was already handling system DNS, the logical next step was to remove recursion from BIND completely.

Confirm BIND is using default recursion behavior

First, check if recursion is explicitly configured:

				
					grep -E "recursion|allow-recursion|allow-query-cache" /etc/bind/named.conf.options
				
			

In this case, there was no output.

That means BIND is using defaults:

				
					recursion yes;
allow-recursion { any; };
				
			

Which effectively makes your server a public DNS resolver.

Understand the risk (before changing anything)

Important: This was a production server with active DNS zones.

So we could NOT:

We only needed to:

Disable recursion while keeping DNS zones working

Disable recursion safely

Unbound Should Be Enabled First

If you disable BIND recursion without another resolver, your system DNS will break.

Edit:

				
					nano /etc/bind/named.conf.options
				
			

Update the options block:

				
					options {
    directory "/var/cache/bind";

    recursion no;

    dnssec-validation auto;

    listen-on-v6 { any; };
};
				
			

That single line:

				
					recursion no;
				
			

completely removes resolver capability without touching authoritative DNS.

Restart BIND

				
					systemctl restart bind9
				
			

Why this works

After this change:

Since Unbound handles recursion internally, nothing else is affected.

Verification

This is the most important part.

Test 1 — Recursion should fail

From another server:

				
					dig @192.0.x.x google.com
				
			

Expected output:

				
					status: REFUSED
WARNING: recursion requested but not available
				
			
recursion requested but not available

This confirms:

Test 2 — Your domains should still resolve

				
					dig @192.0.x.x yourdomain.com
				
			

Expected:

				
					status: NOERROR
flags: qr aa rd
				
			

Common Mistakes / Edge Cases

Need Help Fixing Your VPS?

If you’re stuck with server issues and need a reliable fix, I troubleshoot real VPS problems daily — from Nginx errors and SMTP failures to DNS and performance issues.

Instead of guessing, get a proven fix based on real experience.

Conclusion

This issue wasn’t obvious — everything “worked” at first glance.

But under the hood:

The fix was simple but critical: Disable recursion in BIND and let a dedicated resolver (Unbound) handle DNS lookups.

Now the setup is clean:

This is how production-grade DNS should be structured.

Tharindu

Hey!! I'm Tharindu. I'm from Sri Lanka. I'm a part time freelancer and this is my blog where I write about everything I think might be useful to readers. If you read a tutorial here and want to hire me, contact me here.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button