From a3a51074a02c0b8ee90084af038b59a983890f19 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 12 Dec 2022 22:18:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 + database/backup.sh | 53 + database/dbBak.sh | 59 + database/install_db_v3.sh | 116 ++ database/source_mysql.sh | 93 ++ database/yum-mysql.sh | 81 ++ games/bash2048.sh | 365 ++++++ games/jumpserver.sh | 77 ++ games/snake.sh | 215 ++++ games/tetris.sh | 635 +++++++++++ jumpserver/jumpserver1.0/jumpserver.sh | 29 + jumpserver/jumpserver1.0/tools.sh | 50 + jumpserver/jumpserver2.0/jumpserver.sh | 28 + jumpserver/jumpserver2.0/tools.sh | 56 + os-test/dashboard.sh | 21 + os-test/monitor.sh | 73 ++ os-test/mysql.sh | 68 ++ os-test/netflow.sh | 14 + os-test/osinit.sh | 100 ++ os-test/系统初始化实例脚本.sh | 200 ++++ os/get-cmd-history.sh | 30 + os/get-docker-compose.sh | 8 + os/get-docker-image.sh | 35 + os/get-docker-latest.sh | 34 + os/get-k8s-cmd.sh | 8 + os/get-mysql57.sh | 46 + os/get-os-info.sh | 82 ++ os/get-os-init.sh | 106 ++ os/get-py3104.sh | 39 + os/get-redis-instance.sh | 100 ++ os/get-shadowsocks-all.sh | 1400 ++++++++++++++++++++++++ 31 files changed, 4232 insertions(+) create mode 100644 README.md create mode 100644 database/backup.sh create mode 100644 database/dbBak.sh create mode 100644 database/install_db_v3.sh create mode 100644 database/source_mysql.sh create mode 100644 database/yum-mysql.sh create mode 100644 games/bash2048.sh create mode 100644 games/jumpserver.sh create mode 100644 games/snake.sh create mode 100644 games/tetris.sh create mode 100644 jumpserver/jumpserver1.0/jumpserver.sh create mode 100644 jumpserver/jumpserver1.0/tools.sh create mode 100644 jumpserver/jumpserver2.0/jumpserver.sh create mode 100644 jumpserver/jumpserver2.0/tools.sh create mode 100644 os-test/dashboard.sh create mode 100644 os-test/monitor.sh create mode 100644 os-test/mysql.sh create mode 100644 os-test/netflow.sh create mode 100644 os-test/osinit.sh create mode 100644 os-test/系统初始化实例脚本.sh create mode 100644 os/get-cmd-history.sh create mode 100644 os/get-docker-compose.sh create mode 100644 os/get-docker-image.sh create mode 100644 os/get-docker-latest.sh create mode 100644 os/get-k8s-cmd.sh create mode 100644 os/get-mysql57.sh create mode 100644 os/get-os-info.sh create mode 100644 os/get-os-init.sh create mode 100644 os/get-py3104.sh create mode 100644 os/get-redis-instance.sh create mode 100644 os/get-shadowsocks-all.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..474e964 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# 练习测试脚本 +# 教学使用 + +### 使用方法 + +1、复制仓库地址 git@gitee.com:newrain001/shell-project.git + +2、安装git [yum -y install git] + +3、git clone git@gitee.com:newrain001/shell-project.git + diff --git a/database/backup.sh b/database/backup.sh new file mode 100644 index 0000000..00c158c --- /dev/null +++ b/database/backup.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +<> $logPath + +} +other(){ + # $1 incr|diff 备份的类型 + # $2 需要基于的完整路径 + $backCMD --user=$dbUser --password=$dbPasswd --incremental $backDir/$1 --incremental-basedir=$2 + echo "$3 `ls $backDir/$3 |tail -n 1`" >> $logPath +} + +case ${rule[$datetime]} in # ${rule[5]} +0) + full + ;; +1) + type=$(tail -n 1 $logPath|awk '{print $1}') # 获取上一次备份的类型 + time=$(tail -n 1 $logPath|awk '{print $2}') # 获取上一次备份的目录 + other incr $backDir/$type/$time incr + # /backup/full/2022-05-22_00-00-05 + ;; +2) + time=$(grep full $logPath|awk '{print $2}') + other diff $backDir/full/$time diff + ;; +esac diff --git a/database/dbBak.sh b/database/dbBak.sh new file mode 100644 index 0000000..a9b721d --- /dev/null +++ b/database/dbBak.sh @@ -0,0 +1,59 @@ +#!/usr/bin/bash + +DBUSER=root +DBPASSWORD=123 +BACKUPDIR=/dback +HISTLOG=/tmp/history.log +RULE=(0 1 2 1 2 2 2) # 0 full 1 diff 2 incr +DATE=$(date "+%Y-%m-%d_%H-%M-%S") +logdev=local2 + +full="innobackupex --user=$DBUSER --password=$DBPASSWORD $BACKUPDIR" +diff="innobackupex --user=$DBUSER --password=$DBPASSWORD --incremental $BACKUPDIR --incremental-basedir=${BACKUPDIR}/" + +envCheck(){ + mysql -u$DBUSER -p$DBPASSWORD -e "select user()" &>/dev/null + if [ $? -ne 0 ];then + logger -p ${logdev}.error "mysql 连接异常" && exit 2 + fi + if [ ! -e $BACKUPDIR ];then + logger -p ${logdev}.error "备份目录未正常初始化" && \ + mkdir $BACKUPDIR + fi +} + +work(){ + datetime=$[`date "+%u"`-1] + case ${RULE[$datetime]} in + 0) + mv $HISTLOG $BACKUPDIR/ && \ + tar cvzf /tmp/${DATE}.tar.gz $BACKUPDIR && \ + logger -p ${logdev}.info "历史备份文件打包成功 /tmp/${DATE}.tar.gz" && \ + rm -rf $BACKUPDIR $HISTLOG && mkdir $BACKUPDIR || \ + logger -p ${logdev}.warn "历史备份文件打包异常 ${DATE}" + eval $full && \ + echo "full `ls $BACKUPDIR |tail -n1`" >> $HISTLOG && \ + logger -p ${logdev}.info "完整备份完成 `ls $BACKUPDIR |tail -n1`" || \ + logger -p ${logdev}.error "完整备份异常 ${DATE}" + ;; + 1) + BEFOREDIR=$(awk '$1 ~ /full/{print $2}' $HISTLOG) + eval $diff${BEFOREDIR} && \ + echo "diff `ls $BACKUPDIR |tail -n1`" >> $HISTLOG && \ + logger -p ${logdev}.info "差异备份完成 `ls $BACKUPDIR |tail -n1`" || \ + logger -p ${logdev}.error "差异备份异常 ${DATE}" + ;; + 2) + BEFOREDIR=$(tail -n1 $HISTLOG|awk '{print $2}') + eval $diff${BEFOREDIR} && \ + echo "incr `ls $BACKUPDIR |tail -n1`" >> $HISTLOG && \ + logger -p ${logdev}.info "增量备份完成 `ls $BACKUPDIR |tail -n1`" || \ + logger -p ${logdev}.error "增量备份异常 ${DATE}" + ;; + *) + echo "异常操作" + ;; + esac +} +envCheck +work \ No newline at end of file diff --git a/database/install_db_v3.sh b/database/install_db_v3.sh new file mode 100644 index 0000000..93c5a62 --- /dev/null +++ b/database/install_db_v3.sh @@ -0,0 +1,116 @@ +#!/usr/bin/bash +:</dev/null + mkdir -p /usr/local/{mysql,log,tmp} + echo "系统环境初始化完成" + sleep 1 +} + +install_pack(){ + if [ ! -e mysql-boost-5.7.27.tar.gz ];then + wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.27.tar.gz + fi + tar xvzf mysql-boost-5.7.27.tar.gz && \ + cd ./mysql-5.7.27/ + yum -y install ncurses ncurses-devel openssl-devel bison gcc gcc-c++ make cmake && \ + echo "软件包处理完成" + sleep 1 +} + +make_software(){ + cmake . -DWITH_BOOST=boost/boost_1_59_0/ -DCMAKE_INSTALL_PREFIX=$install_path -DSYSCONFDIR=/etc -DMYSQL_DATADIR=$install_path/data -DINSTALL_MANDIR=/usr/share/man -DMYSQL_TCP_PORT=3306 -DMYSQL_UNIX_ADDR=$tmp_path/mysql.sock -DDEFAULT_CHARSET=utf8 -DEXTRA_CHARSETS=all -DDEFAULT_COLLATION=utf8_general_ci -DWITH_READLINE=1 -DWITH_SSL=system -DWITH_EMBEDDED_SERVER=1 -DENABLED_LOCAL_INFILE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 && \ + make -j `cat /proc/cpuinfo |grep process|wc -l` && make install && \ + echo "编译安装完成" + cat > /etc/my.cnf < /etc/profile.d/mysql.sh < ./$packagename + tar xvf $packagename && \ + color green "源码包准备完成" && \ + cd $source_dir/ + cmake . \ + -DWITH_BOOST=boost/boost_1_59_0/ \ + -DCMAKE_INSTALL_PREFIX=$install_dir \ + -DSYSCONFDIR=$config_dir \ + -DMYSQL_DATADIR=$data_dir \ + -DINSTALL_MANDIR=/usr/share/man \ + -DMYSQL_TCP_PORT=$port \ + -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \ + -DDEFAULT_CHARSET=utf8 \ + -DEXTRA_CHARSETS=all \ + -DDEFAULT_COLLATION=utf8_general_ci \ + -DWITH_READLINE=1 \ + -DWITH_SSL=system \ + -DWITH_EMBEDDED_SERVER=1 \ + -DENABLED_LOCAL_INFILE=1 \ + -DWITH_INNOBASE_STORAGE_ENGINE=1 && \ + make -j $cpus && make install && \ + color green "编译安装完成" +} + +down(){ + cat >> /etc/profile.d/source_mysql.sh <<\EOF + PATH=/usr/local/mysql/bin:$PATH + export PATH +EOF + password=$(${install_dir}/bin/mysqld --initialize --user=mysql --basedir=$install_dir --datadir=$data_dir 2>&1 | grep "A temporary password" | awk '{print $NF}') + if [ -n "$password" ];then + color green "初始化完成,初始密码为$password" + color green "通过mysqladmin -p$password password '新密码'进行修改密码" + color green "启动数据库 mysqld_safe &\nmysql 安装完成" + else + color red "初始化异常,请手动检查" + fi + read -p '是否需要清理安装环境[Y|N]: ' ask + if [ "$ask" = 'Y' ];then + rm -rvf $source_dir + rm -rvf $packagename + color green "清理完成" + else + color green "脚本退出" + fi +} + + +main(){ + checkEnv + installPackage + down +} +main +exit 0 diff --git a/database/yum-mysql.sh b/database/yum-mysql.sh new file mode 100644 index 0000000..024efb0 --- /dev/null +++ b/database/yum-mysql.sh @@ -0,0 +1,81 @@ +#!/usr/bin/bash + +default_password="QianFeng@123" +default_bakdir=/var/lib/mysql.bak + +checkos(){ + [[ -d /var/lib/mysql ]] && \ + echo "当前环境已安装mysql" + #exit 1 + ping -W1 -c1 www.baidu.com &>/dev/null || \ + echo "网络异常,请检查" || exit 1 + [[ $UID -ne 0 ]] && echo "请使用root用户执行" && exit 1 +} + +uninstall() { + pkill -9 mysql &>/dev/null + mkdir -p ${default_bakdir}/`date +"%Y-%m-%d"`/$1 &>/dev/null + mv /etc/my.cnf ${default_bakdir}/`date +"%Y-%m-%d"`/$1 &>/dev/null + mv ~/.mysql_history ${default_bakdir}/`date +"%Y-%m-%d"`/$1 &>/dev/null + mv /var/lib/mysql* ${default_bakdir}/`date +"%Y-%m-%d"`/$1 &>/dev/null + yum erase -y `rpm -qa |grep mysql` && \ + rm -rf /var/log/mysqld.log + echo "mysql已卸载,历史数据备份在${default_bakdir}/`date +"%Y-%m-%d"`" +} + +install(){ + yum install -y yum-utils https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm || exit 2 + yum-config-manager --disable mysql{80,55,56,57}-community &>/dev/null + case $1 in + 5.7) + yum-config-manager --enable mysql57-community + ;; + 5.5) + yum-config-manager --enable mysql55-community + ;; + 5.6) + yum-config-manager --enable mysql56-community + ;; + 8.0) + yum-config-manager --enable mysql80-community + ;; + *) + echo "无效版本" + exit 2 + esac + yum install -y mysql-community-server && \ + echo "mysql 安装完成,即将开始启动" +} + +init(){ + systemctl start mysqld && \ + systemctl enable mysqld + password=`grep "temporary password" /var/log/mysqld.log |awk '{password=$NF}END{print password}'` + cat </dev/null # no logging by default + +trap "end_game 0 1" INT #handle INT signal + +#simplified replacement of seq command +function _seq { + local cur=1 + local max + local inc=1 + case $# in + 1) let max=$1;; + 2) let cur=$1 + let max=$2;; + 3) let cur=$1 + let inc=$2 + let max=$3;; + esac + while test $max -ge $cur; do + printf "$cur " + let cur+=inc + done +} + +# print currect status of the game, last added pieces are marked red +function print_board { + clear + printf "$header pieces=$pieces target=$target score=$score\n" + printf "Board status:\n" >&3 + printf "\n" + printf '/------' + for l in $(_seq 1 $index_max); do + printf '+------' + done + printf '\\\n' + for l in $(_seq 0 $index_max); do + printf '|' + for m in $(_seq 0 $index_max); do + if let ${board[l*$board_size+m]}; then + if let '(last_added==(l*board_size+m))|(first_round==(l*board_size+m))'; then + printf '\033[1m\033[31m %4d \033[0m|' ${board[l*$board_size+m]} + else + printf "\033[1m\033[${colors[${board[l*$board_size+m]}]}m %4d\033[0m |" ${board[l*$board_size+m]} + fi + printf " %4d |" ${board[l*$board_size+m]} >&3 + else + printf ' |' + printf ' |' >&3 + fi + done + let l==$index_max || { + printf '\n|------' + for l in $(_seq 1 $index_max); do + printf '+------' + done + printf '|\n' + printf '\n' >&3 + } + done + printf '\n\\------' + for l in $(_seq 1 $index_max); do + printf '+------' + done + printf '/\n' +} + +# Generate new piece on the board +# inputs: +# $board - original state of the game board +# $pieces - original number of pieces +# outputs: +# $board - new state of the game board +# $pieces - new number of pieces +function generate_piece { + while true; do + let pos=RANDOM%fields_total + let board[$pos] || { + let value=RANDOM%10?2:4 + board[$pos]=$value + last_added=$pos + printf "Generated new piece with value $value at position [$pos]\n" >&3 + break; + } + done + let pieces++ +} + +# perform push operation between two pieces +# inputs: +# $1 - push position, for horizontal push this is row, for vertical column +# $2 - recipient piece, this will hold result if moving or joining +# $3 - originator piece, after moving or joining this will be left empty +# $4 - direction of push, can be either "up", "down", "left" or "right" +# $5 - if anything is passed, do not perform the push, only update number +# of valid moves +# $board - original state of the game board +# outputs: +# $change - indicates if the board was changed this round +# $flag_skip - indicates that recipient piece cannot be modified further +# $board - new state of the game board +function push_pieces { + case $4 in + "up") + let "first=$2*$board_size+$1" + let "second=($2+$3)*$board_size+$1" + ;; + "down") + let "first=(index_max-$2)*$board_size+$1" + let "second=(index_max-$2-$3)*$board_size+$1" + ;; + "left") + let "first=$1*$board_size+$2" + let "second=$1*$board_size+($2+$3)" + ;; + "right") + let "first=$1*$board_size+(index_max-$2)" + let "second=$1*$board_size+(index_max-$2-$3)" + ;; + esac + let ${board[$first]} || { + let ${board[$second]} && { + if test -z $5; then + board[$first]=${board[$second]} + let board[$second]=0 + let change=1 + printf "move piece with value ${board[$first]} from [$second] to [$first]\n" >&3 + else + let moves++ + fi + return + } + return + } + let ${board[$second]} && let flag_skip=1 + let "${board[$first]}==${board[second]}" && { + if test -z $5; then + let board[$first]*=2 + let "board[$first]==$target" && end_game 1 + let board[$second]=0 + let pieces-=1 + let change=1 + let score+=${board[$first]} + printf "joined piece from [$second] with [$first], new value=${board[$first]}\n" >&3 + else + let moves++ + fi + } +} + +function apply_push { + printf "\n\ninput: $1 key\n" >&3 + for i in $(_seq 0 $index_max); do + for j in $(_seq 0 $index_max); do + flag_skip=0 + let increment_max=index_max-j + for k in $(_seq 1 $increment_max); do + let flag_skip && break + push_pieces $i $j $k $1 $2 + done + done + done +} + +function check_moves { + let moves=0 + apply_push up fake + apply_push down fake + apply_push left fake + apply_push right fake +} + +function key_react { + let change=0 + read -d '' -sn 1 + test "$REPLY" = "$ESC" && { + read -d '' -sn 1 -t1 + test "$REPLY" = "[" && { + read -d '' -sn 1 -t1 + case $REPLY in + A) apply_push up;; + B) apply_push down;; + C) apply_push right;; + D) apply_push left;; + esac + } + } || { + case $REPLY in + k) apply_push up;; + j) apply_push down;; + l) apply_push right;; + h) apply_push left;; + + w) apply_push up;; + s) apply_push down;; + d) apply_push right;; + a) apply_push left;; + esac + } +} + +function save_game { + rm -rf "$config_dir" + mkdir "$config_dir" + echo "${board[@]}" > "$config_dir/board" + echo "$board_size" > "$config_dir/board_size" + echo "$pieces" > "$config_dir/pieces" + echo "$target" > "$config_dir/target" +# echo "$log_file" > "$config_dir/log_file" + echo "$score" > "$config_dir/score" + echo "$first_round" > "$config_dir/first_round" +} + +function reload_game { + printf "Loading saved game...\n" >&3 + + if test ! -d "$config_dir"; then + return + fi + board=(`cat "$config_dir/board"`) + board_size=(`cat "$config_dir/board_size"`) + board=(`cat "$config_dir/board"`) + pieces=(`cat "$config_dir/pieces"`) + first_round=(`cat "$config_dir/first_round"`) + target=(`cat "$config_dir/target"`) + score=(`cat "$config_dir/score"`) + + fields_total=board_size*board_size + index_max=board_size-1 +} + +function end_game { + # count game duration + end_time=$(date +%s) + let total_time=end_time-start_time + + print_board + printf "Your score: $score\n" + + printf "This game lasted " + + `date --version > /dev/null 2>&1` + if [[ "$?" -eq 0 ]]; then + date -u -d @${total_time} +%T + else + date -u -r ${total_time} +%T + fi + + stty echo + let $1 && { + printf "Congratulations you have achieved $target\n" + exit 0 + } + let test -z $2 && { + read -n1 -p "Do you want to overwrite saved game? [y|N]: " + test "$REPLY" = "Y" || test "$REPLY" = "y" && { + save_game + printf "\nGame saved. Use -r option next to load this game.\n" + exit 0 + } + test "$REPLY" = "" && { + printf "\nGame not saved.\n" + exit 0 + } + } + printf "\nYou have lost, better luck next time.\033[0m\n" + exit 0 +} + +function help { + cat <=3)&(board_size<=9)' || { + printf "Invalid board size, please choose size between 3 and 9\n" + exit -1 + };; + t ) target="$OPTARG" + printf "obase=2;$target\n" | bc | grep -e '^1[^1]*$' + let $? && { + printf "Invalid target, has to be power of two\n" + exit -1 + };; + r ) reload_flag="1";; + h ) help $0 + exit 0;; + l ) exec 3>$OPTARG;; + \?) printf "Invalid option: -"$opt", try $0 -h\n" >&2 + exit 1;; + : ) printf "Option -"$opt" requires an argument, try $0 -h\n" >&2 + exit 1;; + esac +done + +#init board +let fields_total=board_size*board_size +let index_max=board_size-1 +for i in $(_seq 0 $fields_total); do board[$i]="0"; done +let pieces=0 +generate_piece +first_round=$last_added +generate_piece + +#load saved game if flag is set +if test $reload_flag = "1"; then + reload_game +fi + +while true; do + print_board + key_react + let change && generate_piece + first_round=-1 + let pieces==fields_total && { + check_moves + let moves==0 && end_game 0 #lose the game + } +done diff --git a/games/jumpserver.sh b/games/jumpserver.sh new file mode 100644 index 0000000..4fd7285 --- /dev/null +++ b/games/jumpserver.sh @@ -0,0 +1,77 @@ +#!/usr/bin/bash + +echo -e "\033[31m 1. 防火墙 Selinux 设置 \033[0m" \ + && if [ "$(systemctl status firewalld | grep running)" != "" ]; then firewall-cmd --zone=public --add-port=80/tcp --permanent; firewall-cmd --zone=public --add-port=2222/tcp --permanent; firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="172.17.0.0/16" port protocol="tcp" port="8080" accept"; firewall-cmd --reload; fi \ + && if [ "$(getenforce)" != "Disabled" ]; then setsebool -P httpd_can_network_connect 1; fi + + + +echo -e "\033[31m 2. 部署环境 \033[0m" \ + && yum update -y \ + && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && yum -y install kde-l10n-Chinese \ + && localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 \ + && export LC_ALL=zh_CN.UTF-8 \ + && echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf \ + && yum -y install wget gcc epel-release git \ + && yum install -y yum-utils device-mapper-persistent-data lvm2 \ + && yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo \ + && yum makecache fast \ + && rpm --import https://mirrors.aliyun.com/docker-ce/linux/centos/gpg \ + && echo -e "[nginx-stable]\nname=nginx stable repo\nbaseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/\ngpgcheck=1\nenabled=1\ngpgkey=https://nginx.org/keys/nginx_signing.key" > /etc/yum.repos.d/nginx.repo \ + && rpm --import https://nginx.org/keys/nginx_signing.key \ + && yum -y install redis mariadb mariadb-devel mariadb-server mariadb-shared nginx docker-ce \ + && systemctl enable redis mariadb nginx docker \ + && systemctl start redis mariadb \ + && yum -y install python36 python36-devel \ + && python3.6 -m venv /opt/py3 + + + echo -e "\033[31m 3. 下载组件 \033[0m" \ + && cd /opt \ + && if [ ! -d "/opt/jumpserver" ]; then git clone --depth=1 https://github.com/jumpserver/jumpserver.git; fi \ + && if [ ! -f "/opt/luna.tar.gz" ]; then wget https://demo.jumpserver.org/download/luna/1.5.0/luna.tar.gz; tar xf luna.tar.gz; chown -R root:root luna; fi \ + && yum -y install $(cat /opt/jumpserver/requirements/rpm_requirements.txt) \ + && source /opt/py3/bin/activate \ + && pip install --upgrade pip setuptools -i https://mirrors.aliyun.com/pypi/simple/ \ + && pip install -r /opt/jumpserver/requirements/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ \ + && curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io \ + && systemctl restart docker \ + && docker pull jumpserver/jms_koko:1.5.0 \ + && docker pull jumpserver/jms_guacamole:1.5.0 \ + && rm -rf /etc/nginx/conf.d/default.conf \ + && wget -O /etc/nginx/conf.d/jumpserver.conf https://demo.jumpserver.org/download/nginx/conf.d/jumpserver.conf + + +echo -e "\033[31m 4. 处理配置文件 \033[0m" \ + && if [ "$DB_PASSWORD" = "" ]; then DB_PASSWORD=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 24`; fi \ + && if [ "$SECRET_KEY" = "" ]; then SECRET_KEY=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 50`; echo "SECRET_KEY=$SECRET_KEY" >> ~/.bashrc; fi \ + && if [ "$BOOTSTRAP_TOKEN" = "" ]; then BOOTSTRAP_TOKEN=`cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 16`; echo "BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN" >> ~/.bashrc; fi \ + && if [ "$Server_IP" = "" ]; then Server_IP=`ip addr | grep inet | egrep -v '(127.0.0.1|inet6|docker)' | awk '{print $2}' | tr -d "addr:" | head -n 1 | cut -d / -f1`; fi \ + && if [ ! -d "/var/lib/mysql/jumpserver" ]; then mysql -uroot -e "create database jumpserver default charset 'utf8';grant all on jumpserver.* to 'jumpserver'@'127.0.0.1' identified by '$DB_PASSWORD';flush privileges;"; fi \ + && if [ ! -f "/opt/jumpserver/config.yml" ]; then cp /opt/jumpserver/config_example.yml /opt/jumpserver/config.yml; sed -i "s/SECRET_KEY:/SECRET_KEY: $SECRET_KEY/g" /opt/jumpserver/config.yml; sed -i "s/BOOTSTRAP_TOKEN:/BOOTSTRAP_TOKEN: $BOOTSTRAP_TOKEN/g" /opt/jumpserver/config.yml; sed -i "s/# DEBUG: true/DEBUG: false/g" /opt/jumpserver/config.yml; sed -i "s/# LOG_LEVEL: DEBUG/LOG_LEVEL: ERROR/g" /opt/jumpserver/config.yml; sed -i "s/# SESSION_EXPIRE_AT_BROWSER_CLOSE: false/SESSION_EXPIRE_AT_BROWSER_CLOSE: true/g" /opt/jumpserver/config.yml; sed -i "s/DB_PASSWORD: /DB_PASSWORD: $DB_PASSWORD/g" /opt/jumpserver/config.yml; fi + + +echo -e "\033[31m 5. 启动 Jumpserver \033[0m" \ + && systemctl start nginx \ + && cd /opt/jumpserver \ + && ./jms start all -d \ + && docker run --name jms_koko -d -p 2222:2222 -p 5000:5000 -e CORE_HOST=http://$Server_IP:8080 -e BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN -e LOG_LEVEL=ERROR jumpserver/jms_koko:1.5.0 \ + && docker run --name jms_guacamole -d -p 8081:8081 -e JUMPSERVER_SERVER=http://$Server_IP:8080 -e BOOTSTRAP_TOKEN=$BOOTSTRAP_TOKEN jumpserver/jms_guacamole:1.5.0 \ + && echo -e "\033[31m 你的数据库密码是 $DB_PASSWORD \033[0m" \ + && echo -e "\033[31m 你的SECRET_KEY是 $SECRET_KEY \033[0m" \ + && echo -e "\033[31m 你的BOOTSTRAP_TOKEN是 $BOOTSTRAP_TOKEN \033[0m" \ + && echo -e "\033[31m 你的服务器IP是 $Server_IP \033[0m" \ + && echo -e "\033[31m 请打开浏览器访问 http://$Server_IP 用户名:admin 密码:admin \033[0m" + + +echo -e "\033[31m 6. 配置自启 \033[0m" \ + && if [ ! -f "/usr/lib/systemd/system/jms.service" ]; then wget -O /usr/lib/systemd/system/jms.service https://demo.jumpserver.org/download/shell/centos/jms.service; chmod 755 /usr/lib/systemd/system/jms.service; fi \ + && if [ ! -f "/opt/start_jms.sh" ]; then wget -O /opt/start_jms.sh https://demo.jumpserver.org/download/shell/centos/start_jms.sh; fi \ + && if [ ! -f "/opt/stop_jms.sh" ]; then wget -O /opt/stop_jms.sh https://demo.jumpserver.org/download/shell/centos/stop_jms.sh; fi \ + && if [ "$(cat /etc/rc.local | grep start_jms.sh)" == "" ]; then echo "sh /opt/start_jms.sh" >> /etc/rc.local; chmod +x /etc/rc.d/rc.local; fi \ + && echo -e "\033[31m 启动停止的脚本在 /opt 目录下, 如果自启失败可以手动启动 \033[0m" + + + + diff --git a/games/snake.sh b/games/snake.sh new file mode 100644 index 0000000..c13cfdd --- /dev/null +++ b/games/snake.sh @@ -0,0 +1,215 @@ +#!/bin/bash + +# filename: snake.sh +# snake game +# Author: + +good_game=( + ' ' + ' G A M E O V E R ! ' + ' ' + ' Score: ' + ' press q to quit ' + ' press n to start a new game ' + ' press s to change the speed ' + ' ' +); + +game_start=( + ' ' + ' ~~~ S N A K E ~~~ ' + ' ' + ' Author: LKJ ' + ' space or enter pause/play ' + ' q quit at any time ' + ' s change the speed ' + ' ' + ' Press to start the game ' + ' ' +); + +snake_exit() { #退出游戏 + stty echo; #恢复回显 + tput rmcup; #恢复屏幕 + tput cvvis; #恢复光标 + exit 0; +} + +draw_gui() { # 画边框 + clear; + color="\033[34m*\033[0m"; + for (( i = 0; i < $1; i++ )); do + echo -ne "\033[$i;0H${color}"; + echo -ne "\033[$i;$2H${color}"; + done + + for (( i = 0; i <= $2; i++ )); do + echo -ne "\033[0;${i}H${color}"; + echo -ne "\033[$1;${i}H${color}"; + done + + ch_speed 0; + echo -ne "\033[$Lines;$((yscore-10))H\033[36mScores: 0\033[0m"; + echo -en "\033[$Lines;$((Cols-50))H\033[33mPress or enter to pause game\033[0m"; +} + +snake_init() { + Lines=`tput lines`; Cols=`tput cols`; #得到屏幕的长宽 + xline=$((Lines/2)); ycols=4; #开始的位置 + xscore=$Lines; yscore=$((Cols/2)); #打印分数的位置 + xcent=$xline; ycent=$yscore; #中心点位置 + xrand=0; yrand=0; #随机点 + sumscore=0; liveflag=1; #总分和点存在标记 + sumnode=0; foodscore=0; #总共要加长的节点和点的分数 + + snake="0000 "; #初始化贪吃蛇 + pos=(right right right right right); #开始节点的方向 + xpt=($xline $xline $xline $xline $xline); #开始的各个节点的x坐标 + ypt=(5 4 3 2 1); #开始的各个节点的y坐标 + speed=(0.05 0.1 0.15); spk=${spk:-1}; #速度 默认速度 + + draw_gui $((Lines-1)) $Cols +} + +game_pause() { #暂定游戏 + echo -en "\033[$Lines;$((Cols-50))H\033[33mGame paused, Use space or enter key to continue\033[0m"; + while read -n 1 space; do + [[ ${space:-enter} = enter ]] && \ + echo -en "\033[$Lines;$((Cols-50))H\033[33mPress or enter to pause game \033[0m" && return; + [[ ${space:-enter} = q ]] && snake_exit; + done +} + +# $1 节点位置 +update() { #更新各个节点坐标 + case ${pos[$1]} in + right) ((ypt[$1]++));; + left) ((ypt[$1]--));; + down) ((xpt[$1]++));; + up) ((xpt[$1]--));; + esac +} + +ch_speed() { #更新速度 + [[ $# -eq 0 ]] && spk=$(((spk+1)%3)); + case $spk in + 0) temp="Fast ";; + 1) temp="Medium";; + 2) temp="Slow ";; + esac + echo -ne "\033[$Lines;3H\033[33mSpeed: $temp\033[0m"; +} + +Gooooo() { #更新方向 + case ${key:-enter} in + j|J) [[ ${pos[0]} != "up" ]] && pos[0]="down";; + k|K) [[ ${pos[0]} != "down" ]] && pos[0]="up";; + h|H) [[ ${pos[0]} != "right" ]] && pos[0]="left";; + l|L) [[ ${pos[0]} != "left" ]] && pos[0]="right";; + s|S) ch_speed;; + q|Q) snake_exit;; + enter) game_pause;; + esac +} + +add_node() { #增加节点 + snake="0$snake"; + pos=(${pos[0]} ${pos[@]}); + xpt=(${xpt[0]} ${xpt[@]}); + ypt=(${ypt[0]} ${ypt[@]}); + update 0; + + local x=${xpt[0]} y=${ypt[0]} + (( ((x>=$((Lines-1)))) || ((x<=1)) || ((y>=Cols)) || ((y<=1)) )) && return 1; #撞墙 + + for (( i = $((${#snake}-1)); i > 0; i-- )); do + (( ${xpt[0]} == ${xpt[$i]} && ${ypt[0]} == ${ypt[$i]} )) && return 1; #crashed + done + + echo -ne "\033[${xpt[0]};${ypt[0]}H\033[32m${snake[@]:0:1}\033[0m"; + return 0; +} + +mk_random() { #产生随机点和随机数 + xrand=$((RANDOM%(Lines-3)+2)); + yrand=$((RANDOM%(Cols-2)+2)); + foodscore=$((RANDOM%9+1)); + + echo -ne "\033[$xrand;${yrand}H$foodscore"; + liveflag=0; +} + +new_game() { #重新开始新游戏 + snake_init; + while true; do + read -t ${speed[$spk]} -n 1 key; + [[ $? -eq 0 ]] && Gooooo; + + ((liveflag==0)) || mk_random; + if (( sumnode > 0 )); then + ((sumnode--)); + add_node; (($?==0)) || return 1; + else + update 0; + echo -ne "\033[${xpt[0]};${ypt[0]}H\033[32m${snake[@]:0:1}\033[0m"; + + for (( i = $((${#snake}-1)); i > 0; i-- )); do + update $i; + echo -ne "\033[${xpt[$i]};${ypt[$i]}H\033[32m${snake[@]:$i:1}\033[0m"; + + (( ${xpt[0]} == ${xpt[$i]} && ${ypt[0]} == ${ypt[$i]} )) && return 1; #crashed + [[ ${pos[$((i-1))]} = ${pos[$i]} ]] || pos[$i]=${pos[$((i-1))]}; + done + fi + + local x=${xpt[0]} y=${ypt[0]} + (( ((x>=$((Lines-1)))) || ((x<=1)) || ((y>=Cols)) || ((y<=1)) )) && return 1; #撞墙 + + (( x==xrand && y==yrand )) && ((liveflag=1)) && ((sumnode+=foodscore)) && ((sumscore+=foodscore)); + + echo -ne "\033[$xscore;$((yscore-2))H$sumscore"; + done +} + +print_good_game() { + local x=$((xcent-4)) y=$((ycent-25)) + for (( i = 0; i < 8; i++ )); do + echo -ne "\033[$((x+i));${y}H\033[45m${good_game[$i]}\033[0m"; + done + echo -ne "\033[$((x+3));$((ycent+1))H\033[45m${sumscore}\033[0m"; +} + +print_game_start() { + snake_init; + + local x=$((xcent-5)) y=$((ycent-25)) + for (( i = 0; i < 10; i++ )); do + echo -ne "\033[$((x+i));${y}H\033[45m${game_start[$i]}\033[0m"; + done + + while read -n 1 anykey; do + [[ ${anykey:-enter} = enter ]] && break; + [[ ${anykey:-enter} = q ]] && snake_exit; + [[ ${anykey:-enter} = s ]] && ch_speed; + done + + while true; do + new_game; + print_good_game; + while read -n 1 anykey; do + [[ $anykey = n ]] && break; + [[ $anykey = q ]] && snake_exit; + done + done +} + +game_main() { + trap 'snake_exit;' SIGTERM SIGINT; + stty -echo; #取消回显 + tput civis; #隐藏光标 + tput smcup; clear; #保存屏幕并清屏 + + print_game_start; #开始游戏 +} + +game_main; diff --git a/games/tetris.sh b/games/tetris.sh new file mode 100644 index 0000000..e493ff9 --- /dev/null +++ b/games/tetris.sh @@ -0,0 +1,635 @@ +#!/bin/bash +# filename: tetris.sh +# +# Author: +# Date: 2013.5.14 +# Email: +# + +# const value +#======================================固定值================================# +BXLINES=3; BXCOLNS=6; # 小方块的高和宽 +MAPX=20; MAPY=10; +NAME=('I' 'S' 'Z' 'L' 'J' 'T' 'O'); +FLAG=('2' '2' '2' '4' '4' '4' '1'); + +declare -A mapflag mapname; +mapflag=([I]=2 [S]=2 [Z]=2 [L]=4 [J]=4 [T]=4 [O]=1); +mapname=([I]=1 [S]=2 [Z]=3 [L]=4 [J]=5 [T]=6 [O]=7); +colorone=(31 32 33 34 35 36 37); +colortwo=(31 32 33 34 35 36 37); + +Iax=( 0 0 0 0); Iay=(-1 0 1 2); +Ibx=(-1 0 1 2); Iby=( 0 0 0 0); + +Sax=( 1 1 0 0); Say=(-1 0 0 1); +Sbx=(-1 0 0 1); Sby=( 0 0 1 1); + +Zax=( 0 0 1 1); Zay=(-1 0 0 1); +Zbx=(-1 0 0 1); Zby=( 1 1 0 0); + +Lax=(-1 0 1 1); Lay=( 0 0 0 -1); +Lbx=(-1 0 0 0); Lby=(-1 -1 0 1); +Lcx=(-1 -1 0 1);Lcy=( 1 0 0 0); +Ldx=( 0 0 0 1); Ldy=(-1 0 1 1); + +Jax=(-1 0 1 1); Jay=( 0 0 0 1); +Jbx=( 1 0 0 0); Jby=(-1 -1 0 1); +Jcx=(-1 -1 0 1);Jcy=(-1 0 0 0); +Jdx=( 0 0 0 -1);Jdy=(-1 0 1 1); + +Tax=(0 0 0 -1); Tay=(-1 0 1 0); +Tbx=(-1 0 1 0); Tby=( 0 0 0 1); +Tcx=( 0 0 0 1); Tcy=(-1 0 1 0); +Tdx=(-1 0 1 0); Tdy=(0 0 0 -1); + +Oax=( 0 0 1 1); Oay=( 0 1 0 1); + +good_game=( + ' ' + ' G A M E O V E R ! ' + ' ' + ' Score: ' + ' ' + ' press Q to quit ' + ' press N to start a new game ' + ' press S to change the level ' + ' press R to replay your game ' + ' ' +); + +start_game=( + ' ' + ' ~~~ T E T R I S ~~~ ' + ' ' + ' Author: LKJ ' + ' ' + ' press S to change the level ' + ' ' + ' C H O O S E L E V E L: ' + ' 1 ' + ' ' + ' Press to start the game ' + ' ' +); + +blockarr=(); #记录name 和 flag +keyarray=(); #记录按键 +#------------------------------------------------------------------------# + +#========================================================================# +game_init() { # game_init + SCLINES=`tput lines`; # 屏幕的高 + SCCOLNS=`tput cols`; # 屏幕的宽 + +#主框的属性 + mainw=59; mainh=60; # 主框的宽和高 + mainctx=0; maincty=4; # 主框中心打印点 + upx=$((SCLINES-62)); dnx=$((SCLINES-1)); # 界面的上下 x + lty=$((SCCOLNS/2-50)); rty=$((lty+61)); # 界面的左右 y + +#next的属性 + nextw=40; nexth=16; # next框的高和宽 + ntx=$((upx)); nty=$((rty+2)); # next框的位置 + ntctx=$((ntx+5)); ntcty=$((nty+12)); # next框的中心打印位置 + +#score的属性 + scorw=$nextw; scorh=5; + scx=$((ntx+20)); scy=$((nty)); + scctx=$((scx+4)); sccty=$((scy+19)); + +#level的属性 + levew=$nextw; leveh=5; + lvx=$((scx+9)); lvy=$((scy)); + lvctx=$((lvx+4)); lvcty=$((lvy+20)); + +#help的属性 + helpw=$nextw; helph=21; + hpx=$((lvx+10)); hpy=$((nty)); + hpctx=$((hpx+4)); hpcty=$((hpy+10)); + +#map +MAP=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + ); #所有的格子 + +#paint_gui + clear; paint_gui; + + local x=$((RANDOM%7)); + name=${NAME[$((x))]}; + flag=$((RANDOM%FLAG[$x]+1)); + + nname='I'; nflag=2; #下一个方块 + + centerx=$mainctx; #每个图形的中心打印点 + centery=$maincty; + +#各个方块的相对坐标 + ax="Iax"; ay="Iay"; +} +#------------------------------------------------------------------------# + +game_exit() { + tput rmcup; + tput cvvis; + stty echo; + + (($#==1)) && echo "window is too small"; + exit 0; +} + +#============================三个原子函数paint_block, erase_block, paint_box================= +#打印一个小方块, 四个参数, 两个位置和两个颜色 +paint_block() { + local x=$1 y=$2 crone=$3 crtwo=$4 i + + x=$((upx+x*BXLINES+1)); + y=$((lty+y*BXCOLNS+1)); + + echo -ne "\033[$((x));$((y))H\033[${crone}m+---+\033[0m"; + echo -ne "\033[$((x+1));$((y))H\033[${crone}m|\033[${crtwo}m###\033[0m\033[${crone}m|\033[0m"; + echo -ne "\033[$((x+2));$((y))H\033[${crone}m+---+\033[0m"; +} + +#删除一个小方块, 两个参数,即位置 +erase_block() { + local x=$1 y=$2 + + x=$((upx+x*BXLINES+1)); + y=$((lty+y*BXCOLNS+1)); + + echo -ne "\033[$(( x ));$((y))H "; + echo -ne "\033[$((x+1));$((y))H "; + echo -ne "\033[$((x+2));$((y))H "; +} + +#画一个盒子$1 $2 $3 $4 $5 +paint_box() { + local x=$1 y=$2 w=$3 h=$4 color=$5 i + + echo -ne "\033[$x;$((y))H\033[${color}m+\033[0m"; + echo -ne "\033[$x;$((y+w+1))H\033[${color}m+\033[0m"; + for (( i = 1; i <= w; i++ )); do + echo -ne "\033[$x;$((y+i))H\033[${color}m-\033[0m"; + echo -ne "\033[$((x+h+1));$((y+i))H\033[${color}m-\033[0m"; + done + echo -ne "\033[$((x+h+1));$((y))H\033[${color}m+\033[0m"; + echo -ne "\033[$((x+h+1));$((y+w+1))H\033[${color}m+\033[0m"; + + for (( i = 1; i <= h; i++ )); do + echo -ne "\033[$((x+i));$((y))H\033[${color}mI\033[0m"; + echo -ne "\033[$((x+i));$((y+w+1))H\033[${color}mI\033[0m"; + done +} +#--------------------------------------------------------------------------------------- + +#打印界面 +paint_gui() { + ((upx<=0 || lty<=0)) && game_exit 1; + + paint_box $upx $lty $mainw $mainh 34; #画主框 + paint_box $ntx $nty $nextw $nexth 33; #画next框 + paint_box $lvx $lvy $levew $leveh 32; #画level框 + paint_box $scx $scy $scorw $scorh 36; #画分数框 + paint_box $hpx $hpy $helpw $helph 31; #画帮助框 + +#打印score, help 等提示字符 + echo -ne "\033[$((ntx+2));$((nty+17))H\033[34mN E X T\033[0m"; + + echo -ne "\033[$((scx+2));$((scy+16))H\033[31mS C O R E\033[0m"; + echo -ne "\033[$((scx+4));$((scy+20))H\033[31m0\033[0m"; + + echo -ne "\033[$((lvx+2));$((lvy+16))H\033[31mL E V E L\033[0m"; + echo -ne "\033[$((lvctx));$((lvcty))H\033[31m1\033[0m"; + + echo -ne "\033[$((hpx+2));$((hpy+17))H\033[33mH E L P\033[0m"; + echo -ne "\033[$((hpctx));$((hpcty))H\033[34mH --- Move Left\033[0m"; + echo -ne "\033[$((hpctx+2));$((hpcty))H\033[34mL --- Move Right\033[0m"; + echo -ne "\033[$((hpctx+4));$((hpcty))H\033[34mJ --- Soft Drop\033[0m"; + echo -ne "\033[$((hpctx+6));$((hpcty))H\033[34mK --- Rotate\033[0m"; + echo -ne "\033[$((hpctx+8));$((hpcty))H\033[34mSpace or Enter --- Hard Drop\033[0m"; + + echo -ne "\033[$((hpctx+11));$((hpcty))H\033[34mP --- Pause Game\033[0m"; + echo -ne "\033[$((hpctx+13));$((hpcty))H\033[34mQ --- Quit Game\033[0m"; + echo -ne "\033[$((hpctx+15));$((hpcty))H\033[34mE --- Exit Replay\033[0m"; +} + +#--------------------------------------------------------- + +#在next框中打印下一个方块图形 +paint_next() { + (($#==0)) && mk_random; + local oflag=$flag oname=$name + + ((centerx=mainctx+2)); ((centery=maincty+9)); + erase_x; + flag=$nflag; name=$nname; + + paint_x; + flag=$oflag; name=$oname; + centerx=$mainctx; centery=$maincty; +} + +# 打印分数和level +paint_score() { + level=0; + echo -ne "\033[$((scctx));$((sccty))H\033[31m$score\033[0m"; + ((score>2000 )) && ((level=1)); ((score>5000 )) && ((level=2)); + ((score>9000 )) && ((level=3)); ((score>14000)) && ((level=4)); + ((score>20000)) && ((level=5)); ((score>27000)) && ((level=6)); + ((score>35000)) && ((level=7)); ((score>44000)) && ((level=8)); + ((level=olevel+level)); + ((level>9)) && ((level=9)); + + ((TIME=10-level)); + echo -ne "\033[$((lvctx));$((lvcty))H\033[31m$level\033[0m"; +} + +#根据name选择要打印的方块 +paint_x() { + local x=$centerx y=$centery i + local n=$((${mapname[$name]}-1)); + + find_array; + for (( i = 0; i < 4; i++ )); do + paint_block $((x+${ax}[$i])) $((y+${ay}[$i])) ${colorone[$n]} ${colortwo[$n]} + done +} + +#根据name选择要删除的方块 +erase_x() { + local x=$centerx y=$centery i + + find_array; + for (( i = 0; i < 4; i++ )); do + erase_block $((x+${ax}[$i])) $((y+${ay}[$i])); + done +} + +rotate_x() { + ((flag+=1)); + ((flag>mapflag[$name])) && flag=1; +} +#------------------------------------------------------------------------# + +#========================================================================# +update() { #update the map + local x=$1 n=0 i j + for (( i = 0; i < MAPY; i++ )); do + erase_block $x $i; #消掉一行 + MAP[$((x*MAPY+i))]=0; #更新为0 + done + + #将上面的格子向下移动一行 + for (( i = 0; i < MAPY; i++ )); do + for (( j = x; j > 0; j-- )); do + ((n=MAP[$(((j-1)*MAPY+i))])); + if ((n!=0)); then + erase_block $((j-1)) $i; + paint_block $j $i ${colorone[$((n-1))]} ${colortwo[$((n-1))]}; + fi + done + done + + # 更新MAP的值 + for (( i = 0; i < MAPY; i++ )); do + for (( j = x; j >0; j-- )); do + MAP[$((j*MAPY+i))]=$((MAP[$(((j-1)*MAPY+i))])); + done + done +} + +# 检测是否可以消掉一行 +have_score() { + local n=0 i j; + for (( i = 0; i < MAPX; i++ )); do + for (( j = 0; j < MAPY; j++ )); do + ((MAP[$((10*i+j))]==0)) && break; #有空格就退出 + done + ((j==MAPY)) && ((n+=1)) && update $i; #可以消掉一行 + done + + case $n in + 1) ((score+=100)); ;; + 2) ((score+=200)); ;; + 3) ((score+=400)); ;; + 4) ((score+=800)); ;; + esac +} + +#根据flag 和 name找到其的坐标数组 +find_array() { + case $flag in + 1) ax="${name}ax"; ay="${name}ay"; + ;; + 2) ax="${name}bx"; ay="${name}by"; + ;; + 3) ax="${name}cx"; ay="${name}cy"; + ;; + 4) ax="${name}dx"; ay="${name}dy"; + ;; + esac +} + +# 检测方块首次出现时,是否会越界,并作出矫正或者游戏结束 +check_first() { + local x=$centerx y=$centery minx=0 i + + find_array; +# 检测是否越界 + for (( i = 0; i < 4; i++ )); do + (((x+${ax}[$i])19)) && break; #到底 + ((MAP[$((10*(x+1)+y))] != 0)) && break; #有方块挡住 + done + + if ((i!=4)); then #不能在动了,则记录 + for (( i = 0; i < 4; i++ )); do + ((x=(sx+${ax}[$i]))); ((y=(sy+${ay}[$i]))); + n=$((10*x+y)); MAP[$n]=${mapname[$name]}; + done + have_score; + + return 1; + fi + + return 0; +} + +#检测是否可以移到$1 $2这个格子 +check_next() { + local sx=$1 sy=$2 + local x=0 y=0 n=0 i=0 + + find_array; + for (( i = 0; i < 4; i++ )); do + ((x=(sx+${ax}[$i]))); ((y=(sy+${ay}[$i]))); + + ((x<0 || x>19 || y<0 || y>9)) && return 1; + ((MAP[$((10*x+y))] != 0)) && return 1; #不能移到这个格子 + done + + return 0; +} +#------------------------------------------------------------------------# + +#========================================================================# +go_left() { #向左移一个 + check_next $centerx $((centery-1)); + (($?==1)) && return 1; + + erase_x; ((centery-=1)); + return 0; +} + +go_right() { #向右移一格 + check_next $centerx $((centery+1)); + (($?==1)) && return 1; + + erase_x; ((centery+=1)); + return 0; +} + +go_down() { #加速向下 + check_next $((centerx+1)) $centery + (($?==1)) && return 1; + + erase_x; ((centerx+=1)); + return 0; +} + +go_rotate() { #旋转 + local oflag=$flag #保存原来的flag值 + + rotate_x; + check_next $centerx $centery; + (($?==1)) && ((flag=oflag)) && return 1; + + flag=$oflag; + erase_x; rotate_x; + + return 0; +} + +go_fast() { #快速固定 + erase_x; + check_next $((centerx+1)) $centery + local res=$?; + + while ((res==0)); do + ((centerx+=1)); + check_next $((centerx+1)) $centery + res=$?; + done +} + +game_pause() { + echo -ne "\033[$((hpctx+17));$((hpcty+5))H\033[31mGame Paused\033[0m"; + local pkey; + while true; do + read -n 1 pkey; + [[ $pkey = 'q' ]] || [[ $pkey == 'Q' ]] && game_exit; + [[ $pkey = 'p' ]] || [[ $pkey == 'P' ]] && break; + done + echo -ne "\033[$((hpctx+17));$((hpcty+5))H\033[31m \033[0m"; +} + +# 根据按键作出选择 +keypress() { + local result=0; + case ${key:-space} in + H|h) go_left; result=$?; # 向左一个格子 + ;; + J|j) go_down; result=$?; # 向下, 加速向下一个格子 + ;; + K|k) go_rotate; result=$?; # 向上, 旋转90度 + ;; + L|l) go_right; result=$?; # 向右一个格子 + ;; + Q|q) game_exit; # 退出游戏 + ;; + P|p) game_pause; + ;; + space) + go_fast; nextbk=1; + ;; + esac + ((result==0)) && paint_x; +} +#----------------------------------------------------------------# + +#================================================================# +mk_random() { # 产生下一个随机方块 + local x=$((RANDOM%7)) + + nname=${NAME[$x]}; + nflag=$((RANDOM%FLAG[$x]+1)); +} + +#开始一个新游戏 +new_game() { + local i gmover=0 nextbk=0; + + game_init; #初始化游戏 + while true; do + paint_next; #在next框中打印下一个方块 + blockarr+=($name $flag $nname $nflag); + + check_first; (($?==1)) && return; #检查是否游戏结束 + + while true; do + for (( i = 0; i < TIME; i++ )); do + read -n 1 -t 0.1 key; #等待按键 + (($?==0)) && keypress; + (($?==0)) && keyarray+=(${key:-space}); + (($?==0)) || keyarray+=("nothing"); + + ((nextbk==1)) && !((nextbk=0)) && break; + done + + check_stop; (($?==1)) && break; + erase_x; ((centerx+=1)); paint_x; + done + + name=$nname; flag=$nflag; + ((score+=10)); + done +} + +replay() { + score=0; level=$olevel; + local gmover=0 nextbk=0 i=0 j=0; + local blocklen=$((${#blockarr[@]})) keylen=${#keyarray[@]}; + + game_init; + for ((i=0; i>>:" seq + case $seq in + 1|01) + connHost + ;; + 2|02) + addHost + ;; + Q|q) + kill -9 $$ + ;; + *) + : + esac +done + diff --git a/jumpserver/jumpserver1.0/tools.sh b/jumpserver/jumpserver1.0/tools.sh new file mode 100644 index 0000000..a45c86f --- /dev/null +++ b/jumpserver/jumpserver1.0/tools.sh @@ -0,0 +1,50 @@ +defHostfile=/home/jumpserver/.hostfile +defPort=22 +defRSA=/home/jumpserver/.ssh/id_rsa.pub + +stty erase ^H +# 禁止用户使用ctrl+c 等操作 +warn(){ + echo "禁止的操作" +} + +addHost(){ + if [ ! -f $defHostfile ];then + touch $defHostfile + fi + _id=$[$(cat $defHostfile |wc -l) + 1] + read -p "请输入服务器地址:" rhost + read -p "请输入服务器用户:" ruser + read -p "请输入服务器端口:" rport + read -s -p "请输入服务器密码:" rpasswd + echo "" + read -p "请输入服务器用途:" rdesc + sshpass -p "$rpasswd" ssh-copy-id -o StrictHostKeyChecking=no -i $defRSA -p $defPort ${ruser}@${rhost} &>/dev/null || echo "添加服务器异常,请检查密码或联系管理员" && \ + printf "%5s] %-20s %-10s %-5s %-30s\n" "$_id" "$rhost" "$ruser" "$rport" "$rdesc" >> $defHostfile &&\ + echo -e "$rhost 服务器添加成功\n用户:$ruser\n密码:$rpasswd\n注意,密码仅展示一次!" +} + +connHost(){ + printf "%-5s %-20s %-10s %-5s %-30s\n" "id" "host" "user" "port" "desc" + while read line + do + id=$(echo $line | awk '{print $1}') + host=$(echo $line | awk '{print $2}') + user=$(echo $line | awk '{print $3}') + port=$(echo $line | awk '{print $4}') + desc=$(echo $line | awk '{print $5}') + printf "%-5s %-20s %-10s %-5s %-30s\n" "$id" "$host" "$user" "$port" "$desc" + done<$defHostfile + read -p "请输入服务器编号:" num + num=${num:+$num]} + host=$(grep "$num" $defHostfile) + if [ ! -z "$host" ];then + _host=$(echo $host | awk '{print $2}') + _user=$(echo $host | awk '{print $3}') + _port=$(echo $host | awk '{print $4}') + echo "正在连接服务器 ${_user}@${_host}:${_port} ..." + ssh -o StrictHostKeyChecking=no ${_user}@${_host} -p ${_port} + else + echo "服务器不存在" + fi +} \ No newline at end of file diff --git a/jumpserver/jumpserver2.0/jumpserver.sh b/jumpserver/jumpserver2.0/jumpserver.sh new file mode 100644 index 0000000..1577c5f --- /dev/null +++ b/jumpserver/jumpserver2.0/jumpserver.sh @@ -0,0 +1,28 @@ +#!/usr/bin/bash + +trap "echo 禁止操作" INT +source ./tools.sh +while : +do +clear +echo "[客户端地址] `echo $SSH_CLIENT|awk '{print $1}'`" +echo "[当前时间 ] `date +'%Y-%m-%d %H:%M:%S'`" +echo "===============================================" +printf "%-5s %-20s %-50s\n" "seq" "tool" "desc" +printf "%-5s %-20s %-50s\n" "01" "login host" "这是用户信息数据库" +printf "%-5s %-20s %-50s\n" "02" "add host" "管理员添加服务器" +printf "%-5s %-20s %-50s\n" "q" "quit" "退出跳板机" +read -p "请输入需要执行的序号:" n +case $n in +01|1) + login_host + sleep 10 + ;; +02|2) + add_host + ;; +q|Q) + echo "退出登陆" + exit 0 +esac +done \ No newline at end of file diff --git a/jumpserver/jumpserver2.0/tools.sh b/jumpserver/jumpserver2.0/tools.sh new file mode 100644 index 0000000..1316681 --- /dev/null +++ b/jumpserver/jumpserver2.0/tools.sh @@ -0,0 +1,56 @@ +#!/usr/bin/bash + +DBfile=/home/jumpserver/.userdb +[[ ! -f $DBfile ]] && touch $DBfile +# vim /etc/rsyslog.conf local2.* /home/jumpserver/.login +LOGfile=/home/jumpserver/.login +LOGdev=local2 +defRSA=/home/jumpserver/.ssh/id_rsa.pub +defPort=22 + +shaHash(){ + echo -n "$1" |sha256sum |awk '{print $1}' +} +add_host(){ + read -p "请输入新增ip地址:" nhost + read -p "请输入新增ip用途:" nfunc + read -p "请输入新增ip用户:" nuser + read -p "请输入新增ip描述:" ndesc + read -p "请输入新增ip密码:" npass + if [[ -z $nhost || -z $nfunc || -z $nuser || -z $npass ]];then + echo "输入信息无效" + sleep 1 + return 1 + fi + nseq=$[$(cat $DBfile |wc -l) + 1] + sha_pass=`shaHash $npass` + sshpass -p "$npass" ssh-copy-id -o StrictHostKeyChecking=no -i $defRSA -p $defPort ${nuser}@${nhost} &>/dev/null && \ + echo "$nseq] $nhost $nuser $nfunc $sha_pass $ndesc" >> $DBfile && \ + echo "服务器 $nfunc 已添加" && \ + logger -p ${LOGdev}.info "$nseq $nuser $nhost $nfunc 服务器添加" || \ + echo "添加服务器异常,请联系管理员" + sleep 2 +} + +login_host(){ + printf "%-10s %-20s %-10s %-10s %-50s\n" "host" "ip" "user" "func" "desc" + while read line + do + printf "%-10s %-20s %-10s %-10s %-50s\n" `echo $line |awk '{print $1,$2,$3,$4,$6}'` + done <$DBfile + read -p "请输入服务器序号:" host + if [ ! -z $host ];then + host=${host:+$host]} + else + echo "输入序号无效" + return 2 + fi + data=`grep "$host" $DBfile` + if [ -z "$data" ] ;then + echo "未找到服务器" + return 3 + fi + fip=`echo $data | awk '{print $2}'` + fuser=`echo $data | awk '{print $3}'` + ssh $fuser@$fip +} diff --git a/os-test/dashboard.sh b/os-test/dashboard.sh new file mode 100644 index 0000000..f2a31b0 --- /dev/null +++ b/os-test/dashboard.sh @@ -0,0 +1,21 @@ +#!/usr/bin/bash + +printf "%-10s\t%-30s\t%-100s\n" 序号 功能 描述 +printf "%-10s\t%-30s\t%-100s\n" "01" yum安装mysql 通过yum安装mysql数据库,支持5.5-8.0安装,处理了旧数据 +printf "%-10s\t%-30s\t%-100s\n" "02" "系统初始化" "新系统初始化,安装了常用软件,进行了部分系统优化,检查相关信息,并修改静态ip地址" +printf "%-10s\t%-30s\t%-100s\n" "q" "退出脚本" +echo "" +read -p "请输入功能序号:" num +case $num in +01|1) + source ./mysql.sh + ;; +02|2) + source ./osinit.sh + ;; +q|Q|quit) + : + ;; +*) + echo "该功能暂未添加,敬请期待" +esac diff --git a/os-test/monitor.sh b/os-test/monitor.sh new file mode 100644 index 0000000..d0e22fc --- /dev/null +++ b/os-test/monitor.sh @@ -0,0 +1,73 @@ +#!/usr/bin/bash + +# 定义解释型的信息 +# Author: SZ2201班全体同仁,联系 newrain_wang@163.com +# 监控报警脚本 +# 做mysql、nginx服务存活性检测、重要配置文件防篡改。 + +# mysql 主机 password,在生产中的脚本要写普通用户 +mysqlPassword="QianFeng@123" +mysqlUser="root" +# 监控间隔 +checkInterval=30 +# 配置文件列表 +configFile=("/etc/passwd" "/etc/sudoers" "/etc/hosts" "/etc/resolv.conf" "/etc/sysctl.conf") +hashFile=/tmp/.hashfile +# nginx 检查URL +nginxPath="/index.html" + +# 出现异常,发送邮件通知 +# 安装软件mailx +# 下列内容填写到 /etc/mail.rc +</dev/null + if [ $? -ne 0 ];then + mysql_error="mysql异常\n" + fi + + # 检查nginx是否存活,通过访问nginx的服务来判断是否正常工作 + code=$(curl -I -s http://127.0.0.1${nginxPath} |grep "HTTP/1.1" |awk '{print $2}') +< ${hashFile} + exit 0 + fi + + md5sum -c ${hashFile} 2>/dev/null |grep "FAILED" &>/dev/null + if [ $? -eq 0 ];then + checkFile_error="文件被篡改,请检查\n" + fi + # 如果错误信息变量被赋值至少一个,则邮件通知管理员进行处理。 + if [ -n "$mysql_error" ] || [ -n "$nginx_error" ] || [ -n "$checkFile_error" ];then + echo ${mysql_error}${nginx_error}${checkFile_error} + echo -e "[`date +%F_%T`] 错误:\n${mysql_error}${nginx_error}${checkFile_error}" | mailx -s "报警通知" 1161733918@qq.com + fi + sleep ${checkInterval} +done + diff --git a/os-test/mysql.sh b/os-test/mysql.sh new file mode 100644 index 0000000..8d46b2c --- /dev/null +++ b/os-test/mysql.sh @@ -0,0 +1,68 @@ +#!/usr/bin/bash + +source ./color.sh + +# 检查执行用户 +if [ $UID -ne 0 ];then + red "请使用过ROOT用户执行脚本" + exit 1 +fi + +# mysql 安装检查 +[[ -f /etc/my.cnf ]] || [[ -d /var/lib/mysql ]] || [[ -f /usr/bin/mysql ]] && \ +yellow "经检查发现,当前系统曾安装过mysql数据库,是否进行备份后卸载操作[Y|N]" +read modify +modify=${modify:="N"} +if [ $modify = 'Y' ];then + systemctl stop mysqld mariadb &>/dev/null + yum remove `rpm -qa |grep mysql` + yum remove `rpm -qa |grep maraidb` + mkdir -p /db-save/{conf,log,data} + mv /etc/my.cnf /db-save/conf + mv /var/log/mysql* /db-save/log + mv /var/log/mariadb* /db-save/log + mv /var/lib/mysql/* /db-save/data + userdel -r -f mysql + yellow "我们为您将数据备份到了/db-save目录下" +else + green "为了您的数据安全,我们并未进行任何操作" + exit 0 +fi + +# 网络检查 +ping -w1 -c1 www.baidu.com &>/dev/null +if [ $? -ne 0 ] ;then + red "网络异常" + exit 2 +fi + +# yum源检查 +cd /etc/yum.repos.d/ && \ +rename .repo .repo.bak *.repo +curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo +yum install -y epel-release yum-utils && \ +green "yum源成功安装" + + +green "开始安装mysql yum源" +yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm +green "请输入安装的版本[80|57|56|55](default:57):" +read level +green "请输入初始密码:" +read -s passwd +level=${level:=57} +case $level in +80) + yum -y install mysql-community-server + ;; +*) + yum-config-manager --disable mysql80-community + yum-config-manager --enable mysql${level}-community + yum -y install mysql-community-server + ;; +esac + +systemctl enable mysqld && systemctl start mysqld && green "mysql安装完成并且成功启动" || red "mysql 安装失败请检查" +yellow "mysql 5.6及以下版本没有初始密码" +[[ -f /var/log/mysqld.log ]] && mysql_passwd=$(grep password /var/log/mysqld.log| awk '{print $NF}') || red "数据库日志异常,请手动更新初始密码" +[[ ! -z mysql_passwd ]] && mysqladmin -p"$mysql_passwd" password "$passwd" && green "密码修改成功:原密码:$mysql_passwd 新密码: $passwd" || red "密码修改出错,请手动修改" diff --git a/os-test/netflow.sh b/os-test/netflow.sh new file mode 100644 index 0000000..e49a85f --- /dev/null +++ b/os-test/netflow.sh @@ -0,0 +1,14 @@ +#!/usr/bin/bash +</proc/sys/vm/drop_caches +green "当前内存 $(free |awk 'NR==2{print $4/1024}')M" +green "当前核心 $(grep -E '^processor' /proc/cpuinfo|wc -l)个" +green "核心品牌 $(grep -E '^model name' /proc/cpuinfo |head -n 1 |awk -F: '{print $2}')" +green "启动时长 $(uptime |awk -F',' '{print $1}')" + + +# 网络检测 +ping -w1 -c1 www.baidu.com &>/dev/null +if [ $? -eq 0 ];then + green "网络正常" +else + red "网络异常" + exit 1 +fi + +# yum源检查 +cd /etc/yum.repos.d/ && \ +rename .repo .repo.bak *.repo +curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo +yum install -y epel-release yum-utils && \ +green "yum源初始化安装" + +green "开始安装常用软件" +green "即将为您安装 vim wget unzip lrzsz net-tools yum-utils ntpdate htop psacct 这些软件,如果有其他需要,请手动输入,您有10秒的时间" +read -t 10 -p ">>>:" package +package=${package:=";"} +yum install -y vim wget unzip lrzsz net-tools yum-utils ntpdate psacct $package +if [ $? -eq 0 ];then + green "常用软件安装成功" +else + yellow "部分安装可能出现异常" +fi + +green "开始进行系统优化" +systemctl stop firewalld && systemctl disable firewalld +systemctl stop postfix && systemctl disable postfix +sed -i 's/^SELINUX.*/SELINUX=disabled/' /etc/selinux/config +setenforce 0 2>/dev/null + +green "修改文件打开数、进程打开数" +cat >>/etc/security/limits.conf <> /etc/sysctl.conf +sed -i 's/#UseDNS.*/UseDNS no/' /etc/ssh/sshd_config + + +green "开始进行静态ip修改" +ipaddr=$(ip a |grep ${interface} |grep inet|awk '{print $2}'|awk -F'/' '{print $1}') +netmask=$(ip a |grep ${interface} |grep inet|awk '{print $2}'|awk -F'/' '{print $2}') +cat >/etc/sysconfig/network-scripts/ifcfg-${interface} </dev/null && green "网络配置成功" || red "网络连接异常" +else + red "网卡配置异常" +fi + +green "开始进行主机名配置" +hostname=${hostname:='osinit'} +hostnamectl set-hostname $hostname + +green "系统初始化完成,即将重启,配置生效,是否现在重启[Y|N]" +read -t 5 result +result=${result:='N'} +if [ $result == 'Y' ];then + reboot +else + yellow "配置需要重启后生效" +fi diff --git a/os-test/系统初始化实例脚本.sh b/os-test/系统初始化实例脚本.sh new file mode 100644 index 0000000..48c9740 --- /dev/null +++ b/os-test/系统初始化实例脚本.sh @@ -0,0 +1,200 @@ +#!/usr/bin/bash + +# < /dev/null 2>&1 + if [ $? -ne 0 ];then + colorTools ERROR "网络连接失败" + exit 1 + else + colorTools SUCCESS "网络检测成功" + fi + # 执行用户检测 + colorTools INFO "开始用户检测" + if [ $UID -ne 0 ];then + colorTools ERROR "请使用root用户执行此脚本" + exit 1 + else + colorTools SUCCESS "用户检测完成,当前用户为root" + fi + # 执行系统检测 + colorTools INFO "开始系统检测" + if [ -f /etc/redhat-release ];then + colorTools SUCCESS "系统检测完成,当前系统为CentOS/RedHat" + else + colorTools ERROR "系统检测失败,仅支持CentOS/RedHat" + exit 1 + fi +} + +# 网络配置 +function networkConfigure(){ + systemctl stop NetworkManager &>/dev/null + systemctl disable NetworkManager &>/dev/null + systemctl enable network &>/dev/null + for i in ${netInterface};do + colorTools INFO "开始网络配置,网卡名称 $i" + address=$(ip a show dev $i | grep -oP "[1-9][\d]{1,2}(\.\d{1,3}){3}/(\d+)") + ipaddr=$(echo $address | awk -F'/' '{print $1}') + netmask=$(echo $address | awk -F'/' '{print $2}') + gateway=$(ip r show dev $i | grep -oP "default via \K[1-9][\d]{1,2}(\.\d{1,3}){3}") + cat > /etc/sysconfig/network-scripts/ifcfg-$i </dev/null + set -e + if [ $localYum -eq 1 ];then + curl -s download.beyourself.org.cn/yum.sh | bash + colorTools SUCCESS "配置本地源完成,请在/etc/hosts文件中修改本地源ip地址解析" + elif [ $localYum -eq 0 ];then + curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo + curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo + fi + set +e + colorTools SUCCESS "yum 源配置完成" +} + +# 系统常规配置 +function other(){ + colorTools INFO "开始常规配置" + colorTools INFO "开始防火墙配置" + systemctl stop firewalld && \ + systemctl disable firewalld + colorTools INFO "开始selinux配置" + sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config && \ + setenforce 0 + colorTools INFO "开始安装常用软件 ${yumList}" + yum install -y ${yumList} + colorTools INFO "开始主机名配置 ${HOSTNAME}" + hostnamectl set-hostname $HOSTNAME + colorTools INFO "开始时区配置并进行时间校准" + timedatectl set-timezone Asia/Shanghai && \ + ntpdate ntp.aliyun.com + colorTools SUCCESS "常规配置完成" +} + +# 系统参数优化 +function optimized(){ + colorTools INFO "开始优化系统" + colorTools INFO "开始优化内核参数" + cat > /etc/sysctl.conf < /etc/security/limits.conf </dev/null| awk '{print $NF}'|sed -e 's/[()]//g'` +USER_IP=$(env |grep SSH_CLIENT | awk '{print $1}' | sed 's/SSH_CLIENT=//' | awk -F " " '{print $1}') +# 指定历史命令路径 +HISTDIR=/usr/share/.history +if [ -z $USER_IP ] +then +USER_IP=`hostname` +fi +if [ ! -d $HISTDIR ] +then +mkdir -p $HISTDIR +chmod 777 $HISTDIR +fi +if [ ! -d $HISTDIR/${LOGNAME} ] +then +mkdir -p $HISTDIR/${LOGNAME} +chmod 300 $HISTDIR/${LOGNAME} +fi +# 设置历史命令条数 +export HISTSIZE=4000 +# 设置文件后缀 +DT=`date +%Y%m%d_%H%M%S` +export HISTFILE="$HISTDIR/${LOGNAME}/${USER_IP}.history.$DT" #文件路径 +export HISTTIMEFORMAT="[%Y.%m.%d %H:%M:%S] " #记录格式 +# 设置权限 +chmod 600 $HISTDIR/${LOGNAME}/*.history* 2>/dev/null diff --git a/os/get-docker-compose.sh b/os/get-docker-compose.sh new file mode 100644 index 0000000..7ccbe4c --- /dev/null +++ b/os/get-docker-compose.sh @@ -0,0 +1,8 @@ +#!/usr/bin/bash +echo "版本信息可查看 https://dn-dao-github-mirror.daocloud.io/docker/compose/releases/" +LEVEL=${DOCKER_COMPOSE_LEVEL:-1.20.1} +curl -L https://get.daocloud.io/docker/compose/releases/download/${LEVEL}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod a+x /usr/local/bin/docker-compose + +if [ -z $DOCKER_COMPOSE_LEVEL ];then + echo "采用默认版本1.20.1,如需要指定版本,可以在终端执行 export DOCKER_COMPOSE_LEVEL=版本" +fi \ No newline at end of file diff --git a/os/get-docker-image.sh b/os/get-docker-image.sh new file mode 100644 index 0000000..3669da3 --- /dev/null +++ b/os/get-docker-image.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +TAG_PREFIX= + +save(){ + if [ ! -d "./images" ]; then + mkdir images + fi + cd images + docker images --format "{{.ID}} {{.Repository}}:{{.Tag}} {{.Size}}" |grep $TAG_PREFIX > images_pull.txt + while read line + do + image_id=`echo $line | awk '{print $1}'` + image_repository=`echo $line | awk '{print $2}'` + image_size=`echo $line | awk '{print $3}'` + docker save -o $image_id.tar $image_repository && \ + echo "Image $image_repository saved, size $image_size" + done < images_pull.txt +} + +load(){ + cd images + while read line + do + image_id=`echo $line | awk '{print $1}'` + image_repository=`echo $line | awk '{print $2}'` + docker load -i $image_id.tar && \ + echo "Image $image_repository loaded" + done < images_pull.txt +} +if [ -z "$1" ]; then + echo "Usage: image_operation.sh [save|load]" +fi + +eval $1 diff --git a/os/get-docker-latest.sh b/os/get-docker-latest.sh new file mode 100644 index 0000000..1e1e2df --- /dev/null +++ b/os/get-docker-latest.sh @@ -0,0 +1,34 @@ +#!/usr/bin/bash + +set -e +unset c +color(){ + declare -A c=([Error]=31 [Success]=32 [Warning]=33 [Info]=34) + #echo -e "\033[${c[$1]}m[`date +%T`]($1) $2\033[0m" + printf "\033[${c[$1]}m%-10s%-10s %-30s\033[0m\n" "[`date +%T`]" "($1)" "$2" + sleep 0.5 +} + +install(){ + color Info "开始安装docker服务" + yum install -y yum-utils device-mapper-persistent-data lvm2 git && \ + yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo && \ + yum install -y docker-ce + mkdir -p /etc/docker + color Success "安装完成" + color Info "开始配置镜像加速器" + tee /etc/docker/daemon.json <<-'EOF' +{ + "registry-mirrors": ["https://pilvpemn.mirror.aliyuncs.com"] +} +EOF + cat >> /etc/sysctl.conf <> ~/.bashrc diff --git a/os/get-mysql57.sh b/os/get-mysql57.sh new file mode 100644 index 0000000..f34d7dd --- /dev/null +++ b/os/get-mysql57.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# by newrain +# time 2019-11-28 +# lv 2.0 +level=5.7 +password="QianFeng@123" +remote_user="remote" +remote_passwd="QianFeng@123" +unset c +color(){ + declare -A c=([Error]=31 [Success]=32 [Warning]=33 [Info]=34) + #echo -e "\033[${c[$1]}m[`date +%T`]($1) $2\033[0m" + printf "\033[${c[$1]}m%-10s%-10s %-30s\033[0m\n" "[`date +%T`]" "($1)" "$2" + sleep 0.5 +} + +color Info "此脚本用于yum 安装mysql" +color Warning "此脚本将删除所有mysql数据,如需备份请ctrl+c终止脚本,程序将在3秒后执行" +sleep 3 +if [[ $UID -ne 0 ]];then + color Warning "使用root 执行此脚本" + exit 1 +fi + +color Warning "清理环境" +systemctl stop mysqld mariadb &>/dev/null +yum erase -y `rpm -qa |grep mariadb` 2>/dev/null +yum erase -y `rpm -qa |grep mysql` 2>/dev/null +rm -rvf /etc/my.cnf /var/lib/mysql /var/log/mysql* +userdel -rf mysql &>/dev/null +ping -c1 -w1 www.baidu.com &>/dev/null +if [[ $? -eq 0 ]];then + if [ ! -f /tmp/.init ];then + yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm + fi +else + color Error "网络错误" + exit 22 +fi +yum -y install mysql-community-server mysql-community-devel --disablerepo mysql80 --enablerepo mysql57 --nogpgcheck +systemctl start mysqld +color Warning "启动成功,初始密码如下(mysql5.7前版本没有初始密码)" +passwd=$(grep -o 'root@localhost.*' /var/log/mysqld.log | awk 'END{print $NF}') +mysqladmin -uroot -p$passwd password $password && \ +mysql -uroot -p$password -e "grant all on *.* to \"$remote_user\"@'%' identified by \"$remote_passwd\"; flush privileges;" +color Success "安装完成 初始密码为$password" diff --git a/os/get-os-info.sh b/os/get-os-info.sh new file mode 100644 index 0000000..6339813 --- /dev/null +++ b/os/get-os-info.sh @@ -0,0 +1,82 @@ +#!/usr/bin/bash + +unset c +color(){ + declare -A c=([Error]=31 [Success]=32 [Warning]=33 [Info]=34) + #echo -e "\033[${c[$1]}m[`date +%T`]($1) $2\033[0m" + printf "\033[${c[$1]}m%-10s%-10s %-30s\033[0m\n" "[`date +%T`]" "($1)" "$2" + sleep 0.5 +} +cpu(){ + cpus=$(grep processor /proc/cpuinfo |wc -l) + cpuModel=$(grep "model name" /proc/cpuinfo | uniq | awk -F ':' '{print $2}') + cpuCache=$(grep "cache size" /proc/cpuinfo | uniq | awk -F ':' '{print $2}') + printf "%-10s\t%-50s\n" "[CPU]" "[Info]" + printf "%-10s\t%-50s\n" "cpu核心:" "${cpus/ /}核" + printf "%-10s\t%-50s\n" "cpu型号:" "${cpuModel/ /}" + printf "%-10s\t%-50s\n" "cpu缓存:" "${cpuCache/ /}" +} +memory(){ + memTotal=$(awk -F':' '/MemTotal:/{print $2}' /proc/meminfo | awk '{print $1,$2}') + memFree=$(awk -F':' '/MemFree:/{print $2}' /proc/meminfo | awk '{print $1,$2}') + memBuffer=$(awk -F':' '/Buffers:/{print $2}' /proc/meminfo | awk '{print $1,$2}') + memCached=$(awk -F':' '/^Cached:/{print $2}' /proc/meminfo | awk '{print $1,$2}') + swapTotal=$(awk -F':' '/SwapTotal:/{print $2}' /proc/meminfo | awk '{print $1,$2}') + swapFree=$(awk -F':' '/SwapFree:/{print $2}' /proc/meminfo | awk '{print $1,$2}') + memDevice=$(dmidecode |grep -P -A 5 "Memory Device"|grep Size|grep -v 'Range' | wc -l) + maxMem=$(dmidecode |grep "Maximum Capacity" | awk '{print $3,$4}') + maxHz=$(dmidecode |grep "Max Speed" |uniq | awk '{print $3,$4}') + printf "%-10s\t%-50s\n" "[Memory]" "[Info]" + printf "%-10s\t%-50s\n" "内存总量:" "$memTotal" + printf "%-10s\t%-50s\n" "内存剩余:" "$memFree" + printf "%-10s\t%-50s\n" "内存写缓:" "$memBuffer" + printf "%-10s\t%-50s\n" "内存读缓:" "$memCached" + printf "%-10s\t%-50s\n" "临时缓存总量:" "$swapTotal" + printf "%-10s\t%-50s\n" "临时缓存剩余:" "$swapFree" + printf "%-10s\t%-50s\n" "内存条数:" "$memDevice" + printf "%-10s\t%-50s\n" "最大支持内存:" "$maxMem" + printf "%-10s\t%-50s\n" "内存频率:" "$maxHz" +} +disk(){ + printf "%-10s\t%-15s\t%-30s\t%-5s\n" "[MountPoint]" "[Used]" "[FileSystem]" "[Size]" + df -Th | awk 'BEGIN{ORS="\n"}$2 ~ /(ext|xfs)/{printf "%-10s\t%-15s\t%-30s\t%-5s\n",$NF,$(NF-1),$1,$3}' +} + +os(){ + os_release=$(hostnamectl | awk -F': ' '/Operating System/{print $2}') + os_kernel=$(hostnamectl | awk -F': ' '/Kernel/{print $2}') + hostname=$(hostnamectl | awk -F': ' '/Static hostname/{print $2}') + printf "%-10s\t%-20s\n" "[Info]" "[Value]" + printf "%-20s\t%-20s\n" "系统版本:" "$os_release" + printf "%-20s\t%-20s\n" "内核版本:" "$os_kernel" + printf "%-20s\t%-20s\n" "主机名称:" "$hostname" + netIf=$(ip -f inet a | awk '/^[0-9]/{print $0}' |awk -F':' '{print $2}') + netIfs=$(echo netIf |wc -w) + printf "%-20s\t%-20s\t%-18s\n" "[InterFace]" "[IpAddress]" "[MacAddress]" + for i in $netIf + do + # 网卡ip + iname=$(ip -f inet a show dev $i | awk '/inet/{print $2}') + # 网卡mac + mname=$(ip -f link a show dev $i |awk '/link/{print $2}') + printf "%-20s\t%-20s\t%-18s\n" "$i" "$iname" "$mname" + done +} + +color Info "开始读取本地信息" + +main(){ + color Success "中央处理器信息" + # cpu 信息查询函数 + cpu + color Success "内存信息" + # 内存 信息查询函数 + memory + color Success "网络信息" + os + # 磁盘信息 + color Success "磁盘信息" + disk +} + +main \ No newline at end of file diff --git a/os/get-os-init.sh b/os/get-os-init.sh new file mode 100644 index 0000000..51153a0 --- /dev/null +++ b/os/get-os-init.sh @@ -0,0 +1,106 @@ +#!/usr/bin/bash + +color(){ + unset c + declare -A c=([Error]=31 [Success]=32 [Warning]=33 [Info]=34) + #echo -e "\033[${c[$1]}m[`date +%T`]($1) $2\033[0m" + printf "\033[${c[$1]}m%-10s%-10s %-30s\033[0m\n" "[`date +%T`]" "($1)" "$2" + sleep 0.5 +} + +static_addr(){ +ifname=$(ip -f inet a | awk '/^2/{print $2}') +ifname=$(echo ${ifname/:/}) +ipaddr=$(ip -f inet a show dev $ifname | awk '/inet/{print $2}' | awk -F'/' '{print $1}') +prefix=$(ip -f inet a show dev $ifname | awk '/inet/{print $2}' | awk -F'/' '{print $2}') +gateway=$(ip r |awk '/default/{print $3}') +cat > /etc/sysconfig/network-scripts/ifcfg-$ifname </dev/null && \ +return 10 || \ +return 20 +} + +local_yum_make(){ + cd /etc/yum.repos.d/ && \ + rename .repo .repo.bak *.repo &>/dev/null + grep '10.8.161.40 package.qf.com' /etc/hosts &>/dev/null + if [ $? -ne 0 ];then + cat >> /etc/hosts </dev/null + curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo + curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo + yum repolist && yum clean all && yum makecache && \ + color Success "阿里源配置完成" || color Error "yum配置错误,可以\ncd /etc/yum.repos.d/ && rm -rf centos7.repo && rename .repo.bak .repo *.repo.bak \n使用手动恢复历史yum" +} + +init(){ + color Success "开始配置静态ip" + static_addr + if [ $? -eq 10 ];then + color Success "静态ip配置并检测完成" + else + color Error "静态ip配置异常" + fi + color Info "正在关闭防火墙、selinux" + color Warning "注意,这将降低服务器安全性" + systemctl disable firewalld postfix --now && \ + setenforce 0 ; sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config && \ + color Success "配置完成" || color Error "配置异常,请检查" + color Info "配置yum源, 此操作将备份您的历史源" + ping -w 1 -c 1 10.8.161.40 &>/dev/null + if [ $? -eq 0 ];then + local_yum_make + else + remote_yum_make + fi + color Info "开始安装常用软件" + yum install -y wget unzip vim yum-utils httpd-tools psacct net-tools nc ntpdate jq htop && \ + color Success "安装完成" || color Warning "部分包可能失败" + color Info "开始进行时间校准" + ntpdate ntp.aliyun.com && \ + # 修改时间到硬件 + clock -w + #保存时间到硬件 + hwclock -s + color Success "时间校准完成" + # color Info "修改终端前缀显示" + # cat > /etc/profile.d/psdiy.sh < /tmp/.init +} +if [ -f /tmp/.init ];then + color Success "检测到此前已进行初始化,如需重新执行,请删除: rm -f /tmp/.init" + exit 0 +fi +init +color Success "初始化完成" diff --git a/os/get-py3104.sh b/os/get-py3104.sh new file mode 100644 index 0000000..dee8f79 --- /dev/null +++ b/os/get-py3104.sh @@ -0,0 +1,39 @@ +#!/usr/bin/bash + +path=/opt/py3104 +unset c +color(){ + declare -A c=([Error]=31 [Success]=32 [Warning]=33 [Info]=34) + #echo -e "\033[${c[$1]}m[`date +%T`]($1) $2\033[0m" + printf "\033[${c[$1]}m%-10s%-10s %-30s\033[0m\n" "[`date +%T`]" "($1)" "$2" + sleep 0.5 +} + +mkdir -pv $path +cd $path && \ +yum -y install gcc gcc-c++ zlib-devel bzip2-devel sqlite-devel readline-devel libffi-devel && \ +color Info "openssl 包下载,请稍等..." && \ +wget http://download.beyourself.org.cn/package/openssl-1.1.1n.tar.gz && \ +tar xf openssl-1.1.1n.tar.gz && \ +cd openssl-1.1.1n && \ +./config --prefix=/usr/local/openssl && \ +make -j $(cat /proc/cpuinfo | grep processor |wc -l) && make install && cd .. && \ +wget http://download.beyourself.org.cn/package/Python-3.10.4.tar.xz && \ +tar xf Python-3.10.4.tar.xz && \ +cd Python-3.10.4 && \ +./configure --enable-shared --prefix=/usr/local/python3.10.4 --with-openssl=/usr/local/openssl --with-openssl-rpath=auto && \ +make -j $(cat /proc/cpuinfo | grep processor |wc -l) && \ +make install && \ +echo "/usr/local/python3.10.4/lib" >> /etc/ld.so.conf && \ +ldconfig && \ +echo "export PATH=/usr/local/python3.10.4/bin:\$PATH" >> /etc/profile && \ +color Success "python安装完成" + +color Info "配置pip加速" +mkdir ~/.pip &>/dev/null +tee ~/.pip/pip.conf < +# +# System Required: CentOS 6+, Debian7+, Ubuntu12+ +# +# Reference URL: +# https://github.com/shadowsocks/shadowsocks +# https://github.com/shadowsocks/shadowsocks-go +# https://github.com/shadowsocks/shadowsocks-libev +# https://github.com/shadowsocks/shadowsocks-windows +# https://github.com/shadowsocksr-rm/shadowsocksr +# https://github.com/shadowsocksrr/shadowsocksr +# https://github.com/shadowsocksrr/shadowsocksr-csharp +# +# Thanks: +# @clowwindy +# @breakwa11 +# @cyfdecyf +# @madeye +# @linusyang +# @Akkariiin +# +# Intro: https://teddysun.com/486.html + +red='\033[0;31m' +green='\033[0;32m' +yellow='\033[0;33m' +plain='\033[0m' + +[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1 + +cur_dir=$( pwd ) +software=(Shadowsocks-Python ShadowsocksR Shadowsocks-Go Shadowsocks-libev) + +libsodium_file='libsodium-1.0.18' +libsodium_url='https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz' + +mbedtls_file='mbedtls-2.16.12' +mbedtls_url='https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v2.16.12.tar.gz' + +shadowsocks_python_file='shadowsocks-master' +shadowsocks_python_url='https://github.com/shadowsocks/shadowsocks/archive/master.zip' +shadowsocks_python_init='/etc/init.d/shadowsocks-python' +shadowsocks_python_config='/etc/shadowsocks-python/config.json' +shadowsocks_python_centos='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks' +shadowsocks_python_debian='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-debian' + +shadowsocks_r_file='shadowsocksr-3.2.2' +shadowsocks_r_url='https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz' +shadowsocks_r_init='/etc/init.d/shadowsocks-r' +shadowsocks_r_config='/etc/shadowsocks-r/config.json' +shadowsocks_r_centos='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocksR' +shadowsocks_r_debian='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocksR-debian' + +shadowsocks_go_file_64='shadowsocks-server-linux64-1.2.2' +shadowsocks_go_url_64='https://dl.lamp.sh/shadowsocks/shadowsocks-server-linux64-1.2.2.gz' +shadowsocks_go_file_32='shadowsocks-server-linux32-1.2.2' +shadowsocks_go_url_32='https://dl.lamp.sh/shadowsocks/shadowsocks-server-linux32-1.2.2.gz' +shadowsocks_go_init='/etc/init.d/shadowsocks-go' +shadowsocks_go_config='/etc/shadowsocks-go/config.json' +shadowsocks_go_centos='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-go' +shadowsocks_go_debian='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-go-debian' + +shadowsocks_libev_init='/etc/init.d/shadowsocks-libev' +shadowsocks_libev_config='/etc/shadowsocks-libev/config.json' +shadowsocks_libev_centos='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-libev' +shadowsocks_libev_debian='https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-libev-debian' + +# Stream Ciphers +common_ciphers=( +aes-256-gcm +aes-192-gcm +aes-128-gcm +aes-256-ctr +aes-192-ctr +aes-128-ctr +aes-256-cfb +aes-192-cfb +aes-128-cfb +camellia-128-cfb +camellia-192-cfb +camellia-256-cfb +xchacha20-ietf-poly1305 +chacha20-ietf-poly1305 +chacha20-ietf +chacha20 +salsa20 +rc4-md5 +) +go_ciphers=( +aes-256-cfb +aes-192-cfb +aes-128-cfb +aes-256-ctr +aes-192-ctr +aes-128-ctr +chacha20-ietf +chacha20 +salsa20 +rc4-md5 +) +r_ciphers=( +none +aes-256-cfb +aes-192-cfb +aes-128-cfb +aes-256-cfb8 +aes-192-cfb8 +aes-128-cfb8 +aes-256-ctr +aes-192-ctr +aes-128-ctr +chacha20-ietf +chacha20 +salsa20 +xchacha20 +xsalsa20 +rc4-md5 +) +# Reference URL: +# https://github.com/shadowsocksr-rm/shadowsocks-rss/blob/master/ssr.md +# https://github.com/shadowsocksrr/shadowsocksr/commit/a3cf0254508992b7126ab1151df0c2f10bf82680 +# Protocol +protocols=( +origin +verify_deflate +auth_sha1_v4 +auth_sha1_v4_compatible +auth_aes128_md5 +auth_aes128_sha1 +auth_chain_a +auth_chain_b +auth_chain_c +auth_chain_d +auth_chain_e +auth_chain_f +) +# obfs +obfs=( +plain +http_simple +http_simple_compatible +http_post +http_post_compatible +tls1.2_ticket_auth +tls1.2_ticket_auth_compatible +tls1.2_ticket_fastauth +tls1.2_ticket_fastauth_compatible +) +# libev obfuscating +obfs_libev=(http tls) +# initialization parameter +libev_obfs='' + +disable_selinux(){ + if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config + setenforce 0 + fi +} + +check_sys(){ + local checkType=$1 + local value=$2 + + local release='' + local systemPackage='' + + if [[ -f /etc/redhat-release ]]; then + release='centos' + systemPackage='yum' + elif grep -Eqi 'debian|raspbian' /etc/issue; then + release='debian' + systemPackage='apt' + elif grep -Eqi 'ubuntu' /etc/issue; then + release='ubuntu' + systemPackage='apt' + elif grep -Eqi 'centos|red hat|redhat' /etc/issue; then + release='centos' + systemPackage='yum' + elif grep -Eqi 'debian|raspbian' /proc/version; then + release='debian' + systemPackage='apt' + elif grep -Eqi 'ubuntu' /proc/version; then + release='ubuntu' + systemPackage='apt' + elif grep -Eqi 'centos|red hat|redhat' /proc/version; then + release='centos' + systemPackage='yum' + fi + + if [[ "${checkType}" == 'sysRelease' ]]; then + if [ "${value}" == "${release}" ]; then + return 0 + else + return 1 + fi + elif [[ "${checkType}" == 'packageManager' ]]; then + if [ "${value}" == "${systemPackage}" ]; then + return 0 + else + return 1 + fi + fi +} + +version_ge(){ + test "$(echo "$@" | tr ' ' '\n' | sort -rV | head -n 1)" == "$1" +} + +version_gt(){ + test "$(echo "$@" | tr ' ' '\n' | sort -V | head -n 1)" != "$1" +} + +check_kernel_version(){ + local kernel_version + kernel_version=$(uname -r | cut -d- -f1) + if version_gt "${kernel_version}" 3.7.0; then + return 0 + else + return 1 + fi +} + +check_kernel_headers(){ + if check_sys packageManager yum; then + if rpm -qa | grep -q headers-"$(uname -r)"; then + return 0 + else + return 1 + fi + elif check_sys packageManager apt; then + if dpkg -s linux-headers-"$(uname -r)" > /dev/null 2>&1; then + return 0 + else + return 1 + fi + fi + return 1 +} + +getversion(){ + if [[ -s /etc/redhat-release ]]; then + grep -oE '[0-9.]+' /etc/redhat-release + else + grep -oE '[0-9.]+' /etc/issue + fi +} + +centosversion(){ + if check_sys sysRelease centos; then + local code=$1 + local version + version="$(getversion)" + local main_ver=${version%%.*} + if [ "$main_ver" == "$code" ]; then + return 0 + else + return 1 + fi + else + return 1 + fi +} + +autoconf_version(){ + if [ ! "$(command -v autoconf)" ]; then + echo -e "[${green}Info${plain}] Starting install package autoconf" + if check_sys packageManager yum; then + yum install -y autoconf > /dev/null 2>&1 || echo -e "[${red}Error:${plain}] Failed to install autoconf" + elif check_sys packageManager apt; then + apt-get -y update > /dev/null 2>&1 + apt-get -y install autoconf > /dev/null 2>&1 || echo -e "[${red}Error:${plain}] Failed to install autoconf" + fi + fi + local autoconf_ver + autoconf_ver=$(autoconf --version | grep autoconf | grep -oE '[0-9.]+') + if version_ge "${autoconf_ver}" 2.67; then + return 0 + else + return 1 + fi +} + +get_ip(){ + local IP + IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v '^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\.' | head -n 1 ) + [ -z "${IP}" ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com ) + [ -z "${IP}" ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip ) + echo "${IP}" +} + +get_ipv6(){ + local ipv6 + ipv6=$(wget -qO- -t1 -T2 ipv6.icanhazip.com) + [ -z "${ipv6}" ] && return 1 || return 0 +} + +get_libev_ver(){ + libev_ver=$(wget --no-check-certificate -qO- https://api.github.com/repos/shadowsocks/shadowsocks-libev/releases/latest | grep 'tag_name' | cut -d\" -f4) + [ -z "${libev_ver}" ] && echo -e "[${red}Error${plain}] Get shadowsocks-libev latest version failed" && exit 1 +} + +get_opsy(){ + [ -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 +} + +is_64bit(){ + if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ] ; then + return 0 + else + return 1 + fi +} + +debianversion(){ + if check_sys sysRelease debian;then + local version + version=$( get_opsy ) + local code + code=${1} + local main_ver + main_ver=$( echo "${version}" | sed 's/[^0-9]//g') + if [ "${main_ver}" == "${code}" ];then + return 0 + else + return 1 + fi + else + return 1 + fi +} + +download(){ + local filename + filename=$(basename "$1") + if [ -f "${1}" ]; then + echo "${filename} [found]" + else + echo "${filename} not found, download now..." + wget --no-check-certificate -c -t3 -T60 -O "${1}" "${2}" + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Download ${filename} failed." + exit 1 + fi + fi +} + +download_files(){ + cd "${cur_dir}" || exit + + if [ "${selected}" == '1' ]; then + download "${shadowsocks_python_file}.zip" "${shadowsocks_python_url}" + if check_sys packageManager yum; then + download "${shadowsocks_python_init}" "${shadowsocks_python_centos}" + elif check_sys packageManager apt; then + download "${shadowsocks_python_init}" "${shadowsocks_python_debian}" + fi + elif [ "${selected}" == '2' ]; then + download "${shadowsocks_r_file}.tar.gz" "${shadowsocks_r_url}" + if check_sys packageManager yum; then + download "${shadowsocks_r_init}" "${shadowsocks_r_centos}" + elif check_sys packageManager apt; then + download "${shadowsocks_r_init}" "${shadowsocks_r_debian}" + fi + elif [ "${selected}" == '3' ]; then + if is_64bit; then + download "${shadowsocks_go_file_64}.gz" "${shadowsocks_go_url_64}" + else + download "${shadowsocks_go_file_32}.gz" "${shadowsocks_go_url_32}" + fi + if check_sys packageManager yum; then + download "${shadowsocks_go_init}" "${shadowsocks_go_centos}" + elif check_sys packageManager apt; then + download "${shadowsocks_go_init}" "${shadowsocks_go_debian}" + fi + elif [ "${selected}" == '4' ]; then + get_libev_ver + shadowsocks_libev_file="shadowsocks-libev-$(echo "${libev_ver}" | sed -e 's/^[a-zA-Z]//g')" + shadowsocks_libev_url="https://github.com/shadowsocks/shadowsocks-libev/releases/download/${libev_ver}/${shadowsocks_libev_file}.tar.gz" + + download "${shadowsocks_libev_file}.tar.gz" "${shadowsocks_libev_url}" + if check_sys packageManager yum; then + download "${shadowsocks_libev_init}" "${shadowsocks_libev_centos}" + elif check_sys packageManager apt; then + download "${shadowsocks_libev_init}" "${shadowsocks_libev_debian}" + fi + fi + +} + +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" +} + +error_detect_depends(){ + local command=$1 + local depend + depend=$(echo "${command}" | awk '{print $4}') + echo -e "[${green}Info${plain}] Starting to install package ${depend}" + ${command} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Failed to install ${red}${depend}${plain}" + echo 'Please visit: https://teddysun.com/486.html and contact.' + exit 1 + fi +} + +config_firewall(){ + if centosversion 6; then + /etc/init.d/iptables status > /dev/null 2>&1 + if [ $? -eq 0 ]; then + iptables -L -n | grep -i "${shadowsocksport}" > /dev/null 2>&1 + if [ $? -ne 0 ]; then + iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport "${shadowsocksport}" -j ACCEPT + iptables -I INPUT -m state --state NEW -m udp -p udp --dport "${shadowsocksport}" -j ACCEPT + /etc/init.d/iptables save + /etc/init.d/iptables restart + else + echo -e "[${green}Info${plain}] port ${green}${shadowsocksport}${plain} already be enabled." + fi + else + echo -e "[${yellow}Warning${plain}] iptables looks like not running or not installed, please enable port ${shadowsocksport} manually if necessary." + fi + elif centosversion 7; then + systemctl status firewalld > /dev/null 2>&1 + if [ $? -eq 0 ]; then + default_zone=$(firewall-cmd --get-default-zone) + firewall-cmd --permanent --zone="${default_zone}" --add-port="${shadowsocksport}"/tcp + firewall-cmd --permanent --zone="${default_zone}" --add-port="${shadowsocksport}"/udp + firewall-cmd --reload + else + echo -e "[${yellow}Warning${plain}] firewalld looks like not running or not installed, please enable port ${shadowsocksport} manually if necessary." + fi + fi +} + +config_shadowsocks(){ + +if [ "${selected}" == '1' ]; then + if [ ! -d "$(dirname ${shadowsocks_python_config})" ]; then + mkdir -p $(dirname ${shadowsocks_python_config}) + fi + cat > ${shadowsocks_python_config}<<-EOF +{ + "server":"0.0.0.0", + "server_port":${shadowsocksport}, + "local_address":"127.0.0.1", + "local_port":1080, + "password":"${shadowsockspwd}", + "timeout":300, + "method":"${shadowsockscipher}", + "fast_open":false +} +EOF +elif [ "${selected}" == '2' ]; then + if [ ! -d "$(dirname ${shadowsocks_r_config})" ]; then + mkdir -p $(dirname ${shadowsocks_r_config}) + fi + cat > ${shadowsocks_r_config}<<-EOF +{ + "server":"0.0.0.0", + "server_ipv6":"::", + "server_port":${shadowsocksport}, + "local_address":"127.0.0.1", + "local_port":1080, + "password":"${shadowsockspwd}", + "timeout":120, + "method":"${shadowsockscipher}", + "protocol":"${shadowsockprotocol}", + "protocol_param":"", + "obfs":"${shadowsockobfs}", + "obfs_param":"", + "redirect":"", + "dns_ipv6":false, + "fast_open":false, + "workers":1 +} +EOF +elif [ "${selected}" == '3' ]; then + if [ ! -d "$(dirname ${shadowsocks_go_config})" ]; then + mkdir -p $(dirname ${shadowsocks_go_config}) + fi + cat > ${shadowsocks_go_config}<<-EOF +{ + "server":"0.0.0.0", + "server_port":${shadowsocksport}, + "local_port":1080, + "password":"${shadowsockspwd}", + "method":"${shadowsockscipher}", + "timeout":300 +} +EOF +elif [ "${selected}" == '4' ]; then + local server_value="\"0.0.0.0\"" + if get_ipv6; then + server_value="[\"[::0]\",\"0.0.0.0\"]" + fi + + if [ ! -d "$(dirname ${shadowsocks_libev_config})" ]; then + mkdir -p $(dirname ${shadowsocks_libev_config}) + fi + + if [ "${libev_obfs}" == 'y' ] || [ "${libev_obfs}" == 'Y' ]; then + cat > ${shadowsocks_libev_config}<<-EOF +{ + "server":${server_value}, + "server_port":${shadowsocksport}, + "password":"${shadowsockspwd}", + "timeout":300, + "user":"nobody", + "method":"${shadowsockscipher}", + "fast_open":false, + "nameserver":"1.0.0.1", + "mode":"tcp_and_udp", + "plugin":"obfs-server", + "plugin_opts":"obfs=${shadowsocklibev_obfs}" +} +EOF + else + cat > ${shadowsocks_libev_config}<<-EOF +{ + "server":${server_value}, + "server_port":${shadowsocksport}, + "password":"${shadowsockspwd}", + "timeout":300, + "user":"nobody", + "method":"${shadowsockscipher}", + "fast_open":false, + "nameserver":"1.0.0.1", + "mode":"tcp_and_udp" +} +EOF + fi + +fi +} + +install_dependencies(){ + if check_sys packageManager yum; then + echo -e "[${green}Info${plain}] Checking the EPEL repository..." + if [ ! -f /etc/yum.repos.d/epel.repo ]; then + yum install -y epel-release > /dev/null 2>&1 + fi + [ ! -f /etc/yum.repos.d/epel.repo ] && echo -e "[${red}Error${plain}] Install EPEL repository failed, please check it." && exit 1 + [ ! "$(command -v yum-config-manager)" ] && yum install -y yum-utils > /dev/null 2>&1 + [ x"$(yum-config-manager epel | grep -w enabled | awk '{print $3}')" != x'True' ] && yum-config-manager --enable epel > /dev/null 2>&1 + echo -e "[${green}Info${plain}] Checking the EPEL repository complete..." + + yum_depends=( + unzip gzip openssl openssl-devel gcc python python-devel python-setuptools pcre pcre-devel libtool libevent + autoconf automake make curl curl-devel zlib-devel perl perl-devel cpio expat-devel gettext-devel + libev-devel c-ares-devel git qrencode + ) + for depend in ${yum_depends[@]}; do + error_detect_depends "yum -y install ${depend}" + done + elif check_sys packageManager apt; then + apt_depends=( + gettext build-essential unzip gzip python python-dev python-setuptools curl openssl libssl-dev + autoconf automake libtool gcc make perl cpio libpcre3 libpcre3-dev zlib1g-dev libev-dev libc-ares-dev git qrencode + ) + + apt-get -y update + for depend in ${apt_depends[@]}; do + error_detect_depends "apt-get -y install ${depend}" + done + fi +} + +install_check(){ + if check_sys packageManager yum || check_sys packageManager apt; then + if centosversion 5; then + return 1 + fi + return 0 + else + return 1 + fi +} + +install_select(){ + if ! install_check; then + echo -e "[${red}Error${plain}] Your OS is not supported to run it!" + echo 'Please change to CentOS 6+/Debian 7+/Ubuntu 12+ and try again.' + exit 1 + fi + + clear + while true + do + echo "Which Shadowsocks server you'd select:" + for ((i=1;i<=${#software[@]};i++ )); do + hint="${software[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Please enter a number (Default ${software[0]}):" selected + [ -z "${selected}" ] && selected='1' + case "${selected}" in + 1|2|3|4) + echo + echo "You choose = ${software[${selected}-1]}" + echo + break + ;; + *) + echo -e "[${red}Error${plain}] Please only enter a number [1-4]" + ;; + esac + done +} + +install_prepare_password(){ + echo "Please enter password for ${software[${selected}-1]}" + read -p '(Default password: teddysun.com):' shadowsockspwd + [ -z "${shadowsockspwd}" ] && shadowsockspwd='teddysun.com' + echo + echo "password = ${shadowsockspwd}" + echo +} + +install_prepare_port() { + while true + do + dport=$(shuf -i 9000-19999 -n 1) + echo -e "Please enter a port for ${software[${selected}-1]} [1-65535]" + read -p "(Default port: ${dport}):" shadowsocksport + [ -z "${shadowsocksport}" ] && shadowsocksport=${dport} + expr "${shadowsocksport}" + 1 &>/dev/null + if [ $? -eq 0 ]; then + if [ "${shadowsocksport}" -ge 1 ] && [ "${shadowsocksport}" -le 65535 ] && [ "${shadowsocksport:0:1}" != 0 ]; then + echo + echo "port = ${shadowsocksport}" + echo + break + fi + fi + echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]" + done +} + +install_prepare_cipher(){ + while true + do + echo -e "Please select stream cipher for ${software[${selected}-1]}:" + + if [[ "${selected}" == '1' || "${selected}" == '4' ]]; then + for ((i=1;i<=${#common_ciphers[@]};i++ )); do + hint="${common_ciphers[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Which cipher you'd select(Default: ${common_ciphers[0]}):" pick + [ -z "$pick" ] && pick=1 + expr ${pick} + 1 &>/dev/null + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Please enter a number" + continue + fi + if [[ "$pick" -lt 1 || "$pick" -gt ${#common_ciphers[@]} ]]; then + echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#common_ciphers[@]}" + continue + fi + shadowsockscipher=${common_ciphers[$pick-1]} + elif [ "${selected}" == '2' ]; then + for ((i=1;i<=${#r_ciphers[@]};i++ )); do + hint="${r_ciphers[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Which cipher you'd select(Default: ${r_ciphers[1]}):" pick + [ -z "$pick" ] && pick=2 + expr ${pick} + 1 &>/dev/null + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Please enter a number" + continue + fi + if [[ "$pick" -lt 1 || "$pick" -gt ${#r_ciphers[@]} ]]; then + echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#r_ciphers[@]}" + continue + fi + shadowsockscipher=${r_ciphers[$pick-1]} + elif [ "${selected}" == '3' ]; then + for ((i=1;i<=${#go_ciphers[@]};i++ )); do + hint="${go_ciphers[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Which cipher you'd select(Default: ${go_ciphers[0]}):" pick + [ -z "$pick" ] && pick=1 + expr ${pick} + 1 &>/dev/null + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Please enter a number" + continue + fi + if [[ "$pick" -lt 1 || "$pick" -gt ${#go_ciphers[@]} ]]; then + echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#go_ciphers[@]}" + continue + fi + shadowsockscipher=${go_ciphers[$pick-1]} + fi + + echo + echo "cipher = ${shadowsockscipher}" + echo + break + done +} + +install_prepare_protocol(){ + while true + do + echo -e "Please select protocol for ${software[${selected}-1]}:" + for ((i=1;i<=${#protocols[@]};i++ )); do + hint="${protocols[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Which protocol you'd select(Default: ${protocols[0]}):" protocol + [ -z "$protocol" ] && protocol=1 + expr ${protocol} + 1 &>/dev/null + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Please enter a number" + continue + fi + if [[ "$protocol" -lt 1 || "$protocol" -gt ${#protocols[@]} ]]; then + echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#protocols[@]}" + continue + fi + shadowsockprotocol=${protocols[$protocol-1]} + echo + echo "protocol = ${shadowsockprotocol}" + echo + break + done +} + +install_prepare_obfs(){ + while true + do + echo -e "Please select obfs for ${software[${selected}-1]}:" + for ((i=1;i<=${#obfs[@]};i++ )); do + hint="${obfs[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Which obfs you'd select(Default: ${obfs[0]}):" r_obfs + [ -z "$r_obfs" ] && r_obfs=1 + expr ${r_obfs} + 1 &>/dev/null + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Please enter a number" + continue + fi + if [[ "$r_obfs" -lt 1 || "$r_obfs" -gt ${#obfs[@]} ]]; then + echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#obfs[@]}" + continue + fi + shadowsockobfs=${obfs[$r_obfs-1]} + echo + echo "obfs = ${shadowsockobfs}" + echo + break + done +} + +install_prepare_libev_obfs(){ + if autoconf_version || centosversion 6; then + while true + do + echo -e "Do you want install simple-obfs for ${software[${selected}-1]}? [y/n]" + read -p '(default: n):' libev_obfs + [ -z "$libev_obfs" ] && libev_obfs=n + case "${libev_obfs}" in + y|Y|n|N) + echo + echo "You choose = ${libev_obfs}" + echo + break + ;; + *) + echo -e "[${red}Error${plain}] Please only enter [y/n]" + ;; + esac + done + + if [ "${libev_obfs}" == 'y' ] || [ "${libev_obfs}" == 'Y' ]; then + while true + do + echo -e 'Please select obfs for simple-obfs:' + for ((i=1;i<=${#obfs_libev[@]};i++ )); do + hint="${obfs_libev[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p "Which obfs you'd select(Default: ${obfs_libev[0]}):" r_libev_obfs + [ -z "$r_libev_obfs" ] && r_libev_obfs=1 + expr ${r_libev_obfs} + 1 &>/dev/null + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] Please enter a number" + continue + fi + if [[ "$r_libev_obfs" -lt 1 || "$r_libev_obfs" -gt ${#obfs_libev[@]} ]]; then + echo -e "[${red}Error${plain}] Please enter a number between 1 and ${#obfs_libev[@]}" + continue + fi + shadowsocklibev_obfs=${obfs_libev[$r_libev_obfs-1]} + echo + echo "obfs = ${shadowsocklibev_obfs}" + echo + break + done + fi + else + echo -e "[${green}Info${plain}] autoconf version is less than 2.67, simple-obfs for ${software[${selected}-1]} installation has been skipped" + fi +} + +install_prepare(){ + + if [[ "${selected}" == '1' || "${selected}" == '3' || "${selected}" == '4' ]]; then + install_prepare_password + install_prepare_port + install_prepare_cipher + if [ "${selected}" == '4' ]; then + install_prepare_libev_obfs + fi + elif [ "${selected}" == '2' ]; then + install_prepare_password + install_prepare_port + install_prepare_cipher + install_prepare_protocol + install_prepare_obfs + fi + + echo + echo 'Press any key to start...or Press Ctrl+C to cancel' + char=$(get_char) + +} + +install_libsodium(){ + if [ ! -f /usr/lib/libsodium.a ]; then + cd "${cur_dir}" || exit + download "${libsodium_file}.tar.gz" "${libsodium_url}" + tar zxf ${libsodium_file}.tar.gz + cd ${libsodium_file} || exit + ./configure --prefix=/usr && make && make install + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] ${libsodium_file} install failed." + install_cleanup + exit 1 + fi + else + echo -e "[${green}Info${plain}] ${libsodium_file} already installed." + fi +} + +install_mbedtls(){ + if [ ! -f /usr/lib/libmbedtls.a ]; then + cd "${cur_dir}" || exit + download "${mbedtls_file}.tar.gz" "${mbedtls_url}" + tar zxf "${mbedtls_file}.tar.gz" + cd "${mbedtls_file}" || exit + make SHARED=1 CFLAGS=-fPIC + make DESTDIR=/usr install + if [ $? -ne 0 ]; then + echo -e "[${red}Error${plain}] ${mbedtls_file} install failed." + install_cleanup + exit 1 + fi + else + echo -e "[${green}Info${plain}] ${mbedtls_file} already installed." + fi +} + +install_shadowsocks_python(){ + cd "${cur_dir}" || exit + unzip -q ${shadowsocks_python_file}.zip + if [ $? -ne 0 ];then + echo -e "[${red}Error${plain}] unzip ${shadowsocks_python_file}.zip failed, please check unzip command." + install_cleanup + exit 1 + fi + + cd ${shadowsocks_python_file} || exit + python setup.py install --record /usr/local/shadowsocks_python.log + + if [ -f /usr/bin/ssserver ] || [ -f /usr/local/bin/ssserver ]; then + chmod +x ${shadowsocks_python_init} + local service_name + service_name=$(basename ${shadowsocks_python_init}) + if check_sys packageManager yum; then + chkconfig --add "${service_name}" + chkconfig "${service_name}" on + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" defaults + fi + else + echo + echo -e "[${red}Error${plain}] ${software[0]} install failed." + echo 'Please visit: https://teddysun.com/486.html and contact.' + install_cleanup + exit 1 + fi +} + +install_shadowsocks_r(){ + cd "${cur_dir}" || exit + tar zxf ${shadowsocks_r_file}.tar.gz + mv ${shadowsocks_r_file}/shadowsocks /usr/local/ + if [ -f /usr/local/shadowsocks/server.py ]; then + chmod +x ${shadowsocks_r_init} + local service_name + service_name=$(basename ${shadowsocks_r_init}) + if check_sys packageManager yum; then + chkconfig --add "${service_name}" + chkconfig "${service_name}" on + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" defaults + fi + else + echo + echo -e "[${red}Error${plain}] ${software[1]} install failed." + echo 'Please visit; https://teddysun.com/486.html and contact.' + install_cleanup + exit 1 + fi +} + +install_shadowsocks_go(){ + cd "${cur_dir}" || exit + if is_64bit; then + gzip -d ${shadowsocks_go_file_64}.gz + if [ $? -ne 0 ];then + echo -e "[${red}Error${plain}] Decompress ${shadowsocks_go_file_64}.gz failed." + install_cleanup + exit 1 + fi + mv -f ${shadowsocks_go_file_64} /usr/bin/shadowsocks-server + else + gzip -d ${shadowsocks_go_file_32}.gz + if [ $? -ne 0 ];then + echo -e "[${red}Error${plain}] Decompress ${shadowsocks_go_file_32}.gz failed." + install_cleanup + exit 1 + fi + mv -f ${shadowsocks_go_file_32} /usr/bin/shadowsocks-server + fi + + if [ -f /usr/bin/shadowsocks-server ]; then + chmod +x /usr/bin/shadowsocks-server + chmod +x ${shadowsocks_go_init} + + local service_name + service_name=$(basename ${shadowsocks_go_init}) + if check_sys packageManager yum; then + chkconfig --add "${service_name}" + chkconfig "${service_name}" on + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" defaults + fi + else + echo + echo -e "[${red}Error${plain}] ${software[2]} install failed." + echo 'Please visit: https://teddysun.com/486.html and contact.' + install_cleanup + exit 1 + fi +} + +install_shadowsocks_libev(){ + cd "${cur_dir}" || exit + tar zxf "${shadowsocks_libev_file}".tar.gz + cd "${shadowsocks_libev_file}" || exit + ./configure --disable-documentation && make && make install + if [ $? -eq 0 ]; then + chmod +x ${shadowsocks_libev_init} + local service_name + service_name=$(basename ${shadowsocks_libev_init}) + if check_sys packageManager yum; then + chkconfig --add "${service_name}" + chkconfig "${service_name}" on + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" defaults + fi + else + echo + echo -e "[${red}Error${plain}] ${software[3]} install failed." + echo 'Please visit: https://teddysun.com/486.html and contact.' + install_cleanup + exit 1 + fi +} + +install_shadowsocks_libev_obfs(){ + if [ "${libev_obfs}" == 'y' ] || [ "${libev_obfs}" == 'Y' ]; then + cd "${cur_dir}" || exit + git clone https://github.com/shadowsocks/simple-obfs.git + [ -d simple-obfs ] && cd simple-obfs || echo -e "[${red}Error:${plain}] Failed to git clone simple-obfs." + git submodule update --init --recursive + if centosversion 6; then + if [ ! "$(command -v autoconf268)" ]; then + echo -e "[${green}Info${plain}] Starting install autoconf268..." + yum install -y autoconf268 > /dev/null 2>&1 || echo -e "[${red}Error:${plain}] Failed to install autoconf268." + fi + # replace command autoreconf to autoreconf268 + sed -i 's/autoreconf/autoreconf268/' autogen.sh + # replace #include to #include + sed -i 's@^#include @#include @' src/local.h + sed -i 's@^#include @#include @' src/server.h + fi + ./autogen.sh + ./configure --disable-documentation + make + make install + if [ ! "$(command -v obfs-server)" ]; then + echo -e "[${red}Error${plain}] simple-obfs for ${software[${selected}-1]} install failed." + echo 'Please visit: https://teddysun.com/486.html and contact.' + install_cleanup + exit 1 + fi + [ -f /usr/local/bin/obfs-server ] && ln -s /usr/local/bin/obfs-server /usr/bin + fi +} + +install_completed_python(){ + clear + ${shadowsocks_python_init} start + echo + echo -e "Congratulations, ${green}${software[0]}${plain} server install completed!" + echo -e "Your Server IP : ${red} $(get_ip) ${plain}" + echo -e "Your Server Port : ${red} ${shadowsocksport} ${plain}" + echo -e "Your Password : ${red} ${shadowsockspwd} ${plain}" + echo -e "Your Encryption Method: ${red} ${shadowsockscipher} ${plain}" +} + +install_completed_r(){ + clear + ${shadowsocks_r_init} start + echo + echo -e "Congratulations, ${green}${software[1]}${plain} server install completed!" + echo -e "Your Server IP : ${red} $(get_ip) ${plain}" + echo -e "Your Server Port : ${red} ${shadowsocksport} ${plain}" + echo -e "Your Password : ${red} ${shadowsockspwd} ${plain}" + echo -e "Your Protocol : ${red} ${shadowsockprotocol} ${plain}" + echo -e "Your obfs : ${red} ${shadowsockobfs} ${plain}" + echo -e "Your Encryption Method: ${red} ${shadowsockscipher} ${plain}" +} + +install_completed_go(){ + clear + ${shadowsocks_go_init} start + echo + echo -e "Congratulations, ${green}${software[2]}${plain} server install completed!" + echo -e "Your Server IP : ${red} $(get_ip) ${plain}" + echo -e "Your Server Port : ${red} ${shadowsocksport} ${plain}" + echo -e "Your Password : ${red} ${shadowsockspwd} ${plain}" + echo -e "Your Encryption Method: ${red} ${shadowsockscipher} ${plain}" +} + +install_completed_libev(){ + clear + ldconfig + ${shadowsocks_libev_init} start + echo + echo -e "Congratulations, ${green}${software[3]}${plain} server install completed!" + echo -e "Your Server IP : ${red} $(get_ip) ${plain}" + echo -e "Your Server Port : ${red} ${shadowsocksport} ${plain}" + echo -e "Your Password : ${red} ${shadowsockspwd} ${plain}" + if [ "$(command -v obfs-server)" ]; then + echo -e "Your obfs : ${red} ${shadowsocklibev_obfs} ${plain}" + fi + echo -e "Your Encryption Method: ${red} ${shadowsockscipher} ${plain}" +} + +qr_generate_python(){ + if [ "$(command -v qrencode)" ]; then + local tmp + tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}@$(get_ip):${shadowsocksport}" | base64 -w0) + local qr_code="ss://${tmp}" + echo + echo 'Your QR Code: (For Shadowsocks Windows, OSX, Android and iOS clients)' + echo -e "${green} ${qr_code} ${plain}" + echo -n "${qr_code}" | qrencode -s8 -o "${cur_dir}"/shadowsocks_python_qr.png + echo 'Your QR Code has been saved as a PNG file path:' + echo -e "${green} ${cur_dir}/shadowsocks_python_qr.png ${plain}" + fi +} + +qr_generate_r(){ + if [ "$(command -v qrencode)" ]; then + local tmp1 + tmp1=$(echo -n "${shadowsockspwd}" | base64 -w0 | sed 's/=//g;s/\//_/g;s/+/-/g') + local tmp2 + tmp2=$(echo -n "$(get_ip):${shadowsocksport}:${shadowsockprotocol}:${shadowsockscipher}:${shadowsockobfs}:${tmp1}/?obfsparam=" | base64 -w0) + local qr_code="ssr://${tmp2}" + echo + echo 'Your QR Code: (For ShadowsocksR Windows, Android clients only)' + echo -e "${green} ${qr_code} ${plain}" + echo -n "${qr_code}" | qrencode -s8 -o "${cur_dir}"/shadowsocks_r_qr.png + echo 'Your QR Code has been saved as a PNG file path:' + echo -e "${green} ${cur_dir}/shadowsocks_r_qr.png ${plain}" + fi +} + +qr_generate_go(){ + if [ "$(command -v qrencode)" ]; then + local tmp + tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}@$(get_ip):${shadowsocksport}" | base64 -w0) + local qr_code="ss://${tmp}" + echo + echo 'Your QR Code: (For Shadowsocks Windows, OSX, Android and iOS clients)' + echo -e "${green} ${qr_code} ${plain}" + echo -n "${qr_code}" | qrencode -s8 -o "${cur_dir}"/shadowsocks_go_qr.png + echo 'Your QR Code has been saved as a PNG file path:' + echo -e "${green} ${cur_dir}/shadowsocks_go_qr.png ${plain}" + fi +} + +qr_generate_libev(){ + if [ "$(command -v qrencode)" ]; then + local tmp + tmp=$(echo -n "${shadowsockscipher}:${shadowsockspwd}@$(get_ip):${shadowsocksport}" | base64 -w0) + local qr_code="ss://${tmp}" + echo + echo 'Your QR Code: (For Shadowsocks Windows, OSX, Android and iOS clients)' + echo -e "${green} ${qr_code} ${plain}" + echo -n "${qr_code}" | qrencode -s8 -o "${cur_dir}"/shadowsocks_libev_qr.png + echo 'Your QR Code has been saved as a PNG file path:' + echo -e "${green} ${cur_dir}/shadowsocks_libev_qr.png ${plain}" + fi +} + +install_main(){ + install_libsodium + if ! ldconfig -p | grep -wq '/usr/lib'; then + echo '/usr/lib' > /etc/ld.so.conf.d/lib.conf + fi + ldconfig + + if [ "${selected}" == '1' ]; then + install_shadowsocks_python + install_completed_python + qr_generate_python + elif [ "${selected}" == '2' ]; then + install_shadowsocks_r + install_completed_r + qr_generate_r + elif [ "${selected}" == '3' ]; then + install_shadowsocks_go + install_completed_go + qr_generate_go + elif [ "${selected}" == '4' ]; then + install_mbedtls + install_shadowsocks_libev + install_shadowsocks_libev_obfs + install_completed_libev + qr_generate_libev + fi + + echo + echo 'Welcome to visit: https://teddysun.com/486.html' + echo 'Enjoy it!' + echo +} + +install_cleanup(){ + cd "${cur_dir}" || exit + rm -rf simple-obfs + rm -rf ${libsodium_file} ${libsodium_file}.tar.gz + rm -rf "${mbedtls_file}" "${mbedtls_file}"-apache.tgz + rm -rf ${shadowsocks_python_file} ${shadowsocks_python_file}.zip + rm -rf ${shadowsocks_r_file} ${shadowsocks_r_file}.tar.gz + rm -rf ${shadowsocks_go_file_64}.gz ${shadowsocks_go_file_32}.gz + rm -rf "${shadowsocks_libev_file}" "${shadowsocks_libev_file}".tar.gz +} + +install_shadowsocks(){ + disable_selinux + install_select + install_prepare + install_dependencies + download_files + config_shadowsocks + if check_sys packageManager yum; then + config_firewall + fi + install_main + install_cleanup +} + +uninstall_shadowsocks_python(){ + printf "Are you sure uninstall ${red}${software[0]}${plain}? [y/n]\n" + read -p '(default: n):' answer + [ -z "${answer}" ] && answer='n' + if [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ]; then + ${shadowsocks_python_init} status > /dev/null 2>&1 + if [ $? -eq 0 ]; then + ${shadowsocks_python_init} stop + fi + local service_name + service_name=$(basename ${shadowsocks_python_init}) + if check_sys packageManager yum; then + chkconfig --del "${service_name}" + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" remove + fi + + rm -fr $(dirname ${shadowsocks_python_config}) + rm -f ${shadowsocks_python_init} + rm -f /var/log/shadowsocks.log + if [ -f /usr/local/shadowsocks_python.log ]; then + cat /usr/local/shadowsocks_python.log | xargs rm -rf + rm -f /usr/local/shadowsocks_python.log + fi + echo -e "[${green}Info${plain}] ${software[0]} uninstall success" + else + echo + echo -e "[${green}Info${plain}] ${software[0]} uninstall cancelled, nothing to do..." + echo + fi +} + +uninstall_shadowsocks_r(){ + printf "Are you sure uninstall ${red}${software[1]}${plain}? [y/n]\n" + read -p '(default: n):' answer + [ -z "${answer}" ] && answer='n' + if [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ]; then + ${shadowsocks_r_init} status > /dev/null 2>&1 + if [ $? -eq 0 ]; then + ${shadowsocks_r_init} stop + fi + local service_name + service_name=$(basename ${shadowsocks_r_init}) + if check_sys packageManager yum; then + chkconfig --del "${service_name}" + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" remove + fi + rm -fr $(dirname ${shadowsocks_r_config}) + rm -f ${shadowsocks_r_init} + rm -f /var/log/shadowsocks.log + rm -fr /usr/local/shadowsocks + echo -e "[${green}Info${plain}] ${software[1]} uninstall success" + else + echo + echo -e "[${green}Info${plain}] ${software[1]} uninstall cancelled, nothing to do..." + echo + fi +} + +uninstall_shadowsocks_go(){ + printf "Are you sure uninstall ${red}${software[2]}${plain}? [y/n]\n" + read -p '(default: n):' answer + [ -z "${answer}" ] && answer='n' + if [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ]; then + ${shadowsocks_go_init} status > /dev/null 2>&1 + if [ $? -eq 0 ]; then + ${shadowsocks_go_init} stop + fi + local service_name + service_name=$(basename ${shadowsocks_go_init}) + if check_sys packageManager yum; then + chkconfig --del "${service_name}" + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" remove + fi + rm -fr $(dirname ${shadowsocks_go_config}) + rm -f ${shadowsocks_go_init} + rm -f /usr/bin/shadowsocks-server + echo -e "[${green}Info${plain}] ${software[2]} uninstall success" + else + echo + echo -e "[${green}Info${plain}] ${software[2]} uninstall cancelled, nothing to do..." + echo + fi +} + +uninstall_shadowsocks_libev(){ + printf "Are you sure uninstall ${red}${software[3]}${plain}? [y/n]\n" + read -p '(default: n):' answer + [ -z "${answer}" ] && answer='n' + if [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ]; then + ${shadowsocks_libev_init} status > /dev/null 2>&1 + if [ $? -eq 0 ]; then + ${shadowsocks_libev_init} stop + fi + local service_name + service_name=$(basename ${shadowsocks_libev_init}) + if check_sys packageManager yum; then + chkconfig --del "${service_name}" + elif check_sys packageManager apt; then + update-rc.d -f "${service_name}" remove + fi + rm -fr $(dirname ${shadowsocks_libev_config}) + rm -f /usr/local/bin/ss-local + rm -f /usr/local/bin/ss-tunnel + rm -f /usr/local/bin/ss-server + rm -f /usr/local/bin/ss-manager + rm -f /usr/local/bin/ss-redir + rm -f /usr/local/bin/ss-nat + rm -f /usr/local/bin/obfs-local + rm -f /usr/local/bin/obfs-server + rm -f /usr/local/lib/libshadowsocks-libev.a + rm -f /usr/local/lib/libshadowsocks-libev.la + rm -f /usr/local/include/shadowsocks.h + rm -f /usr/local/lib/pkgconfig/shadowsocks-libev.pc + rm -f /usr/local/share/man/man1/ss-local.1 + rm -f /usr/local/share/man/man1/ss-tunnel.1 + rm -f /usr/local/share/man/man1/ss-server.1 + rm -f /usr/local/share/man/man1/ss-manager.1 + rm -f /usr/local/share/man/man1/ss-redir.1 + rm -f /usr/local/share/man/man1/ss-nat.1 + rm -f /usr/local/share/man/man8/shadowsocks-libev.8 + rm -fr /usr/local/share/doc/shadowsocks-libev + rm -f ${shadowsocks_libev_init} + echo -e "[${green}Info${plain}] ${software[3]} uninstall success" + else + echo + echo -e "[${green}Info${plain}] ${software[3]} uninstall cancelled, nothing to do..." + echo + fi +} + +uninstall_shadowsocks(){ + while true + do + echo 'Which Shadowsocks server you want to uninstall?' + for ((i=1;i<=${#software[@]};i++ )); do + hint="${software[$i-1]}" + echo -e "${green}${i}${plain}) ${hint}" + done + read -p 'Please enter a number [1-4]:' un_select + case "${un_select}" in + 1|2|3|4) + echo + echo "You choose = ${software[${un_select}-1]}" + echo + break + ;; + *) + echo -e "[${red}Error${plain}] Please only enter a number [1-4]" + ;; + esac + done + + if [ "${un_select}" == '1' ]; then + if [ -f ${shadowsocks_python_init} ]; then + uninstall_shadowsocks_python + else + echo -e "[${red}Error${plain}] ${software[${un_select}-1]} not installed, please check it and try again." + echo + exit 1 + fi + elif [ "${un_select}" == '2' ]; then + if [ -f ${shadowsocks_r_init} ]; then + uninstall_shadowsocks_r + else + echo -e "[${red}Error${plain}] ${software[${un_select}-1]} not installed, please check it and try again." + echo + exit 1 + fi + elif [ "${un_select}" == '3' ]; then + if [ -f ${shadowsocks_go_init} ]; then + uninstall_shadowsocks_go + else + echo -e "[${red}Error${plain}] ${software[${un_select}-1]} not installed, please check it and try again." + echo + exit 1 + fi + elif [ "${un_select}" == '4' ]; then + if [ -f ${shadowsocks_libev_init} ]; then + uninstall_shadowsocks_libev + else + echo -e "[${red}Error${plain}] ${software[${un_select}-1]} not installed, please check it and try again." + echo + exit 1 + fi + fi +} + +# Initialization step +action=$1 +[ -z "$1" ] && action=install +case "${action}" in + install|uninstall) + ${action}_shadowsocks + ;; + *) + echo "Arguments error! [${action}]" + echo "Usage: $(basename "$0") [install|uninstall]" + ;; +esac \ No newline at end of file