How to Change DNS Based on User Login in Linux

Automatically adjust DNS configuration when different Linux users log in, enabling user-specific DNS filtering or routing on shared machines.

Step 1: Prerequisites

Before setting up per-user DNS switching, you should be comfortable with:

  • Linux file systems, permissions, and commands like chmod and chown
  • Basic command-line operations and text editors (nano, vi)
  • Bash scripting fundamentals
  • User and group management concepts
  • DNS configuration basics (/etc/resolv.conf)
  • systemd service management

You will also need sudo or root access on the machine.

Step 2: Identify System Users

First, list the regular user accounts on the system. UIDs 1000 and above are typically human user accounts:

awk -F: '$3 >= 1000 {print $1}' /etc/passwd

This filters out system accounts and shows only the users who will need per-user DNS configuration. Note the usernames — you will use them in the DNS switching script.

Step 3: Create the DNS Switching Script

Create a script at /etc/dns_switch.sh that checks the logged-in user and applies the corresponding DNS servers.

sudo nano /etc/dns_switch.sh

Paste the following, adjusting usernames and DNS values for your setup:

#!/bin/bash
# /etc/dns_switch.sh — Per-user DNS configuration
# Back up current resolv.conf
sudo cp /etc/resolv.conf /etc/resolv.conf.bak

CURRENT_USER=$(whoami)

case "$CURRENT_USER" in
  parent)
    # Security Filter only (no content filtering)
    echo "nameserver 185.228.168.9" | sudo tee /etc/resolv.conf > /dev/null
    echo "nameserver 185.228.169.9" | sudo tee -a /etc/resolv.conf > /dev/null
    echo "nameserver 2a0d:2a00:1::2" | sudo tee -a /etc/resolv.conf > /dev/null
    echo "nameserver 2a0d:2a00:2::2" | sudo tee -a /etc/resolv.conf > /dev/null
    ;;
  child)
    # Family Filter (blocks adult + mixed content + safe search)
    echo "nameserver 185.228.168.168" | sudo tee /etc/resolv.conf > /dev/null
    echo "nameserver 185.228.169.168" | sudo tee -a /etc/resolv.conf > /dev/null
    echo "nameserver 2a0d:2a00:1::" | sudo tee -a /etc/resolv.conf > /dev/null
    echo "nameserver 2a0d:2a00:2::" | sudo tee -a /etc/resolv.conf > /dev/null
    ;;
  guest)
    # Adult Filter (blocks adult content)
    echo "nameserver 185.228.168.10" | sudo tee /etc/resolv.conf > /dev/null
    echo "nameserver 185.228.169.11" | sudo tee -a /etc/resolv.conf > /dev/null
    echo "nameserver 2a0d:2a00:1::1" | sudo tee -a /etc/resolv.conf > /dev/null
    echo "nameserver 2a0d:2a00:2::1" | sudo tee -a /etc/resolv.conf > /dev/null
    ;;
  *)
    # Default: Family Filter
    echo "nameserver 185.228.168.168" | sudo tee /etc/resolv.conf > /dev/null
    echo "nameserver 185.228.169.168" | sudo tee -a /etc/resolv.conf > /dev/null
    ;;
esac

echo "DNS switched for user: $CURRENT_USER"

Replace parent, child, and guest with your actual usernames from Step 2. Adjust the DNS values to match the filter level you want for each user. See our Setup Guide for all available filter IPs.

Step 4: Trigger the Script at Login

Append each user's .bashrc file so the script runs automatically when they log in:

# For each user (replace 'child' with actual username)
echo '/etc/dns_switch.sh' >> /home/child/.bashrc

Repeat for every user who needs per-user DNS switching.


Paid Customers: Dynamic IP Update

If you have a paid CleanBrowsing account, add a cURL request to notify CleanBrowsing of the IP change when a user logs in. Add this line to each user's .bashrc after the script call:

# Add after the dns_switch.sh line in .bashrc
curl -fsS "https://my.cleanbrowsing.org/dynip/YOUR_CODE" > /dev/null 2>&1

Replace YOUR_CODE with the dynamic IP code from your CleanBrowsing dashboard.

Step 5: Configure Permissions

Make the script executable:

sudo chmod +x /etc/dns_switch.sh

The script uses sudo to modify /etc/resolv.conf. To allow users to run it without entering a password, update the sudoers file:

sudo visudo

Add a line for each user (replace child with the actual username):

child ALL=(ALL) NOPASSWD: /usr/bin/tee /etc/resolv.conf, /usr/bin/tee -a /etc/resolv.conf, /usr/bin/cp /etc/resolv.conf /etc/resolv.conf.bak

This grants passwordless access only to the specific commands the script needs — not full sudo access.


Prevent Manual Changes

To prevent users from manually editing /etc/resolv.conf and bypassing the filter, you can make the file immutable after each switch by adding this to the end of the script:

sudo chattr +i /etc/resolv.conf

The script would need to remove the immutable flag before writing:

sudo chattr -i /etc/resolv.conf

Add the corresponding chattr commands to the sudoers entry as well.

Step 6: Verify & Troubleshoot

After setting everything up, log in as each user and verify the DNS is set correctly:

# Check current DNS servers
cat /etc/resolv.conf

# Verify filtering is active
dig +short @185.228.168.168 debug.test.cleanbrowsing.org TXT

# Test a blocked domain (should return NXDOMAIN or block page IP on Family filter)
nslookup pornhub.com

Common Issues

  • Script not running at login: Check that the .bashrc line points to the correct script path and the script is executable.
  • Permission denied: Verify the sudoers entry matches the exact commands used in the script.
  • resolv.conf reverts: Some systems (NetworkManager, systemd-resolved) overwrite /etc/resolv.conf. Use chattr +i or configure your network manager to not manage DNS. See our Linux DNS Setup Guide for details.
  • IPv6 leaking: If you configure IPv4 DNS only, IPv6 DNS queries may bypass the filter. Always include both IPv4 and IPv6 nameservers.