Created
April 14, 2025 08:24
-
-
Save Benyaminrmb/35b63987aa9f95313fe018bd1277042d to your computer and use it in GitHub Desktop.
free dns changer تغییر dns در ubuntu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
##################################################### | |
# # | |
# DNS CHANGER FOR UBUNTU # | |
# # | |
# A tool to easily switch between # | |
# different DNS server providers # | |
# # | |
##################################################### | |
# Color codes for terminal output | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[0;33m' | |
BLUE='\033[0;34m' | |
PURPLE='\033[0;35m' | |
CYAN='\033[0;36m' | |
WHITE='\033[1;37m' | |
BOLD='\033[1m' | |
NC='\033[0m' # No Color | |
# DNS server presets | |
declare -A dns_providers=( | |
["Shecan"]="178.22.122.100 185.51.200.2" | |
["Electro"]="78.157.42.100 78.157.42.101" | |
["Radar"]="10.202.10.10 10.202.10.11" | |
["Google"]="8.8.8.8 8.8.4.4" | |
["Cloudflare"]="1.1.1.1 1.0.0.1" | |
["Quad9"]="9.9.9.9 149.112.112.112" | |
["OpenDNS"]="208.67.222.222 208.67.220.220" | |
) | |
# Configuration directory | |
CONFIG_DIR="/etc/dns-changer" | |
HISTORY_FILE="$CONFIG_DIR/history.log" | |
# Check if script is run with sudo | |
check_sudo() { | |
if [ "$EUID" -ne 0 ]; then | |
echo -e "${RED}${BOLD}Error:${NC} Please run this script with sudo privileges" | |
echo -e "Usage: ${YELLOW}sudo $0${NC}" | |
exit 1 | |
fi | |
} | |
# Create config directory if it doesn't exist | |
setup_config() { | |
if [ ! -d "$CONFIG_DIR" ]; then | |
mkdir -p "$CONFIG_DIR" | |
fi | |
touch "$HISTORY_FILE" | |
} | |
# Function to log actions | |
log_action() { | |
local action="$1" | |
local timestamp=$(date "+%Y-%m-%d %H:%M:%S") | |
echo "[$timestamp] $action" >> "$HISTORY_FILE" | |
} | |
# Function to set DNS servers | |
set_dns() { | |
local provider_name="$1" | |
local dns_servers="${dns_providers[$provider_name]}" | |
local primary_dns=$(echo $dns_servers | cut -d' ' -f1) | |
local secondary_dns=$(echo $dns_servers | cut -d' ' -f2) | |
echo -e "\n${BLUE}${BOLD}Setting up $provider_name DNS servers...${NC}" | |
echo -e "Primary: ${CYAN}$primary_dns${NC}" | |
echo -e "Secondary: ${CYAN}$secondary_dns${NC}\n" | |
# Backup the current resolv.conf if backup doesn't exist | |
if [ ! -f /etc/resolv.conf.bak ]; then | |
cp /etc/resolv.conf /etc/resolv.conf.bak | |
echo -e "${GREEN}✓ Created backup of original DNS configuration${NC}" | |
fi | |
# For systems using NetworkManager | |
if command -v nmcli &> /dev/null; then | |
connection=$(nmcli -t -f NAME c show --active | head -n 1) | |
if [ -n "$connection" ]; then | |
echo -e "${YELLOW}➜ Configuring NetworkManager connection: $connection${NC}" | |
nmcli con mod "$connection" ipv4.dns "$primary_dns $secondary_dns" | |
nmcli con down "$connection" && nmcli con up "$connection" | |
echo -e "${GREEN}✓ DNS changed using NetworkManager${NC}" | |
log_action "Set $provider_name DNS via NetworkManager" | |
return 0 | |
fi | |
fi | |
# For systems with systemd-resolved | |
if systemctl is-active systemd-resolved &> /dev/null; then | |
echo -e "${YELLOW}➜ Configuring systemd-resolved${NC}" | |
# Create/update resolv.conf with new DNS | |
echo "nameserver $primary_dns" > /etc/resolv.conf | |
echo "nameserver $secondary_dns" >> /etc/resolv.conf | |
# Also update systemd-resolved config | |
mkdir -p /etc/systemd/resolved.conf.d | |
cat > /etc/systemd/resolved.conf.d/dns_servers.conf << EOF | |
[Resolve] | |
DNS=$primary_dns $secondary_dns | |
EOF | |
systemctl restart systemd-resolved | |
echo -e "${GREEN}✓ DNS changed using systemd-resolved${NC}" | |
log_action "Set $provider_name DNS via systemd-resolved" | |
return 0 | |
fi | |
# Fallback for other systems | |
echo -e "${YELLOW}➜ Using direct configuration method${NC}" | |
echo "nameserver $primary_dns" > /etc/resolv.conf | |
echo "nameserver $secondary_dns" >> /etc/resolv.conf | |
echo -e "${GREEN}✓ DNS changed using direct method${NC}" | |
log_action "Set $provider_name DNS via direct method" | |
} | |
# Function to display menu using whiptail if available, otherwise fallback to text menu | |
show_menu() { | |
if command -v whiptail &> /dev/null; then | |
local options=() | |
local i=1 | |
for provider in "${!dns_providers[@]}"; do | |
options+=("$i" "$provider DNS") | |
((i++)) | |
done | |
options+=("$i" "Reset to default DNS") | |
options+=("$((i+1))" "Show current DNS") | |
options+=("$((i+2))" "View change history") | |
options+=("$((i+3))" "Exit") | |
local choice=$(whiptail --title "DNS Changer for Ubuntu" --menu "Choose a DNS provider:" 18 60 10 "${options[@]}" 3>&1 1>&2 2>&3) | |
if [ -z "$choice" ]; then | |
return 1 | |
fi | |
echo "$choice" | |
return 0 | |
else | |
# Fallback text menu | |
clear | |
echo -e "${BLUE}${BOLD}╔════════════════════════════════════════╗${NC}" | |
echo -e "${BLUE}${BOLD}║ DNS CHANGER FOR UBUNTU ║${NC}" | |
echo -e "${BLUE}${BOLD}╚════════════════════════════════════════╝${NC}" | |
echo | |
local i=1 | |
for provider in "${!dns_providers[@]}"; do | |
echo -e " ${WHITE}$i.${NC} ${CYAN}$provider DNS${NC}" | |
((i++)) | |
done | |
echo -e " ${WHITE}$i.${NC} ${YELLOW}Reset to default DNS${NC}" | |
local reset_option=$i | |
((i++)) | |
echo -e " ${WHITE}$i.${NC} ${PURPLE}Show current DNS${NC}" | |
local show_option=$i | |
((i++)) | |
echo -e " ${WHITE}$i.${NC} ${BLUE}View change history${NC}" | |
local history_option=$i | |
((i++)) | |
echo -e " ${WHITE}$i.${NC} ${RED}Exit${NC}" | |
local exit_option=$i | |
echo | |
echo -e "${BLUE}${BOLD}═════════════════════════════════════════${NC}" | |
echo -n -e "${WHITE}Please select an option [1-$i]:${NC} " | |
read choice | |
# Validate input is a number | |
if ! [[ "$choice" =~ ^[0-9]+$ ]]; then | |
echo -e "${RED}Invalid input. Please enter a number.${NC}" | |
sleep 2 | |
return 1 | |
fi | |
if [ "$choice" -ge 1 ] && [ "$choice" -le "$exit_option" ]; then | |
echo "$choice" | |
return 0 | |
else | |
echo -e "${RED}Invalid option. Please try again.${NC}" | |
sleep 2 | |
return 1 | |
fi | |
fi | |
} | |
# Function to check current DNS | |
check_current_dns() { | |
echo -e "\n${PURPLE}${BOLD}Current DNS Configuration:${NC}" | |
echo -e "${PURPLE}═════════════════════════════════${NC}" | |
if command -v resolvectl &> /dev/null; then | |
resolvectl status | grep -E "DNS Server|DNS Domain" | sed "s/^/ /" | |
else | |
grep "nameserver" /etc/resolv.conf | sed "s/nameserver/ DNS Server: /" | |
fi | |
# Try to get the active connection name if NetworkManager is used | |
if command -v nmcli &> /dev/null; then | |
echo -e "\n${CYAN}Active Network Connection:${NC}" | |
nmcli -t -f NAME,TYPE,DEVICE c show --active | head -n 1 | tr ':' ' ' | sed "s/^/ /" | |
fi | |
echo | |
read -p "Press Enter to continue..." | |
} | |
# Function to view change history | |
view_history() { | |
echo -e "\n${BLUE}${BOLD}DNS Change History:${NC}" | |
echo -e "${BLUE}════════════════════${NC}" | |
if [ -s "$HISTORY_FILE" ]; then | |
tail -n 10 "$HISTORY_FILE" | sed "s/^/ /" | |
echo -e "\n ${YELLOW}(Showing last 10 changes)${NC}" | |
else | |
echo -e " ${YELLOW}No change history available${NC}" | |
fi | |
echo | |
read -p "Press Enter to continue..." | |
} | |
# Function to reset DNS to defaults | |
reset_dns() { | |
echo -e "\n${YELLOW}${BOLD}Resetting to default DNS...${NC}" | |
# Restore from backup if it exists | |
if [ -f /etc/resolv.conf.bak ]; then | |
cp /etc/resolv.conf.bak /etc/resolv.conf | |
echo -e "${GREEN}✓ Restored original DNS configuration${NC}" | |
fi | |
# For NetworkManager connections | |
if command -v nmcli &> /dev/null; then | |
connection=$(nmcli -t -f NAME c show --active | head -n 1) | |
if [ -n "$connection" ]; then | |
echo -e "${YELLOW}➜ Resetting NetworkManager connection: $connection${NC}" | |
nmcli con mod "$connection" ipv4.dns "" | |
nmcli con down "$connection" && nmcli con up "$connection" | |
echo -e "${GREEN}✓ NetworkManager DNS settings reset${NC}" | |
fi | |
fi | |
# For systemd-resolved | |
if systemctl is-active systemd-resolved &> /dev/null; then | |
echo -e "${YELLOW}➜ Resetting systemd-resolved${NC}" | |
if [ -f /etc/systemd/resolved.conf.d/dns_servers.conf ]; then | |
rm /etc/systemd/resolved.conf.d/dns_servers.conf | |
fi | |
systemctl restart systemd-resolved | |
echo -e "${GREEN}✓ systemd-resolved settings reset${NC}" | |
fi | |
log_action "Reset DNS to default settings" | |
echo -e "${GREEN}${BOLD}DNS reset to default settings${NC}" | |
sleep 1 | |
} | |
# Show script banner | |
show_banner() { | |
clear | |
echo -e "${BLUE}${BOLD}" | |
echo " _____ _ _ _____ _____ _ " | |
echo " | __ \| \ | |/ ____| / ____| | " | |
echo " | | | | \| | (___ | | | |__ __ _ _ __ __ _ ___ _ __" | |
echo " | | | | . \` |\___ \ | | | '_ \ / _\` | '_ \ / _\` |/ _ \ '__|" | |
echo " | |__| | |\ |____) | | |____| | | | (_| | | | | (_| | __/ | " | |
echo " |_____/|_| \_|_____/ \_____|_| |_|\__,_|_| |_|\__, |\___|_| " | |
echo " __/ | " | |
echo " |___/ " | |
echo -e "${NC}" | |
echo -e "${WHITE}${BOLD} Easy DNS Configuration for Ubuntu Systems${NC}" | |
echo -e "${CYAN} https://github.com/yourusername/dns-changer${NC}" | |
echo | |
echo -e "${YELLOW}Version 2.0.0${NC}" | |
echo | |
sleep 1 | |
} | |
# Main script function | |
main() { | |
check_sudo | |
setup_config | |
show_banner | |
while true; do | |
choice=$(show_menu) | |
# If menu returns non-zero (cancelled or error), retry | |
if [ $? -ne 0 ]; then | |
continue | |
fi | |
# Calculate where specific options are based on number of DNS providers | |
num_providers=${#dns_providers[@]} | |
reset_option=$((num_providers + 1)) | |
show_option=$((num_providers + 2)) | |
history_option=$((num_providers + 3)) | |
exit_option=$((num_providers + 4)) | |
case $choice in | |
$exit_option) | |
echo -e "\n${GREEN}${BOLD}Thank you for using DNS Changer. Goodbye!${NC}" | |
exit 0 | |
;; | |
$reset_option) | |
reset_dns | |
check_current_dns | |
;; | |
$show_option) | |
check_current_dns | |
;; | |
$history_option) | |
view_history | |
;; | |
*) | |
# Handle DNS provider selection (1 to num_providers) | |
if [ $choice -ge 1 ] && [ $choice -le $num_providers ]; then | |
# Get provider name by index | |
provider_name=$(echo "${!dns_providers[@]}" | tr ' ' '\n' | sed -n "${choice}p") | |
set_dns "$provider_name" | |
check_current_dns | |
else | |
echo -e "${RED}Invalid option. Please try again.${NC}" | |
sleep 2 | |
fi | |
;; | |
esac | |
done | |
} | |
# Run the main function | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment