backup for this
Created
September 12, 2021 11:31
-
-
Save jukrb0x/0d510871777a905b2e5a104ab3ff726e to your computer and use it in GitHub Desktop.
Install latest TCP BBR
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
#!/usr/bin/env bash | |
# | |
# Auto install latest kernel for TCP BBR | |
# | |
# System Required: CentOS 6+, Debian8+, Ubuntu16+ | |
# | |
# Copyright (C) 2016-2021 Teddysun <[email protected]> | |
# | |
# URL: https://teddysun.com/489.html | |
# | |
cur_dir="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" | |
_red() { | |
printf '\033[1;31;31m%b\033[0m' "$1" | |
} | |
_green() { | |
printf '\033[1;31;32m%b\033[0m' "$1" | |
} | |
_yellow() { | |
printf '\033[1;31;33m%b\033[0m' "$1" | |
} | |
_info() { | |
_green "[Info] " | |
printf -- "%s" "$1" | |
printf "\n" | |
} | |
_warn() { | |
_yellow "[Warning] " | |
printf -- "%s" "$1" | |
printf "\n" | |
} | |
_error() { | |
_red "[Error] " | |
printf -- "%s" "$1" | |
printf "\n" | |
exit 1 | |
} | |
_exists() { | |
local cmd="$1" | |
if eval type type > /dev/null 2>&1; then | |
eval type "$cmd" > /dev/null 2>&1 | |
elif command > /dev/null 2>&1; then | |
command -v "$cmd" > /dev/null 2>&1 | |
else | |
which "$cmd" > /dev/null 2>&1 | |
fi | |
local rt=$? | |
return ${rt} | |
} | |
_os() { | |
local os="" | |
[ -f "/etc/debian_version" ] && source /etc/os-release && os="${ID}" && printf -- "%s" "${os}" && return | |
[ -f "/etc/redhat-release" ] && os="centos" && printf -- "%s" "${os}" && return | |
} | |
_os_full() { | |
[ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return | |
[ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return | |
[ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return | |
} | |
_os_ver() { | |
local main_ver="$( echo $(_os_full) | grep -oE "[0-9.]+")" | |
printf -- "%s" "${main_ver%%.*}" | |
} | |
_error_detect() { | |
local cmd="$1" | |
_info "${cmd}" | |
eval ${cmd} | |
if [ $? -ne 0 ]; then | |
_error "Execution command (${cmd}) failed, please check it and try again." | |
fi | |
} | |
_is_digit(){ | |
local input=${1} | |
if [[ "$input" =~ ^[0-9]+$ ]]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
_is_64bit(){ | |
if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
_version_ge(){ | |
test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1" | |
} | |
get_valid_valname(){ | |
local val=${1} | |
local new_val=$(eval echo $val | sed 's/[-.]/_/g') | |
echo ${new_val} | |
} | |
get_hint(){ | |
local val=${1} | |
local new_val=$(get_valid_valname $val) | |
eval echo "\$hint_${new_val}" | |
} | |
#Display Memu | |
display_menu(){ | |
local soft=${1} | |
local default=${2} | |
eval local arr=(\${${soft}_arr[@]}) | |
local default_prompt | |
if [[ "$default" != "" ]]; then | |
if [[ "$default" == "last" ]]; then | |
default=${#arr[@]} | |
fi | |
default_prompt="(default ${arr[$default-1]})" | |
fi | |
local pick | |
local hint | |
local vname | |
local prompt="which ${soft} you'd select ${default_prompt}: " | |
while : | |
do | |
echo -e "\n------------ ${soft} setting ------------\n" | |
for ((i=1;i<=${#arr[@]};i++ )); do | |
vname="$(get_valid_valname ${arr[$i-1]})" | |
hint="$(get_hint $vname)" | |
[[ "$hint" == "" ]] && hint="${arr[$i-1]}" | |
echo -e "${green}${i}${plain}) $hint" | |
done | |
echo | |
read -p "${prompt}" pick | |
if [[ "$pick" == "" && "$default" != "" ]]; then | |
pick=${default} | |
break | |
fi | |
if ! _is_digit "$pick"; then | |
prompt="Input error, please input a number" | |
continue | |
fi | |
if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then | |
prompt="Input error, please input a number between 1 and ${#arr[@]}: " | |
continue | |
fi | |
break | |
done | |
eval ${soft}=${arr[$pick-1]} | |
vname="$(get_valid_valname ${arr[$pick-1]})" | |
hint="$(get_hint $vname)" | |
[[ "$hint" == "" ]] && hint="${arr[$pick-1]}" | |
echo -e "\nyour selection: $hint\n" | |
} | |
get_latest_version() { | |
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)) | |
[ ${#latest_version[@]} -eq 0 ] && _error "Get latest kernel version failed." | |
kernel_arr=() | |
for i in ${latest_version[@]}; do | |
if _version_ge $i 5.9; then | |
kernel_arr+=($i); | |
fi | |
done | |
display_menu kernel last | |
if _is_64bit; then | |
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) | |
deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}" | |
deb_kernel_name="linux-image-${kernel}-amd64.deb" | |
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) | |
deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}" | |
deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb" | |
else | |
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) | |
deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}" | |
deb_kernel_name="linux-image-${kernel}-i386.deb" | |
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) | |
deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}" | |
deb_kernel_modules_name="linux-modules-${kernel}-i386.deb" | |
fi | |
[ -z "${deb_name}" ] && _error "Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again." | |
} | |
get_char() { | |
SAVEDSTTY=`stty -g` | |
stty -echo | |
stty cbreak | |
dd if=/dev/tty bs=1 count=1 2> /dev/null | |
stty -raw | |
stty echo | |
stty $SAVEDSTTY | |
} | |
check_bbr_status() { | |
local param=$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}') | |
if [[ x"${param}" == x"bbr" ]]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
check_kernel_version() { | |
local kernel_version=$(uname -r | cut -d- -f1) | |
if _version_ge ${kernel_version} 4.9; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
# Check OS version | |
check_os() { | |
if _exists "virt-what"; then | |
virt="$(virt-what)" | |
elif _exists "systemd-detect-virt"; then | |
virt="$(systemd-detect-virt)" | |
fi | |
if [ -n "${virt}" -a "${virt}" = "lxc" ]; then | |
_error "Virtualization method is LXC, which is not supported." | |
fi | |
if [ -n "${virt}" -a "${virt}" = "openvz" ] || [ -d "/proc/vz" ]; then | |
_error "Virtualization method is OpenVZ, which is not supported." | |
fi | |
[ -z "$(_os)" ] && _error "Not supported OS" | |
case "$(_os)" in | |
ubuntu) | |
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 16 ] && _error "Not supported OS, please change to Ubuntu 16+ and try again." | |
;; | |
debian) | |
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 8 ] && _error "Not supported OS, please change to Debian 8+ and try again." | |
;; | |
centos) | |
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 6 ] && _error "Not supported OS, please change to CentOS 6+ and try again." | |
;; | |
*) | |
_error "Not supported OS" | |
;; | |
esac | |
} | |
sysctl_config() { | |
sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf | |
sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf | |
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf | |
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf | |
sysctl -p >/dev/null 2>&1 | |
} | |
install_kernel() { | |
case "$(_os)" in | |
centos) | |
if [ -n "$(_os_ver)" ]; then | |
if ! _exists "yum-config-manager"; then | |
_error_detect "yum install -y yum-utils" | |
fi | |
if [ "$(_os_ver)" -eq 6 ]; then | |
_error_detect "rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org" | |
rpm_kernel_url="https://dl.lamp.sh/files/" | |
if _is_64bit; then | |
rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm" | |
rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm" | |
else | |
rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.i686.rpm" | |
rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm" | |
fi | |
_error_detect "wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url}${rpm_kernel_name}" | |
_error_detect "wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url}${rpm_kernel_devel_name}" | |
[ -s "${rpm_kernel_name}" ] && _error_detect "rpm -ivh ${rpm_kernel_name}" || _error "Download ${rpm_kernel_name} failed, please check it." | |
[ -s "${rpm_kernel_devel_name}" ] && _error_detect "rpm -ivh ${rpm_kernel_devel_name}" || _error "Download ${rpm_kernel_devel_name} failed, please check it." | |
rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name} | |
[ ! -f "/boot/grub/grub.conf" ] && _error "/boot/grub/grub.conf not found, please check it." | |
sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf | |
elif [ "$(_os_ver)" -eq 7 ]; then | |
_error_detect "yum -y install centos-release-xen-48" | |
[ x"$(yum-config-manager centos-virt-xen-48 | grep -w enabled | awk '{print $3}')" != x"True" ] && _error_detect "yum-config-manager --enable centos-virt-xen-48" | |
_error_detect "yum -y update kernel" | |
_error_detect "yum -y install kernel-devel" | |
fi | |
fi | |
;; | |
ubuntu|debian) | |
_info "Getting latest kernel version..." | |
get_latest_version | |
if [ -n "${modules_deb_name}" ]; then | |
_error_detect "wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}" | |
fi | |
_error_detect "wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}" | |
_error_detect "dpkg -i ${deb_kernel_modules_name} ${deb_kernel_name}" | |
rm -f ${deb_kernel_modules_name} ${deb_kernel_name} | |
_error_detect "/usr/sbin/update-grub" | |
;; | |
*) | |
;; # do nothing | |
esac | |
} | |
reboot_os() { | |
echo | |
_info "The system needs to reboot." | |
read -p "Do you want to restart system? [y/n]" is_reboot | |
if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then | |
reboot | |
else | |
_info "Reboot has been canceled..." | |
exit 0 | |
fi | |
} | |
install_bbr() { | |
if check_bbr_status; then | |
echo | |
_info "TCP BBR has already been enabled. nothing to do..." | |
exit 0 | |
fi | |
if check_kernel_version; then | |
echo | |
_info "The kernel version is greater than 4.9, directly setting TCP BBR..." | |
sysctl_config | |
_info "Setting TCP BBR completed..." | |
exit 0 | |
fi | |
check_os | |
install_kernel | |
sysctl_config | |
reboot_os | |
} | |
[[ $EUID -ne 0 ]] && _error "This script must be run as root" | |
opsy=$( _os_full ) | |
arch=$( uname -m ) | |
lbit=$( getconf LONG_BIT ) | |
kern=$( uname -r ) | |
clear | |
echo "---------- System Information ----------" | |
echo " OS : $opsy" | |
echo " Arch : $arch ($lbit Bit)" | |
echo " Kernel : $kern" | |
echo "----------------------------------------" | |
echo " Automatically enable TCP BBR script" | |
echo | |
echo " URL: https://teddysun.com/489.html" | |
echo "----------------------------------------" | |
echo | |
echo "Press any key to start...or Press Ctrl+C to cancel" | |
char=$(get_char) | |
install_bbr 2>&1 | tee ${cur_dir}/install_bbr.log |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment