syndns脚本让您的网速飞起

作为一名科研人员,从一些知名期刊下载论文是一个重要的工作。然而,有些网站要么打不开,要么特别慢,然后这些科研网站又都是正规的网站。本文发布一款shell脚本来彻底解决这一痛点。

注意:本文发布有脚本目前仅支持Arch Linux,主要是安装依赖关系,其他Linux发行版可以自行修改。暂无发布Windows版的计划,如果您可以用Python实现对Windows的支持,欢迎联系本人共同拓展syndns.sh.

脚本编写思路

当前的网络设备已经完全可以满足大众上网的需求,一些网站为了增加功能等,会默认调用大量的js脚本等,因此打开这个网站时就会附加后台打开若干网站。通过后台链接传输的数据不是很大,现行的网速完全可以几乎瞬时完成,造成访问不畅通的瓶颈在于DNS,因为DNS不断的去解析这些网站包括的所有域名,在来来回回的解析过程中耽误了大量的时间,所以本脚本的核心思路在于解决DNS解析痛点。 整体方法包括:

  • 针对大众: 根据大家常用的网站,把这些网站的IP和域名统一写入本地/etc/hosts, 这样每次访问这些高频网站,系统就会从本地寻址,加快了解析速度。
  • 针对个人: 从firefox导出近几个月的历史记录~/bookmarks-2024-12-02.json, 然后执行syndns, 脚本自动从历史记录中把您自己常用的网站通过谷歌的8.8.8.8解析出可靠的IP列表,并写入到本地文件~/.host_dns_autoadd.txt, 然后syndns会把它载入到内存供dnsmasq调用。
  • 安装 dnsmasq 并启用,实现本地作为 DNS 服务器的功能,同时把 /etc/hosts~/.host_dns_autoadd.txt 中的映射关系统一放入内存 /dev/shm/dnsrecord.txt 文件中, 之后 dnsmasq 每次查询IP就会读取一次文件 /dev/shm/dnsrecord.txt , 而这成为最快的方式。如果不调入内存,那每次查询 IP , 系统都会去读取 /etc/hosts, 这个文件位于硬盘上,所以它的读取速度不是最快的,相对而言固态硬盘要比机械硬盘好很多,但是仍然远不如内存快, 所以调入内存是终极大招。

脚本源码

本文发布之时(2024年12月02日) syndns.sh 版本为 V1.5 , 最新脚本请前往: https://gitlab.com/fengzhenhua/script/syndns.sh

syndns.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#! /bin/sh
#
# Program : syndns.sh
# Version : v1.5
# Date : 2024-12-02 11:20
# Author : fengzhenhua
# Email : fengzhenhua@outlook.com
# CopyRight: Copyright (C) 2022-2025 FengZhenhua(冯振华)
# License : Distributed under terms of the MIT license.
#
# 检测软件依懒, 若未检测到,则自动安装
SYNDNS_DEPEND(){
for VAR in $1 ;do
pacman -Qq $VAR &> /dev/null
if [[ $? != 0 ]]; then
sudo pacman -S $VAR
fi
done
}
# 变量
SYN_EXE="/usr/local/bin/${0%.sh}"
SYN_AUTO="$HOME/.config/autostart/${0%.sh}.desktop"
SYN_SUDO="/etc/sudoers.d/01_$USER"
SYN_HOS="/etc/hosts"
SYN_REC=$(grep "addn-hosts" /etc/dnsmasq.conf |grep "/dev/shm/")
SYN_REC=${SYN_REC#*=}
SYN_ADD="$HOME/.host_dns_autoadd.txt"
#
# 主程序
SYNDNS_PROCESS(){
cat $SYN_HOS |grep -v '^$'|grep -v '^#'|sort |uniq -u > $SYN_REC
if [ -e $SYN_ADD ]; then
cat $SYN_ADD |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq -u >> $SYN_REC
fi
echo "$(hostname -i) localhost:" >> $SYN_REC
systemctl is-active --quiet dnsmasq
if [[ $? == 0 ]]; then
sudo systemctl restart dnsmasq.service
else
sudo systemctl start dnsmasq.service
fi
}
# 安装和更新
if [ $# -gt 0 ]; then
if [ $1 == "-i" -o $1 == "-I" ]; then
SYNDNS_DEPEND "dnsutils inetutils dnsmasq jq"
sudo cp -f $0 $SYN_EXE
sudo chmod +x $SYN_EXE
if [ ! -e $SYN_AUTO ]; then
sudo touch $SYN_AUTO
cat > $SYN_AUTO <<EOF
[Desktop Entry]
Name=SynDns
TryExec=syndns
Exec=$SYN_EXE
Type=Application
Categories=GNOME;GTK;System;Utility;TerminalEmulator;
StartupNotify=true
X-Desktop-File-Install-Version=0.22
X-GNOME-Autostart-enabled=true
Hidden=false
NoDisplay=false
EOF
sudo sh -c "cat > /etc/dnsmasq.conf" <<EOA
domain-needed
bogus-priv
resolv-file=/etc/resolv.conf
no-poll
interface=lo
listen-address=127.0.0.1
bind-interfaces
no-hosts
addn-hosts=/dev/shm/dnsrecord.txt
cache-size=9999
port=53
EOA
fi
if [ ! -e $SYN_SUDO ]; then
sudo touch $SYN_SUDO
sudo sh -c "cat > $SYN_SUDO" <<EOB
$USER ALL=(ALL) NOPASSWD: /bin/systemctl start stirling-pdf.service, /bin/systemctl stop stirling-pdf.service, /bin/systemctl restart dnsmasq.service, /bin/systemctl start dnsmasq.service
EOB
fi
elif [[ $1 =~ ".json" ]]; then
Address=($(cat $1|jq -r '.children[]' |grep "\"uri\":"))
Address=(${Address[*]#*//})
Address=(${Address[*]/\"uri\":})
Address=(${Address[*]%%/*})
Address=(${Address[*]%%\"*})
Address=(${Address[*]%%*[0-9]}) # 去除非域名
Address=(`echo ${Address[@]}|sed -e 's/ /\n/g'|sort |uniq`)
if [ -e $SYN_ADD ]; then
rm $SYN_ADD
fi
touch $SYN_ADD
for i in ${Address[*]} ; do
unset SYN_IP
SYN_IP=($(dig @8.8.8.8 +short $i)) # 默认从Google Public DNS 解析历史IP
SYN_IP=(${SYN_IP[*]%%*\.})
for ipc in ${SYN_IP[*]}; do
echo "$ipc $i" >> $SYN_ADD
let j+=1
done
done
SYNDNS_PROCESS
fi
fi
# 默认执行主程序
SYNDNS_PROCESS

使用方法

  1. 将上述脚本 syndns.sh 保存到本地,并赋于执行权限
    1
    sudo chmod+x syndns.sh
  2. 安装脚本
    1
    syndns.sh -i
  3. 导入由firefox生成的历史记录文件:
    1
    syndns ~/bookmarks-2024-12-02.json

注意:Firefox 生成历史记录文件方法,历史管理历史导入和备份备份...

参考文章