├── menu.png ├── test_mirrors.png ├── README.md └── m-switch.sh /menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sir-MmD/M-Switch/HEAD/menu.png -------------------------------------------------------------------------------- /test_mirrors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sir-MmD/M-Switch/HEAD/test_mirrors.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # M-Switch 2 | (Mirror Switch Tool) 3 | 4 | ## What is M-Switch? 5 | M-Switch is a mirror switch tool. You can use this script to update your sources.list with the fastest mirrors available. This tool uses `curl` to test connection with the mirrors, make sure you have it before executing the script! 6 | | Supported OS | Status | 7 | |:-:| :-:| 8 | | **Kali Linux** | ✅ | 9 | 10 | This script uses official Kali Mirrors which can be found on https://http.kali.org/README?mirrorstats 11 | ### Run: 12 | ``` 13 | bash <(curl -Ls https://raw.githubusercontent.com/Sir-MmD/m-switch/master/m-switch.sh) 14 | ``` 15 | 16 | ### Screenshots: 17 | ![](https://github.com/Sir-MmD/m-switch/blob/main/menu.png) 18 | ![](https://github.com/Sir-MmD/m-switch/blob/main/test_mirrors.png) 19 | -------------------------------------------------------------------------------- /m-switch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #MmD 3 | 4 | check_root_user() { 5 | if [ "$EUID" -ne 0 ]; then 6 | echo "This script must be run as ${RED}root${NC}." 7 | exit 1 8 | fi 9 | } 10 | 11 | check_os_kali() { 12 | if [ -f /etc/os-release ]; then 13 | . /etc/os-release 14 | if [ "$ID" != "kali" ]; then 15 | echo "This script must be run on ${RED}Kali Linux${NC}." 16 | exit 1 17 | fi 18 | else 19 | echo "OS information not found." 20 | exit 1 21 | fi 22 | } 23 | 24 | declare -a hostnames=( 25 | "kali.download" 26 | "mirrors.jevincanders.net" 27 | "kali.cs.nycu.edu.tw" 28 | "mirror.kku.ac.th" 29 | "mirrors.neusoft.edu.cn" 30 | "kali.darklab.sh" 31 | "kali.mirror.garr.it" 32 | "kali.mirror.rafal.ca" 33 | "mirrors.netix.net" 34 | "mirror.freedif.org" 35 | "mirror.aktkn.sg" 36 | "mirrors.ocf.berkeley.edu" 37 | "mirror1.sox.rs" 38 | "mirror.pyratelan.org" 39 | "mirror.johnnybegood.fr" 40 | "ftp.free.fr" 41 | "archive-4.kali.org" 42 | "ftp.halifax.rwth-aachen.de" 43 | "mirror.netcologne.de" 44 | "free.nchc.org.tw" 45 | "mirror.twds.com.tw" 46 | "mirror.init7.net" 47 | "mirror.0xem.ma" 48 | "mirror.vinehost.net" 49 | "xsrv.moratelindo.io" 50 | "mirror.primelink.net.id" 51 | "mirror.cspacehostings.com" 52 | "mirror.leitecastro.com" 53 | "mirror.cedia.org.ec" 54 | "mirrors.ustc.edu.cn" 55 | "elmirror.cl" 56 | "ftp.nluug.nl" 57 | "mirror.ufro.cl" 58 | "repo.jing.rocks" 59 | "mirrors.dotsrc.org" 60 | "ftp.ne.jp" 61 | "ftp.jaist.ac.jp" 62 | "ftp.riken.jp" 63 | "mirror.lagoon.nc" 64 | "ftp.yz.yamagata-u.ac.jp" 65 | "ftp.belnet.be" 66 | "quantum-mirror.hu" 67 | "kali.koyanet.lv" 68 | "mirror.2degrees.nz" 69 | "mirror.accum.se" 70 | "wlglam.fsmg.org.nz" 71 | "hlzmel.fsmg.org.nz" 72 | "mirror.truenetwork.ru" 73 | "ftp.cc.uoc.gr" 74 | "kali.itsec.am" 75 | "kali.mirror1.gnc.am" 76 | "mirror.math.princeton.edu/pub" 77 | "fastmirror.pp.ua" 78 | ) 79 | 80 | GREEN=$(tput setaf 2) 81 | RED=$(tput setaf 1) 82 | BLUE=$(tput setaf 4) 83 | NC=$(tput sgr0) # No Color 84 | 85 | set_mirror_auto() { 86 | backup_sources_list 87 | 88 | test_mirror 89 | 90 | if [ -n "$best_hostname" ]; then 91 | sudo sed -i "s|deb http://[^/]\+/kali|deb http://$best_hostname/kali|g" /etc/apt/sources.list 92 | echo "" 93 | echo "Updated /etc/apt/sources.list with the best mirror: ${BLUE}$best_hostname${NC}" 94 | echo "" 95 | apt update -y 96 | echo "" 97 | echo "${GREEN}Update complete! Enjoy!${NC}" 98 | echo "" 99 | else 100 | echo "Failed to find a suitable mirror." 101 | fi 102 | } 103 | 104 | prompt_apt_update() { 105 | read -p "Do you want to run 'apt update' now? (y/n): " update_choice 106 | case "$update_choice" in 107 | [yY]|[yY][eE][sS]) 108 | sudo apt update 109 | echo "apt update has been executed." 110 | ;; 111 | *) 112 | echo "You can run 'apt update' later to apply the changes." 113 | ;; 114 | esac 115 | } 116 | 117 | set_mirror_manual() { 118 | for i in "${!hostnames[@]}"; do 119 | echo "$((i+1)). ${hostnames[$i]}" 120 | done 121 | read -p "Select a hostname: " num 122 | if [ $num -ge 1 ] && [ $num -le ${#hostnames[@]} ]; then 123 | selected_hostname=${hostnames[$((num-1))]} 124 | echo "Hostname set to: ${BLUE}$selected_hostname${NC}" 125 | sudo sed -i "s|deb http://[^/]\+/kali|deb http://$selected_hostname/kali|g" /etc/apt/sources.list 126 | echo "" 127 | echo "Updated /etc/apt/sources.list with the selected hostname." 128 | echo "" 129 | prompt_apt_update 130 | else 131 | echo "Invalid number. Please enter a number from 1 to ${#hostnames[@]}." 132 | set_mirror_manual 133 | fi 134 | } 135 | 136 | best_hostname="" 137 | 138 | test_mirror() { 139 | echo "" 140 | echo "Testing mirrors connectivity:" 141 | echo "" 142 | ok_count=0 143 | failed_count=0 144 | best_time=9999999 145 | 146 | for hostname in "${hostnames[@]}"; do 147 | echo -n "Testing connectivity to ${BLUE}$hostname${NC} " 148 | 149 | start_time=$(date +%s%N) # Start time in nanoseconds 150 | 151 | if curl --max-time 5 --output /dev/null --silent --head --fail "$hostname"; then 152 | end_time=$(date +%s%N) # End time in nanoseconds 153 | duration=$(( (end_time - start_time) / 1000000 )) # Duration in milliseconds 154 | echo -e "${GREEN}OK${NC} ${duration}ms" 155 | ((ok_count++)) 156 | if [ $duration -lt $best_time ]; then 157 | best_time=$duration 158 | best_hostname=$hostname 159 | fi 160 | else 161 | echo -e "${RED}FAILED${NC}" 162 | ((failed_count++)) 163 | fi 164 | done 165 | 166 | echo "------------------------" 167 | echo "${GREEN}OK Mirrors${NC}: $ok_count" 168 | echo "${RED}FAILED Mirrors${NC}: $failed_count" 169 | echo "Best Mirror: ${BLUE}$best_hostname${NC} with ${best_time}ms" 170 | echo "------------------------" 171 | } 172 | 173 | backup_sources_list() { 174 | if [ -f /etc/apt/sources.list.backup ]; then 175 | echo "" 176 | echo "Backup of sources.list already exists: /etc/apt/sources.list.backup" 177 | echo "" 178 | else 179 | sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup 180 | echo "" 181 | echo "Backup of sources.list created: /etc/apt/sources.list.backup" 182 | echo "" 183 | fi 184 | } 185 | 186 | restore_sources_list() { 187 | sudo cp /etc/apt/sources.list.backup /etc/apt/sources.list 188 | echo "" 189 | echo "Restored sources.list from backup: /etc/apt/sources.list.backup" 190 | echo "" 191 | } 192 | 193 | display_menu() { 194 | echo "" 195 | echo "███ ███ ███████ ██ ██ ██ ████████ ██████ ██ ██ " 196 | echo "████ ████ ██ ██ ██ ██ ██ ██ ██ ██ " 197 | echo "██ ████ ██ ${RED}█████${NC} ███████ ██ █ ██ ██ ██ ██ ███████ " 198 | echo "██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ " 199 | echo "██ ██ ███████ ███ ███ ██ ██ ██████ ██ ██ " 200 | echo " " 201 | echo "" 202 | echo "1. Update Mirror Automatically (Recommended)" 203 | echo "2. Update Mirror Manually" 204 | echo "3. Test Mirror Only" 205 | echo "4. Backup sources.list" 206 | echo "5. Restore sources.list" 207 | echo "6. Exit" 208 | } 209 | 210 | while true; do 211 | check_root_user 212 | check_os_kali 213 | display_menu 214 | echo "" 215 | read -p "Enter your choice: " choice 216 | echo "" 217 | case $choice in 218 | 1) 219 | set_mirror_auto 220 | ;; 221 | 2) 222 | set_mirror_manual 223 | ;; 224 | 3) 225 | test_mirror 226 | ;; 227 | 4) 228 | backup_sources_list 229 | ;; 230 | 5) 231 | restore_sources_list 232 | ;; 233 | 6) 234 | echo "Exiting..." 235 | exit 0 236 | ;; 237 | *) 238 | echo "Invalid option. Please enter a number from 1 to 6." 239 | ;; 240 | esac 241 | done 242 | --------------------------------------------------------------------------------