为什么想到这个呢,算法什么的又不太懂,这是 因为搭建VPN + BBR 与之简直绝配
有的人搭建SSR ,配一个什么锐速,还需要降内核版本, 而且还容易出错,降了之后更加容易出现兼容性问题,所以偶尔看到了google的BBR 拥塞阻塞算法
算法原理不知道,也不想去深究 。 原理 这篇博客 讲得还是很清楚的 ,可以一探
Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经用上了该算法。根据谷歌的风格,Google 总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。
根据大佬的实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。
根据某个大佬开发的一键安装的脚本,可以实现最新内核的安装和 TCP BBR 脚本
脚本如下:
1 #!/usr/bin/env bash 2 # 3 # Auto install latest kernel for TCP BBR 4 # 5 # System Required: CentOS 6+, Debian7+, Ubuntu12+ 6 # 7 # Copyright (C) 2016-2018 Teddysun 8 # 9 # URL: https://teddysun.com/489.html 10 # 11 12 red='\033[0;31m' 13 green='\033[0;32m' 14 yellow='\033[0;33m' 15 plain='\033[0m' 16 17 cur_dir=$(pwd) 18 19 [[ $EUID -ne 0 ]] && echo -e "${red}Error:${plain} This script must be run as root!" && exit 1 20 21 [[ -d "/proc/vz" ]] && echo -e "${red}Error:${plain} Your VPS is based on OpenVZ, which is not supported." && exit 1 22 23 if [ -f /etc/redhat-release ]; then 24 release="centos" 25 elif cat /etc/issue | grep -Eqi "debian"; then 26 release="debian" 27 elif cat /etc/issue | grep -Eqi "ubuntu"; then 28 release="ubuntu" 29 elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then 30 release="centos" 31 elif cat /proc/version | grep -Eqi "debian"; then 32 release="debian" 33 elif cat /proc/version | grep -Eqi "ubuntu"; then 34 release="ubuntu" 35 elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 36 release="centos" 37 else 38 release="" 39 fi 40 41 is_digit(){ 42 local input=${1} 43 if [[ "$input" =~ ^[0-9]+$ ]]; then 44 return 0 45 else 46 return 1 47 fi 48 } 49 50 is_64bit(){ 51 if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ]; then 52 return 0 53 else 54 return 1 55 fi 56 } 57 58 get_valid_valname(){ 59 local val=${1} 60 local new_val=$(eval echo $val | sed 's/[-.]/_/g') 61 echo ${new_val} 62 } 63 64 get_hint(){ 65 local val=${1} 66 local new_val=$(get_valid_valname $val) 67 eval echo "\$hint_${new_val}" 68 } 69 70 #Display Memu 71 display_menu(){ 72 local soft=${1} 73 local default=${2} 74 eval local arr=(\${${soft}_arr[@]}) 75 local default_prompt 76 if [[ "$default" != "" ]]; then 77 if [[ "$default" == "last" ]]; then 78 default=${#arr[@]} 79 fi 80 default_prompt="(default ${arr[$default-1]})" 81 fi 82 local pick 83 local hint 84 local vname 85 local prompt="which ${soft} you'd select ${default_prompt}: " 86 87 while : 88 do 89 echo -e "\n------------ ${soft} setting ------------\n" 90 for ((i=1;i<=${#arr[@]};i++ )); do 91 vname="$(get_valid_valname ${arr[$i-1]})" 92 hint="$(get_hint $vname)" 93 [[ "$hint" == "" ]] && hint="${arr[$i-1]}" 94 echo -e "${green}${i}${plain}) $hint" 95 done 96 echo 97 read -p "${prompt}" pick 98 if [[ "$pick" == "" && "$default" != "" ]]; then 99 pick=${default}100 break101 fi102 103 if ! is_digit "$pick"; then104 prompt="Input error, please input a number"105 continue106 fi107 108 if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then109 prompt="Input error, please input a number between 1 and ${#arr[@]}: "110 continue111 fi112 113 break114 done115 116 eval ${soft}=${arr[$pick-1]}117 vname="$(get_valid_valname ${arr[$pick-1]})"118 hint="$(get_hint $vname)"119 [[ "$hint" == "" ]] && hint="${arr[$pick-1]}"120 echo -e "\nyour selection: $hint\n"121 }122 123 version_ge(){124 test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"125 }126 127 get_latest_version() {128 latest_version=($(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ | awk -F'\"v' '/v[4-9]./{print $2}' | cut -d/ -f1 | grep -v - | sort -V))129 130 [ ${#latest_version[@]} -eq 0 ] && echo -e "${red}Error:${plain} Get latest kernel version failed." && exit 1131 132 kernel_arr=()133 for i in ${latest_version[@]}; do134 if version_ge $i 4.14; then135 kernel_arr+=($i);136 fi137 done138 139 display_menu kernel last140 141 if [[ `getconf WORD_BIT` == "32" && `getconf LONG_BIT` == "64" ]]; then142 deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)143 deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"144 deb_kernel_name="linux-image-${kernel}-amd64.deb"145 modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)146 deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"147 deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb"148 else149 deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)150 deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"151 deb_kernel_name="linux-image-${kernel}-i386.deb"152 modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)153 deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"154 deb_kernel_modules_name="linux-modules-${kernel}-i386.deb"155 fi156 157 [ -z ${deb_name} ] && echo -e "${red}Error:${plain} Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again." && exit 1158 }159 160 get_opsy() {161 [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return162 [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return163 [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return164 }165 166 opsy=$( get_opsy )167 arch=$( uname -m )168 lbit=$( getconf LONG_BIT )169 kern=$( uname -r )170 171 get_char() {172 SAVEDSTTY=`stty -g`173 stty -echo174 stty cbreak175 dd if=/dev/tty bs=1 count=1 2> /dev/null176 stty -raw177 stty echo178 stty $SAVEDSTTY179 }180 181 getversion() {182 if [[ -s /etc/redhat-release ]]; then183 grep -oE "[0-9.]+" /etc/redhat-release184 else185 grep -oE "[0-9.]+" /etc/issue186 fi187 }188 189 centosversion() {190 if [ x"${release}" == x"centos" ]; then191 local code=$1192 local version="$(getversion)"193 local main_ver=${version%%.*}194 if [ "$main_ver" == "$code" ]; then195 return 0196 else197 return 1198 fi199 else200 return 1201 fi202 }203 204 check_bbr_status() {205 local param=$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')206 if [[ x"${param}" == x"bbr" ]]; then207 return 0208 else209 return 1210 fi211 }212 213 check_kernel_version() {214 local kernel_version=$(uname -r | cut -d- -f1)215 if version_ge ${kernel_version} 4.9; then216 return 0217 else218 return 1219 fi220 }221 222 install_elrepo() {223 224 if centosversion 5; then225 echo -e "${red}Error:${plain} not supported CentOS 5."226 exit 1227 fi228 229 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org230 231 if centosversion 6; then232 rpm -Uvh https://www.elrepo.org/elrepo-release-6-9.el6.elrepo.noarch.rpm233 elif centosversion 7; then234 rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm235 fi236 237 if [ ! -f /etc/yum.repos.d/elrepo.repo ]; then238 echo -e "${red}Error:${plain} Install elrepo failed, please check it."239 exit 1240 fi241 }242 243 sysctl_config() {244 sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf245 sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf246 echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf247 echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf248 sysctl -p >/dev/null 2>&1249 }250 251 install_config() {252 if [[ x"${release}" == x"centos" ]]; then253 if centosversion 6; then254 if [ ! -f "/boot/grub/grub.conf" ]; then255 echo -e "${red}Error:${plain} /boot/grub/grub.conf not found, please check it."256 exit 1257 fi258 sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf259 elif centosversion 7; then260 if [ ! -f "/boot/grub2/grub.cfg" ]; then261 echo -e "${red}Error:${plain} /boot/grub2/grub.cfg not found, please check it."262 exit 1263 fi264 grub2-set-default 0265 fi266 elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then267 /usr/sbin/update-grub268 fi269 }270 271 reboot_os() {272 echo273 echo -e "${green}Info:${plain} The system needs to reboot."274 read -p "Do you want to restart system? [y/n]" is_reboot275 if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then276 reboot277 else278 echo -e "${green}Info:${plain} Reboot has been canceled..."279 exit 0280 fi281 }282 283 install_bbr() {284 check_bbr_status285 if [ $? -eq 0 ]; then286 echo287 echo -e "${green}Info:${plain} TCP BBR has already been installed. nothing to do..."288 exit 0289 fi290 check_kernel_version291 if [ $? -eq 0 ]; then292 echo293 echo -e "${green}Info:${plain} Your kernel version is greater than 4.9, directly setting TCP BBR..."294 sysctl_config295 echo -e "${green}Info:${plain} Setting TCP BBR completed..."296 exit 0297 fi298 299 if [[ x"${release}" == x"centos" ]]; then300 install_elrepo301 [ ! "$(command -v yum-config-manager)" ] && yum install -y yum-utils > /dev/null 2>&1302 [ x"$(yum-config-manager elrepo-kernel | grep -w enabled | awk '{print $3}')" != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null 2>&1303 if centosversion 6; then304 if is_64bit; then305 rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm"306 rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm"307 rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/x86_64/RPMS/"308 else309 rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.i686.rpm"310 rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm"311 rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/i386/RPMS/"312 fi313 rpm_kernel_url_2="https://dl.lamp.sh/files/"314 wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_1}${rpm_kernel_name}315 if [ $? -ne 0 ]; then316 rm -rf ${rpm_kernel_name}317 wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_2}${rpm_kernel_name}318 fi319 wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_1}${rpm_kernel_devel_name}320 if [ $? -ne 0 ]; then321 rm -rf ${rpm_kernel_devel_name}322 wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_2}${rpm_kernel_devel_name}323 fi324 if [ -f "${rpm_kernel_name}" ]; then325 rpm -ivh ${rpm_kernel_name}326 else327 echo -e "${red}Error:${plain} Download ${rpm_kernel_name} failed, please check it."328 exit 1329 fi330 if [ -f "${rpm_kernel_devel_name}" ]; then331 rpm -ivh ${rpm_kernel_devel_name}332 else333 echo -e "${red}Error:${plain} Download ${rpm_kernel_devel_name} failed, please check it."334 exit 1335 fi336 rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name}337 elif centosversion 7; then338 yum -y install kernel-ml kernel-ml-devel339 if [ $? -ne 0 ]; then340 echo -e "${red}Error:${plain} Install latest kernel failed, please check it."341 exit 1342 fi343 fi344 elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then345 [[ ! -e "/usr/bin/wget" ]] && apt-get -y update && apt-get -y install wget346 echo -e "${green}Info:${plain} Getting latest kernel version..."347 get_latest_version348 if [ -n ${modules_deb_name} ]; then349 wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}350 if [ $? -ne 0 ]; then351 echo -e "${red}Error:${plain} Download ${deb_kernel_modules_name} failed, please check it."352 exit 1353 fi354 fi355 wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}356 if [ $? -ne 0 ]; then357 echo -e "${red}Error:${plain} Download ${deb_kernel_name} failed, please check it."358 exit 1359 fi360 [ -f ${deb_kernel_modules_name} ] && dpkg -i ${deb_kernel_modules_name}361 dpkg -i ${deb_kernel_name}362 rm -f ${deb_kernel_name} ${deb_kernel_modules_name}363 else364 echo -e "${red}Error:${plain} OS is not be supported, please change to CentOS/Debian/Ubuntu and try again."365 exit 1366 fi367 368 install_config369 sysctl_config370 reboot_os371 }372 373 374 clear375 echo "---------- System Information ----------"376 echo " OS : $opsy"377 echo " Arch : $arch ($lbit Bit)"378 echo " Kernel : $kern"379 echo "----------------------------------------"380 echo " Auto install latest kernel for TCP BBR"381 echo382 echo " URL: https://teddysun.com/489.html"383 echo "----------------------------------------"384 echo385 echo "Press any key to start...or Press Ctrl+C to cancel"386 char=`get_char`387 388 install_bbr 2>&1 | tee ${cur_dir}/install_bbr.log
View Code
也可以采用在线安装的方式:
wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh && chmod +x bbr.sh && ./bbr.sh
安装完成后,脚本会提示需要重启 VPS,输入 y 并回车后重启。
重启完成后,进入 VPS,验证一下是否成功安装最新内核并开启 TCP BBR,输入命令:
uname -r
查看内核版本,显示为最新版就表示 OK了
sysctl net.ipv4.tcp_available_congestion_control
返回值一般为:
net.ipv4.tcp_available_congestion_control = bbr cubic reno
或者为:
net.ipv4.tcp_available_congestion_control = reno cubic bbr
=================================================================================
sysctl net.ipv4.tcp_congestion_control
返回值一般为:
net.ipv4.tcp_congestion_control = bbr
=================================================================================
sysctl net.core.default_qdisc
返回值一般为:
net.core.default_qdisc = fq
==================================================================================lsmod | grep bbr
返回值有 tcp_bbr 模块即说明 bbr 已启动。注意:并不是所有的 VPS 都会有此返回值,若没有也属正常。
另外:
附上大佬的CentOS 下最新版内核 headers 安装方法
本来打算在脚本里直接安装 kernel-ml-headers,但会出现和原版内核 headers 冲突的问题。因此在这里添加一个脚本执行完后,手动安装最新版内核 headers 之教程。
执行以下命令
yum --enablerepo=elrepo-kernel -y install kernel-ml-headers
根据 CentOS 版本的不同,此时一般会出现类似于以下的错误提示:
Error: kernel-ml-headers conflicts with kernel-headers-2.6.32-696.20.1.el6.x86_64
Error: kernel-ml-headers conflicts with kernel-headers-3.10.0-693.17.1.el7.x86_64
因此需要先卸载原版内核 headers ,然后再安装最新版内核 headers。执行命令:
yum remove kernel-headers
确认无误后,输入 y,回车开始卸载。注意,有时候这么操作还会卸载一些对内核 headers 依赖的安装包,比如 gcc、gcc-c++ 之类的。不过不要紧,我们可以在安装完最新版内核 headers 后再重新安装回来即可。
卸载完成后,再次执行上面给出的安装命令。
yum --enablerepo=elrepo-kernel -y install kernel-ml-headers
成功安装后,再把那些之前对内核 headers 依赖的安装包,比如 gcc、gcc-c++ 之类的再安装一次即可。
为什么要安装最新版内核 headers 呢?
这是因为 ss-libev 版有个 tcp fast open 功能,如果不安装的话,这个功能是无法开启的。
内核升级方法
如果是 CentOS 系统,执行如下命令即可升级内核:
yum -y install kernel-ml kernel-ml-devel
如果你还手动安装了新版内核 headers ,那么还需要以下命令来升级 headers :
yum -y install kernel-ml-headers
CentOS 6 的话,执行命令:
sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf
CentOS 7 的话,执行命令:
grub2-set-default 0
如果是 Debian/Ubuntu 系统,则需要手动下载最新版内核来安装升级。
去这里下载最新版的内核 deb 安装包。
如果系统是 64 位,则下载 amd64 的 linux-image 中含有 generic 这个 deb 包;
如果系统是 32 位,则下载 i386 的 linux-image 中含有 generic 这个 deb 包;
安装的命令如下(以最新版的 64 位 4.12.4 举例而已,请替换为下载好的 deb 包):
dpkg -i linux-image-4.12.4-041204-generic_4.12.4-041204.201707271932_amd64.deb
安装完成后,再执行命令:
/usr/sbin/update-grub
最后,重启 VPS 即可。
特别说明
如果你使用的是 Google Cloud Platform (GCP)更换内核,有时会遇到重启后,整个磁盘变为只读的情况。只需执行以下命令即可恢复:
mount -o remount rw /