diff --git a/Flatfy V3.zip b/Flatfy V3.zip deleted file mode 100644 index 945b0714..00000000 Binary files a/Flatfy V3.zip and /dev/null differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..5c93f456 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README.md b/README.md index b4701da1..6d3b075a 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,228 @@ -# 一键脚本 +# 网络跳越一键脚本 -## CentOS +官网: -1. CentOS 7/8系统Shadowsocks/SS一键脚本:centos_install_ss.sh,使用教程: -2. CentOS 7/8系统ShadowsocksR/SSR一键脚本:centos_install_ssr.sh,使用教程: -3. CentOS 7/8系统V2Ray一键脚本:centos_install_v2ray.sh,使用教程: -4. CentOS 7/8系统带伪装V2Ray一键脚本:centos_install_v2ray2.sh,使用教程: +论坛: -## Ubuntu +TG讨论组: [@hijkclub](https://t.me/hijkclub) -1. Ubuntu TLS系统Shadowsocks/SS一键脚本:ubuntu_install_ss.sh,使用教程: -2. Ubuntu TLS系统ShadowsocksR/SS一键脚本:ubuntu_install_ssr.sh,使用教程: -3. Ubuntu TLS系统V2Ray一键脚本:ubuntu_install_v2ray.sh,使用教程: -4. Ubuntu TLS系统带伪装V2Ray一键脚本:ubuntu_install_v2ray2.sh,使用教程: +Youtube频道: + +联系邮箱:hijk.pw@protonmail.ch + + +> **PS**: 本站所有文章和Github上所有脚本均可随意转载和修改使用,无任何约束,无需附上原文链接和本人名字 + +## 一键脚本 + +[本站脚本资源汇总](https://v2raytech.com/script-collection/) + +[CentOS 7/8系统Shadowsocks/SS一键脚本](https://v2raytech.com/shadowsocks-ss-one-click-script) + +[Ubuntu TLS/Debian系统Shadowsocks/SS一键脚本](https://v2raytech.com/ubuntu-shadowsocks-ss-one-click-script/) + +[CentOS 7/8系统ShadowsocksR/SSR一键脚本](https://v2raytech.com/shadowsocksr-ssr-one-click-script/) + +[Ubuntu TLS/Debian系统ShadowsocksR/SS一键脚本](https://v2raytech.com/ubuntu-shadowsocksr-ssr-one-click-script/) + +[CentOS 7/8系统V2Ray一键脚本](https://v2raytech.com/centos-one-click-install-v2ray/) + +[Ubuntu TLS/Debian系统V2Ray一键脚本](https://v2raytech.com/ubuntu-one-click-install-v2ray/) + +[CentOS 7/8系统带伪装V2Ray一键脚本](https://v2raytech.com/v2ray-one-click-script-with-mask/) + +[Ubuntu TLS/Debian系统带伪装V2Ray一键脚本](https://v2raytech.com/ubuntu-v2ray-one-click-script-with-mask/) + +[trojan一键脚本](https://v2raytech.com/trojan-one-click-scrip/) + +[一键搭建Telegram的MTProto代理](https://v2raytech.com/one-click-telegram-mtproto-proxy/) + +[trojan-go一键脚本](https://v2raytech.com/trojan-go-one-click-script/) + +[V2ray多合一脚本,支持VMESS+websocket+TLS+Nginx、VLESS+TCP+XTLS、VLESS+TCP+TLS等组合](https://v2raytech.com/v2ray-all-in-one-script-vless-tcp-xtls-support/) + +[Xray一键脚本](https://v2raytech.com/xray-one-click-script/) # 客户端配置教程 ## SS -[Shadowsocks/SS windows客户端配置教程](https://www.hijk.pw/shadowsocks-windows-client-config-tutorial/) +[Shadowsocks/SS windows客户端配置教程](https://v2raytech.com/shadowsocks-windows-client-config-tutorial/) -[Shadowsocks/SS安卓配置教程](https://www.hijk.pw/shadowsocks-android-config-tutorial/) +[Shadowsocks/SS安卓配置教程](https://v2raytech.com/shadowsocks-android-config-tutorial/) -[小火箭(Shadowrocket)配置ss/ssr教程](https://www.hijk.pw/shadowrocket-config-shadowsocks-shadowsocksr-tutorial/) +[小火箭(Shadowrocket)配置ss/ssr教程](https://v2raytech.com/shadowrocket-config-shadowsocks-shadowsocksr-tutorial/) -[ShadowsocksX-NG配置教程](https://www.hijk.pw/shadowsocksx-ng-config-tutorial/) +[ShadowsocksX-NG配置教程](https://v2raytech.com/shadowsocksx-ng-config-tutorial/) ## SSR -[ShadowsocksR/SSR windows客户端配置教程](https://www.hijk.pw/shadowsocksr-ssr-windows-client-config-tutorial/) +[ShadowsocksR/SSR windows客户端配置教程](https://v2raytech.com/shadowsocksr-ssr-windows-client-config-tutorial/) -[ShadowsocksR/SSR/SSRR安卓客户端配置教程](https://www.hijk.pw/shadowsocksr-ssr-ssrr-android-config-tutorial/) +[ShadowsocksR/SSR/SSRR安卓客户端配置教程](https://v2raytech.com/shadowsocksr-ssr-ssrr-android-config-tutorial/) -[小火箭(Shadowrocket)配置ss/ssr教程](https://www.hijk.pw/shadowrocket-config-shadowsocks-shadowsocksr-tutorial/) +[小火箭(Shadowrocket)配置ss/ssr教程](https://v2raytech.com/shadowrocket-config-shadowsocks-shadowsocksr-tutorial/) -[SSR版ShadowsocksX-NG配置教程](https://www.hijk.pw/ssr-shadowsocksx-ng-config-tutorial/) +[SSR版ShadowsocksX-NG配置教程](https://v2raytech.com/ssr-shadowsocksx-ng-config-tutorial/) ## V2Ray -[V2rayN配置教程](https://www.hijk.pw/v2rayn-config-tutorial/) +[V2rayN 4.12配置教程](https://v2raytech.com/v2rayn-4-12-config-tutorial/) -[V2rayW配置教程](https://www.hijk.pw/v2rayw-config-tutorial/) +[V2rayN配置教程](https://v2raytech.com/v2rayn-config-tutorial/) -[V2rayU配置教程](https://www.hijk.pw/v2rayu-config-tutorial/) +[V2rayW配置教程](https://v2raytech.com/v2rayw-config-tutorial/) -[V2rayX配置教程](https://www.hijk.pw/v2rayx-config-tutorial/) +[V2rayU配置教程](https://v2raytech.com/v2rayu-config-tutorial/) -[V2rayNG配置教程](https://www.hijk.pw/v2rayng-config-tutorial/) - +[V2rayX配置教程](https://v2raytech.com/v2rayx-config-tutorial/) + +[V2rayNG配置教程](https://v2raytech.com/v2rayng-config-tutorial/) + +[Kitsunebi安卓版配置教程](https://v2raytech.com/kitsunebi-android-config-tutorial/) + +[bifrostV配置教程](https://v2raytech.com/bifrostv-config-tutorial/) + +[v2ray多用户配置](https://v2raytech.com/v2ray-multiple-users/) + +[v2ray伪装建站教程](https://v2raytech.com/v2ray-mask-with-website/) + +[Clash for Windows配置V2ray教程](https://v2raytech.com/clash-for-windows-v2ray-tutorial/) + +[ClashX配置V2ray教程](https://v2raytech.com/clashx-config-v2ray-tutorial/) + +[Clash for Android配置V2ray教程](https://v2raytech.com/clash-for-android-config-v2ray-tutorial/) + +## trojan + +[trojan Windows客户端配置教程](https://v2raytech.com/trojan-windows-client-tutorial/) + +[trojan安卓客户端配置教程](https://v2raytech.com/trojan-android-client-config-tutorial/) + +[trojan mac客户端配置教程](https://v2raytech.com/trojan-mac-client-config-tutorial/) + +[Shadowrocket配置trojan教程](https://v2raytech.com/shadowrocket-config-trojan-tutorial/) + +[Clash for Windows配置trojan教程](https://v2raytech.com/clash-for-windows-trojan-config/) + +[ClashX配置Trojan教程](https://v2raytech.com/clashx-config-trojan-tutorial/) + +[Clash for Android配置trojan教程](https://v2raytech.com/clash-for-android-config-trojan-tutorial/) + +[trojan建站教程](https://v2raytech.com/build-website-with-trojan/) + +[trojan-go建站教程](https://v2raytech.com/trojan-go-with-website/) + +# VPS教程 + +[VPS可以用来做什么?](https://v2raytech.com/what-can-vps-do/) + +[CN2 GIA商家推荐](https://v2raytech.com/cn2-gia-merchants/) + +[做站VPS推荐](https://v2raytech.com/vps-for-website/) + +[搬瓦工购买服务器详细教程](https://v2raytech.com/bandwagonghost-buy-vps-tutorial/) + +[购买vultr服务器超详细图文教程](https://v2raytech.com/vultr-buy-vps-tutorial/) + +[DMIT服务器购买和使用教程](https://v2raytech.com/dmit-vps-tutorial/) + +[性价比最高的香港服务器](https://v2raytech.com/best-hongkong-vps/) + +[HostDare购买服务器超详细教程](https://v2raytech.com/hostdare-buy-vps-tutorial/) + +[vps ping测试、去程/回程路由跟踪、vps一键测试脚本](https://v2raytech.com/benchmark-your-vps/) + +[IP、域名、DNS和VPS之间的关系](https://v2raytech.com/ip-vps-domain-relations/) + +[为什么回程路由比去程路由重要?](https://v2raytech.com/why-return-route-important/) + +[CloudCone CN2 GIA套餐开售了,趁还没超售可买来香一把](https://v2raytech.com/cloudcone-cn2-gia-plans-on-sale/) + +[Bitvise连接Linux服务器教程](https://v2raytech.com/bitvise-connect-linux-server-tutorial/) + +[Mac电脑连接Linux教程](https://v2raytech.com/mac-connect-to-linux-tutorial/) + +[vultr常见问题](https://v2raytech.com/vultr-faq/) + +[v2ray使用cloudflare中转流量,拯救被墙ip](https://v2raytech.com/use-cloudflare-unlock-blocked-ip/) + +[CloudCone特价VPS促销,就在今天!](https://v2raytech.com/cloudcone-special-vps-offers/) + +[购买VPS的建议](https://v2raytech.com/buy-vps-tips/) + +[使用NAT VPS中转加速](https://v2raytech.com/use-nat-vps-forward-traffic/) + +[frp内网穿透教程](https://v2raytech.com/frp-nat-tunnel-tutorial/) + +[流畅看1080p、2k、4k视频需要多大带宽?](https://v2raytech.com/1080p-2k-4k-video-bandwidth-requirement/) + +[阿里云卸载云盾/安骑士](https://v2raytech.com/uninstall-aliyun-dun/) + +[腾讯云监控软件一键卸载脚本](https://v2raytech.com/uninstall-tencent-cloud-monitors/) + +[致富经:每天1000+京豆,京东薅羊毛全攻略(星推官、红包、游戏、签到等)](https://v2raytech.com/jd-script-to-get-rich/) + +# Just My Socks + +[Just My Socks购买和使用教程](https://v2raytech.com/just-my-socks-buy-and-use-tutorial/) + +[Just My Socks Windows配置教程](https://v2raytech.com/just-my-socks-windows-config-tutorial/) + +[Just My Socks安卓配置教程](https://v2raytech.com/just-my-socks-android-config-tutorial/) + +[Just My Socks iOS配置教程](https://v2raytech.com/just-my-socks-ios-config-tutorial/) + +[Just My Socks苹果配置教程](https://v2raytech.com/just-my-socks-mac-config-tutorial/) + +[Clash for Windows配置Just My Socks教程](https://v2raytech.com/clash-for-windows-config-just-my-socks-tutorial/) + +[ClashX配置Just My Socks教程](https://v2raytech.com/clashx-config-just-my-socks-tutorial/) + +[Clash for Android配置Just My Socks教程](https://v2raytech.com/clash-for-android-config-just-my-socks-tutorial/) + +[深入理解Clash配置文件](https://v2raytech.com/deep-in-clash-config-file/) + +# 其他 -# VPS +[境外apple id信息汇总](https://v2raytech.com/external-apple-id-summary/) -[搬瓦工购买服务器详细教程](https://www.hijk.pw/bandwagonghost-buy-vps-tutorial/) +[切换apple id下载其它国家和地区的应用](https://v2raytech.com/switch-appleid-to-download-app/) -[购买vultr服务器超详细图文教程](https://www.hijk.pw/vultr-buy-vps-tutorial/) +[Namesilo购买域名详细教程](https://v2raytech.com/namesilo-buy-domain-tutorial/) -[HostDare购买服务器超详细教程](https://www.hijk.pw/hostdare-buy-vps-tutorial/) +[免费vpn有风险,请慎用](https://v2raytech.com/be-careful-when-use-free-vpn/) -[手机购买vultr服务器图文教程](https://www.hijk.pw/buy-vultr-vps-in-mobile/) +[对机场/vpn的看法](https://v2raytech.com/opinion-on-vpn-service/) -[Bitvise连接Linux服务器教程](https://www.hijk.pw/bitvise-connect-linux-server-tutorial/) +[Telegram新手指南和使用教程](https://v2raytech.com/telegram-tutorial/) -[Mac电脑连接Linux教程](https://www.hijk.pw/mac-connect-to-linux-tutorial/) +[别太把自己当回事](https://v2raytech.com/do-not-treat-yourself-important/) -[vultr常见问题](hijk.pw/vultr-faq/) +[那些年跑路的机场](https://v2raytech.com/proxy-service-suspended-unexpected/) +[科学上网常见问题](https://v2raytech.com/vpn-faq/) -## 其他 +[PC端科学上网常见问题](https://v2raytech.com/pc-vpn-problem-faq/) -[境外apple id信息汇总](https://www.hijk.pw/external-apple-id-summary/) +[通过国内服务器转发流量](https://v2raytech.com/forward-traffic-via-internal-vps/) -[切换apple id下载其它国家和地区的应用](https://www.hijk.pw/switch-appleid-to-download-app/) +[该选用哪种加密算法?](https://v2raytech.com/choose-crypto-method/) -[免费vpn有风险,请慎用](https://www.hijk.pw/be-careful-when-use-free-vpn/) +[添加ipv6支持](https://v2raytech.com/add-ipv6-support/) -[科学上网常见问题](https://www.hijk.pw/vpn-faq/) +[不建议开启tcp fast open功能](https://v2raytech.com/donot-use-tcp-fast-open/) -[通过国内服务器转发流量](https://www.hijk.pw/forward-traffic-via-internal-vps/) +[安装魔改BBR/BBR Plus/锐速(Lotserver)](https://v2raytech.com/install-bbr-plus-lotserver/) -[该选用哪种加密算法?](https://www.hijk.pw/choose-crypto-method/) +[配置Telegram走SS/SSR/V2ray/trojan代理](https://v2raytech.com/pc-config-telegram-use-proxy/) -[添加ipv6支持](https://www.hijk.pw/add-ipv6-support/) +[WordPress插件推荐及性能优化建议](https://v2raytech.com/wordpress-plugin-recommand-and-mentions/) -[不建议开启tcp fast open功能](https://www.hijk.pw/donot-use-tcp-fast-open/) +[Google Scholar/谷歌学术403: your client does not have permission to get URL或者we’re sorry的解决办法](https://v2raytech.com/google-scholar-403-error-solution/) -[Namesilo购买域名详细教程](https://www.hijk.pw/namesilo-buy-domain-tutorial/) +## 捐赠 +BTC: 1ND1Gg7oEQCNVPyHVoAaq1sM9Ee3XLJZQG +ETH: 0x3921dc87110467324A01e1113E6aFa3c8DCD865D diff --git a/centos7_install_ss.sh b/centos7_install_ss.sh deleted file mode 100644 index 625ef65f..00000000 --- a/centos7_install_ss.sh +++ /dev/null @@ -1,293 +0,0 @@ -#!/bin/bash -# shadowsocks/ss CentOS一键安装教程 -# Author: hijk - -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' - -function checkSystem() -{ - result=$(id | awk '{print $1}') - if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" - exit 1 - fi - - if [ ! -f /etc/centos-release ];then - echo "系统不是CentOS" - exit 1 - fi - - result=`cat /etc/centos-release|grep -oE "[0-9.]+"` - main=${result%%.*} - if [ "$main" != "7" ]; then - echo "不受支持的CentOS版本" - exit 1 - fi -} - -function getData() -{ - read -p "请设置SS的密码(不输入则随机生成):" password - [ -z "$password" ] && password=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` - echo "" - echo "密码: $password" - echo "" - - while true - do - read -p "请设置SS的端口号[1025-65535]:" port - [ -z "$port" ] && port="12345" - expr $port + 0 &>/dev/null - if [ $? -eq 0 ]; then - if [ $port -ge 1025 ] && [ $port -le 65535 ]; then - echo "" - echo "端口号: $port" - echo "" - break - else - echo "输入错误,端口号为1025-65535的数字" - fi - else - echo "输入错误,端口号为1025-65535的数字" - fi - done - echo "请选择SS的加密方式:" - echo "1)aes-256-gcm" - echo "2)aes-192-gcm" - echo "3)aes-128-gcm" - echo "4)aes-256-ctr" - echo "5)aes-192-ctr" - echo "6)aes-128-ctr" - echo "7)aes-256-cfb" - echo "8)aes-192-cfb" - echo "9)aes-128-cfb" - echo "10)camellia-128-cfb" - echo "11)camellia-192-cfb" - echo "12)camellia-256-cfb" - echo "13)chacha20-ietf" - echo "14)chacha20-ietf-poly1305" - echo "15)xchacha20-ietf-poly1305" - read -p "请选择(默认aes-256-cfb)" answer - if [ -z "$answer" ]; then - method="aes-256-cfb" - else - case $answer in - 1) - method="aes-256-gcm" - ;; - 2) - method="aes-192-gcm" - ;; - 3) - method="aes-128-gcm" - ;; - 4) - method="aes-256-ctr" - ;; - 5) - method="aes-192-ctr" - ;; - 6) - method="aes-128-ctr" - ;; - 7) - method="aes-256-cfb" - ;; - 8) - method="aes-192-cfb" - ;; - 9) - method="aes-128-cfb" - ;; - 10) - method="camellia-128-cfb" - ;; - 11) - method="camellia-192-cfb" - ;; - 12) - method="camellia-256-cfb" - ;; - 13) - method="chacha20-ietf" - ;; - 14) - method="chacha20-ietf-poly1305" - ;; - 15) - method="xchacha20-ietf-poly1305" - ;; - *) - echo "无效的选择,使用默认的aes-256-cfb" - method="aes-256-cfb" - esac - fi - echo "" - echo "加密方式: $method" - echo "" -} - -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - yum update -y - fi - - echo "安装必要软件" - yum install -y epel-release telnet wget vim net-tools unzip - yum install -y nginx - systemctl enable nginx && systemctl restart nginx - - if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then - sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config - setenforce 0 - fi -} - -function installSS() -{ - echo 安装SS... - wget -O /etc/yum.repos.d/librehat-shadowsocks-epel-7.repo 'https://copr.fedorainfracloud.org/coprs/librehat/shadowsocks/repo/epel-7/librehat-shadowsocks-epel-7.repo' >> /dev/null 2>&1 - yum install -y shadowsocks-libev - - if [ ! -d /etc/shadowsocks-libev ];then - mkdir /etc/shadowsocks-libev - fi - cat > /etc/shadowsocks-libev/config.json<<-EOF -{ - "server":"0.0.0.0", - "server_port":${port}, - "local_port":1080, - "password":"${password}", - "timeout":600, - "method":"${method}", - "nameserver":"8.8.8.8", - "mode":"tcp_and_udp", - "fast_open":false -} -EOF - systemctl enable shadowsocks-libev - systemctl restart shadowsocks-libev - sleep 3 - res=`netstat -nltp | grep ${port} | grep 'ss-server'` - if [ "${res}" = "" ]; then - echo "ss启动失败,请检查端口是否被占用!" - exit 1 - fi -} - -function setFirewall() -{ - systemctl status firewalld > /dev/null 2>&1 - if [ $? -eq 0 ];then - firewall-cmd --permanent --add-port=${port}/tcp - firewall-cmd --permanent --add-port=${port}/udp - firewall-cmd --permanent --add-service=http - firewall-cmd --reload - fi -} - -function installBBR() -{ - result=$(lsmod | grep bbr) - if [ "$result" != "" ]; then - echo BBR模块已安装 - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=true - return; - fi - - echo 安装BBR模块... - rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org - rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm - yum --enablerepo=elrepo-kernel install kernel-ml -y - grub2-set-default 0 - echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false -} - -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/shadowsocks-libev/config.json | grep server_port | cut -d: -f2 | tr -d \",' '` - res=`netstat -nltp | grep ${port} | grep python` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - password=`cat /etc/shadowsocks-libev/config.json | grep password | cut -d: -f2 | tr -d \",' '` - method=`cat /etc/shadowsocks-libev/config.json | grep method | cut -d: -f2 | tr -d \",' '` - - echo ============================================ - echo -e " ss运行状态:${status}" - echo -e " ss配置文件:${red}/etc/shadowsocks-libev/config.json${plain}" - echo "" - echo -e "${red}ss配置信息:${plain}" - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " 密码(password):${red}${password}${plain}" - echo -e " 加密方式(method): ${red}${method}${plain}" - echo - echo ============================================ -} - -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then - echo - echo 为使BBR模块生效,系统将在30秒后重启 - echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" - sleep 30 - reboot - fi -} - - -function install() -{ - echo -n "系统版本: " - cat /etc/centos-release - checkSystem - getData - preinstall - installBBR - installSS - setFirewall - - info - bbrReboot -} - -function uninstall() -{ - read -p "您确定真的要卸载SS吗?(y/n)" answer - [ -z ${answer} ] && answer="n" - - if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then - systemctl stop shadowsocks-libev - systemctl disable shadowsocks-libev - yum remove shadowsocks-libev - echo "SS卸载完成" - fi -} - -action=$1 -[ -z $1 ] && action=install -case "$action" in - install|uninstall|info) - ${action} - ;; - *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall|info]" - ;; -esac diff --git a/centos8_install_ss.sh b/centos8_install_ss.sh deleted file mode 100644 index ef7368ff..00000000 --- a/centos8_install_ss.sh +++ /dev/null @@ -1,294 +0,0 @@ -#!/bin/bash -# shadowsocks/ss CentOS8一键安装脚本 -# Author: hijk - -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' -BASE=`pwd` - -function checkSystem() -{ - result=$(id | awk '{print $1}') - if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" - exit 1 - fi - - if [ ! -f /etc/centos-release ];then - echo "系统不是CentOS" - exit 1 - fi - - result=`cat /etc/centos-release|grep -oE "[0-9.]+"` - main=${result%%.*} - if [ "$main" != "8" ]; then - echo "不受支持的CentOS版本" - exit 1 - fi -} - -function getData() -{ - read -p "请设置SS的密码(不输入则随机生成):" password - [ -z "$password" ] && password=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` - echo "" - echo "密码: $password" - echo "" - - while true - do - read -p "请设置SS的端口号[1025-65535]:" port - [ -z "$port" ] && port="12345" - expr $port + 0 &>/dev/null - if [ $? -eq 0 ]; then - if [ $port -ge 1025 ] && [ $port -le 65535 ]; then - echo ""1234 - echo "端口号: $port" - echo "" - break - else - echo "输入错误,端口号为1025-65535的数字" - fi - else - echo "输入错误,端口号为1025-65535的数字" - fi - done - echo "请选择SS的加密方式:" - echo "1)aes-256-gcm" - echo "2)aes-192-gcm" - echo "3)aes-128-gcm" - echo "4)aes-256-ctr" - echo "5)aes-192-ctr" - echo "6)aes-128-ctr" - echo "7)aes-256-cfb" - echo "8)aes-192-cfb" - echo "9)aes-128-cfb" - echo "10)camellia-128-cfb" - echo "11)camellia-192-cfb" - echo "12)camellia-256-cfb" - echo "13)chacha20-ietf" - echo "14)chacha20-ietf-poly1305" - echo "15)xchacha20-ietf-poly1305" - read -p "请选择(默认aes-256-cfb)" answer - if [ -z "$answer" ]; then - method="aes-256-cfb" - else - case $answer in - 1) - method="aes-256-gcm" - ;; - 2) - method="aes-192-gcm" - ;; - 3) - method="aes-128-gcm" - ;; - 4) - method="aes-256-ctr" - ;; - 5) - method="aes-192-ctr" - ;; - 6) - method="aes-128-ctr" - ;; - 7) - method="aes-256-cfb" - ;; - 8) - method="aes-192-cfb" - ;; - 9) - method="aes-128-cfb" - ;; - 10) - method="camellia-128-cfb" - ;; - 11) - method="camellia-192-cfb" - ;; - 12) - method="camellia-256-cfb" - ;; - 13) - method="chacha20-ietf" - ;; - 14) - method="chacha20-ietf-poly1305" - ;; - 15) - method="xchacha20-ietf--poly1305" - ;; - *) - echo "无效的选择,使用默认的aes-256-cfb" - method="aes-256-cfb" - esac - fi - echo "" - echo "加密方式: $method" - echo "" -} - -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - yum update -y - fi - - echo "安装必要软件" - yum install -y epel-release telnet wget vim net-tools unzip - yum install -y nginx openssl openssl-devel gettext gcc autoconf libtool automake make asciidoc xmlto udns-devel libev-devel pcre pcre-devel mbedtls mbedtls-devel libsodium libsodium-devel c-ares c-ares-devel - systemctl enable nginx && systemctl restart nginx - - if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then - sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config - setenforce 0 - fi -} - -function installSS() -{ - echo 安装SS... - - if ! wget 'https://github.com/shadowsocks/shadowsocks-libev/releases/download/v3.3.3/shadowsocks-libev-3.3.3.tar.gz' -O shadowsocks-libev-3.3.3.tar.gz; then - echo "下载文件失败!" - exit 1 - fi - tar zxf shadowsocks-libev-3.3.3.tar.gz - cd shadowsocks-libev-3.3.3 - ./configure - make && make install - if [ $? -ne 0 ]; then - echo - echo -e "[${red}错误${plain}] Shadowsocks-libev 安装失败! 请打开 https://www.hijk.pw 反馈" - cd ${BASE} && rm -rf shadowsocks-libev-3.3.3* - exit 1 - fi - cd ${BASE} && rm -rf shadowsocks-libev-3.3.3* - - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - if [ ! -d /etc/shadowsocks-libev ];then - mkdir /etc/shadowsocks-libev - fi - cat > /etc/shadowsocks-libev/config.json<<-EOF -{ - "server":"0.0.0.0", - "server_port":${port}, - "local_port":1080, - "password":"${password}", - "timeout":600, - "method":"${method}", - "nameserver":"8.8.8.8", - "mode":"tcp_and_udp", - "fast_open":false -} -EOF - cat > /usr/lib/systemd/system/shadowsocks-libev.service <<-EOF -[Unit] -Description=shadowsocks -Documentation=https://www.hijk.pw/ -After=network-online.target -Wants=network-online.target - -[Service] -Type=simple -PIDFile=/var/run/shadowsocks-libev.pid -LimitNOFILE=32768 -ExecStart=/usr/local/bin/ss-server -c /etc/shadowsocks-libev/config.json -f /var/run/shadowsocks-libev.pid -ExecReload=/bin/kill -s HUP $MAINPID -ExecStop=/bin/kill -s TERM $MAINPID - -[Install] -WantedBy=multi-user.target -EOF - systemctl daemon-reload - systemctl enable shadowsocks-libev - systemctl restart shadowsocks-libev - sleep 3 - res=`netstat -nltp | grep ${port} | grep 'ss-server'` - if [ "${res}" = "" ]; then - echo "ss启动失败,请检查端口是否被占用!" - exit 1 - fi -} - -function setFirewall() -{ - systemctl status firewalld > /dev/null 2>&1 - if [ $? -eq 0 ];then - firewall-cmd --permanent --add-port=${port}/tcp - firewall-cmd --permanent --add-port=${port}/udp - firewall-cmd --permanent --add-service=http - firewall-cmd --reload - fi -} - -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/shadowsocks-libev/config.json | grep server_port | cut -d: -f2 | tr -d \",' '` - res=`netstat -nltp | grep ${port} | grep 'ss-server'` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - password=`cat /etc/shadowsocks-libev/config.json | grep password | cut -d: -f2 | tr -d \",' '` - method=`cat /etc/shadowsocks-libev/config.json | grep method | cut -d: -f2 | tr -d \",' '` - - echo ============================================ - echo -e " ss运行状态:${status}" - echo -e " ss配置文件:${red}/etc/shadowsocks-libev/config.json${plain}" - echo "" - echo -e "${red}ss配置信息:${plain}" - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " 密码(password):${red}${password}${plain}" - echo -e " 加密方式(method): ${red}${method}${plain}" - echo - echo ============================================ -} - -function install() -{ - echo -n "系统版本: " - cat /etc/centos-release - checkSystem - getData - preinstall - installSS - setFirewall - - info -} - -function uninstall() -{ - read -p "您确定真的要卸载SS吗?(y/n)" answer - [ -z ${answer} ] && answer="n" - - if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then - systemctl stop shadowsocks-libev && systemctl disable shadowsocks-libev - rm -rf /usr/lib/systemd/system/shadowsocks-libev.service - cd /usr/local/bin && rm -rf ss-local ss-manager ss-nat ss-redir ss-server ss-tunnel - rm -rf /usr/lib64/libshadowsocks-libev* - rm -rf /usr/share/doc/shadowsocks-libev - rm -rf /usr/share/man/man1/ss-*.1.gz - rm -rf /usr/share/man/man8/shadowsocks-libev.8.gz - echo "SS卸载完成" - fi -} - -action=$1 -[ -z $1 ] && action=install -case "$action" in - install|uninstall|info) - ${action} - ;; - *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall|info]" - ;; -esac diff --git a/centos_install_ss.sh b/centos_install_ss.sh index 84cce35b..25beea03 100644 --- a/centos_install_ss.sh +++ b/centos_install_ss.sh @@ -1,59 +1,370 @@ #!/bin/bash -# shadowsocks/ss CentOS 7/8一键安装脚本 -# Author: hijk +# shadowsocks/ss CentOS一键安装脚本 +# Author: hijk -echo "#############################################################" -echo "# CentOS 7/8 Shadowsocks/SS 一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" -red='\033[0;31m' -plain='\033[0m' +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' -function checkSystem() -{ +BASE=`pwd` +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +CONFIG_FILE="/etc/shadowsocks-libev/config.json" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { result=$(id | awk '{print $1}') - if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" + if [[ "$result" != "uid=0(root)" ]]; then + colorEcho $RED " 请以root身份执行该脚本" exit 1 fi - if [ ! -f /etc/centos-release ];then - echo "系统不是CentOS" - exit 1 + if [[ ! -f /etc/centos-release ]]; then + res=`which yum` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统不是CentOS" + exit 1 + fi + else + result=`cat /etc/centos-release|grep -oE "[0-9.]+"` + main=${result%%.*} + if [[ $main -lt 7 ]]; then + colorEcho $RED " 不受支持的CentOS版本" + exit 1 + fi + fi +} + +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}CentOS 7/8 Shadowsocks/SS 一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" +} + +getData() { + read -p " 请设置SS的密码(不输入则随机生成):" PASSWORD + [[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + echo "" + colorEcho $BLUE " 密码: $PASSWORD" + echo "" + + while true + do + read -p " 请设置SS的端口号[1025-65535]:" PORT + [[ -z "$PORT" ]] && PORT="12345" + if [[ "${PORT:0:1}" = "0" ]]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null + if [[ $? -eq 0 ]]; then + if [[ $PORT -ge 1025 ]] && [[ $PORT -le 65535 ]]; then + echo "" + colorEcho $BLUE " 端口号: $PORT" + echo "" + break + else + colorEcho $RED " 输入错误,端口号为1025-65535的数字" + fi + else + colorEcho $RED " 输入错误,端口号为1025-65535的数字" + fi + done + colorEcho $RED " 请选择加密方式:" + echo " 1)aes-256-gcm" + echo " 2)aes-192-gcm" + echo " 3)aes-128-gcm" + echo " 4)aes-256-ctr" + echo " 5)aes-192-ctr" + echo " 6)aes-128-ctr" + echo " 7)aes-256-cfb" + echo " 8)aes-192-cfb" + echo " 9)aes-128-cfb" + echo " 10)camellia-128-cfb" + echo " 11)camellia-192-cfb" + echo " 12)camellia-256-cfb" + echo " 13)chacha20-ietf" + echo " 14)chacha20-ietf-poly1305" + echo " 15)xchacha20-ietf-poly1305" + read -p " 请选择(默认aes-256-gcm)" answer + if [[ -z "$answer" ]]; then + METHOD="aes-256-gcm" + else + case $answer in + 1) + METHOD="aes-256-gcm" + ;; + 2) + METHOD="aes-192-gcm" + ;; + 3) + METHOD="aes-128-gcm" + ;; + 4) + METHOD="aes-256-ctr" + ;; + 5) + METHOD="aes-192-ctr" + ;; + 6) + METHOD="aes-128-ctr" + ;; + 7) + METHOD="aes-256-cfb" + ;; + 8) + METHOD="aes-192-cfb" + ;; + 9) + METHOD="aes-128-cfb" + ;; + 10) + METHOD="camellia-128-cfb" + ;; + 11) + METHOD="camellia-192-cfb" + ;; + 12) + METHOD="camellia-256-cfb" + ;; + 13) + METHOD="chacha20-ietf" + ;; + 14) + METHOD="chacha20-ietf-poly1305" + ;; + 15) + METHOD="xchacha20-ietf-poly1305" + ;; + *) + colorEcho $RED " 无效的选择,使用默认的aes-256-gcm" + METHOD="aes-256-gcm" + esac fi + echo "" + colorEcho $BLUE "加密方式: $METHOD" + echo "" +} + +preinstall() { + yum clean all + #yum update -y - result=`cat /etc/centos-release|grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 7 ]; then - echo "不受支持的CentOS版本" + colorEcho $BULE " 安装必要软件" + yum install -y epel-release telnet wget vim net-tools unzip tar qrencode + yum install -y openssl openssl-devel gettext gcc autoconf libtool automake make asciidoc xmlto udns-devel libev-devel pcre pcre-devel mbedtls mbedtls-devel libsodium libsodium-devel c-ares c-ares-devel + res=`which wget` + [[ "$?" != "0" ]] && yum install -y wget + res=`which netstat` + [[ "$?" != "0" ]] && yum install -y net-tools + + + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +normalizeVersion() { + if [ -n "$1" ]; then + case "$1" in + v*) + echo "${1:1}" + ;; + *) + echo "$1" + ;; + esac + else + echo "" + fi +} + +installNewVer() { + new_ver=$1 + if ! wget "${V6_PROXY}https://github.com/shadowsocks/shadowsocks-libev/releases/download/v${new_ver}/shadowsocks-libev-${new_ver}.tar.gz" -O shadowsocks-libev.tar.gz; then + colorEcho $RED " 下载安装文件失败!" + exit 1 + fi + tar zxf shadowsocks-libev.tar.gz + cd shadowsocks-libev-${new_ver} + ./configure + make && make install + if [[ $? -ne 0 ]]; then + echo + echo -e " [${RED}错误${PLAIN}]: $OS Shadowsocks-libev 安装失败! 请打开 https://hijk.art 反馈" + cd ${BASE} && rm -rf shadowsocks-libev* exit 1 fi + cd ${BASE} && rm -rf shadowsocks-libev* } -checkSystem +installSS() { + colorEcho $BLUE " 安装SS..." -action=$1 -[ -z $1 ] && action=install -case "$action" in - install) - if [ $main -eq 7 ]; then - bash <(curl -L -s https://raw.githubusercontent.com/hijkpw/scripts/master/centos7_install_ss.sh) + tag_url="${V6_PROXY}https://api.github.com/repos/shadowsocks/shadowsocks-libev/releases/latest" + new_ver="$(normalizeVersion "$(curl -s "${tag_url}" --connect-timeout 10| grep 'tag_name' | cut -d\" -f4)")" + export PATH=/usr/local/bin:$PATH + ssPath=`which ss-server` + if [[ "$?" != "0" ]]; then + installNewVer $new_ver + else + ver=`ss-server -h | grep shadowsocks-libev | grep -oE '[0-9+\.]+'` + if [[ $ver != $new_ver ]]; then + installNewVer $new_ver else - bash <(curl -L -s https://raw.githubusercontent.com/hijkpw/scripts/master/centos8_install_ss.sh) + colorEcho $YELLOW " 已安装最新版SS" fi - ;; - uninstall) - if [ $main -eq 7 ]; then - bash <(curl -L -s https://raw.githubusercontent.com/hijkpw/scripts/master/centos7_install_ss.sh) uninstall - else - bash <(curl -L -s https://raw.githubusercontent.com/hijkpw/scripts/master/centos8_install_ss.sh) uninstall + fi + + interface="0.0.0.0" + if [[ "$V6_PROXY" != "" ]]; then + interface="::" + fi + mkdir -p /etc/shadowsocks-libev + ssPath=`which ss-server` + cat > $CONFIG_FILE<<-EOF +{ + "server":"$interface", + "server_port":${PORT}, + "local_port":1080, + "password":"${PASSWORD}", + "timeout":600, + "method":"${METHOD}", + "nameserver":"8.8.8.8", + "mode":"tcp_and_udp", + "fast_open":false +} +EOF + cat > /usr/lib/systemd/system/shadowsocks-libev.service <<-EOF +[Unit] +Description=shadowsocks +Documentation=https://hijk.art/ +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +PIDFile=/var/run/shadowsocks-libev.pid +LimitNOFILE=32768 +ExecStart=$ssPath -c $CONFIG_FILE -f /var/run/shadowsocks-libev.pid +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable shadowsocks-libev + systemctl restart shadowsocks-libev + sleep 3 + res=`netstat -nltp | grep ${PORT} | grep 'ss-server'` + if [[ "${res}" = "" ]]; then + colorEcho $RED " ss启动失败,请检查端口是否被占用!" + exit 1 + fi +} + +setFirewall() { + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT fi + fi +} + +info() { + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep 'ss-server'` + [[ -z "$res" ]] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + + res=`echo -n "${method}:${password}@${IP}:${port}" | base64 -w 0` + link="ss://${res}" + + echo ============================================ + echo -e " ${BLUE}ss运行状态${PLAIN}:${status}" + echo -e " ${BLUE}ss配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo "" + echo -e " ${RED}ss配置信息:${PLAIN}" + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}加密方式(method):${PLAIN} ${RED}${method}${PLAIN}" + echo + echo -e " ${BLUE}ss链接${PLAIN}: ${link}" + qrencode -o - -t utf8 ${link} +} + +install() { + echo -n -e " ${BLUE}系统版本:$PLAIN " + cat /etc/centos-release + checkSystem + getData + preinstall + installSS + setFirewall + + info +} + +uninstall() { + echo "" + read -p " 确定卸载SS吗?(y/n)" answer + [[ -z ${answer} ]] && answer="n" + + if [[ "${answer}" == "y" ]] || [[ "${answer}" == "Y" ]]; then + systemctl stop shadowsocks-libev && systemctl disable shadowsocks-libev + rm -rf /usr/lib/systemd/system/shadowsocks-libev.service + cd /usr/local/bin && rm -rf ss-local ss-manager ss-nat ss-redir ss-server ss-tunnel + rm -rf /usr/lib64/libshadowsocks-libev* + rm -rf /usr/share/doc/shadowsocks-libev + rm -rf /usr/share/man/man1/ss-*.1.gz + rm -rf /usr/share/man/man8/shadowsocks-libev.8.gz + colorEcho $GREEN " SS卸载成功" + fi +} + +checkSystem + +slogon + +action=$1 +[[ -z $1 ]] && action=install +case "$action" in + install|uninstall|info) + ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall|info]" ;; esac diff --git a/centos_install_ssr.sh b/centos_install_ssr.sh index af1f01c4..ef30d73b 100644 --- a/centos_install_ssr.sh +++ b/centos_install_ssr.sh @@ -1,248 +1,277 @@ #!/bin/bash # shadowsocksR/SSR CentOS 7/8一键安装教程 -# Author: hijk +# Author: hijk -echo "#############################################################" -echo "# CentOS 7/8 ShadowsocksR/SSR 一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi FILENAME="ShadowsocksR-v3.2.2" -URL="https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz" +URL="${V6_PROXY}https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz" BASE=`pwd` -function checkSystem() -{ +OS=`hostnamectl | grep -i system | cut -d: -f2` + +CONFIG_FILE="/etc/shadowsocksR.json" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + + +checkSystem() { result=$(id | awk '{print $1}') if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" + colorEcho $RED " 请以root身份执行该脚本" exit 1 fi if [ ! -f /etc/centos-release ];then - echo "系统不是CentOS" - exit 1 - fi - - result=`cat /etc/centos-release|grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 7 ]; then - echo "不受支持的CentOS版本" - exit 1 + res=`which yum` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统不是CentOS" + exit 1 + fi + else + result=`cat /etc/centos-release|grep -oE "[0-9.]+"` + main=${result%%.*} + if [ $main -lt 7 ]; then + colorEcho $RED " 不受支持的CentOS版本" + exit 1 + fi fi } -function getData() -{ - read -p "请设置SSR的密码(不输入则随机生成):" password - [ -z "$password" ] && password=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}CentOS 7/8 ShadowsocksR/SSR 一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" +} + +getData() { + read -p " 请设置SSR的密码(不输入则随机生成):" PASSWORD + [ -z "$PASSWORD" ] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` echo "" - echo "密码: $password" + colorEcho $BLUE " 密码: $PASSWORD" echo "" while true do - read -p "请设置SSR的端口号[1-65535]:" port - [ -z "$port" ] && port="12345" - expr $port + 0 &>/dev/null + read -p " 请设置SSR的端口号[1-65535]:" PORT + [ -z "$PORT" ] && PORT="12345" + if [ "${PORT:0:1}" = "0" ]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null if [ $? -eq 0 ]; then - if [ $port -ge 1 ] && [ $port -le 65535 ]; then + if [ $PORT -ge 1 ] && [ $PORT -le 65535 ]; then echo "" - echo "端口号: $port" + colorEcho $BLUE " 端口号: $PORT" echo "" break else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi done - echo "请选择SSR的加密方式:" - echo "1)aes-256-cfb" - echo "2)aes-192-cfb" - echo "3)aes-128-cfb" - echo "4)aes-256-ctr" - echo "5)aes-192-ctr" - echo "6)aes-128-ctr" - echo "7)aes-256-cfb8" - echo "8)aes-192-cfb8" - echo "9)aes-128-cfb8" - echo "10)camellia-128-cfb" - echo "11)camellia-192-cfb" - echo "12)camellia-256-cfb" - echo "13)chacha20-ietf" - read -p "请选择加密方式(默认aes-256-cfb)" answer + + + colorEcho $BLUE " 请选择SSR的加密方式:" + echo " 1)aes-256-cfb" + echo " 2)aes-192-cfb" + echo " 3)aes-128-cfb" + echo " 4)aes-256-ctr" + echo " 5)aes-192-ctr" + echo " 6)aes-128-ctr" + echo " 7)aes-256-cfb8" + echo " 8)aes-192-cfb8" + echo " 9)aes-128-cfb8" + echo " 10)camellia-128-cfb" + echo " 11)camellia-192-cfb" + echo " 12)camellia-256-cfb" + echo " 13)chacha20-ietf" + read -p " 请选择加密方式(默认aes-256-cfb)" answer if [ -z "$answer" ]; then - method="aes-256-cfb" + METHOD="aes-256-cfb" else case $answer in 1) - method="aes-256-cfb" + METHOD="aes-256-cfb" ;; 2) - method="aes-192-cfb" + METHOD="aes-192-cfb" ;; 3) - method="aes-128-cfb" + METHOD="aes-128-cfb" ;; 4) - method="aes-256-ctr" + METHOD="aes-256-ctr" ;; 5) - method="aes-192-ctr" + METHOD="aes-192-ctr" ;; 6) - method="aes-128-ctr" + METHOD="aes-128-ctr" ;; 7) - method="aes-256-cfb8" + METHOD="aes-256-cfb8" ;; 8) - method="aes-192-cfb8" + METHOD="aes-192-cfb8" ;; 9) - method="aes-128-cfb8" + METHOD="aes-128-cfb8" ;; 10) - method="camellia-128-cfb" + METHOD="camellia-128-cfb" ;; 11) - method="camellia-192-cfb" + METHOD="camellia-192-cfb" ;; 12) - method="camellia-256-cfb" + METHOD="camellia-256-cfb" ;; 13) - method="chacha20-ietf" + METHOD="chacha20-ietf" ;; *) - echo "无效的选择,使用默认加密方式" - method="aes-256-cfb" + colorEcho $RED " 无效的选择,使用默认加密方式" + METHOD="aes-256-cfb" esac fi echo "" - echo "加密方式: $method" + colorEcho $BLUE " 加密方式: $METHOD" echo "" - echo "请选择SSR的协议:" - echo "1)origin" - echo "2)verify_deflate" - echo "3)auth_sha1_v4" - echo "4)auth_aes128_md5" - echo "5)auth_aes128_sha1" - echo "6)auth_chain_a" - echo "7)auth_chain_b" - echo "8)auth_chain_c" - echo "9)auth_chain_d" - echo "10)auth_chain_e" - echo "11)auth_chain_f" - read -p "请选择加密方式(默认origin)" answer + colorEcho $BLUE " 请选择SSR协议:" + echo " 1)origin" + echo " 2)verify_deflate" + echo " 3)auth_sha1_v4" + echo " 4)auth_aes128_md5" + echo " 5)auth_aes128_sha1" + echo " 6)auth_chain_a" + echo " 7)auth_chain_b" + echo " 8)auth_chain_c" + echo " 9)auth_chain_d" + echo " 10)auth_chain_e" + echo " 11)auth_chain_f" + read -p " 请选择SSR协议(默认origin)" answer if [ -z "$answer" ]; then - protocol="origin" + PROTOCOL="origin" else case $answer in 1) - protocol="origin" + PROTOCOL="origin" ;; 2) - protocol="verify_deflate" + PROTOCOL="verify_deflate" ;; 3) - protocol="auth_sha1_v4" + PROTOCOL="auth_sha1_v4" ;; 4) - protocol="auth_aes128_md5" + PROTOCOL="auth_aes128_md5" ;; 5) - protocol="auth_aes128_sha1" + PROTOCOL="auth_aes128_sha1" ;; 6) - protocol="auth_chain_a" + PROTOCOL="auth_chain_a" ;; 7) - protocol="auth_chain_b" + PROTOCOL="auth_chain_b" ;; 8) - protocol="auth_chain_c" + PROTOCOL="auth_chain_c" ;; 9) - protocol="auth_chain_d" + PROTOCOL="auth_chain_d" ;; 10) - protocol="auth_chain_e" + PROTOCOL="auth_chain_e" ;; 11) - protocol="auth_chain_f" + PROTOCOL="auth_chain_f" ;; *) - echo "无效的选择,使用默认协议" - protocol="origin" + colorEcho $RED " 无效的选择,使用默认协议" + PROTOCOL="origin" esac fi echo "" - echo "协议: $protocol" + colorEcho $BLUE " SSR协议: $PROTOCOL" echo "" - echo "请选择SSR混淆模式:" - echo "1)plain" - echo "2)http_simple" - echo "3)http_post" - echo "4)tls1.2_ticket_auth" - echo "5)tls1.2_ticket_fastauth" - read -p "请选择混淆模式(默认plain)" answer + colorEcho $BLUE " 请选择SSR混淆模式:" + echo " 1)plain" + echo " 2)http_simple" + echo " 3)http_post" + echo " 4)tls1.2_ticket_auth" + echo " 5)tls1.2_ticket_fastauth" + read -p " 请选择混淆模式(默认plain)" answer if [ -z "$answer" ]; then - obfs="plain" + OBFS="plain" else case $answer in 1) - obfs="plain" + OBFS="plain" ;; 2) - obfs="http_simple" + OBFS="http_simple" ;; 3) - obfs="http_post" + OBFS="http_post" ;; 4) - obfs="tls1.2_ticket_auth" + OBFS="tls1.2_ticket_auth" ;; 5) - obfs="tls1.2_ticket_fastauth" + OBFS="tls1.2_ticket_fastauth" ;; *) - echo "无效的选择,使用默认混淆模式" - obfs="plain" + colorEcho $RED " 无效的选择,使用默认混淆模式" + OBFS="plain" esac fi echo "" - echo "混淆: $obfs" + colorEcho $BLUE " 混淆模式: $OBFS" echo "" } -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - yum update -y - fi - echo "安装必要软件" - yum install -y epel-release telnet curl wget vim net-tools libsodium openssl unzip +preinstall() { + colorEcho $BLUE " 更新系统..." + yum clean all + #yum update -y + colorEcho $BLUE " 安装必要软件" + yum install -y epel-release telnet curl wget vim net-tools libsodium openssl unzip tar qrencode + res=`which wget` + [ "$?" != "0" ] && yum install -y wget + res=`which netstat` + [ "$?" != "0" ] && yum install -y net-tools if [ $main -eq 8 ]; then ln -s /usr/bin/python3 /usr/bin/python fi - yum install -y nginx - systemctl enable nginx && systemctl restart nginx if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config @@ -250,36 +279,36 @@ function preinstall() fi } -function installSSR() -{ +installSSR() { if [ ! -d /usr/local/shadowsocks ]; then echo 下载安装文件 if ! wget --no-check-certificate -O ${FILENAME}.tar.gz ${URL}; then - echo -e "[${red}Error${plain}] 下载文件失败!" + echo -e " [${RED}Error${PLAIN}] 下载文件失败!" exit 1 fi tar -zxf ${FILENAME}.tar.gz mv shadowsocksr-3.2.2/shadowsocks /usr/local if [ ! -f /usr/local/shadowsocks/server.py ]; then - echo "安装失败,请到 https://www.hijk.pw 网站反馈" + colorEcho $RED " $OS 安装失败,请到 https://hijk.art 网站反馈" cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz exit 1 fi + cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz fi - cat > /etc/shadowsocksR.json<<-EOF + cat > $CONFIG_FILE<<-EOF { "server":"0.0.0.0", - "server_ipv6":"[::]", - "server_port":${port}, + "server_ipv6":"::", + "server_port":${PORT}, "local_port":1080, - "password":"${password}", + "password":"${PASSWORD}", "timeout":600, - "method":"${method}", - "protocol":"${protocol}", + "method":"${METHOD}", + "protocol":"${PROTOCOL}", "protocol_param":"", - "obfs":"${obfs}", + "obfs":"${OBFS}", "obfs_param":"", "redirect":"", "dns_ipv6":false, @@ -291,16 +320,16 @@ EOF cat > /usr/lib/systemd/system/shadowsocksR.service <<-EOF [Unit] Description=shadowsocksR -Documentation=https://www.hijk.pw/ +Documentation=https://hijk.art/ After=network-online.target Wants=network-online.target [Service] Type=forking LimitNOFILE=32768 -ExecStart=/usr/local/shadowsocks/server.py -c /etc/shadowsocksR.json -d start -ExecReload=/bin/kill -s HUP $MAINPID -ExecStop=/bin/kill -s TERM $MAINPID +ExecStart=/usr/local/shadowsocks/server.py -c $CONFIG_FILE -d start +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID [Install] WantedBy=multi-user.target @@ -309,99 +338,109 @@ EOF systemctl daemon-reload systemctl enable shadowsocksR && systemctl restart shadowsocksR sleep 3 - res=`netstat -nltp | grep ${port} | grep python` + res=`netstat -nltp | grep ${PORT} | grep python` if [ "${res}" = "" ]; then - echo "ssr启动失败,请检查端口是否被占用!" + colorEcho $RED " ssr启动失败,请检查端口是否被占用!" exit 1 fi } -function setFirewall() -{ +setFirewall() { systemctl status firewalld > /dev/null 2>&1 - if [ $? -eq 0 ];then - firewall-cmd --permanent --add-port=${port}/tcp - firewall-cmd --permanent --add-port=${port}/udp + if [[ $? -eq 0 ]];then firewall-cmd --permanent --add-service=http + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi fi } -function installBBR() -{ +installBBR() { result=$(lsmod | grep bbr) if [ "$result" != "" ]; then - echo BBR模块已安装 - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=true + colorEcho $GREEN " BBR模块已安装" + INSTALL_BBR=false + return + fi + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false return fi - if [ $main -eq 8 ]; then - echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - sysctl -p - bbr=true + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false return fi - echo 安装BBR模块... + colorEcho $BLUE " 安装BBR模块..." rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm yum --enablerepo=elrepo-kernel install kernel-ml -y yum remove kernel-3.* -y grub2-set-default 0 echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + INSTALL_BBR=true } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/shadowsocksR.json | grep server_port | cut -d: -f2 | tr -d \",' '` +info() { + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` res=`netstat -nltp | grep ${port} | grep python` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - password=`cat /etc/shadowsocksR.json | grep password | cut -d: -f2 | tr -d \",' '` - method=`cat /etc/shadowsocksR.json | grep method | cut -d: -f2 | tr -d \",' '` - protocol=`cat /etc/shadowsocksR.json | grep protocol | cut -d: -f2 | tr -d \",' '` - obfs=`cat /etc/shadowsocksR.json | grep obfs | cut -d: -f2 | tr -d \",' '` + [ -z "$res" ] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + protocol=`grep protocol $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + obfs=`grep obfs $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` - echo ============================================ - echo -e " ssr运行状态:${status}" - echo -e " ssr配置文件:${red}/etc/shadowsocksR.json${plain}" + p1=`echo -n ${password} | base64 -w 0` + p1=`echo -n ${p1} | tr -d =` + res=`echo -n "${IP}:${port}:${protocol}:${method}:${obfs}:${p1}/?remarks=&protoparam=&obfsparam=" | base64 -w 0` + res=`echo -n ${res} | tr -d =` + link="ssr://${res}" + echo "" - echo -e "${red}ssr配置信息:${plain}" - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " 密码(password):${red}${password}${plain}" - echo -e " 加密方式(method): ${red}${method}${plain}" - echo -e " 协议(protocol):" ${red}${protocol}${plain} - echo -e " 混淆(obfuscation):" ${red}${obfs}${plain} - echo echo ============================================ + echo -e " ${BLUE}ssr运行状态:${PLAIN}${status}" + echo -e " ${BLUE}ssr配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo "" + echo -e " ${RED}ssr配置信息:${PLAIN}" + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}加密方式(method):${PLAIN} ${RED}${method}${PLAIN}" + echo -e " ${BLUE}协议(protocol):${PLAIN} ${RED}${protocol}${PLAIN}" + echo -e " ${BLUE}混淆(obfuscation):${PLAIN} ${RED}${obfs}${PLAIN}" + echo + echo -e " ${BLUE}ssr链接:${PLAIN} $link" + qrencode -o - -t utf8 $link } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [ "${INSTALL_BBR}" == "true" ]; then echo echo 为使BBR模块生效,系统将在30秒后重启 echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ +install() { echo -n "系统版本: " cat /etc/centos-release checkSystem @@ -413,25 +452,25 @@ function install() info - cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz - bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载SSR吗?(y/n)" answer +uninstall() { + echo "" + read -p " 确定卸载SSR吗?(y/n)" answer [ -z ${answer} ] && answer="n" if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then - rm -f /etc/shadowsocksR.json + rm -f $CONFIG_FILE rm -f /var/log/shadowsocks.log rm -rf /usr/local/shadowsocks systemctl disable shadowsocksR && systemctl stop shadowsocksR && rm -rf /usr/lib/systemd/system/shadowsocksR.service fi - echo -e " ${red}卸载成功${plain}" + echo -e " ${RED}卸载成功${PLAIN}" } +slogon + action=$1 [ -z $1 ] && action=install case "$action" in @@ -439,7 +478,7 @@ case "$action" in ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall]" ;; esac diff --git a/centos_install_v2ray.sh b/centos_install_v2ray.sh index 98eae3c9..f4e5e6dd 100644 --- a/centos_install_v2ray.sh +++ b/centos_install_v2ray.sh @@ -1,72 +1,105 @@ #!/bin/bash # v2ray centos系统一键安装教程 -# Author: hijk +# Author: hijk -echo "#############################################################" -echo "# CentOS 7/8 v2ray 一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' +OS=`hostnamectl | grep -i system | cut -d: -f2` -function checkSystem() -{ +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +CONFIG_FILE="/etc/v2ray/config.json" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { result=$(id | awk '{print $1}') if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" + colorEcho $RED " 请以root身份执行该脚本" exit 1 fi if [ ! -f /etc/centos-release ];then - echo "系统不是CentOS" - exit 1 - fi - - result=`cat /etc/centos-release|grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 7 ]; then - echo "不受支持的CentOS版本" - exit 1 + res=`which yum` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统不是CentOS" + exit 1 + fi + res=`which systemctl` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统版本过低,请重装系统到高版本后再使用本脚本!" + exit 1 + fi + else + result=`cat /etc/centos-release|grep -oE "[0-9.]+"` + main=${result%%.*} + if [ $main -lt 7 ]; then + colorEcho $RED " 不受支持的CentOS版本" + exit 1 + fi fi } -function getData() -{ +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}CentOS 7/8 V2ray一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" +} + +getData() { while true do - read -p "请输入v2ray的端口[1-65535]:" port - [ -z "$port" ] && port="21568" - expr $port + 0 &>/dev/null + read -p " 请输入v2ray的端口[1-65535]:" PORT + [ -z "$PORT" ] && PORT="21568" + if [ "${PORT:0:1}" = "0" ]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null if [ $? -eq 0 ]; then - if [ $port -ge 1 ] && [ $port -le 65535 ]; then + if [ $PORT -ge 1 ] && [ $PORT -le 65535 ]; then echo "" - echo "端口号: $port" + colorEcho $BLUE " 端口号: $PORT" echo "" break else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi done } -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - yum update -y - fi - echo "安装必要软件" +preinstall() { + colorEcho $BLUE " 更新系统..." + yum clean all + #yum update -y + + colorEcho $BLUE " 安装必要软件" yum install -y epel-release telnet wget vim net-tools ntpdate unzip + res=`which wget` + [ "$?" != "0" ] && yum install -y wget + res=`which netstat` + [ "$?" != "0" ] && yum install -y net-tools yum install -y nginx systemctl enable nginx && systemctl start nginx @@ -76,112 +109,144 @@ function preinstall() fi } -function installV2ray() -{ - echo 安装v2ray... - bash <(curl -L -s https://install.direct/go.sh) +installV2ray() { + colorEcho $BLUE " 安装v2ray..." + bash <(curl -sL ${V6_PROXY}https://raw.githubusercontent.com/hijkpw/scripts/master/goV2.sh) - if [ ! -f /etc/v2ray/config.json ]; then - echo "安装失败,请到 https://www.hijk.pw 网站反馈" + if [ ! -f $CONFIG_FILE ]; then + colorEcho $RED " $OS 安装V2ray失败,请到 https://hijk.art 网站反馈" exit 1 fi - sed -i -e "s/port\":.*[0-9]*,/port\": ${port},/" /etc/v2ray/config.json - logsetting=`cat /etc/v2ray/config.json|grep loglevel` - if [ "${logsetting}" = "" ]; then - sed -i '1a\ "log": {\n "loglevel": "info",\n "access": "/var/log/v2ray/access.log",\n "error": "/var/log/v2ray/error.log"\n },' /etc/v2ray/config.json - fi - alterid=`shuf -i50-90 -n1` - sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" /etc/v2ray/config.json - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` + sed -i -e "s/port\":.*[0-9]*,/port\": ${PORT},/" $CONFIG_FILE + alterid=`shuf -i50-80 -n1` + sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" $CONFIG_FILE + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ntpdate -u time.nist.gov - systemctl enable v2ray && systemctl restart v2ray + + systemctl enable v2ray + systemctl restart v2ray sleep 3 - res=`netstat -ntlp| grep ${port} | grep v2ray` + res=`ss -ntlp| grep ${PORT} | grep v2ray` if [ "${res}" = "" ]; then - echo “v2ray启动失败,请检查端口是否已被占用!” + colorEcho $RED " 端口号:${PORT}, v2启动失败,请检查端口是否被占用!" exit 1 fi - echo "v2ray安装成功!" + colorEcho $GREEN " v2ray安装成功!" } -function setFirewall() -{ +setFirewall() { systemctl status firewalld > /dev/null 2>&1 - if [ $? -eq 0 ];then - firewall-cmd --permanent --add-port=${port}/tcp - firewall-cmd --permanent --add-port=${port}/udp + if [[ $? -eq 0 ]];then firewall-cmd --permanent --add-service=http + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi fi } -function installBBR() -{ +installBBR() { result=$(lsmod | grep bbr) if [ "$result" != "" ]; then - echo BBR模块已安装 - bbr=true - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf + colorEcho $YELLOW " BBR模块已安装" + INSTALL_BBR=false return; fi - echo 安装BBR模块... - rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org - rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm - yum --enablerepo=elrepo-kernel install kernel-ml -y - grub2-set-default 0 - echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + yum --enablerepo=elrepo-kernel install kernel-ml -y + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/v2ray/config.json | grep port | cut -d: -f2 | tr -d \",' '` +info() { + if [ ! -f $CONFIG_FILE ]; then + echo -e " ${RED}未安装v2ray!${PLAIN}" + exit 1 + fi + + port=`grep port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` res=`netstat -nltp | grep ${port} | grep v2ray` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` - alterid=`cat /etc/v2ray/config.json | grep alterId | cut -d: -f2 | tr -d \",' '` - res=`cat /etc/v2ray/config.json | grep network` - [ -z "$res" ] && network="tcp" || network=`cat /etc/v2ray/config.json | grep network | cut -d: -f2 | tr -d \",' '` + [ -z "$res" ] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + alterid=`grep alterId $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`grep network $CONFIG_FILE` + [ -z "$res" ] && network="tcp" || network=`grep network $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` security="auto" + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"tcp\", + \"type\":\"none\", + \"host\":\"\", + \"path\":\"\", + \"tls\":\"\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + echo ============================================ - echo -e " v2ray运行状态:${status}" - echo -e " v2ray配置文件:${red}/etc/v2ray/config.json${plain}" + echo -e " ${BLUE}v2ray运行状态:${PLAIN} ${status}" + echo -e " ${BLUE}v2ray配置文件:${PLAIN} ${RED}$CONFIG_FILE${PLAIN}" echo "" - echo -e "${red}v2ray配置信息:${plain} " - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " id(uuid):${red}${uid}${plain}" - echo -e " 额外id(alterid): ${red}${alterid}${plain}" - echo -e " 加密方式(security): ${red}$security${plain}" - echo -e " 传输协议(network): ${red}${network}${plain}" - echo - echo ============================================ + echo -e " ${RED}v2ray配置信息:${PLAIN} " + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN} ${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN} ${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}$security${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo + echo -e " ${BLUE}vmess链接:${PLAIN} $link" } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [ "$INSTALL_BBR" == "true" ]; then echo - echo 为使BBR模块生效,系统将在30秒后重启 + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ +install() { echo -n "系统版本: " cat /etc/centos-release @@ -197,9 +262,9 @@ function install() bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载v2ray吗?(y/n)" answer +uninstall() { + echo "" + read -p " 确定卸载v2ray吗?(y/n)" answer [ -z ${answer} ] && answer="n" if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then systemctl stop v2ray @@ -208,10 +273,12 @@ function uninstall() rm -rf /usr/bin/v2ray/* rm -rf /var/log/v2ray/* rm -rf /etc/systemd/system/v2ray.service - echo -e " ${red}卸载成功${plain}" + rm -rf /etc/systemd/system/multi-user.target.wants/v2ray.service + echo -e " ${RED}卸载成功${PLAIN}" fi } +slogon action=$1 [ -z $1 ] && action=install @@ -220,7 +287,7 @@ case "$action" in ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall]" ;; esac diff --git a/centos_install_v2ray2.sh b/centos_install_v2ray2.sh index af09fa0a..4feade97 100644 --- a/centos_install_v2ray2.sh +++ b/centos_install_v2ray2.sh @@ -1,188 +1,370 @@ #!/bin/bash # v2ray centos系统一键安装脚本 -# Author: hijk - -echo "#############################################################" -echo "# CentOS 7/8 v2ray 带伪装一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" - -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' - -function checkSystem() -{ +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +# 以下网站是随机从Google上找到的无广告小说网站,不喜欢请改成其他网址,以http或https开头 +# 搭建好后无法打开伪装域名,可能是反代小说网站挂了,请在网站留言,或者Github发issue,以便替换新的网站 +SITES=( +http://www.zhuizishu.com/ +http://xs.56dyc.com/ +#http://www.xiaoshuosk.com/ +#https://www.quledu.net/ +http://www.ddxsku.com/ +http://www.biqu6.com/ +https://www.wenshulou.cc/ +#http://www.auutea.com/ +http://www.55shuba.com/ +http://www.39shubao.com/ +https://www.23xsw.cc/ +#https://www.huanbige.com/ +https://www.jueshitangmen.info/ +https://www.zhetian.org/ +http://www.bequgexs.com/ +http://www.tjwl.com/ +) + +CONFIG_FILE="/etc/v2ray/config.json" + +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" + +res=`which bt 2>/dev/null` +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +checkSystem() { result=$(id | awk '{print $1}') - if [ $result != "uid=0(root)" ]; then + if [[ $result != "uid=0(root)" ]]; then echo "请以root身份执行该脚本" exit 1 fi - if [ ! -f /etc/centos-release ];then - echo "系统不是CentOS" - exit 1 - fi - - result=`cat /etc/centos-release|grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 7 ]; then - echo "不受支持的CentOS版本" - exit 1 + if [[ ! -f /etc/centos-release ]];then + res=`which yum` + if [[ "$?" != "0" ]]; then + echo "系统不是CentOS" + exit 1 + fi + res=`which systemctl` + if [[ "$?" != "0" ]]; then + echo "系统版本过低,请重装系统到高版本后再使用本脚本!" + exit 1 + fi + else + result=`cat /etc/centos-release|grep -oE "[0-9.]+"` + main=${result%%.*} + if [[ $main -lt 7 ]]; then + echo "不受支持的CentOS版本" + exit 1 + fi fi } -function getData() -{ - yum install -y bind-utils curl - IP=`curl -s -4 icanhazip.com` +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}CentOS 7/8 v2ray 带伪装一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" +} + +getData() { echo " " echo " 本脚本为带伪装的一键脚本,运行之前请确认如下条件已经具备:" - echo -e " ${red}1. 一个域名${plain}" - echo -e " ${red}2. 域名的某个主机名解析指向当前服务器ip(${IP})${plain}" + colorEcho ${YELLOW} " 1. 一个伪装域名" + colorEcho ${YELLOW} " 2. 伪装域名DNS解析指向当前服务器ip(${IP})" + colorEcho ${BLUE} " 3. 如果/root目录下有 v2ray.pem 和 v2ray.key 证书密钥文件,无需理会条件2" echo " " - read -p "确认满足按y,按其他退出脚本:" answer - if [ "${answer}" != "y" ]; then + read -p " 确认满足按y,按其他退出脚本:" answer + if [[ "${answer}" != "y" ]]; then exit 0 fi + echo "" while true do - read -p "请输入您的主机名:" domain - if [ -z "${domain}" ]; then - echo "主机名输入错误,请重新输入!" + read -p " 请输入伪装域名:" DOMAIN + if [[ -z "${DOMAIN}" ]]; then + colorEcho $RED " 域名输入错误,请重新输入!" else break fi done - - res=`host ${domain}` - res=`echo -n ${res} | grep ${IP}` - if [ -z "${res}" ]; then - echo -n "${domain} 解析结果:" - host ${domain} - echo "主机未解析到当前服务器IP(${IP})!" - exit 1 + DOMAIN=${DOMAIN,,} + colorEcho ${BLUE} " 伪装域名(host):$DOMAIN" + + echo "" + if [[ -f ~/v2ray.pem && -f ~/v2ray.key ]]; then + colorEcho ${BLUE} " 检测到自有证书,将使用其部署" + echo + CERT_FILE="/etc/v2ray/${DOMAIN}.pem" + KEY_FILE="/etc/v2ray/${DOMAIN}.key" + else + resolve=`curl -sL https://hijk.art/hostip.php?d=${DOMAIN}` + res=`echo -n ${resolve} | grep ${IP}` + if [[ -z "${res}" ]]; then + colorEcho ${BLUE} "${DOMAIN} 解析结果:${resolve}" + colorEcho ${RED} " 域名未解析到当前服务器IP(${IP})!" + exit 1 + fi fi + echo "" while true do - read -p "请输入伪装路径,以/开头:" path - if [ -z "${path}" ]; then - echo "请输入伪装路径,以/开头!" - elif [ "${path:0:1}" != "/" ]; then - echo "伪装路径必须以/开头!" - elif [ "${path}" = "/" ]; then - echo "不能使用根路径!" + read -p " 请输入伪装路径,以/开头(不懂请直接回车):" WSPATH + if [[ -z "${WSPATH}" ]]; then + len=`shuf -i5-12 -n1` + ws=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1` + WSPATH="/$ws" + break + elif [[ "${WSPATH:0:1}" != "/" ]]; then + colorEcho ${RED} " 伪装路径必须以/开头!" + elif [[ "${WSPATH}" = "/" ]]; then + colorEcho ${RED} " 不能使用根路径!" else break fi done -} + colorEcho ${BLUE} " 伪装路径:$WSPATH" -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - yum update -y + echo "" + read -p " 请输入Nginx端口[100-65535的一个数字,默认443]:" PORT + [[ -z "${PORT}" ]] && PORT=443 + if [[ "${PORT:0:1}" = "0" ]]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + colorEcho ${BLUE} " Nginx端口:$PORT" + + echo "" + colorEcho $BLUE " 请选择伪装站类型:" + echo " 1) 静态网站(位于/usr/share/nginx/html)" + echo " 2) 小说站(随机选择)" + echo " 3) 美女站(https://imeizi.me)" + echo " 4) 高清壁纸站(https://bing.imeizi.me)" + echo " 5) 自定义反代站点(需以http或者https开头)" + read -p " 请选择伪装网站类型[默认:高清壁纸站]" answer + if [[ -z "$answer" ]]; then + PROXY_URL="https://bing.imeizi.me" + else + case $answer in + 1) + PROXY_URL="" + ;; + 2) + len=${#SITES[@]} + ((len--)) + while true + do + index=`shuf -i0-${len} -n1` + PROXY_URL=${SITES[$index]} + host=`echo ${PROXY_URL} | cut -d/ -f3` + ip=`curl -sL https://hijk.art/hostip.php?d=${host}` + res=`echo -n ${ip} | grep ${host}` + if [[ "${res}" = "" ]]; then + echo "$ip $host" >> /etc/hosts + break + fi + done + ;; + 3) + PROXY_URL="https://imeizi.me" + ;; + 4) + PROXY_URL="https://bing.imeizi.me" + ;; + 5) + read -p " 请输入反代站点(以http或者https开头):" PROXY_URL + if [[ -z "$PROXY_URL" ]]; then + colorEcho $RED " 请输入反代网站!" + exit 1 + elif [[ "${PROXY_URL:0:4}" != "http" ]]; then + colorEcho $RED " 反代网站必须以http或https开头!" + exit 1 + fi + ;; + *) + colorEcho $RED " 请输入正确的选项!" + exit 1 + esac + fi + REMOTE_HOST=`echo ${PROXY_URL} | cut -d/ -f3` + echo "" + colorEcho $BLUE " 伪装网站:$PROXY_URL" + + echo "" + colorEcho $BLUE " 是否允许搜索引擎爬取网站?[默认:不允许]" + echo " y)允许,会有更多ip请求网站,但会消耗一些流量,vps流量充足情况下推荐使用" + echo " n)不允许,爬虫不会访问网站,访问ip比较单一,但能节省vps流量" + read -p " 请选择:[y/n]" answer + if [[ -z "$answer" ]]; then + ALLOW_SPIDER="n" + elif [[ "${answer,,}" = "y" ]]; then + ALLOW_SPIDER="y" + else + ALLOW_SPIDER="n" fi - echo "安装必要软件" + echo "" + colorEcho $BLUE " 允许搜索引擎:$ALLOW_SPIDER" + + echo "" + read -p " 是否安装BBR(安装请按y,不安装请输n,默认安装):" NEED_BBR + [[ -z "$NEED_BBR" ]] && NEED_BBR=y + [[ "$NEED_BBR" = "Y" ]] && NEED_BBR=y + colorEcho $BLUE " 安装BBR:$NEED_BBR" +} + +preinstall() { + colorEcho $BLUE " 更新系统..." + yum clean all + #yum update -y + colorEcho $BLUE " 安装必要软件" yum install -y epel-release telnet wget vim net-tools ntpdate unzip + res=`which wget` + [[ "$?" != "0" ]] && yum install -y wget + res=`which netstat` + [[ "$?" != "0" ]] && yum install -y net-tools - if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config setenforce 0 fi } -function installV2ray() -{ - echo 安装v2ray... - bash <(curl -L -s https://install.direct/go.sh) +getCert() { + mkdir -p /etc/v2ray + if [[ -z ${CERT_FILE+x} ]]; then + stopNginx + systemctl stop v2ray + res=`netstat -ntlp| grep -E ':80 |:443 '` + if [[ "${res}" != "" ]]; then + colorEcho ${RED} " 其他进程占用了80或443端口,请先关闭再运行一键脚本" + echo " 端口占用信息如下:" + echo ${res} + exit 1 + fi - if [ ! -f /etc/v2ray/config.json ]; then - echo "安装失败,请到 https://www.hijk.pw 网站反馈" - exit 1 + yum install -y socat openssl cronie + systemctl enable crond + systemctl start crond + curl -sL https://get.acme.sh | sh -s email=hijk.pw@protonmail.ch + source ~/.bashrc + ~/.acme.sh/acme.sh --upgrade --auto-upgrade + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt + if [[ "$BT" = "false" ]]; then + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "systemctl stop nginx" --post-hook "systemctl restart nginx" --standalone + else + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "nginx -s stop || { echo -n ''; }" --post-hook "nginx -c /www/server/nginx/conf/nginx.conf || { echo -n ''; }" --standalone + fi + [[ -f ~/.acme.sh/${DOMAIN}_ecc/ca.cer ]] || { + colorEcho $RED " 获取证书失败,请复制上面的红色文字到 https://hijk.art 反馈" + exit 1 + } + CERT_FILE="/etc/v2ray/${DOMAIN}.pem" + KEY_FILE="/etc/v2ray/${DOMAIN}.key" + ~/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \ + --key-file $KEY_FILE \ + --fullchain-file $CERT_FILE \ + --reloadcmd "service nginx force-reload" + [[ -f $CERT_FILE && -f $KEY_FILE ]] || { + colorEcho $RED " 获取证书失败,请到 https://hijk.art 反馈" + exit 1 + } + else + cp ~/v2ray.pem /etc/v2ray/${DOMAIN}.pem + cp ~/v2ray.key /etc/v2ray/${DOMAIN}.key fi +} + +installV2ray() { + colorEcho $BLUE " 安装v2ray..." + bash <(curl -sL ${V6_PROXY}https://raw.githubusercontent.com/hijkpw/scripts/master/goV2.sh) - logsetting=`cat /etc/v2ray/config.json|grep loglevel` - if [ "${logsetting}" = "" ]; then - sed -i '1a\ "log": {\n "loglevel": "info",\n "access": "/var/log/v2ray/access.log",\n "error": "/var/log/v2ray/error.log"\n },' /etc/v2ray/config.json + if [[ ! -f $CONFIG_FILE ]]; then + colorEcho $RED " $OS 安装V2ray失败,请到 https://hijk.art 网站反馈" + exit 1 fi - alterid=`shuf -i50-90 -n1` - sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" /etc/v2ray/config.json - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` - port=`cat /etc/v2ray/config.json | grep port | cut -d: -f2 | tr -d \",' '` + + alterid=0 + sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" $CONFIG_FILE + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + V2PORT=`grep port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ntpdate -u time.nist.gov - res=`cat /etc/v2ray/config.json | grep streamSettings` - if [ "$res" = "" ]; then - line=`grep -n '}]' /etc/v2ray/config.json | head -n1 | cut -d: -f1` + + res=`grep streamSettings $CONFIG_FILE` + if [[ "$res" = "" ]]; then + line=`grep -n '}]' $CONFIG_FILE | head -n1 | cut -d: -f1` line=`expr ${line} - 1` - sed -i "${line}s/}/},/" /etc/v2ray/config.json - sed -i "${line}a\ \"streamSettings\": {\n \"network\": \"ws\",\n \"wsSettings\": {\n \"path\": \"${path}\",\n \"headers\": {\n \"Host\": \"${domain}\"\n }\n }\n },\n \"listen\": \"127.0.0.1\"" /etc/v2ray/config.json + sed -i "${line}s/}/},/" $CONFIG_FILE + sed -i "${line}a\ \"streamSettings\": {\n \"network\": \"ws\",\n \"wsSettings\": {\n \"path\": \"${WSPATH}\",\n \"headers\": {\n \"Host\": \"${DOMAIN}\"\n }\n }\n },\n \"listen\": \"127.0.0.1\"" $CONFIG_FILE else - sed -i -e "s/path\":.*/path\": \"\\${path}\",/" /etc/v2ray/config.json + sed -i -e "s/path\":.*/path\": \"\\${WSPATH}\",/" $CONFIG_FILE fi - systemctl enable v2ray && systemctl restart v2ray + + systemctl enable v2ray + systemctl restart v2ray sleep 3 - res=`netstat -nltp | grep ${port} | grep v2ray` - if [ "${res}" = "" ]; then - echo "v2ray启动失败,请检查端口是否被占用!" + res=`ss -ntlp| grep ${V2PORT} | grep v2ray` + if [[ "${res}" = "" ]]; then + colorEcho $RED " $OS 端口号:${PORT},伪装路径:${WSPATH}, v2启动失败,请检查端口是否被占用或伪装路径是否有特殊字符!!" exit 1 fi - echo "v2ray安装成功!" + colorEcho $GREEN " v2ray安装成功!" } -function installNginx() -{ - yum install -y nginx - systemctl stop nginx - res=`netstat -ntlp| grep -E ':80|:443'` - if [ "${res}" != "" ]; then - echo " 其他进程占用了80或443端口,请先关闭再运行一键脚本" - echo " 端口占用信息如下:" - echo ${res} - exit 1 - fi - res=`which pip3` - if [ "$?" != "0" ]; then - yum install -y python36 - fi - res=`which pip3` - if [ "$?" != "0" ]; then - echo -e " pip3安装失败,请到 ${red}https://www.hijk.pw${plain} 反馈" - exit 1 - fi - pip3 install certbot - res=`which certbot` - if [ "$?" != "0" ]; then - export PATH=$PATH:/usr/local/bin - fi - certbot certonly --standalone --agree-tos --register-unsafely-without-email -d ${domain} - if [ "$?" != "0" ]; then - echo -e " 获取证书失败,请到 ${red}https://www.hijk.pw${plain} 反馈" - exit 1 +installNginx() { + if [[ "$BT" = "false" ]]; then + yum install -y nginx + res=$(command -v nginx) + if [[ "$res" = "" ]]; then + colorEcho $RED " Nginx安装失败,请到 https://hijk.art 反馈" + exit 1 + fi + systemctl enable nginx + else + res=$(command -v nginx) + if [[ "$res" = "" ]]; then + colorEcho $RED " 您安装了宝塔,请在宝塔后台安装nginx后再运行本脚本" + exit 1 + fi fi + + getCert - res=`cat /usr/share/nginx/html/index.html| grep Flatfy` - if [ "${res}" = "" ]; then - mv /usr/share/nginx/html /usr/share/nginx/html.bak - wget 'https://github.com/hijkpw/scripts/raw/master/Flatfy%20V3.zip' -O theme.zip - unzip theme.zip - rm -rf __MACOSX/ - mv Flatfy\ V3 /usr/share/nginx/html - rm -rf theme.zip - fi - if [ ! -f /etc/nginx/nginx.conf.bak ]; then - mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak - fi - cat > /etc/nginx/nginx.conf<<-EOF + if [[ "$BT" = "false" ]]; then + if [ ! -f /etc/nginx/nginx.conf.bak ]; then + mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak + fi + cat > /etc/nginx/nginx.conf<<-EOF user nginx; worker_processes auto; error_log /var/log/nginx/error.log; @@ -202,6 +384,7 @@ http { access_log /var/log/nginx/access.log main; + gzip on; sendfile on; tcp_nopush on; tcp_nodelay on; @@ -218,41 +401,61 @@ http { } EOF - mkdir -p /etc/nginx/conf.d; - cat > /etc/nginx/conf.d/${domain}.conf<<-EOF + mkdir -p /etc/nginx/conf.d + fi + + mkdir -p /usr/share/nginx/html + if [[ "$ALLOW_SPIDER" = "n" ]]; then + echo 'User-Agent: *' > /usr/share/nginx/html/robots.txt + echo 'Disallow: /' >> /usr/share/nginx/html/robots.txt + fi + if [[ "$PROXY_URL" = "" ]]; then + action="" + else + action="proxy_ssl_server_name on; + proxy_pass $PROXY_URL; + proxy_set_header Accept-Encoding ''; + sub_filter \"$REMOTE_HOST\" \"$DOMAIN\"; + sub_filter_once off;" + fi + cat > ${NGINX_CONF_PATH}${DOMAIN}.conf<<-EOF server { - listen 80 default_server; - server_name ${domain}; - rewrite ^(.*) https://\$server_name\$1 permanent; + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${PORT}\$request_uri; } server { - listen 443 ssl http2; - server_name ${domain}; + listen ${PORT} ssl http2; + listen [::]:${PORT} ssl http2; + server_name ${DOMAIN}; charset utf-8; # ssl配置 - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_ecdh_curve secp384r1; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; - ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem; - - access_log /var/log/nginx/${domain}.access.log; - error_log /var/log/nginx/${domain}.error.log; + ssl_certificate $CERT_FILE; + ssl_certificate_key $KEY_FILE; + + # placeholder + # placeholder root /usr/share/nginx/html; location / { - index index.html; + $action + } + location = /robots.txt { } - location ${path} { + location ${WSPATH} { proxy_redirect off; - proxy_pass http://127.0.0.1:${port}; + proxy_pass http://127.0.0.1:${V2PORT}; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; @@ -263,106 +466,174 @@ server { } } EOF - res=`cat /etc/crontab | grep certbot` - if [ "${res}" = "" ]; then - echo '0 3 1 */2 0 root systemctl stop nginx && certbot renew && systemctl start nginx' >> /etc/crontab - fi - systemctl enable nginx && systemctl restart nginx + + startNginx + systemctl start v2ray + sleep 3 - res=`netstat -nltp | grep 443 | grep nginx` - if [ "${res}" = "" ]; then - echo -e "nginx启动失败! 请到 ${red}https://www.hijk.pw${plain} 反馈" + res=`netstat -nltp | grep ${PORT} | grep nginx` + if [[ "${res}" = "" ]]; then + nginx -t + echo -e " nginx启动失败! 请到 ${RED}https://hijk.art${PLAIN} 反馈" exit 1 fi } +startNginx() { + if [[ "$BT" = "false" ]]; then + systemctl start nginx + else + nginx -c /www/server/nginx/conf/nginx.conf + fi +} + +stopNginx() { + if [[ "$BT" = "false" ]]; then + systemctl stop nginx + else + res=`ps aux | grep -i nginx` + if [[ "$res" != "" ]]; then + nginx -s stop + fi + fi +} + function setFirewall() { systemctl status firewalld > /dev/null 2>&1 - if [ $? -eq 0 ];then + if [[ $? -eq 0 ]];then firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https + if [[ "$PORT" != "443" ]]; then + firewall-cmd --permanent --add-port=${PORT}/tcp + fi firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + fi + fi fi } -function installBBR() -{ +installBBR() { + if [[ "$NEED_BBR" != "y" ]]; then + INSTALL_BBR=false + return + fi result=$(lsmod | grep bbr) - if [ "$result" != "" ]; then - echo BBR模块已安装 - bbr=true - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf + if [[ "$result" != "" ]]; then + colorEcho $YELLOW " BBR模块已安装" + INSTALL_BBR=false return; fi - - echo 安装BBR模块... - rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org - rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm - yum --enablerepo=elrepo-kernel install kernel-ml -y - grub2-set-default 0 - echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + res=`hostnamectl | grep -i openvz` + if [[ "$res" != "" ]]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + yum --enablerepo=elrepo-kernel install kernel-ml -y + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=443 +info() { + if [[ ! -f $CONFIG_FILE ]]; then + echo -e " ${RED}未安装v2ray!${PLAIN}" + exit 1 + fi + res=`netstat -nltp | grep v2ray` - [ -z "$res" ] && v2status="${red}已停止${plain}" || v2status="${green}正在运行${plain}" + [[ -z "$res" ]] && v2status="${RED}已停止${PLAIN}" || v2status="${GREEN}正在运行${PLAIN}" + + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + alterid=`grep alterId $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + network=`grep network $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + domain=`grep Host $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + if [[ -z "$domain" ]]; then + colorEcho $RED " 不是伪装版本的v2ray" + exit 1 + fi + path=`grep path $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + port=`cat ${NGINX_CONF_PATH}${domain}.conf | grep -i ssl | head -n1 | awk '{print $2}'` + security="none" + res=`netstat -nltp | grep ${port} | grep nginx` - [ -z "$res" ] && ngstatus="${red}已停止${plain}" || ngstatus="${green}正在运行${plain}" - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` - alterid=`cat /etc/v2ray/config.json | grep alterId | cut -d: -f2 | tr -d \",' '` - network=`cat /etc/v2ray/config.json | grep network | cut -d: -f2 | tr -d \",' '` - domain=`cat /etc/v2ray/config.json | grep Host | cut -d: -f2 | tr -d \",' '` - path=`cat /etc/v2ray/config.json | grep path | cut -d: -f2 | tr -d \",' '` - security="auto" + [[ -z "$res" ]] && ngstatus="${RED}已停止${PLAIN}" || ngstatus="${GREEN}正在运行${PLAIN}" + + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"${network}\", + \"type\":\"none\", + \"host\":\"${domain}\", + \"path\":\"${path}\", + \"tls\":\"tls\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + echo ============================================ - echo -e " v2ray运行状态:${v2status}" - echo -e " v2ray配置文件:${red}/etc/v2ray/config.json${plain}" - echo -e " nginx运行状态:${ngstatus}" - echo -e " nginx配置文件:${red}/etc/nginx/conf.d/${domain}.conf${plain}" + echo -e " ${BLUE}v2ray运行状态:${PLAIN}${v2status}" + echo -e " ${BLUE}v2ray配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo -e " ${BLUE}nginx运行状态:${PLAIN}${ngstatus}" + echo -e " ${BLUE}nginx配置文件:${PLAIN}${RED}${NGINX_CONF_PATH}${domain}.conf${PLAIN}" echo "" - echo -e "${red}v2ray配置信息:${plain} " - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " id(uuid):${red}${uid}${plain}" - echo -e " 额外id(alterid): ${red}${alterid}${plain}" - echo -e " 加密方式(security): ${red}$security${plain}" - echo -e " 传输协议(network): ${red}${network}${plain}" - echo -e " 主机名(host):${red}${domain}${plain}" - echo -e " 路径(path):${red}${path}${plain}" - echo -e " 安全传输(security):${red}TLS${plain}" + echo -e " ${RED}v2ray配置信息:${PLAIN} " + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}$security${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none${PLAIN}" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}路径(path):${PLAIN}${RED}${path}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" echo - echo ============================================ + echo -e " ${BLUE}vmess链接:${PLAIN} $link" } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [[ "${INSTALL_BBR}" == "true" ]]; then echo - echo 为使BBR模块生效,系统将在30秒后重启 + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ - echo -n "系统版本: " - cat /etc/centos-release - +install() { checkSystem getData preinstall @@ -375,37 +646,42 @@ function install() bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载v2ray吗?(y/n)" answer - [ -z ${answer} ] && answer="n" +uninstall() { + echo "" + read -p " 确定卸载v2ray吗?(y/n)" answer + [[ -z ${answer} ]] && answer="n" - if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then + if [[ "${answer}" == "y" ]] || [[ "${answer}" == "Y" ]]; then systemctl stop v2ray systemctl disable v2ray + domain=`grep Host $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` rm -rf /etc/v2ray/* rm -rf /usr/bin/v2ray/* rm -rf /var/log/v2ray/* rm -rf /etc/systemd/system/v2ray.service yum remove -y nginx - if [ -d /usr/share/nginx/html.bak ]; then + if [[ -d /usr/share/nginx/html.bak ]]; then rm -rf /usr/share/nginx/html mv /usr/share/nginx/html.bak /usr/share/nginx/html fi - echo -e " ${red}卸载成功${plain}" + rm -rf /etc/nginx/conf.d/${domain}.conf + ~/.acme.sh/acme.sh --uninstall + echo -e " ${RED}卸载成功${PLAIN}" fi } +slogon + action=$1 -[ -z $1 ] && action=install +[[ -z $1 ]] && action=install case "$action" in install|uninstall|info) ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall|info]" ;; esac diff --git a/goV2.sh b/goV2.sh new file mode 100644 index 00000000..afee8864 --- /dev/null +++ b/goV2.sh @@ -0,0 +1,525 @@ +#!/bin/bash + +# This file is accessible as https://install.direct/go.sh +# Original source is located at github.com/v2ray/v2ray-core/release/install-release.sh + +# If not specify, default meaning of return value: +# 0: Success +# 1: System error +# 2: Application error +# 3: Network error + +# CLI arguments +PROXY='' +HELP='' +FORCE='' +CHECK='' +REMOVE='' +VERSION='' +VSRC_ROOT='/tmp/v2ray' +EXTRACT_ONLY='' +LOCAL='' +LOCAL_INSTALL='' +DIST_SRC='github' +ERROR_IF_UPTODATE='' + +CUR_VER="" +NEW_VER="" +VDIS='' +ZIPFILE="/tmp/v2ray/v2ray.zip" +V2RAY_RUNNING=0 + +CMD_INSTALL="" +CMD_UPDATE="" +SOFTWARE_UPDATED=0 + +SYSTEMCTL_CMD=$(command -v systemctl 2>/dev/null) +SERVICE_CMD=$(command -v service 2>/dev/null) + +#######color code######## +RED="31m" # Error message +GREEN="32m" # Success message +YELLOW="33m" # Warning message +BLUE="36m" # Info message + +V6_PROXY="" +res=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + V6_PROXY="https://gh.hijk.art/" +fi + +######################### +while [[ $# > 0 ]]; do + case "$1" in + -p|--proxy) + PROXY="-x ${2}" + shift # past argument + ;; + -h|--help) + HELP="1" + ;; + -f|--force) + FORCE="1" + ;; + -c|--check) + CHECK="1" + ;; + --remove) + REMOVE="1" + ;; + --version) + VERSION="$2" + shift + ;; + --extract) + VSRC_ROOT="$2" + shift + ;; + --extractonly) + EXTRACT_ONLY="1" + ;; + -l|--local) + LOCAL="$2" + LOCAL_INSTALL="1" + shift + ;; + --source) + DIST_SRC="$2" + shift + ;; + --errifuptodate) + ERROR_IF_UPTODATE="1" + ;; + *) + # unknown option + ;; + esac + shift # past argument or value +done + +############################### +colorEcho(){ + echo -e "\033[${1}${@:2}\033[0m" 1>& 2 +} + +archAffix(){ + case "${1:-"$(uname -m)"}" in + i686|i386) + echo '32' + ;; + x86_64|amd64) + echo '64' + ;; + *armv7*) + echo 'arm32-v7a' + ;; + armv6*) + echo 'arm32-v6a' + ;; + *armv8*|aarch64) + echo 'arm64-v8a' + ;; + *mips64le*) + echo 'mips64le' + ;; + *mips64*) + echo 'mips64' + ;; + *mipsle*) + echo 'mipsle' + ;; + *mips*) + echo 'mips' + ;; + *s390x*) + echo 's390x' + ;; + ppc64le) + echo 'ppc64le' + ;; + ppc64) + echo 'ppc64' + ;; + *) + return 1 + ;; + esac + + return 0 +} + +zipRoot() { + unzip -lqq "$1" | awk -e ' + NR == 1 { + prefix = $4; + } + NR != 1 { + prefix_len = length(prefix); + cur_len = length($4); + + for (len = prefix_len < cur_len ? prefix_len : cur_len; len >= 1; len -= 1) { + sub_prefix = substr(prefix, 1, len); + sub_cur = substr($4, 1, len); + + if (sub_prefix == sub_cur) { + prefix = sub_prefix; + break; + } + } + + if (len == 0) { + prefix = ""; + nextfile; + } + } + END { + print prefix; + } + ' +} + +downloadV2Ray(){ + rm -rf /tmp/v2ray + mkdir -p /tmp/v2ray + if [[ "${DIST_SRC}" == "jsdelivr" ]]; then + DOWNLOAD_LINK="https://cdn.jsdelivr.net/gh/v2fly/dist/v2ray-linux-${VDIS}.zip" + else + DOWNLOAD_LINK="${V6_PROXY}https://github.com/v2fly/v2ray-core/releases/download/${NEW_VER}/v2ray-linux-${VDIS}.zip" + fi + colorEcho ${BLUE} "Downloading V2Ray: ${DOWNLOAD_LINK}" + curl ${PROXY} -L -H "Cache-Control: no-cache" -o ${ZIPFILE} ${DOWNLOAD_LINK} + if [ $? != 0 ];then + colorEcho ${RED} "Failed to download! Please check your network or try again." + return 3 + fi + return 0 +} + +installSoftware(){ + COMPONENT=$1 + if [[ -n `command -v $COMPONENT` ]]; then + return 0 + fi + + getPMT + if [[ $? -eq 1 ]]; then + colorEcho ${RED} "The system package manager tool isn't APT or YUM, please install ${COMPONENT} manually." + return 1 + fi + if [[ $SOFTWARE_UPDATED -eq 0 ]]; then + colorEcho ${BLUE} "Updating software repo" + $CMD_UPDATE + SOFTWARE_UPDATED=1 + fi + + colorEcho ${BLUE} "Installing ${COMPONENT}" + $CMD_INSTALL $COMPONENT + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to install ${COMPONENT}. Please install it manually." + return 1 + fi + return 0 +} + +# return 1: not apt, yum, or zypper +getPMT(){ + if [[ -n `command -v apt-get` ]];then + CMD_INSTALL="apt-get -y -qq install" + CMD_UPDATE="apt-get -qq update" + elif [[ -n `command -v yum` ]]; then + CMD_INSTALL="yum -y -q install" + CMD_UPDATE="yum -q makecache" + elif [[ -n `command -v zypper` ]]; then + CMD_INSTALL="zypper -y install" + CMD_UPDATE="zypper ref" + else + return 1 + fi + return 0 +} + +normalizeVersion() { + if [ -n "$1" ]; then + case "$1" in + v*) + echo "$1" + ;; + *) + echo "v$1" + ;; + esac + else + echo "" + fi +} + +# 1: new V2Ray. 0: no. 2: not installed. 3: check failed. 4: don't check. +getVersion(){ + if [[ -n "$VERSION" ]]; then + NEW_VER="$(normalizeVersion "$VERSION")" + return 4 + else + VER="$(/usr/bin/v2ray/v2ray -version 2>/dev/null)" + RETVAL=$? + CUR_VER="$(normalizeVersion "$(echo "$VER" | head -n 1 | cut -d " " -f2)")" + TAG_URL="${V6_PROXY}https://api.github.com/repos/v2fly/v2ray-core/releases/latest" + NEW_VER="$(normalizeVersion "$(curl ${PROXY} -s "${TAG_URL}" --connect-timeout 10| grep 'tag_name' | cut -d\" -f4)")" + + if [[ "${NEW_VER}" =~ "https" ]]; then + NEW_VER="v4.33.0" + fi + if [[ $? -ne 0 ]] || [[ $NEW_VER == "" ]]; then + colorEcho ${RED} "Failed to fetch release information. Please check your network or try again." + return 3 + elif [[ $RETVAL -ne 0 ]];then + return 2 + elif [[ $NEW_VER != $CUR_VER ]];then + return 1 + fi + return 0 + fi +} + +stopV2ray(){ + colorEcho ${BLUE} "Shutting down V2Ray service." + if [[ -n "${SYSTEMCTL_CMD}" ]] || [[ -f "/lib/systemd/system/v2ray.service" ]] || [[ -f "/etc/systemd/system/v2ray.service" ]]; then + ${SYSTEMCTL_CMD} stop v2ray + elif [[ -n "${SERVICE_CMD}" ]] || [[ -f "/etc/init.d/v2ray" ]]; then + ${SERVICE_CMD} v2ray stop + fi + if [[ $? -ne 0 ]]; then + colorEcho ${YELLOW} "Failed to shutdown V2Ray service." + return 2 + fi + return 0 +} + +startV2ray(){ + if [ -n "${SYSTEMCTL_CMD}" ] && [[ -f "/lib/systemd/system/v2ray.service" || -f "/etc/systemd/system/v2ray.service" ]]; then + ${SYSTEMCTL_CMD} start v2ray + elif [ -n "${SERVICE_CMD}" ] && [ -f "/etc/init.d/v2ray" ]; then + ${SERVICE_CMD} v2ray start + fi + if [[ $? -ne 0 ]]; then + colorEcho ${YELLOW} "Failed to start V2Ray service." + return 2 + fi + return 0 +} + +installV2Ray(){ + # Install V2Ray binary to /usr/bin/v2ray + mkdir -p '/etc/v2ray' '/var/log/v2ray' && \ + unzip -oj "$1" "$2v2ray" "$2v2ctl" "$2geoip.dat" "$2geosite.dat" -d '/usr/bin/v2ray' && \ + chmod +x '/usr/bin/v2ray/v2ray' '/usr/bin/v2ray/v2ctl' || { + colorEcho ${RED} "Failed to copy V2Ray binary and resources." + return 1 + } + + # Install V2Ray server config to /etc/v2ray + if [ ! -f '/etc/v2ray/config.json' ]; then + local PORT="$(($RANDOM + 10000))" + local UUID="$(cat '/proc/sys/kernel/random/uuid')" + + unzip -pq "$1" "$2vpoint_vmess_freedom.json" | \ + sed -e "s/10086/${PORT}/g; s/23ad6b10-8d1a-40f7-8ad0-e3e35cd38297/${UUID}/g;" - > \ + '/etc/v2ray/config.json' || { + colorEcho ${YELLOW} "Failed to create V2Ray configuration file. Please create it manually." + return 1 + } + + colorEcho ${BLUE} "PORT:${PORT}" + colorEcho ${BLUE} "UUID:${UUID}" + fi +} + + +installInitScript(){ + if [[ -n "${SYSTEMCTL_CMD}" ]]; then + systemctl disable v2ray + rm -rf /etc/systemd/system/v2ray.service /lib/systemd/system/v2ray.service /etc/systemd/system/v2ray.service.d + cat >/etc/systemd/system/v2ray.service<<-EOF +[Unit] +Description=V2Ray Service +Documentation=https://www.v2ray.com/ https://www.v2fly.org/ +After=network.target nss-lookup.target + +[Service] +# If the version of systemd is 240 or above, then uncommenting Type=exec and commenting out Type=simple +#Type=exec +Type=simple +# This service runs as root. You may consider to run it as another user for security concerns. +# By uncommenting User=nobody and commenting out User=root, the service will run as user nobody. +# More discussion at https://github.com/v2ray/v2ray-core/issues/1011 +User=root +#User=nobody +NoNewPrivileges=true +ExecStart=/usr/bin/v2ray/v2ray -config /etc/v2ray/config.json +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable v2ray.service + elif [[ -n "${SERVICE_CMD}" ]] && [[ ! -f "/etc/init.d/v2ray" ]]; then + installSoftware 'daemon' && \ + unzip -oj "$1" "$2systemv/v2ray" -d '/etc/init.d' && \ + chmod +x '/etc/init.d/v2ray' && \ + update-rc.d v2ray defaults + fi +} + +Help(){ + cat - 1>& 2 << EOF +./install-release.sh [-h] [-c] [--remove] [-p proxy] [-f] [--version vx.y.z] [-l file] + -h, --help Show help + -p, --proxy To download through a proxy server, use -p socks5://127.0.0.1:1080 or -p http://127.0.0.1:3128 etc + -f, --force Force install + --version Install a particular version, use --version v3.15 + -l, --local Install from a local file + --remove Remove installed V2Ray + -c, --check Check for update +EOF +} + +remove(){ + if [[ -n "${SYSTEMCTL_CMD}" ]] && [[ -f "/etc/systemd/system/v2ray.service" ]];then + if pgrep "v2ray" > /dev/null ; then + stopV2ray + fi + systemctl disable v2ray.service + rm -rf "/usr/bin/v2ray" "/etc/systemd/system/v2ray.service" + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to remove V2Ray." + return 0 + else + colorEcho ${GREEN} "Removed V2Ray successfully." + colorEcho ${BLUE} "If necessary, please remove configuration file and log file manually." + return 0 + fi + elif [[ -n "${SYSTEMCTL_CMD}" ]] && [[ -f "/lib/systemd/system/v2ray.service" ]];then + if pgrep "v2ray" > /dev/null ; then + stopV2ray + fi + systemctl disable v2ray.service + rm -rf "/usr/bin/v2ray" "/lib/systemd/system/v2ray.service" + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to remove V2Ray." + return 0 + else + colorEcho ${GREEN} "Removed V2Ray successfully." + colorEcho ${BLUE} "If necessary, please remove configuration file and log file manually." + return 0 + fi + elif [[ -n "${SERVICE_CMD}" ]] && [[ -f "/etc/init.d/v2ray" ]]; then + if pgrep "v2ray" > /dev/null ; then + stopV2ray + fi + rm -rf "/usr/bin/v2ray" "/etc/init.d/v2ray" + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to remove V2Ray." + return 0 + else + colorEcho ${GREEN} "Removed V2Ray successfully." + colorEcho ${BLUE} "If necessary, please remove configuration file and log file manually." + return 0 + fi + else + colorEcho ${YELLOW} "V2Ray not found." + return 0 + fi +} + +checkUpdate(){ + echo "Checking for update." + VERSION="" + getVersion + RETVAL="$?" + if [[ $RETVAL -eq 1 ]]; then + colorEcho ${BLUE} "Found new version ${NEW_VER} for V2Ray.(Current version:$CUR_VER)" + elif [[ $RETVAL -eq 0 ]]; then + colorEcho ${BLUE} "No new version. Current version is ${NEW_VER}." + elif [[ $RETVAL -eq 2 ]]; then + colorEcho ${YELLOW} "No V2Ray installed." + colorEcho ${BLUE} "The newest version for V2Ray is ${NEW_VER}." + fi + return 0 +} + +main(){ + #helping information + [[ "$HELP" == "1" ]] && Help && return + [[ "$CHECK" == "1" ]] && checkUpdate && return + [[ "$REMOVE" == "1" ]] && remove && return + + local ARCH=$(uname -m) + VDIS="$(archAffix)" + + # extract local file + if [[ $LOCAL_INSTALL -eq 1 ]]; then + colorEcho ${YELLOW} "Installing V2Ray via local file. Please make sure the file is a valid V2Ray package, as we are not able to determine that." + NEW_VER=local + rm -rf /tmp/v2ray + ZIPFILE="$LOCAL" + #FILEVDIS=`ls /tmp/v2ray |grep v2ray-v |cut -d "-" -f4` + #SYSTEM=`ls /tmp/v2ray |grep v2ray-v |cut -d "-" -f3` + #if [[ ${SYSTEM} != "linux" ]]; then + # colorEcho ${RED} "The local V2Ray can not be installed in linux." + # return 1 + #elif [[ ${FILEVDIS} != ${VDIS} ]]; then + # colorEcho ${RED} "The local V2Ray can not be installed in ${ARCH} system." + # return 1 + #else + # NEW_VER=`ls /tmp/v2ray |grep v2ray-v |cut -d "-" -f2` + #fi + else + # download via network and extract + installSoftware "curl" || return $? + getVersion + RETVAL="$?" + if [[ $RETVAL == 0 ]] && [[ "$FORCE" != "1" ]]; then + colorEcho ${BLUE} "Latest version ${CUR_VER} is already installed." + if [ -n "${ERROR_IF_UPTODATE}" ]; then + return 10 + fi + return + elif [[ $RETVAL == 3 ]]; then + return 3 + else + colorEcho ${BLUE} "Installing V2Ray ${NEW_VER} on ${ARCH}" + downloadV2Ray || return $? + fi + fi + + local ZIPROOT="$(zipRoot "${ZIPFILE}")" + installSoftware unzip || return $? + + if [ -n "${EXTRACT_ONLY}" ]; then + colorEcho ${BLUE} "Extracting V2Ray package to ${VSRC_ROOT}." + + if unzip -o "${ZIPFILE}" -d ${VSRC_ROOT}; then + colorEcho ${GREEN} "V2Ray extracted to ${VSRC_ROOT%/}${ZIPROOT:+/${ZIPROOT%/}}, and exiting..." + return 0 + else + colorEcho ${RED} "Failed to extract V2Ray." + return 2 + fi + fi + + if pgrep "v2ray" > /dev/null ; then + V2RAY_RUNNING=1 + stopV2ray + fi + installV2Ray "${ZIPFILE}" "${ZIPROOT}" || return $? + installInitScript "${ZIPFILE}" "${ZIPROOT}" || return $? + if [[ ${V2RAY_RUNNING} -eq 1 ]];then + colorEcho ${BLUE} "Restarting V2Ray service." + startV2ray + fi + colorEcho ${GREEN} "V2Ray ${NEW_VER} is installed." + rm -rf /tmp/v2ray + return 0 +} + +main diff --git a/mtproto.sh b/mtproto.sh new file mode 100644 index 00000000..24455a34 --- /dev/null +++ b/mtproto.sh @@ -0,0 +1,422 @@ +#!/bin/bash +# MTProto一键安装脚本 +# Author: hijk + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +export MTG_CONFIG="${MTG_CONFIG:-$HOME/.config/mtg}" +export MTG_ENV="$MTG_CONFIG/env" +export MTG_SECRET="$MTG_CONFIG/secret" +export MTG_CONTAINER="${MTG_CONTAINER:-mtg}" +export MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:1}" + +DOCKER_CMD="$(command -v docker)" +OSNAME=`hostnamectl | grep -i system | cut -d: -f2` + +IP=`curl -sL -4 ip.sb` + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { + result=$(id | awk '{print $1}') + if [[ $result != "uid=0(root)" ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=`which yum` + if [[ "$?" != "0" ]]; then + res=`which apt` + if [ "$?" != "0" ]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + res=`hostnamectl | grep -i ubuntu` + if [[ "${res}" != "" ]]; then + OS="ubuntu" + else + OS="debian" + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + else + OS="centos" + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + fi + res=`which systemctl` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +status() { + if [[ "$DOCKER_CMD" = "" ]]; then + echo 0 + return + elif [[ ! -f $MTG_ENV ]]; then + echo 1 + return + fi + port=`grep MTG_PORT $MTG_ENV|cut -d= -f2` + if [[ -z "$port" ]]; then + echo 2 + return + fi + res=`ss -ntlp| grep ${port} | grep docker` + if [[ -z "$res" ]]; then + echo 3 + else + echo 4 + fi +} + +statusText() { + res=`status` + case $res in + 3) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 4) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +getData() { + read -p " 请输入MTProto端口[100-65535的一个数字]:" PORT + [[ -z "${PORT}" ]] && { + echo -e " ${RED}请输入MTProto端口!${PLAIN}" + exit 1 + } + if [[ "${PORT:0:1}" = "0" ]]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + MTG_PORT=$PORT + mkdir -p $MTG_CONFIG + echo "MTG_IMAGENAME=$MTG_IMAGENAME" > "$MTG_ENV" + echo "MTG_PORT=$MTG_PORT" >> "$MTG_ENV" + echo "MTG_CONTAINER=$MTG_CONTAINER" >> "$MTG_ENV" +} + +installDocker() { + if [[ "$DOCKER_CMD" != "" ]]; then + systemctl enable docker + systemctl start docker + selinux + return + fi + + #$CMD_REMOVE docker docker-engine docker.io containerd runc + $PMT clean all + $CMD_INSTALL wget curl + if [[ $PMT = "apt" ]]; then + apt clean all + apt-get -y install \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg-agent \ + software-properties-common + curl -fsSL https://download.docker.com/linux/$OS/gpg | apt-key add - + add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/$OS \ + $(lsb_release -cs) \ + stable" + apt update + else + wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo + yum clean all + fi + $CMD_INSTALL docker-ce docker-ce-cli containerd.io + + DOCKER_CMD="$(command -v docker)" + if [[ "$DOCKER_CMD" = "" ]]; then + echo -e " ${RED}$OSNAME docker安装失败,请到https://hijk.art反馈${PLAIN}" + exit 1 + fi + systemctl enable docker + systemctl start docker + + selinux +} + +pullImage() { + if [[ "$DOCKER_CMD" = "" ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + exit 1 + fi + + set -a + source "$MTG_ENV" + set +a + + $DOCKER_CMD pull "$MTG_IMAGENAME" > /dev/null +} + +selinux() { + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +firewall() { + port=$1 + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-port=$port/tcp + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [ "$nl" != "3" ]; then + iptables -I INPUT -p tcp --dport=$port -j ACCEPT + else + res=`ufw status | grep -i inactive` + if [ "$res" = "" ]; then + ufw allow $port/tcp + fi + fi + fi +} + +start() { + res=`status` + if [[ $res -lt 3 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + set -a + source "$MTG_ENV" + set +a + + if [[ ! -f "$MTG_SECRET" ]]; then + $DOCKER_CMD run \ + --rm \ + "$MTG_IMAGENAME" \ + generate-secret tls -c "$(openssl rand -hex 16).com" \ + > "$MTG_SECRET" + fi + + $DOCKER_CMD ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r $DOCKER_CMD rm -fv > /dev/null + $DOCKER_CMD run \ + -d \ + --restart=unless-stopped \ + --name "$MTG_CONTAINER" \ + --ulimit nofile=51200:51200 \ + -p "$MTG_PORT:3128" \ + "$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")" > /dev/null + + sleep 3 + res=`ss -ntlp| grep ${MTG_PORT} | grep docker` + if [[ "$res" = "" ]]; then + docker logs $MTG_CONTAINER | tail + echo -e " ${RED}$OSNAME 启动docker镜像失败,请到 https://hijk.art 反馈${PLAIN}" + exit 1 + else + colorEcho $BLUE " MTProto启动成功!" + fi +} + +stop() { + res=`status` + if [[ $res -lt 3 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + set -a + source "$MTG_ENV" + set +a + + $DOCKER_CMD stop $MTG_CONTAINER >> /dev/null + colorEcho $BLUE " MTProto停止成功!" +} + +showInfo() { + res=`status` + if [[ $res -lt 3 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + SECRET=$(cat "$MTG_SECRET") + set -a + source "$MTG_ENV" + set +a + + echo + echo -e " ${RED}MTProto代理信息:${PLAIN}" + echo + echo -n -e " ${BLUE}当前状态:${PLAIN}" + statusText + echo -e " ${BLUE}IP:${PLAIN}${RED}$IP${PLAIN}" + echo -e " ${BLUE}端口:${PLAIN}${RED}$MTG_PORT${PLAIN}" + echo -e " ${BLUE}密钥:${PLAIN}${RED}$SECRET${PLAIN}" + echo "" + echo -e " 如需获取tg://proxy形式的链接,请打开telegrame关注${GREEN}@MTProxybot${PLAIN}生成" + echo "" +} + +install() { + getData + installDocker + pullImage + start + firewall $MTG_PORT + showInfo +} + +update() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + pullImage + stop + start + showInfo +} + +uninstall() { + echo "" + read -p " 确定卸载MTProto?[y/n]:" answer + if [[ "$answer" = "y" ]] || [[ "$answer" = "Y" ]]; then + stop + rm -rf $MTG_CONFIG + docker system prune -af + systemctl stop docker + systemctl disable docker + $CMD_REMOVE docker-ce docker-ce-cli containerd.io + colorEcho $GREEN " 卸载成功" + fi +} + +restart() { + res=`status` + if [[ $res -lt 3 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + stop + start +} + +reconfig() +{ + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + getData + stop + start + firewall $MTG_PORT + showInfo +} + +showLog() { + res=`status` + if [[ $res -lt 3 ]]; then + echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}" + return + fi + + set -a + source "$MTG_ENV" + set +a + + $DOCKER_CMD logs $MTG_CONTAINER | tail +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}MTProto一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" + + echo -e " ${GREEN}1.${PLAIN} 安装MTProto代理" + echo -e " ${GREEN}2.${PLAIN} 更新MTProto代理" + echo -e " ${GREEN}3.${PLAIN} 卸载MTProto代理" + echo " -------------" + echo -e " ${GREEN}4.${PLAIN} 启动MTProto代理" + echo -e " ${GREEN}5.${PLAIN} 重启MTProto代理" + echo -e " ${GREEN}6.${PLAIN} 停止MTProto代理" + echo " -------------" + echo -e " ${GREEN}7.${PLAIN} 查看MTProto信息" + echo -e " ${GREEN}8.${PLAIN} 修改MTProto配置" + echo -e " ${GREEN}9.${PLAIN} 查看MTProto日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-9]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + update + ;; + 3) + uninstall + ;; + 4) + start + ;; + 5) + restart + ;; + 6) + stop + ;; + 7) + showInfo + ;; + 8) + reconfig + ;; + 9) + showLog + ;; + *) + echo -e " ${RED}请选择正确的操作!${PLAIN}" + exit 1 + ;; + esac +} + +checkSystem + +menu diff --git a/ss.sh b/ss.sh new file mode 100644 index 00000000..df9b5504 --- /dev/null +++ b/ss.sh @@ -0,0 +1,668 @@ +#!/bin/bash +# shadowsocks/ss一键安装脚本 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +BASE=`pwd` +OS=`hostnamectl | grep -i system | cut -d: -f2` + +NAME="shadowsocks-libev" +CONFIG_FILE="/etc/${NAME}/config.json" +SERVICE_FILE="/etc/systemd/system/${NAME}.service" + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { + result=$(id | awk '{print $1}') + if [[ $result != "uid=0(root)" ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=`which yum 2>/dev/null` + if [[ "$?" != "0" ]]; then + res=`which apt 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + fi + res=`which systemctl 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +status() { + export PATH=/usr/local/bin:$PATH + cmd="$(command -v ss-server)" + if [[ "$cmd" = "" ]]; then + echo 0 + return + fi + if [[ ! -f $CONFIG_FILE ]]; then + echo 1 + return + fi + port=`grep server_port $CONFIG_FILE|cut -d: -f2| tr -d \",' '` + res=`ss -ntlp| grep ${port} | grep ss-server` + if [[ -z "$res" ]]; then + echo 2 + else + echo 3 + fi +} + +statusText() { + res=`status` + case $res in + 2) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 3) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +getData() { + echo "" + read -p " 请设置SS的密码(不输入则随机生成):" PASSWORD + [[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + echo "" + colorEcho $BLUE " 密码: $PASSWORD" + + echo "" + while true + do + read -p " 请设置SS的端口号[1025-65535]:" PORT + [[ -z "$PORT" ]] && PORT=`shuf -i1025-65000 -n1` + if [[ "${PORT:0:1}" = "0" ]]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null + if [[ $? -eq 0 ]]; then + if [[ $PORT -ge 1025 ]] && [[ $PORT -le 65535 ]]; then + echo "" + colorEcho $BLUE " 端口号: $PORT" + echo "" + break + else + colorEcho $RED " 输入错误,端口号为1025-65535的数字" + fi + else + colorEcho $RED " 输入错误,端口号为1025-65535的数字" + fi + done + colorEcho $RED " 请选择加密方式:" + echo " 1)aes-256-gcm" + echo " 2)aes-192-gcm" + echo " 3)aes-128-gcm" + echo " 4)aes-256-ctr" + echo " 5)aes-192-ctr" + echo " 6)aes-128-ctr" + echo " 7)aes-256-cfb" + echo " 8)aes-192-cfb" + echo " 9)aes-128-cfb" + echo " 10)camellia-128-cfb" + echo " 11)camellia-192-cfb" + echo " 12)camellia-256-cfb" + echo " 13)chacha20-ietf" + echo " 14)chacha20-ietf-poly1305" + echo " 15)xchacha20-ietf-poly1305" + read -p " 请选择(默认aes-256-gcm)" answer + if [[ -z "$answer" ]]; then + METHOD="aes-256-gcm" + else + case $answer in + 1) + METHOD="aes-256-gcm" + ;; + 2) + METHOD="aes-192-gcm" + ;; + 3) + METHOD="aes-128-gcm" + ;; + 4) + METHOD="aes-256-ctr" + ;; + 5) + METHOD="aes-192-ctr" + ;; + 6) + METHOD="aes-128-ctr" + ;; + 7) + METHOD="aes-256-cfb" + ;; + 8) + METHOD="aes-192-cfb" + ;; + 9) + METHOD="aes-128-cfb" + ;; + 10) + METHOD="camellia-128-cfb" + ;; + 11) + METHOD="camellia-192-cfb" + ;; + 12) + METHOD="camellia-256-cfb" + ;; + 13) + METHOD="chacha20-ietf" + ;; + 14) + METHOD="chacha20-ietf-poly1305" + ;; + 15) + METHOD="xchacha20-ietf-poly1305" + ;; + *) + colorEcho $RED " 无效的选择,使用默认的aes-256-gcm" + METHOD="aes-256-gcm" + esac + fi + echo "" + colorEcho $BLUE "加密方式: $METHOD" +} + +preinstall() { + $PMT clean all + #echo $CMD_UPGRADE | bash + [[ "$PMT" = "apt" ]] && $PMT update + + echo "" + colorEcho $BULE " 安装必要软件" + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + fi + $CMD_INSTALL wget vim net-tools unzip tar qrencode + $CMD_INSTALL openssl gettext gcc autoconf libtool automake make asciidoc xmlto + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL openssl-devel udns-devel libev-devel pcre pcre-devel mbedtls mbedtls-devel libsodium libsodium-devel c-ares c-ares-devel + else + $CMD_INSTALL libssl-dev libudns-dev libev-dev libpcre3 libpcre3-dev libmbedtls-dev libc-ares2 libc-ares-dev g++ + $CMD_INSTALL libsodium* + fi + res=`which wget 2>/dev/null` + [[ "$?" != "0" ]] && $CMD_INSTALL wget + res=`which netstat 2>/dev/null` + [[ "$?" != "0" ]] && $CMD_INSTALL net-tools + + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +normalizeVersion() { + if [ -n "$1" ]; then + case "$1" in + v*) + echo "${1:1}" + ;; + *) + echo "$1" + ;; + esac + else + echo "" + fi +} + +installNewVer() { + new_ver=$1 + if ! wget "${V6_PROXY}https://github.com/shadowsocks/shadowsocks-libev/releases/download/v${new_ver}/shadowsocks-libev-${new_ver}.tar.gz" -O ${NAME}.tar.gz; then + colorEcho $RED " 下载安装文件失败!" + exit 1 + fi + tar zxf ${NAME}.tar.gz + cd shadowsocks-libev-${new_ver} + ./configure + make && make install + if [[ $? -ne 0 ]]; then + echo + echo -e " [${RED}错误${PLAIN}]: $OS Shadowsocks-libev 安装失败! 请打开 https://hijk.art 反馈" + cd ${BASE} && rm -rf shadowsocks-libev* + exit 1 + fi + ssPath=`which ss-server 2>/dev/null` + [[ "$ssPath" != "" ]] || { + cd ${BASE} && rm -rf shadowsocks-libev* + colorEcho $RED " SS安装失败,请到 https://hijk.art 反馈" + exit 1 + } + cat > $SERVICE_FILE <<-EOF +[Unit] +Description=shadowsocks +Documentation=https://hijk.art/ +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +PIDFile=/var/run/${NAME}.pid +LimitNOFILE=32768 +ExecStart=$ssPath -c $CONFIG_FILE -f /var/run/${NAME}.pid +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable ${NAME} + cd ${BASE} && rm -rf shadowsocks-libev* + + colorEcho $BLUE " 安装成功!" +} + +installSS() { + echo "" + colorEcho $BLUE " 安装最新版SS..." + + tag_url="${V6_PROXY}https://api.github.com/repos/shadowsocks/shadowsocks-libev/releases/latest" + new_ver="$(normalizeVersion "$(curl -s "${tag_url}" --connect-timeout 10| grep 'tag_name' | cut -d\" -f4)")" + export PATH=/usr/local/bin:$PATH + ssPath=`which ss-server 2>/dev/null` + if [[ "$?" != "0" ]]; then + [[ "$new_ver" != "" ]] || new_ver="3.3.5" + installNewVer $new_ver + else + ver=`ss-server -h | grep ${NAME} | grep -oE '[0-9+\.]+'` + if [[ $ver != $new_ver ]]; then + installNewVer $new_ver + else + colorEcho $YELLOW " 已安装最新版SS" + fi + fi +} + +configSS(){ + interface="0.0.0.0" + if [[ "$V6_PROXY" != "" ]]; then + interface="::" + fi + + mkdir -p /etc/${NAME} + cat > $CONFIG_FILE<<-EOF +{ + "server":"$interface", + "server_port":${PORT}, + "local_port":1080, + "password":"${PASSWORD}", + "timeout":600, + "method":"${METHOD}", + "nameserver":"8.8.8.8", + "mode":"tcp_and_udp", + "fast_open":false +} +EOF +} + +installBBR() { + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已安装" + INSTALL_BBR=false + return + fi + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + echo "" + colorEcho $BLUE " 安装BBR模块..." + if [[ "$PMT" = "yum" ]]; then + if [[ "${V6_PROXY}" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + $CMD_INSTALL --enablerepo=elrepo-kernel kernel-ml + $CMD_REMOVE kernel-3.* + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi + else + $CMD_INSTALL --install-recommends linux-generic-hwe-16.04 + grub-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi +} + +setFirewall() { + res=`which firewall-cmd 2>/dev/null` + if [[ $? -eq 0 ]]; then + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + fi + else + res=`which iptables 2>/dev/null` + if [[ $? -eq 0 ]]; then + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + else + res=`which ufw 2>/dev/null` + if [[ $? -eq 0 ]]; then + res=`ufw status | grep -i inactive` + if [[ "$res" = "" ]]; then + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp + fi + fi + fi + fi +} + +showInfo() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + + port=`grep server_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep 'ss-server'` + [[ -z "$res" ]] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + + res=`echo -n "${method}:${password}@${IP}:${port}" | base64 -w 0` + link="ss://${res}" + + echo ============================================ + echo -e " ${BLUE}ss运行状态${PLAIN}:${status}" + echo -e " ${BLUE}ss配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo "" + echo -e " ${RED}ss配置信息:${PLAIN}" + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}加密方式(method):${PLAIN} ${RED}${method}${PLAIN}" + echo + echo -e " ${BLUE}ss链接${PLAIN}: ${link}" + #qrencode -o - -t utf8 ${link} +} + +showQR() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + + port=`grep server_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep 'ss-server'` + [[ -z "$res" ]] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + + res=`echo -n "${method}:${password}@${IP}:${port}" | base64 -w 0` + link="ss://${res}" + qrencode -o - -t utf8 ${link} +} + +function bbrReboot() { + if [ "${INSTALL_BBR}" == "true" ]; then + echo + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" + echo + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" + sleep 30 + reboot + fi +} + +install() { + getData + + preinstall + installSS + configSS + installBBR + setFirewall + + start + showInfo + + bbrReboot +} + +reconfig() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + getData + configSS + restart + setFirewall + + showInfo +} + +update() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + installSS + restart +} + +start() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + systemctl restart ${NAME} + sleep 2 + port=`grep server_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + res=`ss -nltp | grep ${port} | grep ss-server` + if [[ "$res" = "" ]]; then + colorEcho $RED " SS启动失败,请检查端口是否被占用!" + else + colorEcho $BLUE " SS启动成功!" + fi +} + +restart() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + + stop + start +} + +stop() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + systemctl stop ${NAME} + colorEcho $BLUE " SS停止成功" +} + +uninstall() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + + echo "" + read -p " 确定卸载SS吗?(y/n)" answer + [[ -z ${answer} ]] && answer="n" + + if [[ "${answer}" == "y" ]] || [[ "${answer}" == "Y" ]]; then + systemctl stop ${NAME} && systemctl disable ${NAME} + rm -rf $SERVICE_FILE + cd /usr/local/bin && rm -rf ss-local ss-manager ss-nat ss-redir ss-server ss-tunnel + rm -rf /usr/lib64/libshadowsocks-libev* + rm -rf /usr/share/doc/shadowsocks-libev* + rm -rf /usr/share/man/man1/ss-*.gz + rm -rf /usr/share/man/man8/shadowsocks-libev* + colorEcho $GREEN " SS卸载成功" + fi +} + +showLog() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + journalctl -xen --no-pager -u ${NAME} +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}Shadowsocks/SS 一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" + + echo -e " ${GREEN}1.${PLAIN} 安装SS" + echo -e " ${GREEN}2.${PLAIN} 更新SS" + echo -e " ${GREEN}3. ${RED}卸载SS${PLAIN}" + echo " -------------" + echo -e " ${GREEN}4.${PLAIN} 启动SS" + echo -e " ${GREEN}5.${PLAIN} 重启SS" + echo -e " ${GREEN}6.${PLAIN} 停止SS" + echo " -------------" + echo -e " ${GREEN}7.${PLAIN} 查看SS配置" + echo -e " ${GREEN}8.${PLAIN} 查看配置二维码" + echo -e " ${GREEN}9. ${RED}修改SS配置${PLAIN}" + echo -e " ${GREEN}10.${PLAIN} 查看SS日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-10]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + update + ;; + 3) + uninstall + ;; + 4) + start + ;; + 5) + restart + ;; + 6) + stop + ;; + 7) + showInfo + ;; + 8) + showQR + ;; + 9) + reconfig + ;; + 10) + showLog + ;; + *) + echo -e "$RED 请选择正确的操作!${PLAIN}" + exit 1 + ;; + esac +} + +checkSystem + +action=$1 +[[ -z $1 ]] && action=menu +case "$action" in + menu|install|update|uninstall|start|restart|stop|showInfo|showQR|showLog) + ${action} + ;; + *) + echo " 参数错误" + echo " 用法: `basename $0` [menu|install|update|uninstall|start|restart|stop|showInfo|showQR|showLog]" + ;; +esac diff --git a/ssr.sh b/ssr.sh new file mode 100644 index 00000000..ce7203cf --- /dev/null +++ b/ssr.sh @@ -0,0 +1,700 @@ +#!/bin/bash +# shadowsocksR/SSR一键安装教程 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +FILENAME="ShadowsocksR-v3.2.2" +URL="${V6_PROXY}https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz" +BASE=`pwd` + +OS=`hostnamectl | grep -i system | cut -d: -f2` + +CONFIG_FILE="/etc/shadowsocksR.json" +SERVICE_FILE="/etc/systemd/system/shadowsocksR.service" +NAME="shadowsocksR" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + + +checkSystem() { + result=$(id | awk '{print $1}') + if [[ $result != "uid=0(root)" ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=`which yum 2>/dev/null` + if [[ "$?" != "0" ]]; then + res=`which apt 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update && apt upgrade -y; apt autoremove -y" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + fi + res=`which systemctl 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +getData() { + echo "" + read -p " 请设置SSR的密码(不输入则随机生成):" PASSWORD + [[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + echo "" + colorEcho $BLUE " 密码: $PASSWORD" + + echo "" + while true + do + read -p " 请设置SSR的端口号[1-65535]:" PORT + [[ -z "$PORT" ]] && PORT=`shuf -i1025-65000 -n1` + if [[ "${PORT:0:1}" = "0" ]]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null + if [[ $? -eq 0 ]]; then + if [ $PORT -ge 1 ] && [ $PORT -le 65535 ]; then + echo "" + colorEcho $BLUE " 端口号: $PORT" + break + else + colorEcho $RED " 输入错误,端口号为1-65535的数字" + fi + else + colorEcho $RED " 输入错误,端口号为1-65535的数字" + fi + done + + echo "" + colorEcho $BLUE " 请选择SSR的加密方式:" + echo " 1)aes-256-cfb" + echo " 2)aes-192-cfb" + echo " 3)aes-128-cfb" + echo " 4)aes-256-ctr" + echo " 5)aes-192-ctr" + echo " 6)aes-128-ctr" + echo " 7)aes-256-cfb8" + echo " 8)aes-192-cfb8" + echo " 9)aes-128-cfb8" + echo " 10)camellia-128-cfb" + echo " 11)camellia-192-cfb" + echo " 12)camellia-256-cfb" + echo " 13)chacha20-ietf" + read -p " 请选择加密方式(默认aes-256-cfb)" answer + if [[ -z "$answer" ]]; then + METHOD="aes-256-cfb" + else + case $answer in + 1) + METHOD="aes-256-cfb" + ;; + 2) + METHOD="aes-192-cfb" + ;; + 3) + METHOD="aes-128-cfb" + ;; + 4) + METHOD="aes-256-ctr" + ;; + 5) + METHOD="aes-192-ctr" + ;; + 6) + METHOD="aes-128-ctr" + ;; + 7) + METHOD="aes-256-cfb8" + ;; + 8) + METHOD="aes-192-cfb8" + ;; + 9) + METHOD="aes-128-cfb8" + ;; + 10) + METHOD="camellia-128-cfb" + ;; + 11) + METHOD="camellia-192-cfb" + ;; + 12) + METHOD="camellia-256-cfb" + ;; + 13) + METHOD="chacha20-ietf" + ;; + *) + colorEcho $RED " 无效的选择,使用默认加密方式" + METHOD="aes-256-cfb" + esac + fi + echo "" + colorEcho $BLUE " 加密方式: $METHOD" + + echo "" + colorEcho $BLUE " 请选择SSR协议:" + echo " 1)origin" + echo " 2)verify_deflate" + echo " 3)auth_sha1_v4" + echo " 4)auth_aes128_md5" + echo " 5)auth_aes128_sha1" + echo " 6)auth_chain_a" + echo " 7)auth_chain_b" + echo " 8)auth_chain_c" + echo " 9)auth_chain_d" + echo " 10)auth_chain_e" + echo " 11)auth_chain_f" + read -p " 请选择SSR协议(默认origin)" answer + if [[ -z "$answer" ]]; then + PROTOCOL="origin" + else + case $answer in + 1) + PROTOCOL="origin" + ;; + 2) + PROTOCOL="verify_deflate" + ;; + 3) + PROTOCOL="auth_sha1_v4" + ;; + 4) + PROTOCOL="auth_aes128_md5" + ;; + 5) + PROTOCOL="auth_aes128_sha1" + ;; + 6) + PROTOCOL="auth_chain_a" + ;; + 7) + PROTOCOL="auth_chain_b" + ;; + 8) + PROTOCOL="auth_chain_c" + ;; + 9) + PROTOCOL="auth_chain_d" + ;; + 10) + PROTOCOL="auth_chain_e" + ;; + 11) + PROTOCOL="auth_chain_f" + ;; + *) + colorEcho $RED " 无效的选择,使用默认协议" + PROTOCOL="origin" + esac + fi + echo "" + colorEcho $BLUE " SSR协议: $PROTOCOL" + + echo "" + colorEcho $BLUE " 请选择SSR混淆模式:" + echo " 1)plain" + echo " 2)http_simple" + echo " 3)http_post" + echo " 4)tls1.2_ticket_auth" + echo " 5)tls1.2_ticket_fastauth" + read -p " 请选择混淆模式(默认plain)" answer + if [[ -z "$answer" ]]; then + OBFS="plain" + else + case $answer in + 1) + OBFS="plain" + ;; + 2) + OBFS="http_simple" + ;; + 3) + OBFS="http_post" + ;; + 4) + OBFS="tls1.2_ticket_auth" + ;; + 5) + OBFS="tls1.2_ticket_fastauth" + ;; + *) + colorEcho $RED " 无效的选择,使用默认混淆模式" + OBFS="plain" + esac + fi + echo "" + colorEcho $BLUE " 混淆模式: $OBFS" +} + +status() { + res=`which python 2>/dev/null` + if [[ "$?" != "0" ]]; then + echo 0 + return + fi + if [[ ! -f $CONFIG_FILE ]]; then + echo 1 + return + fi + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep python` + if [[ -z "$res" ]]; then + echo 2 + else + echo 3 + fi +} + +statusText() { + res=`status` + case $res in + 2) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 3) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +preinstall() { + $PMT clean all + [[ "$PMT" = "apt" ]] && $PMT update + #echo $CMD_UPGRADE | bash + echo "" + colorEcho $BLUE " 安装必要软件" + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + fi + $CMD_INSTALL curl wget vim net-tools libsodium* openssl unzip tar qrencode + res=`which wget 2>/dev/null` + [[ "$?" != "0" ]] && $CMD_INSTALL wget + res=`which netstat 2>/dev/null` + [[ "$?" != "0" ]] && $CMD_INSTALL net-tools + res=`which python 2>/dev/null` + if [[ "$?" != "0" ]]; then + ln -s /usr/bin/python3 /usr/bin/python + fi + + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +installSSR() { + if [[ ! -d /usr/local/shadowsocks ]]; then + colorEcho $BLUE " 下载安装文件" + if ! wget --no-check-certificate -O ${FILENAME}.tar.gz ${URL}; then + echo -e " [${RED}Error${PLAIN}] 下载文件失败!" + exit 1 + fi + + tar -zxf ${FILENAME}.tar.gz + mv shadowsocksr-3.2.2/shadowsocks /usr/local + if [[ ! -f /usr/local/shadowsocks/server.py ]]; then + colorEcho $RED " $OS 安装失败,请到 https://hijk.art 网站反馈" + cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz + exit 1 + fi + cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz + fi + +cat > $SERVICE_FILE <<-EOF +[Unit] +Description=shadowsocksR +Documentation=https://hijk.art/ +After=network-online.target +Wants=network-online.target + +[Service] +Type=forking +LimitNOFILE=32768 +ExecStart=/usr/local/shadowsocks/server.py -c $CONFIG_FILE -d start +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable shadowsocksR +} + +configSSR() { + cat > $CONFIG_FILE<<-EOF +{ + "server":"0.0.0.0", + "server_ipv6":"::", + "server_port":${PORT}, + "local_port":1080, + "password":"${PASSWORD}", + "timeout":600, + "method":"${METHOD}", + "protocol":"${PROTOCOL}", + "protocol_param":"", + "obfs":"${OBFS}", + "obfs_param":"", + "redirect":"", + "dns_ipv6":false, + "fast_open":false, + "workers":1 +} +EOF +} + +setFirewall() { + res=`which firewall-cmd 2>/dev/null` + if [[ $? -eq 0 ]]; then + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + fi + else + res=`which iptables 2>/dev/null` + if [[ $? -eq 0 ]]; then + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + else + res=`which ufw 2>/dev/null` + if [[ $? -eq 0 ]]; then + res=`ufw status | grep -i inactive` + if [[ "$res" = "" ]]; then + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp + fi + fi + fi + fi +} + +installBBR() { + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已安装" + INSTALL_BBR=false + return + fi + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$PMT" = "yum" ]]; then + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + $CMD_INSTALL --enablerepo=elrepo-kernel kernel-ml + $CMD_REMOVE kernel-3.* + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi + else + $CMD_INSTALL --install-recommends linux-generic-hwe-16.04 + grub-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi +} + +showInfo() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SSR未安装,请先安装!${PLAIN}" + return + fi + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep python` + [[ -z "$res" ]] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + protocol=`grep protocol $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + obfs=`grep obfs $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + + p1=`echo -n ${password} | base64 -w 0` + p1=`echo -n ${p1} | tr -d =` + res=`echo -n "${IP}:${port}:${protocol}:${method}:${obfs}:${p1}/?remarks=&protoparam=&obfsparam=" | base64 -w 0` + res=`echo -n ${res} | tr -d =` + link="ssr://${res}" + + echo "" + echo ============================================ + echo -e " ${BLUE}ssr运行状态:${PLAIN}${status}" + echo -e " ${BLUE}ssr配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo "" + echo -e " ${RED}ssr配置信息:${PLAIN}" + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}加密方式(method):${PLAIN} ${RED}${method}${PLAIN}" + echo -e " ${BLUE}协议(protocol):${PLAIN} ${RED}${protocol}${PLAIN}" + echo -e " ${BLUE}混淆(obfuscation):${PLAIN} ${RED}${obfs}${PLAIN}" + echo + echo -e " ${BLUE}ssr链接:${PLAIN} $link" + #qrencode -o - -t utf8 $link +} + +showQR() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SSR未安装,请先安装!${PLAIN}" + return + fi + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep python` + [[ -z "$res" ]] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + protocol=`grep protocol $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + obfs=`grep obfs $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + + p1=`echo -n ${password} | base64 -w 0` + p1=`echo -n ${p1} | tr -d =` + res=`echo -n "${IP}:${port}:${protocol}:${method}:${obfs}:${p1}/?remarks=&protoparam=&obfsparam=" | base64 -w 0` + res=`echo -n ${res} | tr -d =` + link="ssr://${res}" + qrencode -o - -t utf8 $link +} + +bbrReboot() { + if [[ "${INSTALL_BBR}" == "true" ]]; then + echo + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" + echo + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" + sleep 30 + reboot + fi +} + + +install() { + getData + preinstall + installBBR + installSSR + configSSR + setFirewall + + start + showInfo + + bbrReboot +} + +reconfig() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SSR未安装,请先安装!${PLAIN}" + return + fi + getData + configSSR + setFirewall + restart + + showInfo +} + +uninstall() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SSR未安装,请先安装!${PLAIN}" + return + fi + + echo "" + read -p " 确定卸载SSR吗?(y/n)" answer + [[ -z ${answer} ]] && answer="n" + + if [[ "${answer}" == "y" ]] || [[ "${answer}" == "Y" ]]; then + rm -f $CONFIG_FILE + rm -f /var/log/shadowsocksr.log + rm -rf /usr/local/shadowsocks + systemctl disable shadowsocksR && systemctl stop shadowsocksR && rm -rf $SERVICE_FILE + fi + echo -e " ${RED}卸载成功${PLAIN}" +} + +start() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SS未安装,请先安装!${PLAIN}" + return + fi + systemctl restart ${NAME} + sleep 2 + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`netstat -nltp | grep ${port} | grep python` + if [[ "$res" = "" ]]; then + colorEcho $RED " SSR启动失败,请检查端口是否被占用!" + else + colorEcho $BLUE " SSR启动成功!" + fi +} + +restart() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SSR未安装,请先安装!${PLAIN}" + return + fi + + stop + start +} + +stop() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}SSR未安装,请先安装!${PLAIN}" + return + fi + systemctl stop ${NAME} + colorEcho $BLUE " SSR停止成功" +} + +showLog() { + tail /var/log/shadowsocksr.log +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}ShadowsocksR/SSR 一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" + + echo -e " ${GREEN}1.${PLAIN} 安装SSR" + echo -e " ${GREEN}2. ${RED}卸载SSR${PLAIN}" + echo " -------------" + echo -e " ${GREEN}4.${PLAIN} 启动SSR" + echo -e " ${GREEN}5.${PLAIN} 重启SSR" + echo -e " ${GREEN}6.${PLAIN} 停止SSR" + echo " -------------" + echo -e " ${GREEN}7.${PLAIN} 查看SSR配置" + echo -e " ${GREEN}8.${PLAIN} 查看配置二维码" + echo -e " ${GREEN}9. ${RED}修改SSR配置${PLAIN}" + echo -e " ${GREEN}10.${PLAIN} 查看SSR日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-10]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + uninstall + ;; + 4) + start + ;; + 5) + restart + ;; + 6) + stop + ;; + 7) + showInfo + ;; + 8) + showQR + ;; + 9) + reconfig + ;; + 10) + showLog + ;; + *) + echo -e "$RED 请选择正确的操作!${PLAIN}" + exit 1 + ;; + esac +} + +checkSystem + +action=$1 +[[ -z $1 ]] && action=menu +case "$action" in + menu|install|uninstall|start|restart|stop|showInfo|showQR|showLog) + ${action} + ;; + *) + echo " 参数错误" + echo " 用法: `basename $0` [menu|install|uninstall|start|restart|stop|showInfo|showQR|showLog]" + ;; +esac + diff --git a/trojan-go.sh b/trojan-go.sh new file mode 100644 index 00000000..cff64361 --- /dev/null +++ b/trojan-go.sh @@ -0,0 +1,1012 @@ +#!/bin/bash +# trojan-go一键安装脚本 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" + +res=`which bt 2>/dev/null` +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +# 以下网站是随机从Google上找到的无广告小说网站,不喜欢请改成其他网址,以http或https开头 +# 搭建好后无法打开伪装域名,可能是反代小说网站挂了,请在网站留言,或者Github发issue,以便替换新的网站 +SITES=( +http://www.zhuizishu.com/ +http://xs.56dyc.com/ +#http://www.xiaoshuosk.com/ +#https://www.quledu.net/ +http://www.ddxsku.com/ +http://www.biqu6.com/ +https://www.wenshulou.cc/ +#http://www.auutea.com/ +http://www.55shuba.com/ +http://www.39shubao.com/ +https://www.23xsw.cc/ +#https://www.huanbige.com/ +https://www.jueshitangmen.info/ +https://www.zhetian.org/ +http://www.bequgexs.com/ +http://www.tjwl.com/ +) + +ZIP_FILE="trojan-go" +CONFIG_FILE="/etc/trojan-go/config.json" + +WS="false" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { + result=$(id | awk '{print $1}') + if [[ $result != "uid=0(root)" ]]; then + echo -e " ${RED}请以root身份执行该脚本${PLAIN}" + exit 1 + fi + + res=`which yum 2>/dev/null` + if [[ "$?" != "0" ]]; then + res=`which apt 2>/dev/null` + if [[ "$?" != "0" ]]; then + echo -e " ${RED}不受支持的Linux系统${PLAIN}" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + fi + res=`which systemctl 2>/dev/null` + if [[ "$?" != "0" ]]; then + echo -e " ${RED}系统版本过低,请升级到最新版本${PLAIN}" + exit 1 + fi +} + +status() { + trojan_cmd="$(command -v trojan-go)" + if [[ "$trojan_cmd" = "" ]]; then + echo 0 + return + fi + if [[ ! -f $CONFIG_FILE ]]; then + echo 1 + return + fi + port=`grep local_port $CONFIG_FILE|cut -d: -f2| tr -d \",' '` + res=`ss -ntlp| grep ${port} | grep trojan-go` + if [[ -z "$res" ]]; then + echo 2 + else + echo 3 + fi +} + +statusText() { + res=`status` + case $res in + 2) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 3) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +getVersion() { + VERSION=`curl -fsSL ${V6_PROXY}https://api.github.com/repos/p4gefau1t/trojan-go/releases | grep tag_name | sed -E 's/.*"v(.*)".*/\1/'| head -n1` + if [[ ${VERSION:0:1} != "v" ]];then + VERSION="v${VERSION}" + fi +} + +archAffix() { + case "${1:-"$(uname -m)"}" in + i686|i386) + echo '386' + ;; + x86_64|amd64) + echo 'amd64' + ;; + *armv7*|armv6l) + echo 'armv7' + ;; + *armv8*|aarch64) + echo 'armv8' + ;; + *armv6*) + echo 'armv6' + ;; + *arm*) + echo 'arm' + ;; + *mips64le*) + echo 'mips64le' + ;; + *mips64*) + echo 'mips64' + ;; + *mipsle*) + echo 'mipsle-softfloat' + ;; + *mips*) + echo 'mips-softfloat' + ;; + *) + return 1 + ;; + esac + + return 0 +} + +getData() { + echo "" + can_change=$1 + if [[ "$can_change" != "yes" ]]; then + echo " trojan-go一键脚本,运行之前请确认如下条件已经具备:" + echo -e " ${RED}1. 一个伪装域名${PLAIN}" + echo -e " ${RED}2. 伪装域名DNS解析指向当前服务器ip(${IP})${PLAIN}" + echo -e " 3. 如果/root目录下有 ${GREEN}trojan-go.pem${PLAIN} 和 ${GREEN}trojan-go.key${PLAIN} 证书密钥文件,无需理会条件2" + echo " " + read -p " 确认满足按y,按其他退出脚本:" answer + if [[ "${answer,,}" != "y" ]]; then + exit 0 + fi + + echo "" + while true + do + read -p " 请输入伪装域名:" DOMAIN + if [[ -z "${DOMAIN}" ]]; then + echo -e " ${RED}伪装域名输入错误,请重新输入!${PLAIN}" + else + break + fi + done + colorEcho $BLUE " 伪装域名(host):$DOMAIN" + + echo "" + DOMAIN=${DOMAIN,,} + if [[ -f ~/trojan-go.pem && -f ~/trojan-go.key ]]; then + echo -e "${GREEN} 检测到自有证书,将使用其部署${PLAIN}" + CERT_FILE="/etc/trojan-go/${DOMAIN}.pem" + KEY_FILE="/etc/trojan-go/${DOMAIN}.key" + else + resolve=`curl -sL https://hijk.art/hostip.php?d=${DOMAIN}` + res=`echo -n ${resolve} | grep ${IP}` + if [[ -z "${res}" ]]; then + echo " ${DOMAIN} 解析结果:${resolve}" + echo -e " ${RED}伪装域名未解析到当前服务器IP(${IP})!${PLAIN}" + exit 1 + fi + fi + else + DOMAIN=`grep sni $CONFIG_FILE | cut -d\" -f4` + CERT_FILE=`grep cert $CONFIG_FILE | cut -d\" -f4` + KEY_FILE=`grep key $CONFIG_FILE | cut -d\" -f4` + read -p " 是否转换成WS版本?[y/n]" answer + if [[ "${answer,,}" = "y" ]]; then + WS="true" + fi + fi + + echo "" + read -p " 请设置trojan-go密码(不输则随机生成):" PASSWORD + [[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + colorEcho $BLUE " trojan-go密码:$PASSWORD" + echo "" + while true + do + read -p " 是否需要再设置一组密码?[y/n]" answer + if [[ ${answer,,} = "n" ]]; then + break + fi + read -p " 请设置trojan-go密码(不输则随机生成):" pass + [[ -z "$pass" ]] && pass=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + echo "" + colorEcho $BLUE " trojan-go密码:$pass" + PASSWORD="${PASSWORD}\",\"$pass" + done + + echo "" + read -p " 请输入trojan-go端口[100-65535的一个数字,默认443]:" PORT + [[ -z "${PORT}" ]] && PORT=443 + if [[ "${PORT:0:1}" = "0" ]]; then + echo -e "${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + colorEcho $BLUE " trojan-go端口:$PORT" + + if [[ ${WS} = "true" ]]; then + echo "" + while true + do + read -p " 请输入伪装路径,以/开头(不懂请直接回车):" WSPATH + if [[ -z "${WSPATH}" ]]; then + len=`shuf -i5-12 -n1` + ws=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1` + WSPATH="/$ws" + break + elif [[ "${WSPATH:0:1}" != "/" ]]; then + echo " 伪装路径必须以/开头!" + elif [[ "${WSPATH}" = "/" ]]; then + echo " 不能使用根路径!" + else + break + fi + done + echo "" + colorEcho $BLUE " ws路径:$WSPATH" + fi + + echo "" + colorEcho $BLUE " 请选择伪装站类型:" + echo " 1) 静态网站(位于/usr/share/nginx/html)" + echo " 2) 小说站(随机选择)" + echo " 3) 美女站(https://imeizi.me)" + echo " 4) 高清壁纸站(https://bing.imeizi.me)" + echo " 5) 自定义反代站点(需以http或者https开头)" + read -p " 请选择伪装网站类型[默认:高清壁纸站]" answer + if [[ -z "$answer" ]]; then + PROXY_URL="https://bing.imeizi.me" + else + case $answer in + 1) + PROXY_URL="" + ;; + 2) + len=${#SITES[@]} + ((len--)) + while true + do + index=`shuf -i0-${len} -n1` + PROXY_URL=${SITES[$index]} + host=`echo ${PROXY_URL} | cut -d/ -f3` + ip=`curl -sL https://hijk.art/hostip.php?d=${host}` + res=`echo -n ${ip} | grep ${host}` + if [[ "${res}" = "" ]]; then + echo "$ip $host" >> /etc/hosts + break + fi + done + ;; + 3) + PROXY_URL="https://imeizi.me" + ;; + 4) + PROXY_URL="https://bing.imeizi.me" + ;; + 5) + read -p " 请输入反代站点(以http或者https开头):" PROXY_URL + if [[ -z "$PROXY_URL" ]]; then + colorEcho $RED " 请输入反代网站!" + exit 1 + elif [[ "${PROXY_URL:0:4}" != "http" ]]; then + colorEcho $RED " 反代网站必须以http或https开头!" + exit 1 + fi + ;; + *) + colorEcho $RED " 请输入正确的选项!" + exit 1 + esac + fi + REMOTE_HOST=`echo ${PROXY_URL} | cut -d/ -f3` + echo "" + colorEcho $BLUE " 伪装网站:$PROXY_URL" + + echo "" + colorEcho $BLUE " 是否允许搜索引擎爬取网站?[默认:不允许]" + echo " y)允许,会有更多ip请求网站,但会消耗一些流量,vps流量充足情况下推荐使用" + echo " n)不允许,爬虫不会访问网站,访问ip比较单一,但能节省vps流量" + read -p " 请选择:[y/n]" answer + if [[ -z "$answer" ]]; then + ALLOW_SPIDER="n" + elif [[ "${answer,,}" = "y" ]]; then + ALLOW_SPIDER="y" + else + ALLOW_SPIDER="n" + fi + echo "" + colorEcho $BLUE " 允许搜索引擎:$ALLOW_SPIDER" + + echo "" + read -p " 是否安装BBR(默认安装)?[y/n]:" NEED_BBR + [[ -z "$NEED_BBR" ]] && NEED_BBR=y + [[ "$NEED_BBR" = "Y" ]] && NEED_BBR=y + colorEcho $BLUE " 安装BBR:$NEED_BBR" +} + +installNginx() { + echo "" + colorEcho $BLUE " 安装nginx..." + if [[ "$BT" = "false" ]]; then + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ "$?" != "0" ]]; then + echo '[nginx-stable] +name=nginx stable repo +baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ +gpgcheck=1 +enabled=1 +gpgkey=https://nginx.org/keys/nginx_signing.key +module_hotfixes=true' > /etc/yum.repos.d/nginx.repo + fi + fi + $CMD_INSTALL nginx + if [[ "$?" != "0" ]]; then + colorEcho $RED " Nginx安装失败,请到 https://hijk.art 反馈" + exit 1 + fi + systemctl enable nginx + else + res=`which nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 您安装了宝塔,请在宝塔后台安装nginx后再运行本脚本" + exit 1 + fi + fi +} + +startNginx() { + if [[ "$BT" = "false" ]]; then + systemctl start nginx + else + nginx -c /www/server/nginx/conf/nginx.conf + fi +} + +stopNginx() { + if [[ "$BT" = "false" ]]; then + systemctl stop nginx + else + res=`ps aux | grep -i nginx` + if [[ "$res" != "" ]]; then + nginx -s stop + fi + fi +} + +getCert() { + mkdir -p /etc/trojan-go + if [[ -z ${CERT_FILE+x} ]]; then + stopNginx + systemctl stop trojan-go + sleep 2 + res=`ss -ntlp| grep -E ':80 |:443 '` + if [[ "${res}" != "" ]]; then + echo -e "${RED} 其他进程占用了80或443端口,请先关闭再运行一键脚本${PLAIN}" + echo " 端口占用信息如下:" + echo ${res} + exit 1 + fi + + $CMD_INSTALL socat openssl + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL cronie + systemctl start crond + systemctl enable crond + else + $CMD_INSTALL cron + systemctl start cron + systemctl enable cron + fi + curl -sL https://get.acme.sh | sh -s email=hijk.pw@protonmail.ch + source ~/.bashrc + ~/.acme.sh/acme.sh --upgrade --auto-upgrade + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt + if [[ "$BT" = "false" ]]; then + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "systemctl stop nginx" --post-hook "systemctl restart nginx" --standalone + else + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "nginx -s stop || { echo -n ''; }" --post-hook "nginx -c /www/server/nginx/conf/nginx.conf || { echo -n ''; }" --standalone + fi + [[ -f ~/.acme.sh/${DOMAIN}_ecc/ca.cer ]] || { + colorEcho $RED " 获取证书失败,请复制上面的红色文字到 https://hijk.art 反馈" + exit 1 + } + CERT_FILE="/etc/trojan-go/${DOMAIN}.pem" + KEY_FILE="/etc/trojan-go/${DOMAIN}.key" + ~/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \ + --key-file $KEY_FILE \ + --fullchain-file $CERT_FILE \ + --reloadcmd "service nginx force-reload" + [[ -f $CERT_FILE && -f $KEY_FILE ]] || { + colorEcho $RED " 获取证书失败,请到 https://hijk.art 反馈" + exit 1 + } + else + cp ~/trojan-go.pem /etc/trojan-go/${DOMAIN}.pem + cp ~/trojan-go.key /etc/trojan-go/${DOMAIN}.key + fi +} + +configNginx() { + mkdir -p /usr/share/nginx/html + if [[ "$ALLOW_SPIDER" = "n" ]]; then + echo 'User-Agent: *' > /usr/share/nginx/html/robots.txt + echo 'Disallow: /' >> /usr/share/nginx/html/robots.txt + ROBOT_CONFIG=" location = /robots.txt {}" + else + ROBOT_CONFIG="" + fi + if [[ "$BT" = "false" ]]; then + if [[ ! -f /etc/nginx/nginx.conf.bak ]]; then + mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak + fi + res=`id nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + user="www-data" + else + user="nginx" + fi + cat > /etc/nginx/nginx.conf<<-EOF +user $user; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' + '\$status \$body_bytes_sent "\$http_referer" ' + '"\$http_user_agent" "\$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + server_tokens off; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + gzip on; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; +} +EOF + fi + + mkdir -p $NGINX_CONF_PATH + if [[ "$PROXY_URL" = "" ]]; then + cat > $NGINX_CONF_PATH${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + root /usr/share/nginx/html; + + $ROBOT_CONFIG +} +EOF + else + cat > $NGINX_CONF_PATH${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + root /usr/share/nginx/html; + location / { + proxy_ssl_server_name on; + proxy_pass $PROXY_URL; + proxy_set_header Accept-Encoding ''; + sub_filter "$REMOTE_HOST" "$DOMAIN"; + sub_filter_once off; + } + + $ROBOT_CONFIG +} +EOF + fi +} + +downloadFile() { + SUFFIX=`archAffix` + DOWNLOAD_URL="${V6_PROXY}https://github.com/p4gefau1t/trojan-go/releases/download/${VERSION}/trojan-go-linux-${SUFFIX}.zip" + wget -O /tmp/${ZIP_FILE}.zip $DOWNLOAD_URL + if [[ ! -f /tmp/${ZIP_FILE}.zip ]]; then + echo -e "{$RED} trojan-go安装文件下载失败,请检查网络或重试${PLAIN}" + exit 1 + fi +} + +installTrojan() { + rm -rf /tmp/${ZIP_FILE} + unzip /tmp/${ZIP_FILE}.zip -d /tmp/${ZIP_FILE} + cp /tmp/${ZIP_FILE}/trojan-go /usr/bin + cp /tmp/${ZIP_FILE}/example/trojan-go.service /etc/systemd/system/ + sed -i '/User=nobody/d' /etc/systemd/system/trojan-go.service + systemctl daemon-reload + + systemctl enable trojan-go + rm -rf /tmp/${ZIP_FILE} + + colorEcho $BLUE " trojan-go安装成功!" +} + +configTrojan() { + mkdir -p /etc/trojan-go + cat > $CONFIG_FILE <<-EOF +{ + "run_type": "server", + "local_addr": "::", + "local_port": ${PORT}, + "remote_addr": "127.0.0.1", + "remote_port": 80, + "password": [ + "$PASSWORD" + ], + "ssl": { + "cert": "${CERT_FILE}", + "key": "${KEY_FILE}", + "sni": "${DOMAIN}", + "alpn": [ + "http/1.1" + ], + "session_ticket": true, + "reuse_session": true, + "fallback_addr": "127.0.0.1", + "fallback_port": 80 + }, + "tcp": { + "no_delay": true, + "keep_alive": true, + "prefer_ipv4": false + }, + "mux": { + "enabled": false, + "concurrency": 8, + "idle_timeout": 60 + }, + "websocket": { + "enabled": ${WS}, + "path": "${WSPATH}", + "host": "${DOMAIN}" + }, + "mysql": { + "enabled": false, + "server_addr": "localhost", + "server_port": 3306, + "database": "", + "username": "", + "password": "", + "check_rate": 60 + } +} +EOF +} + +setSelinux() { + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +setFirewall() { + res=`which firewall-cmd 2>/dev/null` + if [[ $? -eq 0 ]]; then + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-service=http + firewall-cmd --permanent --add-service=https + if [[ "$PORT" != "443" ]]; then + firewall-cmd --permanent --add-port=${PORT}/tcp + fi + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + fi + fi + fi + else + res=`which iptables 2>/dev/null` + if [[ $? -eq 0 ]]; then + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + fi + fi + else + res=`which ufw 2>/dev/null` + if [[ $? -eq 0 ]]; then + res=`ufw status | grep -i inactive` + if [[ "$res" = "" ]]; then + ufw allow http/tcp + ufw allow https/tcp + if [[ "$PORT" != "443" ]]; then + ufw allow ${PORT}/tcp + fi + fi + fi + fi + fi +} + +installBBR() { + if [[ "$NEED_BBR" != "y" ]]; then + INSTALL_BBR=false + return + fi + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + echo " BBR模块已安装" + INSTALL_BBR=false + return + fi + res=`hostnamectl | grep -i openvz` + if [[ "$res" != "" ]]; then + echo " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + echo " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$PMT" = "yum" ]]; then + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + $CMD_INSTALL --enablerepo=elrepo-kernel kernel-ml + $CMD_REMOVE kernel-3.* + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi + else + $CMD_INSTALL --install-recommends linux-generic-hwe-16.04 + grub-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi +} + +install() { + getData + + $PMT clean all + [[ "$PMT" = "apt" ]] && $PMT update + #echo $CMD_UPGRADE | bash + $CMD_INSTALL wget vim unzip tar gcc openssl + $CMD_INSTALL net-tools + if [[ "$PMT" = "apt" ]]; then + $CMD_INSTALL libssl-dev g++ + fi + res=`which unzip 2>/dev/null` + if [[ $? -ne 0 ]]; then + echo -e " ${RED}unzip安装失败,请检查网络${PLAIN}" + exit 1 + fi + + installNginx + setFirewall + getCert + configNginx + + echo " 安装trojan-go..." + getVersion + downloadFile + installTrojan + configTrojan + + setSelinux + installBBR + + start + showInfo + + bbrReboot +} + +bbrReboot() { + if [[ "${INSTALL_BBR}" == "true" ]]; then + echo + echo " 为使BBR模块生效,系统将在30秒后重启" + echo + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" + sleep 30 + reboot + fi +} + +update() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + echo " 安装最新版trojan-go" + getVersion + downloadFile + installTrojan + + stop + start +} + +uninstall() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + echo "" + read -p " 确定卸载trojan-go?[y/n]:" answer + if [[ "${answer,,}" = "y" ]]; then + domain=`grep sni $CONFIG_FILE | cut -d\" -f4` + + stop + rm -rf /etc/trojan-go + rm -rf /usr/bin/trojan-go + systemctl disable trojan-go + rm -rf /etc/systemd/system/trojan-go.service + + if [[ "$BT" = "false" ]]; then + systemctl disable nginx + $CMD_REMOVE nginx + if [[ "$PMT" = "apt" ]]; then + $CMD_REMOVE nginx-common + fi + rm -rf /etc/nginx/nginx.conf + if [[ -f /etc/nginx/nginx.conf.bak ]]; then + mv /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf + fi + fi + + rm -rf $NGINX_CONF_PATH${domain}.conf + ~/.acme.sh/acme.sh --uninstall + echo -e " ${GREEN}trojan-go卸载成功${PLAIN}" + fi +} + +start() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e "${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + stopNginx + startNginx + systemctl restart trojan-go + sleep 2 + port=`grep local_port $CONFIG_FILE|cut -d: -f2| tr -d \",' '` + res=`ss -ntlp| grep ${port} | grep trojan-go` + if [[ "$res" = "" ]]; then + colorEcho $RED " trojan-go启动失败,请检查端口是否被占用!" + else + colorEcho $BLUE " trojan-go启动成功" + fi +} + +stop() { + stopNginx + systemctl stop trojan-go + colorEcho $BLUE " trojan-go停止成功" +} + + +restart() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + stop + start +} + +reconfig() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + line1=`grep -n 'websocket' $CONFIG_FILE | head -n1 | cut -d: -f1` + line11=`expr $line1 + 1` + WS=`sed -n "${line11}p" $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + getData true + configTrojan + setFirewall + getCert + configNginx + stop + start + showInfo + + bbrReboot +} + + +showInfo() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + domain=`grep sni $CONFIG_FILE | cut -d\" -f4` + port=`grep local_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + line1=`grep -n 'password' $CONFIG_FILE | head -n1 | cut -d: -f1` + line11=`expr $line1 + 1` + password=`sed -n "${line11}p" $CONFIG_FILE | tr -d \"' '` + line1=`grep -n 'websocket' $CONFIG_FILE | head -n1 | cut -d: -f1` + line11=`expr $line1 + 1` + ws=`sed -n "${line11}p" $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + echo "" + echo -n " trojan-go运行状态:" + statusText + echo "" + echo -e " ${BLUE}trojan-go配置文件: ${PLAIN} ${RED}${CONFIG_FILE}${PLAIN}" + echo -e " ${BLUE}trojan-go配置信息:${PLAIN}" + echo -e " IP:${RED}$IP${PLAIN}" + echo -e " 伪装域名/主机名(host)/SNI/peer名称:${RED}$domain${PLAIN}" + echo -e " 端口(port):${RED}$port${PLAIN}" + echo -e " 密码(password):${RED}$password${PLAIN}" + if [[ $ws = "true" ]]; then + echo -e " websocket:${RED}true${PLAIN}" + wspath=`grep path $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + echo -e " ws路径(ws path):${RED}${wspath}${PLAIN}" + fi + echo "" +} + +showLog() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e "${RED}trojan-go未安装,请先安装!${PLAIN}" + return + fi + + journalctl -xen -u trojan-go --no-pager +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}trojan-go一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" + + echo -e " ${GREEN}1.${PLAIN} 安装trojan-go" + echo -e " ${GREEN}2.${PLAIN} 安装trojan-go+WS" + echo -e " ${GREEN}3.${PLAIN} 更新trojan-go" + echo -e " ${GREEN}4. ${RED}卸载trojan-go${PLAIN}" + echo " -------------" + echo -e " ${GREEN}5.${PLAIN} 启动trojan-go" + echo -e " ${GREEN}6.${PLAIN} 重启trojan-go" + echo -e " ${GREEN}7.${PLAIN} 停止trojan-go" + echo " -------------" + echo -e " ${GREEN}8.${PLAIN} 查看trojan-go配置" + echo -e " ${GREEN}9. ${RED}修改trojan-go配置${PLAIN}" + echo -e " ${GREEN}10.${PLAIN} 查看trojan-go日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-10]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + WS="true" + install + ;; + 3) + update + ;; + 4) + uninstall + ;; + 5) + start + ;; + 6) + restart + ;; + 7) + stop + ;; + 8) + showInfo + ;; + 9) + reconfig + ;; + 10) + showLog + ;; + *) + echo -e "$RED 请选择正确的操作!${PLAIN}" + exit 1 + ;; + esac +} + +checkSystem + +action=$1 +[[ -z $1 ]] && action=menu +case "$action" in + menu|update|uninstall|start|restart|stop|showInfo|showLog) + ${action} + ;; + *) + echo " 参数错误" + echo " 用法: `basename $0` [menu|update|uninstall|start|restart|stop|showInfo|showLog]" + ;; +esac diff --git a/trojan.sh b/trojan.sh new file mode 100644 index 00000000..d12739d9 --- /dev/null +++ b/trojan.sh @@ -0,0 +1,944 @@ +#!/bin/bash +# trojan一键安装脚本 +# Author: hijk + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" +res=`which bt 2>/dev/null` +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +# 以下网站是随机从Google上找到的无广告小说网站,不喜欢请改成其他网址,以http或https开头 +# 搭建好后无法打开伪装域名,可能是反代小说网站挂了,请在网站留言,或者Github发issue,以便替换新的网站 +SITES=( +http://www.zhuizishu.com/ +http://xs.56dyc.com/ +#http://www.xiaoshuosk.com/ +#https://www.quledu.net/ +http://www.ddxsku.com/ +http://www.biqu6.com/ +https://www.wenshulou.cc/ +#http://www.auutea.com/ +http://www.55shuba.com/ +http://www.39shubao.com/ +https://www.23xsw.cc/ +#https://www.huanbige.com/ +https://www.jueshitangmen.info/ +https://www.zhetian.org/ +http://www.bequgexs.com/ +http://www.tjwl.com/ +) + +CONFIG_FILE=/usr/local/etc/trojan/config.json + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +function checkSystem() +{ + result=$(id | awk '{print $1}') + if [ $result != "uid=0(root)" ]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=`which yum 2>/dev/null` + if [ "$?" != "0" ]; then + res=`which apt 2>/dev/null` + if [ "$?" != "0" ]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT=apt + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + else + PMT=yum + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + fi + res=`which systemctl 2>/dev/null` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +status() { + if [[ ! -f /usr/local/bin/trojan ]]; then + echo 0 + return + fi + + if [[ ! -f $CONFIG_FILE ]]; then + echo 1 + return + fi + port=`grep local_port $CONFIG_FILE|cut -d: -f2| tr -d \",' '` + res=`ss -ntlp| grep ${port} | grep trojan` + if [[ -z "$res" ]]; then + echo 2 + else + echo 3 + fi +} + +statusText() { + res=`status` + case $res in + 2) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 3) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +function getData() +{ + echo " " + echo " 本脚本为trojan一键脚本,运行之前请确认如下条件已经具备:" + echo -e " ${RED}1. 一个伪装域名${PLAIN}" + echo -e " ${RED}2. 伪装域名DNS解析指向当前服务器ip(${IP})${PLAIN}" + echo -e " 3. 如果/root目录下有 ${GREEN}trojan.pem${PLAIN} 和 ${GREEN}trojan.key${PLAIN} 证书密钥文件,无需理会条件2" + echo " " + read -p " 确认满足按y,按其他退出脚本:" answer + if [ "${answer}" != "y" ] && [ "${answer}" != "Y" ]; then + exit 0 + fi + + echo "" + while true + do + read -p " 请输入伪装域名:" DOMAIN + if [ -z "${DOMAIN}" ]; then + echo " 域名输入错误,请重新输入!" + else + break + fi + done + DOMAIN=${DOMAIN,,} + colorEcho $BLUE " 伪装域名(host): $DOMAIN" + + echo "" + if [[ -f ~/trojan.pem && -f ~/trojan.key ]]; then + echo -e "${GREEN} 检测到自有证书,将使用其部署${PLAIN}" + echo + CERT_FILE="/usr/local/etc/trojan/${DOMAIN}.pem" + KEY_FILE="/usr/local/etc/trojan/${DOMAIN}.key" + else + resolve=`curl -sL https://hijk.art/hostip.php?d=${DOMAIN}` + res=`echo -n ${resolve} | grep ${IP}` + if [[ -z "${res}" ]]; then + echo " ${DOMAIN} 解析结果:${resolve}" + echo -e " ${RED}域名未解析到当前服务器IP(${IP})!${PLAIN}" + exit 1 + fi + fi + + echo "" + read -p " 请设置trojan密码(不输入则随机生成):" PASSWORD + [ -z "$PASSWORD" ] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + colorEcho $BLUE " 密码: " $PASSWORD + + echo "" + read -p " 请输入trojan端口[100-65535的一个数字,默认443]:" PORT + [ -z "${PORT}" ] && PORT=443 + if [ "${PORT:0:1}" = "0" ]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + colorEcho $BLUE " trojan端口: " $PORT + + echo "" + colorEcho $BLUE " 请选择伪装站类型:" + echo " 1) 静态网站(位于/usr/share/nginx/html)" + echo " 2) 小说站(随机选择)" + echo " 3) 美女站(https://imeizi.me)" + echo " 4) 高清壁纸站(https://bing.imeizi.me)" + echo " 5) 自定义反代站点(需以http或者https开头)" + read -p " 请选择伪装网站类型[默认:高清壁纸站]" answer + if [[ -z "$answer" ]]; then + PROXY_URL="https://bing.imeizi.me" + else + case $answer in + 1) + PROXY_URL="" + ;; + 2) + len=${#SITES[@]} + ((len--)) + index=`shuf -i0-${len} -n1` + PROXY_URL=${SITES[$index]} + ;; + 3) + PROXY_URL="https://imeizi.me" + ;; + 4) + PROXY_URL="https://bing.imeizi.me" + ;; + 5) + read -p " 请输入反代站点(以http或者https开头):" PROXY_URL + if [[ -z "$PROXY_URL" ]]; then + colorEcho $RED " 请输入反代网站!" + exit 1 + elif [[ "${PROXY_URL:0:4}" != "http" ]]; then + colorEcho $RED " 反代网站必须以http或https开头!" + exit 1 + fi + ;; + *) + colorEcho $RED " 请输入正确的选项!" + exit 1 + esac + fi + REMOTE_HOST=`echo ${PROXY_URL} | cut -d/ -f3` + echo "" + colorEcho $BLUE " 伪装域名:$PROXY_URL" + + echo "" + colorEcho $BLUE " 是否允许搜索引擎爬取网站?[默认:不允许]" + echo " y)允许,会有更多ip请求网站,但会消耗一些流量,vps流量充足情况下推荐使用" + echo " n)不允许,爬虫不会访问网站,访问ip比较单一,但能节省vps流量" + read -p " 请选择:[y/n]" answer + if [[ -z "$answer" ]]; then + ALLOW_SPIDER="n" + elif [[ "${answer,,}" = "y" ]]; then + ALLOW_SPIDER="y" + else + ALLOW_SPIDER="n" + fi + echo "" + colorEcho $BLUE " 允许搜索引擎:$ALLOW_SPIDER" + + echo "" + read -p " 是否安装BBR(默认安装)?[y/n]:" NEED_BBR + [ -z "$NEED_BBR" ] && NEED_BBR=y + [ "$NEED_BBR" = "Y" ] && NEED_BBR=y + colorEcho $BLUE " 安装BBR:$NEED_BBR" +} + +function preinstall() +{ + $PMT clean all + [[ "$PMT" = "apt" ]] && $PMT update + #colorEcho $BLUE " 更新系统..." + #echo $CMD_UPGRADE | bash + + colorEcho $BLUE " 安装必要软件" + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + fi + $CMD_INSTALL wget vim unzip tar gcc openssl + $CMD_INSTALL net-tools + if [[ "$PMT" = "apt" ]]; then + $CMD_INSTALL libssl-dev g++ + fi + + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +function installTrojan() +{ + colorEcho $BLUE " 安装最新版trojan..." + rm -rf $CONFIG_FILE + rm -rf /etc/systemd/system/trojan.service + + NAME=trojan + VERSION=`curl -fsSL ${V6_PROXY}https://api.github.com/repos/trojan-gfw/trojan/releases/latest | grep tag_name | sed -E 's/.*"v(.*)".*/\1/'` + TARBALL="$NAME-$VERSION-linux-amd64.tar.xz" + DOWNLOADURL="${V6_PROXY}https://github.com/trojan-gfw/$NAME/releases/download/v$VERSION/$TARBALL" + TMPDIR="$(mktemp -d)" + INSTALLPREFIX=/usr/local + SYSTEMDPREFIX=/etc/systemd/system + + BINARYPATH="$INSTALLPREFIX/bin/$NAME" + CONFIGPATH="$INSTALLPREFIX/etc/$NAME/config.json" + SYSTEMDPATH="$SYSTEMDPREFIX/$NAME.service" + + echo Entering temp directory $TMPDIR... + cd "$TMPDIR" + + echo Downloading $NAME $VERSION... + curl -LO --progress-bar "$DOWNLOADURL" || wget -q --show-progress "$DOWNLOADURL" + + echo Unpacking $NAME $VERSION... + tar xf "$TARBALL" + cd "$NAME" + + echo Installing $NAME $VERSION to $BINARYPATH... + cp "$NAME" "$BINARYPATH" + chmod 755 "$BINARYPATH" + + mkdir -p $INSTALLPREFIX/etc/$NAME + + echo Installing $NAME systemd service to $SYSTEMDPATH... + cat > "$SYSTEMDPATH" << EOF +[Unit] +Description=$NAME +Documentation=https://trojan-gfw.github.io/$NAME/config https://trojan-gfw.github.io/$NAME/ +After=network.target network-online.target nss-lookup.target mysql.service mariadb.service mysqld.service + +[Service] +Type=simple +StandardError=journal +ExecStart="$BINARYPATH" "$CONFIGPATH" +ExecReload=/bin/kill -HUP \$MAINPID +LimitNOFILE=51200 +Restart=on-failure +RestartSec=1s + +[Install] +WantedBy=multi-user.target +EOF + + echo Reloading systemd daemon... + systemctl daemon-reload + + echo Deleting temp directory $TMPDIR... + rm -rf "$TMPDIR" + + echo Done! + + if [[ ! -f "$BINARYPATH" ]]; then + colorEcho $RED " $OS 安装trojan失败,请到 https://hijk.art 反馈" + exit 1 + fi + + systemctl enable trojan + colorEcho $GREEN " trojan安装成功!" +} + +configTrojan() { + ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime + + cat >$CONFIG_FILE<<-EOF +{ + "run_type": "server", + "local_addr": "::", + "local_port": ${PORT}, + "remote_addr": "127.0.0.1", + "remote_port": 80, + "password": [ + "$PASSWORD" + ], + "log_level": 1, + "ssl": { + "cert": "$CERT_FILE", + "key": "$KEY_FILE", + "key_password": "", + "sni": "$DOMAIN", + "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384", + "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384", + "prefer_server_cipher": true, + "alpn": [ + "http/1.1", "h2" + ], + "alpn_port_override": { + "h2": 81 + }, + "reuse_session": true, + "session_ticket": false, + "session_timeout": 600, + "plain_http_response": "", + "curves": "", + "dhparam": "" + }, + "tcp": { + "prefer_ipv4": false, + "no_delay": true, + "keep_alive": true, + "reuse_port": false, + "fast_open": false, + "fast_open_qlen": 20 + }, + "mysql": { + "enabled": false, + "server_addr": "127.0.0.1", + "server_port": 3306, + "database": "trojan", + "username": "trojan", + "password": "", + "key": "", + "cert": "", + "ca": "" + } +} +EOF +} + +getCert() { + mkdir -p /usr/local/etc/trojan + if [[ -z ${CERT_FILE+x} ]]; then + stopNginx + res=`netstat -ntlp| grep -E ':80 |:443 '` + if [[ "${res}" != "" ]]; then + colorEcho $RED " 其他进程占用了80或443端口,请先关闭再运行一键脚本" + echo " 端口占用信息如下:" + echo ${res} + exit 1 + fi + + $CMD_INSTALL socat openssl + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL cronie + systemctl start crond + systemctl enable crond + else + $CMD_INSTALL cron + systemctl start cron + systemctl enable cron + fi + curl -sL https://get.acme.sh | sh -s email=hijk.pw@protonmail.ch + source ~/.bashrc + ~/.acme.sh/acme.sh --upgrade --auto-upgrade + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt + if [[ "$BT" = "false" ]]; then + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "systemctl stop nginx" --post-hook "systemctl restart nginx" --standalone + else + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "nginx -s stop || { echo -n ''; }" --post-hook "nginx -c /www/server/nginx/conf/nginx.conf || { echo -n ''; }" --standalone + fi + [[ -f ~/.acme.sh/${DOMAIN}_ecc/ca.cer ]] || { + colorEcho $RED " 获取证书失败,请复制上面的红色文字到 https://hijk.art 反馈" + exit 1 + } + CERT_FILE="/usr/local/etc/trojan/${DOMAIN}.pem" + KEY_FILE="/usr/local/etc/trojan/${DOMAIN}.key" + ~/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \ + --key-file $KEY_FILE \ + --fullchain-file $CERT_FILE \ + --reloadcmd "service nginx force-reload" + [[ -f $CERT_FILE && -f $KEY_FILE ]] || { + colorEcho $RED " 获取证书失败,请到 https://hijk.art 反馈" + exit 1 + } + else + cp ~/trojan.pem /usr/local/etc/trojan/${DOMAIN}.pem + cp ~/trojan.key /usr/local/etc/trojan/${DOMAIN}.key + fi +} + +function installNginx() +{ + colorEcho $BLUE " 安装nginx..." + if [[ "$BT" = "false" ]]; then + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ "$?" != "0" ]]; then + echo '[nginx-stable] +name=nginx stable repo +baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ +gpgcheck=1 +enabled=1 +gpgkey=https://nginx.org/keys/nginx_signing.key +module_hotfixes=true' > /etc/yum.repos.d/nginx.repo + fi + fi + $CMD_INSTALL nginx + if [[ "$?" != "0" ]]; then + colorEcho $RED " Nginx安装失败,请到 https://hijk.art 反馈" + exit 1 + fi + systemctl enable nginx + else + res=`which nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 您安装了宝塔,请在宝塔后台安装nginx后再运行本脚本" + exit 1 + fi + fi +} + +configNginx() { + mkdir -p /usr/share/nginx/html + if [[ "$ALLOW_SPIDER" = "n" ]]; then + echo 'User-Agent: *' > /usr/share/nginx/html/robots.txt + echo 'Disallow: /' >> /usr/share/nginx/html/robots.txt + ROBOT_CONFIG=" location = /robots.txt {}" + else + ROBOT_CONFIG="" + fi + + if [[ "$BT" = "false" ]]; then + if [ ! -f /etc/nginx/nginx.conf.bak ]; then + mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak + fi + res=`id nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + user="www-data" + else + user="nginx" + fi + cat > /etc/nginx/nginx.conf<<-EOF +user $user; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' + '\$status \$body_bytes_sent "\$http_referer" ' + '"\$http_user_agent" "\$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + gzip on; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; +} +EOF + fi + + mkdir -p $NGINX_CONF_PATH + if [[ "$PROXY_URL" = "" ]]; then + cat > $NGINX_CONF_PATH${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + listen 81 http2; + server_name ${DOMAIN}; + root /usr/share/nginx/html; + + $ROBOT_CONFIG +} +EOF + else + cat > $NGINX_CONF_PATH${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + listen 81 http2; + server_name ${DOMAIN}; + root /usr/share/nginx/html; + location / { + proxy_ssl_server_name on; + proxy_pass $PROXY_URL; + proxy_set_header Accept-Encoding ''; + sub_filter "$REMOTE_HOST" "$DOMAIN"; + sub_filter_once off; + } + + $ROBOT_CONFIG +} +EOF + fi +} + +startNginx() { + if [[ "$BT" = "false" ]]; then + systemctl start nginx + else + nginx -c /www/server/nginx/conf/nginx.conf + fi +} + +stopNginx() { + if [[ "$BT" = "false" ]]; then + systemctl stop nginx + else + res=`ps aux | grep -i nginx` + if [[ "$res" != "" ]]; then + nginx -s stop + fi + fi +} + +function setFirewall() +{ + res=`which firewall-cmd 2>/dev/null` + if [[ $? -eq 0 ]]; then + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-service=http + firewall-cmd --permanent --add-service=https + if [[ "$PORT" != "443" ]]; then + firewall-cmd --permanent --add-port=${PORT}/tcp + fi + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + fi + fi + fi + else + res=`which iptables 2>/dev/null` + if [[ $? -eq 0 ]]; then + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + fi + fi + else + res=`which ufw 2>/dev/null` + if [[ $? -eq 0 ]]; then + res=`ufw status | grep -i inactive` + if [[ "$res" = "" ]]; then + ufw allow http/tcp + ufw allow https/tcp + if [[ "$PORT" != "443" ]]; then + ufw allow ${PORT}/tcp + fi + fi + fi + fi + fi +} + +function installBBR() +{ + if [ "$NEED_BBR" != "y" ]; then + INSTALL_BBR=false + return + fi + + result=$(lsmod | grep bbr) + if [ "$result" != "" ]; then + colorEcho $YELLOW " BBR模块已安装" + INSTALL_BBR=false + return; + fi + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$PMT" = "yum" ]]; then + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + $CMD_INSTALL --enablerepo=elrepo-kernel kernel-ml + $CMD_REMOVE kernel-3.* + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi + else + $CMD_INSTALL --install-recommends linux-generic-hwe-16.04 + grub-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi +} + +function showInfo() +{ + res=`netstat -nltp | grep trojan` + [[ -z "$res" ]] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + + domain=`grep sni $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" = "" ]]; then + domain=`grep -m1 cert $CONFIG_FILE | cut -d/ -f5` + fi + port=`grep local_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + line1=`grep -n 'password' $CONFIG_FILE | head -n1 | cut -d: -f1` + line11=`expr $line1 + 1` + password=`sed -n "${line11}p" $CONFIG_FILE | tr -d \",' '` + + res=`netstat -nltp | grep ${port} | grep nginx` + [[ -z "$res" ]] && ngstatus="${RED}已停止${PLAIN}" || ngstatus="${GREEN}正在运行${PLAIN}" + + echo ============================================ + echo -e " ${BLUE}trojan运行状态:${PLAIN}${status}" + echo "" + echo -e " ${BLUE}trojan配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo -e " ${BLUE}trojan配置信息:${PLAIN} " + echo -e " ${BLUE}IP/address:${PLAIN} ${RED}$IP${PLAIN}" + echo -e " ${BLUE}域名/SNI/peer名称:${PLAIN} ${RED}${domain}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}$password${PLAIN}" + echo + echo ============================================ +} + +function bbrReboot() { + if [ "${INSTALL_BBR}" == "true" ]; then + echo "" + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" + echo + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" + sleep 30 + reboot + fi +} + + +function install() { + getData + preinstall + installBBR + setFirewall + installNginx + getCert + configNginx + installTrojan + configTrojan + + start + showInfo + bbrReboot +} + +reconfig() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan未安装,请先安装!${PLAIN}" + return + fi + + getData + setFirewall + getCert + configNginx + configTrojan + restart + showInfo +} + +update() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan未安装,请先安装!${PLAIN}" + return + fi + + installTrojan + + stop + start + colorEcho $BLUE " 成功更新到最新版trojan" +} + +start() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e "${RED}trojan未安装,请先安装!${PLAIN}" + return + fi + stopNginx + startNginx + systemctl restart trojan + sleep 2 + port=`grep local_port $CONFIG_FILE|cut -d: -f2| tr -d \",' '` + res=`ss -ntlp| grep ${port} | grep trojan` + if [[ "$res" = "" ]]; then + colorEcho $RED " trojan启动失败,请检查端口是否被占用!" + else + colorEcho $BLUE " trojan启动成功" + fi +} + +stop() { + stopNginx + systemctl stop trojan + colorEcho $BLUE " trojan停止成功" +} + + +restart() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e " ${RED}trojan未安装,请先安装!${PLAIN}" + return + fi + + stop + start +} + +showLog() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e "${RED}trojan未安装,请先安装!${PLAIN}" + return + fi + + journalctl -xen -u trojan --no-pager +} + +function uninstall() { + res=`status` + if [[ $res -lt 2 ]]; then + echo -e "${RED}trojan未安装,请先安装!${PLAIN}" + return + fi + + echo "" + read -p " 确定卸载trojan?(y/n)" answer + [[ -z ${answer} ]] && answer="n" + + if [[ "${answer}" == "y" ]] || [[ "${answer}" == "Y" ]]; then + domain=`grep sni $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" = "" ]]; then + domain=`grep -m1 cert $CONFIG_FILE | cut -d/ -f5` + fi + + systemctl stop trojan + systemctl disable trojan + rm -rf /usr/local/bin/trojan + rm -rf /usr/local/etc/trojan + rm -rf /etc/systemd/system/trojan.service + + if [[ "$BT" = "false" ]]; then + $CMD_REMOVE nginx + if [[ "$PMT" = "apt" ]]; then + $CMD_REMOVE nginx-common + fi + if [[ -d /usr/share/nginx/html.bak ]]; then + rm -rf /usr/share/nginx/html + mv /usr/share/nginx/html.bak /usr/share/nginx/html + fi + fi + rm -rf $NGINX_CONF_PATH${domain}.conf + ~/.acme.sh/acme.sh --uninstall + colorEcho $GREEN " trojan卸载成功" + fi +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}trojan一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" + + echo -e " ${GREEN}1.${PLAIN} 安装trojan" + echo -e " ${GREEN}2.${PLAIN} 更新trojan" + echo -e " ${GREEN}3. ${RED}卸载trojan${PLAIN}" + echo " -------------" + echo -e " ${GREEN}4.${PLAIN} 启动trojan" + echo -e " ${GREEN}5.${PLAIN} 重启trojan" + echo -e " ${GREEN}6.${PLAIN} 停止trojan" + echo " -------------" + echo -e " ${GREEN}7.${PLAIN} 查看trojan配置" + echo -e " ${GREEN}8. ${RED}修改trojan配置${PLAIN}" + echo -e " ${GREEN}9.${PLAIN} 查看trojan日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-10]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + update + ;; + 3) + uninstall + ;; + 4) + start + ;; + 5) + restart + ;; + 6) + stop + ;; + 7) + showInfo + ;; + 8) + reconfig + ;; + 9) + showLog + ;; + *) + echo -e "$RED 请选择正确的操作!${PLAIN}" + exit 1 + ;; + esac +} + +checkSystem + +action=$1 +[[ -z $1 ]] && action=menu +case "$action" in + menu|install|update|uninstall|start|restart|stop|showInfo|showLog) + ${action} + ;; + *) + echo " 参数错误" + echo " 用法: `basename $0` [menu|install|update|uninstall|start|restart|stop|showInfo|showLog]" + ;; +esac diff --git a/ubuntu_install_ss.sh b/ubuntu_install_ss.sh index ac3d7a41..f6324bca 100644 --- a/ubuntu_install_ss.sh +++ b/ubuntu_install_ss.sh @@ -1,189 +1,254 @@ #!/bin/bash # shadowsocks/ss Ubuntu一键安装脚本 -# Author: hijk - -echo "#############################################################" -echo "# Ubuntu TLS Shadowsocks/SS 一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" - -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' +# Author: hijk + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + BASE=`pwd` +OS=`hostnamectl | grep -i system | cut -d: -f2` -function checkSystem() -{ +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +CONFIG_FILE="/etc/shadowsocks-libev/config.json" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { result=$(id | awk '{print $1}') if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" + colorEcho $RED " 请以root身份执行该脚本" exit 1 fi res=`lsb_release -d | grep -i ubuntu` - if [ "${res}" = "" ];then - echo "系统不是Ubuntu" - exit 1 - fi - - result=`lsb_release -d | grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 16 ]; then - echo "不受支持的Ubuntu版本" - exit 1 - fi + if [ "$?" != "0" ]; then + res=`which apt` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统不是Ubuntu" + exit 1 + fi + else + result=`lsb_release -d | grep -oE "[0-9.]+"` + main=${result%%.*} + if [ $main -lt 16 ]; then + colorEcho $RED " 不受支持的Ubuntu版本" + exit 1 + fi + fi } -function getData() -{ - read -p "请设置SS的密码(不输入则随机生成):" password - [ -z "$password" ] && password=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}Ubuntu LTS Shadowsocks/SS 一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" echo "" - echo "密码: $password" +} + +getData() { + read -p " 请设置SS的密码(不输入则随机生成):" PASSWORD + [ -z "$PASSWORD" ] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + echo "" + colorEcho $BLUE " 密码: $PASSWORD" echo "" while true do - read -p "请设置SS的端口号[1025-65535]:" port - [ -z "$port" ] && port="12345" - expr $port + 0 &>/dev/null + read -p " 请设置SS的端口号[1025-65535]:" PORT + [ -z "$PORT" ] && PORT="12345" + if [ "${PORT:0:1}" = "0" ]; then + echo -e "${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null if [ $? -eq 0 ]; then - if [ $port -ge 1025 ] && [ $port -le 65535 ]; then - echo ""1234 - echo "端口号: $port" + if [ $PORT -ge 1025 ] && [ $PORT -le 65535 ]; then + echo "" + colorEcho $BLUE " 端口号: $PORT" echo "" break else - echo "输入错误,端口号为1025-65535的数字" + colorEcho $RED " 输入错误,端口号为1025-65535的数字" fi else - echo "输入错误,端口号为1025-65535的数字" + colorEcho $RED " 输入错误,端口号为1025-65535的数字" fi done - echo "请选择SS的加密方式:" - echo "1)aes-256-gcm" - echo "2)aes-192-gcm" - echo "3)aes-128-gcm" - echo "4)aes-256-ctr" - echo "5)aes-192-ctr" - echo "6)aes-128-ctr" - echo "7)aes-256-cfb" - echo "8)aes-192-cfb" - echo "9)aes-128-cfb" - echo "10)camellia-128-cfb" - echo "11)camellia-192-cfb" - echo "12)camellia-256-cfb" - echo "13)chacha20-ietf" - echo "14)chacha20-ietf-poly1305" - echo "15)xchacha20-ietf-poly1305" - read -p "请选择(默认aes-256-cfb)" answer + colorEcho $BLUE " 请选择SS的加密方式:" + echo " 1)aes-256-gcm" + echo " 2)aes-192-gcm" + echo " 3)aes-128-gcm" + echo " 4)aes-256-ctr" + echo " 5)aes-192-ctr" + echo " 6)aes-128-ctr" + echo " 7)aes-256-cfb" + echo " 8)aes-192-cfb" + echo " 9)aes-128-cfb" + echo " 10)camellia-128-cfb" + echo " 11)camellia-192-cfb" + echo " 12)camellia-256-cfb" + echo " 13)chacha20-ietf" + echo " 14)chacha20-ietf-poly1305" + echo " 15)xchacha20-ietf-poly1305" + read -p " 请选择加密方式(默认aes-256-gcm)" answer if [ -z "$answer" ]; then - method="aes-256-cfb" + METHOD="aes-256-gcm" else case $answer in 1) - method="aes-256-gcm" + METHOD="aes-256-gcm" ;; 2) - method="aes-192-gcm" + METHOD="aes-192-gcm" ;; 3) - method="aes-128-gcm" + METHOD="aes-128-gcm" ;; 4) - method="aes-256-ctr" + METHOD="aes-256-ctr" ;; 5) - method="aes-192-ctr" + METHOD="aes-192-ctr" ;; 6) - method="aes-128-ctr" + METHOD="aes-128-ctr" ;; 7) - method="aes-256-cfb" + METHOD="aes-256-cfb" ;; 8) - method="aes-192-cfb" + METHOD="aes-192-cfb" ;; 9) - method="aes-128-cfb" + METHOD="aes-128-cfb" ;; 10) - method="camellia-128-cfb" + METHOD="camellia-128-cfb" ;; 11) - method="camellia-192-cfb" + METHOD="camellia-192-cfb" ;; 12) - method="camellia-256-cfb" + METHOD="camellia-256-cfb" ;; 13) - method="chacha20-ietf" + METHOD="chacha20-ietf" ;; 14) - method="chacha20-ietf-poly1305" + METHOD="chacha20-ietf-poly1305" ;; 15) - method="xchacha20-ietf--poly1305" + METHOD="xchacha20-ietf-poly1305" ;; *) - echo "无效的选择,使用默认的aes-256-cfb" - method="aes-256-cfb" + colorEcho $RED " 无效的选择,使用默认的aes-256-gcm" + METHOD="aes-256-gcm" esac fi echo "" - echo "加密方式: $method" + colorEcho $BLUE " 加密方式: $METHOD" echo "" } -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - echo "更新系统..." - apt update && apt upgrade -y +preinstall() { + colorEcho $BLUE " 更新系统..." + apt clean all + apt update + #apt upgrade -y - echo "安装必要软件" - apt install -y telnet wget vim net-tools unzip - apt install -y make openssl libssl-dev gettext gcc autoconf libtool automake make asciidoc xmlto libudns-dev libev-dev libpcre3 libpcre3-dev libmbedtls10 libmbedtls-dev libsodium18 libsodium-dev libc-ares2 libc-ares-dev gcc g++ + colorEcho $BLUE " 安装必要软件" + apt install -y telnet wget vim net-tools unzip tar qrencode + apt install -y make openssl libssl-dev gettext gcc autoconf libtool automake make asciidoc xmlto libudns-dev libev-dev libpcre3 libpcre3-dev libmbedtls-dev libsodium-dev libc-ares2 libc-ares-dev g++ + apt install -y libsodium* apt autoremove -y + res=`which wget` + [ "$?" != "0" ] && apt install -y wget + res=`which netstat` + [ "$?" != "0" ] && apt install -y net-tools } -function installSS() -{ - echo 安装SS... +normalizeVersion() { + if [ -n "$1" ]; then + case "$1" in + v*) + echo "${1:1}" + ;; + *) + echo "$1" + ;; + esac + else + echo "" + fi +} - if ! wget 'https://github.com/shadowsocks/shadowsocks-libev/releases/download/v3.3.3/shadowsocks-libev-3.3.3.tar.gz' -O shadowsocks-libev-3.3.3.tar.gz; then - echo "下载文件失败!" +installNewVer() { + new_ver=$1 + if ! wget "${V6_PROXY}https://github.com/shadowsocks/shadowsocks-libev/releases/download/v${new_ver}/shadowsocks-libev-${new_ver}.tar.gz" -O shadowsocks-libev.tar.gz; then + colorEcho $RED " 下载安装文件失败!" exit 1 fi - tar zxf shadowsocks-libev-3.3.3.tar.gz - cd shadowsocks-libev-3.3.3 + tar zxf shadowsocks-libev.tar.gz + cd shadowsocks-libev-${new_ver} ./configure make && make install - if [ $? -ne 0 ]; then + if [[ $? -ne 0 ]]; then echo - echo -e "[${red}错误${plain}] Shadowsocks-libev 安装失败! 请打开 https://www.hijk.pw 反馈" - cd ${BASE} && rm -rf shadowsocks-libev-3.3.3* + echo -e " [${RED}错误${PLAIN}]: $OS Shadowsocks-libev 安装失败! 请打开 https://hijk.art 反馈" + cd ${BASE} && rm -rf shadowsocks-libev* exit 1 fi - cd ${BASE} && rm -rf shadowsocks-libev-3.3.3* + cd ${BASE} && rm -rf shadowsocks-libev* +} + +installSS() { + colorEcho $BLUE " 安装SS..." + + tag_url="${V6_PROXY}https://api.github.com/repos/shadowsocks/shadowsocks-libev/releases/latest" + new_ver="$(normalizeVersion "$(curl -s "${tag_url}" --connect-timeout 10| grep 'tag_name' | cut -d\" -f4)")" + export PATH=/usr/local/bin:$PATH + res=`which ss-server` + if [ "$?" != "0" ]; then + installNewVer $new_ver + else + ver=`ss-server -h | grep shadowsocks-libev | grep -oE '[0-9+\.]+'` + if [[ $ver != $new_ver ]]; then + installNewVer $new_ver + else + colorEcho $YELLOW " 已安装最新版SS" + fi + fi - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - if [ ! -d /etc/shadowsocks-libev ];then - mkdir /etc/shadowsocks-libev + interface="0.0.0.0" + if [[ "$V6_PROXY" != "" ]]; then + interface="::" fi - cat > /etc/shadowsocks-libev/config.json<<-EOF + mkdir -p /etc/shadowsocks-libev + ssPath=`which ss-server` + cat > $CONFIG_FILE<<-EOF { - "server":"0.0.0.0", - "server_port":${port}, + "server":"$interface", + "server_port":${PORT}, "local_port":1080, - "password":"${password}", + "password":"${PASSWORD}", "timeout":600, - "method":"${method}", + "method":"${METHOD}", "nameserver":"8.8.8.8", "mode":"tcp_and_udp", "fast_open":false @@ -192,7 +257,7 @@ EOF cat > /lib/systemd/system/shadowsocks-libev.service <<-EOF [Unit] Description=shadowsocks -Documentation=https://www.hijk.pw/ +Documentation=https://hijk.art/ After=network-online.target Wants=network-online.target @@ -200,9 +265,9 @@ Wants=network-online.target Type=simple PIDFile=/var/run/shadowsocks-libev.pid LimitNOFILE=32768 -ExecStart=/usr/local/bin/ss-server -c /etc/shadowsocks-libev/config.json -f /var/run/shadowsocks-libev.pid -ExecReload=/bin/kill -s HUP $MAINPID -ExecStop=/bin/kill -s TERM $MAINPID +ExecStart=/usr/local/bin/ss-server -c $CONFIG_FILE -f /var/run/shadowsocks-libev.pid +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID [Install] WantedBy=multi-user.target @@ -211,81 +276,90 @@ EOF systemctl enable shadowsocks-libev systemctl restart shadowsocks-libev sleep 3 - res=`netstat -nltp | grep ${port} | grep 'ss-server'` + res=`netstat -nltp | grep ${PORT} | grep 'ss-server'` if [ "${res}" = "" ]; then - echo "ss启动失败,请检查端口是否被占用!" + colorEcho $RED " ss启动失败,请检查端口是否被占用!" exit 1 fi } -function setFirewall() -{ +setFirewall() { res=`ufw status | grep -i inactive` if [ "$res" = "" ];then - ufw allow ${port}/tcp - ufw allow ${port}/udp + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp fi } -function installBBR() -{ +installBBR() { result=$(lsmod | grep bbr) if [ "$result" != "" ]; then - echo BBR模块已安装 - bbr=true - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf + colorEcho $BLUE " BBR模块已安装" + INSTALL_BBR=false return; fi - echo 安装BBR模块... + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." apt install -y --install-recommends linux-generic-hwe-16.04 grub-set-default 0 echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + INSTALL_BBR=true } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/shadowsocks-libev/config.json | grep server_port | cut -d: -f2 | tr -d \",' '` +info() { + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` res=`netstat -nltp | grep ${port} | grep 'ss-server'` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - password=`cat /etc/shadowsocks-libev/config.json | grep password | cut -d: -f2 | tr -d \",' '` - method=`cat /etc/shadowsocks-libev/config.json | grep method | cut -d: -f2 | tr -d \",' '` + [ -z "$res" ] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`echo -n ${method}:${password}@${IP}:${port} | base64 -w 0` + link="ss://${res}" + echo ============================================ - echo -e " ss运行状态:${status}" - echo -e " ss配置文件:${red}/etc/shadowsocks-libev/config.json${plain}" + echo -e " ${BLUE}ss运行状态:${PLAIN}${status}" + echo -e " ${BLUE}ss配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" echo "" - echo -e "${red}ss配置信息:${plain}" - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " 密码(password):${red}${password}${plain}" - echo -e " 加密方式(method): ${red}${method}${plain}" - echo - echo ============================================ + echo -e " ${RED}ss配置信息:${PLAIN}" + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}加密方式(method):${PLAIN} ${RED}${method}${PLAIN}" + echo + echo -e " ${BLUE}ss链接:${PLAIN} ${link}" + qrencode -o - -t utf8 ${link} } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [ "${INSTALL_BBR}" == "true" ]; then echo - echo 为使BBR模块生效,系统将在30秒后重启 + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ - echo -n "系统版本: " +install() { + echo -n " 系统版本: " lsb_release -a checkSystem @@ -298,9 +372,8 @@ function install() bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载SS吗?(y/n)" answer +uninstall() { + read -p " 确定卸载SS吗?(y/n)" answer [ -z ${answer} ] && answer="n" if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then @@ -311,10 +384,12 @@ function uninstall() rm -rf /usr/share/doc/shadowsocks-libev rm -rf /usr/share/man/man1/ss-*.1.gz rm -rf /usr/share/man/man8/shadowsocks-libev.8.gz - echo "SS卸载完成" + colorEcho $GREEN " SS卸载完成" fi } +slogon + action=$1 [ -z $1 ] && action=install case "$action" in @@ -322,7 +397,7 @@ case "$action" in ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall|info]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall|info]" ;; esac diff --git a/ubuntu_install_ssr.sh b/ubuntu_install_ssr.sh index dcaafab0..ca65831b 100644 --- a/ubuntu_install_ssr.sh +++ b/ubuntu_install_ssr.sh @@ -1,241 +1,273 @@ #!/bin/bash # shadowsocksR/SSR Ubuntu一键安装教程 -# Author: hijk +# Author: hijk -echo "#############################################################" -echo "# Ubuntu TLS ShadowsocksR/SSR 一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi FILENAME="ShadowsocksR-v3.2.2" -URL="https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz" +URL="${V6_PROXY}https://github.com/shadowsocksrr/shadowsocksr/archive/3.2.2.tar.gz" BASE=`pwd` +OS=`hostnamectl | grep -i system | cut -d: -f2` -function checkSystem() -{ +CONFIG_FILE="/etc/shadowsocksR.json" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { result=$(id | awk '{print $1}') if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" + colorEcho $RED " 请以root身份执行该脚本" exit 1 fi res=`lsb_release -d | grep -i ubuntu` - if [ "${res}" = "" ];then - echo "系统不是Ubuntu" - exit 1 - fi - - result=`lsb_release -d | grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 16 ]; then - echo "不受支持的Ubuntu版本" - exit 1 - fi + if [ "$?" != "0" ]; then + res=`which apt` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统不是Ubuntu" + exit 1 + fi + else + result=`lsb_release -d | grep -oE "[0-9.]+"` + main=${result%%.*} + if [ $main -lt 16 ]; then + colorEcho $RED " 不受支持的Ubuntu版本" + exit 1 + fi + fi } -function getData() -{ - read -p "请设置SSR的密码(不输入则随机生成):" password - [ -z "$password" ] && password=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}Ubuntu LTS ShadowsocksR/SSR 一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" echo "" - echo "密码: $password" +} + +getData() { + read -p " 请设置SSR的密码(不输入则随机生成):" PASSWORD + [ -z "$PASSWORD" ] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + echo "" + colorEcho $BLUE " 密码: $PASSWORD" echo "" while true do - read -p "请设置SSR的端口号[1-65535]:" port - [ -z "$port" ] && port="12345" - expr $port + 0 &>/dev/null + read -p " 请设置SSR的端口号[1-65535]:" PORT + [ -z "$PORT" ] && PORT="12345" + if [ "${PORT:0:1}" = "0" ]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null if [ $? -eq 0 ]; then - if [ $port -ge 1 ] && [ $port -le 65535 ]; then + if [ $PORT -ge 1 ] && [ $PORT -le 65535 ]; then echo "" - echo "端口号: $port" + colorEcho $BLUE " 端口号: $PORT" echo "" break else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED "输入错误,端口号为1-65535的数字" fi done - echo "请选择SSR的加密方式:" - echo "1)aes-256-cfb" - echo "2)aes-192-cfb" - echo "3)aes-128-cfb" - echo "4)aes-256-ctr" - echo "5)aes-192-ctr" - echo "6)aes-128-ctr" - echo "7)aes-256-cfb8" - echo "8)aes-192-cfb8" - echo "9)aes-128-cfb8" - echo "10)camellia-128-cfb" - echo "11)camellia-192-cfb" - echo "12)camellia-256-cfb" - echo "13)chacha20-ietf" - read -p "请选择加密方式(默认aes-256-cfb)" answer + colorEcho $BLUE " 请选择SSR的加密方式:" + echo " 1)aes-256-cfb" + echo " 2)aes-192-cfb" + echo " 3)aes-128-cfb" + echo " 4)aes-256-ctr" + echo " 5)aes-192-ctr" + echo " 6)aes-128-ctr" + echo " 7)aes-256-cfb8" + echo " 8)aes-192-cfb8" + echo " 9)aes-128-cfb8" + echo " 10)camellia-128-cfb" + echo " 11)camellia-192-cfb" + echo " 12)camellia-256-cfb" + echo " 13)chacha20-ietf" + read -p " 请选择加密方式(默认aes-256-cfb)" answer if [ -z "$answer" ]; then - method="aes-256-cfb" + METHOD="aes-256-cfb" else case $answer in 1) - method="aes-256-cfb" + METHOD="aes-256-cfb" ;; 2) - method="aes-192-cfb" + METHOD="aes-192-cfb" ;; 3) - method="aes-128-cfb" + METHOD="aes-128-cfb" ;; 4) - method="aes-256-ctr" + METHOD="aes-256-ctr" ;; 5) - method="aes-192-ctr" + METHOD="aes-192-ctr" ;; 6) - method="aes-128-ctr" + METHOD="aes-128-ctr" ;; 7) - method="aes-256-cfb8" + METHOD="aes-256-cfb8" ;; 8) - method="aes-192-cfb8" + METHOD="aes-192-cfb8" ;; 9) - method="aes-128-cfb8" + METHOD="aes-128-cfb8" ;; 10) - method="camellia-128-cfb" + METHOD="camellia-128-cfb" ;; 11) - method="camellia-192-cfb" + METHOD="camellia-192-cfb" ;; 12) - method="camellia-256-cfb" + METHOD="camellia-256-cfb" ;; 13) - method="chacha20-ietf" + METHOD="chacha20-ietf" ;; *) - echo "无效的选择,使用默认加密方式" - method="aes-256-cfb" + colorEcho $RED " 无效的选择,使用默认加密方式" + METHOD="aes-256-cfb" esac fi echo "" - echo "加密方式: $method" + colorEcho $BLUE " 加密方式: $METHOD" echo "" - echo "请选择SSR的协议:" - echo "1)origin" - echo "2)verify_deflate" - echo "3)auth_sha1_v4" - echo "4)auth_aes128_md5" - echo "5)auth_aes128_sha1" - echo "6)auth_chain_a" - echo "7)auth_chain_b" - echo "8)auth_chain_c" - echo "9)auth_chain_d" - echo "10)auth_chain_e" - echo "11)auth_chain_f" - read -p "请选择加密方式(默认origin)" answer + colorEcho $BLUE " 请选择SSR协议:" + echo " 1)origin" + echo " 2)verify_deflate" + echo " 3)auth_sha1_v4" + echo " 4)auth_aes128_md5" + echo " 5)auth_aes128_sha1" + echo " 6)auth_chain_a" + echo " 7)auth_chain_b" + echo " 8)auth_chain_c" + echo " 9)auth_chain_d" + echo " 10)auth_chain_e" + echo " 11)auth_chain_f" + read -p " 请选择协议(默认origin)" answer if [ -z "$answer" ]; then - protocol="origin" + PROTOCOL="origin" else case $answer in 1) - protocol="origin" + PROTOCOL="origin" ;; 2) - protocol="verify_deflate" + PROTOCOL="verify_deflate" ;; 3) - protocol="auth_sha1_v4" + PROTOCOL="auth_sha1_v4" ;; 4) - protocol="auth_aes128_md5" + PROTOCOL="auth_aes128_md5" ;; 5) - protocol="auth_aes128_sha1" + PROTOCOL="auth_aes128_sha1" ;; 6) - protocol="auth_chain_a" + PROTOCOL="auth_chain_a" ;; 7) - protocol="auth_chain_b" + PROTOCOL="auth_chain_b" ;; 8) - protocol="auth_chain_c" + PROTOCOL="auth_chain_c" ;; 9) - protocol="auth_chain_d" + PROTOCOL="auth_chain_d" ;; 10) - protocol="auth_chain_e" + PROTOCOL="auth_chain_e" ;; 11) - protocol="auth_chain_f" + PROTOCOL="auth_chain_f" ;; *) - echo "无效的选择,使用默认协议" - protocol="origin" + colorEcho $RED "无效的选择,使用默认协议" + PROTOCOL="origin" esac fi echo "" - echo "协议: $protocol" + colorEcho $BLUE "协议: $PROTOCOL" echo "" - echo "请选择SSR混淆模式:" - echo "1)plain" - echo "2)http_simple" - echo "3)http_post" - echo "4)tls1.2_ticket_auth" - echo "5)tls1.2_ticket_fastauth" - read -p "请选择混淆模式(默认plain)" answer + colorEcho $BLUE " 请选择SSR混淆模式:" + echo " 1)plain" + echo " 2)http_simple" + echo " 3)http_post" + echo " 4)tls1.2_ticket_auth" + echo " 5)tls1.2_ticket_fastauth" + read -p " 请选择混淆模式(默认plain)" answer if [ -z "$answer" ]; then - obfs="plain" + OBFS="plain" else case $answer in 1) - obfs="plain" + OBFS="plain" ;; 2) - obfs="http_simple" + OBFS="http_simple" ;; 3) - obfs="http_post" + OBFS="http_post" ;; 4) - obfs="tls1.2_ticket_auth" + OBFS="tls1.2_ticket_auth" ;; 5) - obfs="tls1.2_ticket_fastauth" + OBFS="tls1.2_ticket_fastauth" ;; *) echo "无效的选择,使用默认混淆模式" - obfs="plain" + OBFS="plain" esac fi echo "" - echo "混淆: $obfs" + colorEcho $BLUE "混淆模式: $OBFS" echo "" } -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - apt update && apt upgrade -y +preinstall() { + colorEcho $BLUE " 更新系统" + auto clean all + apt update + #apt upgrade -y - echo "安装必要软件" - apt install -y telnet curl wget vim net-tools libsodium18 openssl unzip + colorEcho $BLUE " 安装必要软件" + apt install -y telnet curl wget vim net-tools libsodium18 openssl unzip qrencode + res=`which wget` + [ "$?" != "0" ] && apt install -y wget + res=`which netstat` + [ "$?" != "0" ] && apt install -y net-tools apt autoremove -y res=`which python` if [ "$?" != "0" ]; then @@ -243,36 +275,36 @@ function preinstall() fi } -function installSSR() -{ +installSSR() { if [ ! -d /usr/local/shadowsocks ]; then - echo 下载安装文件 + colorEcho $BLUE " 下载安装文件" if ! wget --no-check-certificate -O ${FILENAME}.tar.gz ${URL}; then - echo -e "[${red}Error${plain}] 下载文件失败!" + echo -e "[${RED}Error${PLAIN}] 下载文件失败!" exit 1 fi tar -zxf ${FILENAME}.tar.gz mv shadowsocksr-3.2.2/shadowsocks /usr/local if [ ! -f /usr/local/shadowsocks/server.py ]; then - echo "安装失败,请到 https://www.hijk.pw 网站反馈" + colorEcho $RED " $OS 安装SSR失败,请到 https://hijk.art 网站反馈" cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz exit 1 fi + cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz fi - cat > /etc/shadowsocksR.json<<-EOF + cat > $CONFIG_FILE<<-EOF { "server":"0.0.0.0", - "server_ipv6":"[::]", - "server_port":${port}, + "server_ipv6":"::", + "server_port":${PORT}, "local_port":1080, - "password":"${password}", + "password":"${PASSWORD}", "timeout":600, - "method":"${method}", - "protocol":"${protocol}", + "method":"${METHOD}", + "protocol":"${PROTOCOL}", "protocol_param":"", - "obfs":"${obfs}", + "obfs":"${OBFS}", "obfs_param":"", "redirect":"", "dns_ipv6":false, @@ -284,16 +316,16 @@ EOF cat > /lib/systemd/system/shadowsocksR.service <<-EOF [Unit] Description=shadowsocksR -Documentation=https://www.hijk.pw/ +Documentation=https://hijk.art/ After=network-online.target Wants=network-online.target [Service] Type=forking LimitNOFILE=32768 -ExecStart=/usr/local/shadowsocks/server.py -c /etc/shadowsocksR.json -d start -ExecReload=/bin/kill -s HUP $MAINPID -ExecStop=/bin/kill -s TERM $MAINPID +ExecStart=/usr/local/shadowsocks/server.py -c $CONFIG_FILE -d start +ExecReload=/bin/kill -s HUP \$MAINPID +ExecStop=/bin/kill -s TERM \$MAINPID [Install] WantedBy=multi-user.target @@ -302,86 +334,98 @@ EOF systemctl daemon-reload systemctl enable shadowsocksR && systemctl restart shadowsocksR sleep 3 - res=`netstat -nltp | grep ${port} | grep python` + res=`netstat -nltp | grep ${PORT} | grep python` if [ "${res}" = "" ]; then - echo "ssr启动失败,请检查端口是否被占用!" + colorEcho $RED " $OS ssr启动失败,请检查端口是否被占用!" exit 1 fi } -function setFirewall() -{ +setFirewall() { res=`ufw status | grep -i inactive` if [ "$res" = "" ];then - ufw allow ${port}/tcp - ufw allow ${port}/udp + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp fi } -function installBBR() -{ +installBBR() { result=$(lsmod | grep bbr) if [ "$result" != "" ]; then - echo BBR模块已安装 - bbr=true - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - return; + colorEcho $BLUE " BBR模块已安装" + INSTALL_BBR=false + return + fi + + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return fi - echo 安装BBR模块... + colorEcho $BLUE " 安装BBR模块..." apt install -y --install-recommends linux-generic-hwe-16.04 grub-set-default 0 echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + INSTALL_BBR=false } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/shadowsocksR.json | grep server_port | cut -d: -f2 | tr -d \",' '` +info() { + port=`grep server_port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` res=`netstat -nltp | grep ${port} | grep python` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - password=`cat /etc/shadowsocksR.json | grep password | cut -d: -f2 | tr -d \",' '` - method=`cat /etc/shadowsocksR.json | grep method | cut -d: -f2 | tr -d \",' '` - protocol=`cat /etc/shadowsocksR.json | grep protocol | cut -d: -f2 | tr -d \",' '` - obfs=`cat /etc/shadowsocksR.json | grep obfs | cut -d: -f2 | tr -d \",' '` + [ -z "$res" ] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + password=`grep password $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + method=`grep method $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + protocol=`grep protocol $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + obfs=`grep obfs $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + p1=`echo -n ${password} | base64 -w 0` + p1=`echo -n ${p1} | tr -d =` + res=`echo -n "${IP}:${port}:${protocol}:${method}:${obfs}:${p1}/?remarks=&protoparam=&obfsparam=" | base64 -w 0` + res=`echo -n ${res} | tr -d =` + link="ssr://${res}" + echo ============================================ - echo -e " ssr运行状态:${status}" - echo -e " ssr配置文件:${red}/etc/shadowsocksR.json${plain}" + echo -e " ${BLUE}ssr运行状态:${PLAIN}${status}" + echo -e " ${BLUE}ssr配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" echo "" - echo -e "${red}ssr配置信息:${plain}" - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " 密码(password):${red}${password}${plain}" - echo -e " 加密方式(method): ${red}${method}${plain}" - echo -e " 协议(protocol):" ${red}${protocol}${plain} - echo -e " 混淆(obfuscation):" ${red}${obfs}${plain} - echo - echo ============================================ + echo -e " ${RED}ssr配置信息:${PLAIN}" + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port)${PLAIN}:${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}加密方式(method):${PLAIN} ${RED}${method}${PLAIN}" + echo -e " ${BLUE}协议(protocol):${PLAIN} ${RED}${protocol}${PLAIN}" + echo -e " ${BLUE}混淆(obfuscation):${PLAIN} ${RED}${obfs}${PLAIN}" + echo + echo -e " ${BLUE}ssr链接:${PLAIN} $link" + qrencode -o - -t utf8 $link } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [ "${INSTALL_BBR}" == "false" ]; then echo - echo 为使BBR模块生效,系统将在30秒后重启 + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ - echo -n "系统版本: " +install() { + echo -n " 系统版本: " lsb_release -a checkSystem @@ -393,25 +437,24 @@ function install() info - cd ${BASE} && rm -rf shadowsocksr-3.2.2 ${FILENAME}.tar.gz - bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载SSR吗?(y/n)" answer +uninstall() { + read -p " 确定卸载SSR吗?(y/n)" answer [ -z ${answer} ] && answer="n" if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then - rm -f /etc/shadowsocksR.json + rm -f $CONFIG_FILE rm -f /var/log/shadowsocks.log rm -rf /usr/local/shadowsocks systemctl disable shadowsocksR && systemctl stop shadowsocksR && rm -rf /lib/systemd/system/shadowsocksR.service fi - echo -e " ${red}卸载成功${plain}" + echo -e " ${RED}卸载成功${PLAIN}" } +slogon + action=$1 [ -z $1 ] && action=install case "$action" in @@ -419,7 +462,7 @@ case "$action" in ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall|info]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall|info]" ;; esac diff --git a/ubuntu_install_v2ray.sh b/ubuntu_install_v2ray.sh index 99ab2c58..014f509d 100644 --- a/ubuntu_install_v2ray.sh +++ b/ubuntu_install_v2ray.sh @@ -1,180 +1,236 @@ #!/bin/bash # v2ray Ubuntu系统一键安装脚本 -# Author: hijk +# Author: hijk -echo "#############################################################" -echo "# Ubuntu 16.04 TLS v2ray 带一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' +OS=`hostnamectl | grep -i system | cut -d: -f2` -function checkSystem() -{ +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +CONFIG_FILE="/etc/v2ray/config.json" + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { result=$(id | awk '{print $1}') if [ $result != "uid=0(root)" ]; then - echo "请以root身份执行该脚本" + colorEcho $RED " 请以root身份执行该脚本" exit 1 fi res=`lsb_release -d | grep -i ubuntu` - if [ "${res}" = "" ];then - echo "系统不是Ubuntu" - exit 1 - fi - - result=`lsb_release -d | grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 16 ]; then - echo "不受支持的Ubuntu版本" - exit 1 - fi + if [ "$?" != "0" ]; then + res=`which apt` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统不是Ubuntu" + exit 1 + fi + res=`which systemctl` + if [ "$?" != "0" ]; then + colorEcho $RED " 系统版本过低,请重装系统到高版本后再使用本脚本!" + exit 1 + fi + else + result=`lsb_release -d | grep -oE "[0-9.]+"` + main=${result%%.*} + if [ $main -lt 16 ]; then + colorEcho $RED " 不受支持的Ubuntu版本" + exit 1 + fi + fi +} + +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}Ubuntu LTS v2ray一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" } -function getData() -{ +getData() { while true do - read -p "请输入v2ray的端口[1-65535]:" port - [ -z "$port" ] && port="21568" - expr $port + 0 &>/dev/null + read -p " 请输入v2ray的端口[1-65535]:" PORT + [ -z "$PORT" ] && PORT="21568" + if [ "${PORT:0:1}" = "0" ]; then + echo -e " ${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + expr $PORT + 0 &>/dev/null if [ $? -eq 0 ]; then - if [ $port -ge 1 ] && [ $port -le 65535 ]; then + if [ $PORT -ge 1 ] && [ $PORT -le 65535 ]; then echo "" - echo "端口号: $port" + colorEcho $BLUE " 端口号: $PORT" echo "" break else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi else - echo "输入错误,端口号为1-65535的数字" + colorEcho $RED " 输入错误,端口号为1-65535的数字" fi done } -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - apt update && apt -y upgrade - fi - echo "安装必要软件" +preinstall() { + colorEcho $BLUE " 更新系统..." + apt clean all + apt update + apt -y upgrade + colorEcho $BLUE " 安装必要软件" apt install -y telnet wget vim net-tools ntpdate unzip + res=`which wget` + [ "$?" != "0" ] && apt install -y wget + res=`which netstat` + [ "$?" != "0" ] && apt install -y net-tools apt autoremove -y } -function installV2ray() -{ - echo 安装v2ray... - bash <(curl -L -s https://install.direct/go.sh) +installV2ray() { + colorEcho $BLUE " 安装v2ray..." + bash <(curl -sL ${V6_PROXY}https://raw.githubusercontent.com/hijkpw/scripts/master/goV2.sh) - if [ ! -f /etc/v2ray/config.json ]; then - echo "安装失败,请到 https://www.hijk.pw 网站反馈" + if [ ! -f $CONFIG_FILE ]; then + colorEcho $RED " $OS 安装V2ray失败,请到 https://hijk.art 网站反馈" exit 1 fi - sed -i -e "s/port\":.*[0-9]*,/port\": ${port},/" /etc/v2ray/config.json - logsetting=`cat /etc/v2ray/config.json|grep loglevel` - if [ "${logsetting}" = "" ]; then - sed -i '1a\ "log": {\n "loglevel": "info",\n "access": "/var/log/v2ray/access.log",\n "error": "/var/log/v2ray/error.log"\n },' /etc/v2ray/config.json - fi - alterid=`shuf -i50-90 -n1` - sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" /etc/v2ray/config.json - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` + sed -i -e "s/port\":.*[0-9]*,/port\": ${PORT},/" $CONFIG_FILE + alterid=`shuf -i50-80 -n1` + sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" $CONFIG_FILE + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ntpdate -u time.nist.gov - systemctl enable v2ray && systemctl restart v2ray + + systemctl enable v2ray + systemctl restart v2ray sleep 3 - res=`netstat -nltp | grep ${port} | grep v2ray` + res=`netstat -ntlp| grep ${PORT} | grep v2ray` if [ "${res}" = "" ]; then - echo "v2ray启动失败,请检查端口是否被占用!" + colorEcho $red " $OS 端口号:${PORT},v2启动失败,请检查端口是否被占用!" exit 1 fi - echo "v2ray安装成功!" + colorEcho $GREEN " v2ray安装成功!" } -function setFirewall() -{ +setFirewall() { res=`ufw status | grep -i inactive` if [ "$res" = "" ];then - ufw allow ${port}/tcp - ufw allow ${port}/udp + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp fi } -function installBBR() -{ +installBBR() { result=$(lsmod | grep bbr) if [ "$result" != "" ]; then - echo BBR模块已安装 - bbr=true - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf + colorEcho $BLUE " BBR模块已安装" + INSTALL_BBR=false return; fi - echo 安装BBR模块... + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." apt install -y --install-recommends linux-generic-hwe-16.04 grub-set-default 0 echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + INSTALL_BBR=false } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=`cat /etc/v2ray/config.json | grep port | cut -d: -f2 | tr -d \",' '` +info() { + if [ ! -f $CONFIG_FILE ]; then + echo -e " ${RED}未安装v2ray!${PLAIN}" + exit 1 + fi + + port=`grep port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` res=`netstat -nltp | grep ${port} | grep v2ray` - [ -z "$res" ] && status="${red}已停止${plain}" || status="${green}正在运行${plain}" - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` - alterid=`cat /etc/v2ray/config.json | grep alterId | cut -d: -f2 | tr -d \",' '` - res=`cat /etc/v2ray/config.json | grep network` - [ -z "$res" ] && network="tcp" || network=`cat /etc/v2ray/config.json | grep network | cut -d: -f2 | tr -d \",' '` + [ -z "$res" ] && status="${RED}已停止${PLAIN}" || status="${GREEN}正在运行${PLAIN}" + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + alterid=`grep alterId $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + res=`grep network $CONFIG_FILE` + [ -z "$res" ] && network="tcp" || network=`grep network $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` security="auto" - + + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"tcp\", + \"type\":\"none\", + \"host\":\"\", + \"path\":\"\", + \"tls\":\"\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + echo ============================================ - echo -e " v2ray运行状态:${status}" - echo -e " v2ray配置文件:${red}/etc/v2ray/config.json${plain}" + echo -e " ${BLUE}v2ray运行状态:${PLAIN}${status}" + echo -e " ${BLUE}v2ray配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" echo "" - echo -e "${red}v2ray配置信息:${plain} " - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " id(uuid):${red}${uid}${plain}" - echo -e " 额外id(alterid): ${red}${alterid}${plain}" - echo -e " 加密方式(security): ${red}$security${plain}" - echo -e " 传输协议(network): ${red}${network}${plain}" - echo - echo ============================================ + echo -e " ${RED}v2ray配置信息:${PLAIN} " + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}$security${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo + echo -e " ${BLUE}vmess链接:${PLAIN} $link" } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [ "${INSTALL_BBR}" == "true" ]; then echo - echo 为使BBR模块生效,系统将在30秒后重启 + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ - echo -n "系统版本: " +install() { + echo -n " 系统版本: " lsb_release -a checkSystem @@ -188,9 +244,8 @@ function install() bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载v2ray吗?(y/n)" answer +uninstall() { + read -p " 确定卸载v2ray吗?(y/n)" answer [ -z ${answer} ] && answer="n" if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then @@ -200,11 +255,14 @@ function uninstall() rm -rf /usr/bin/v2ray/* rm -rf /var/log/v2ray/* rm -rf /etc/systemd/system/v2ray.service + rm -rf /etc/systemd/system/multi-user.target.wants/v2ray.service - echo -e " ${red}卸载成功${plain}" + echo -e " ${RED}卸载成功${PLAIN}" fi } +slogon + action=$1 [ -z $1 ] && action=install case "$action" in @@ -212,7 +270,7 @@ case "$action" in ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall]" ;; esac diff --git a/ubuntu_install_v2ray2.sh b/ubuntu_install_v2ray2.sh index 4ee9cf85..077a6908 100644 --- a/ubuntu_install_v2ray2.sh +++ b/ubuntu_install_v2ray2.sh @@ -1,20 +1,46 @@ #!/bin/bash # v2ray Ubuntu系统一键安装脚本 -# Author: hijk - -echo "#############################################################" -echo "# Ubuntu 16.04 TLS v2ray 带伪装一键安装脚本 #" -echo "# 网址: https://www.hijk.pw #" -echo "# 作者: hijk #" -echo "#############################################################" -echo "" - -red='\033[0;31m' -green="\033[0;32m" -plain='\033[0m' - -function checkSystem() -{ +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +# 以下网站是随机从Google上找到的无广告小说网站,不喜欢请改成其他网址,以http或https开头 +# 搭建好后无法打开伪装域名,可能是反代小说网站挂了,请在网站留言,或者Github发issue,以便替换新的网站 +SITES=( +http://www.zhuizishu.com/ +http://xs.56dyc.com/ +#http://www.xiaoshuosk.com/ +#https://www.quledu.net/ +http://www.ddxsku.com/ +http://www.biqu6.com/ +https://www.wenshulou.cc/ +#http://www.auutea.com/ +http://www.55shuba.com/ +http://www.39shubao.com/ +https://www.23xsw.cc/ +#https://www.huanbige.com/ +https://www.jueshitangmen.info/ +https://www.zhetian.org/ +http://www.bequgexs.com/ +http://www.tjwl.com/ +) + +CONFIG_FILE="/etc/v2ray/config.json" +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +checkSystem() { result=$(id | awk '{print $1}') if [ $result != "uid=0(root)" ]; then echo "请以root身份执行该脚本" @@ -22,165 +48,306 @@ function checkSystem() fi res=`lsb_release -d | grep -i ubuntu` - if [ "${res}" = "" ];then - echo "系统不是Ubuntu" - exit 1 - fi - - result=`lsb_release -d | grep -oE "[0-9.]+"` - main=${result%%.*} - if [ $main -lt 16 ]; then - echo "不受支持的Ubuntu版本" - exit 1 - fi + if [ "$?" != "0" ]; then + res=`which apt` + if [ "$?" != "0" ]; then + echo "系统不是Ubuntu" + exit 1 + fi + res=`which systemctl` + if [ "$?" != "0" ]; then + echo "系统版本过低,请重装系统到高版本后再使用本脚本!" + exit 1 + fi + else + result=`lsb_release -d | grep -oE "[0-9.]+"` + main=${result%%.*} + if [ $main -lt 16 ]; then + echo "不受支持的Ubuntu版本" + exit 1 + fi + fi } -function getData() -{ - apt install -y dnsutils curl - IP=`curl -s -4 icanhazip.com` +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +slogon() { + clear + echo "#############################################################" + echo -e "# ${RED}Ubuntu LTS v2ray带伪装一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo "" +} + +getData() { echo " " echo " 本脚本为带伪装的一键脚本,运行之前请确认如下条件已经具备:" - echo -e " ${red}1. 一个域名${plain}" - echo -e " ${red}2. 域名的某个主机名解析指向当前服务器ip(${IP})${plain}" + colorEcho ${YELLOW} " 1. 一个伪装域名" + colorEcho ${YELLOW} " 2. 伪装域名DNS解析指向当前服务器ip(${IP})" + colorEcho ${BLUE} " 3. 如果/root目录下有 v2ray.pem 和 v2ray.key 证书密钥文件,无需理会条件2" echo " " - read -p "确认满足按y,按其他退出脚本:" answer - if [ "${answer}" != "y" ]; then - exit 0 - fi + read -p " 确认满足按y,按其他退出脚本:" answer + [ "${answer}" != "y" ] && exit 0 + echo "" while true do - read -p "请输入您的主机名:" domain - if [ -z "${domain}" ]; then - echo "主机名输入错误,请重新输入!" + read -p " 请输入伪装域名:" DOMAIN + if [ -z "${DOMAIN}" ]; then + colorEcho $RED " 域名输入错误,请重新输入!" else break fi done - - res=`host ${domain}` - res=`echo -n ${res} | grep ${IP}` - if [ -z "${res}" ]; then - echo -n "${domain} 解析结果:" - host ${domain} - echo "主机未解析到当前服务器IP(${IP})!" - exit 1 + DOMAIN=${DOMAIN,,} + colorEcho ${BLUE} " 伪装域名(host):$DOMAIN" + + echo "" + if [[ -f ~/v2ray.pem && -f ~/v2ray.key ]]; then + colorEcho ${BLUE} " 检测到自有证书,将使用其部署" + echo + CERT_FILE="/etc/v2ray/${DOMAIN}.pem" + KEY_FILE="/etc/v2ray/${DOMAIN}.key" + else + resolve=`curl -sL https://hijk.art/hostip.php?d=${DOMAIN}` + res=`echo -n ${resolve} | grep ${IP}` + if [[ -z "${res}" ]]; then + colorEcho ${BLUE} "${DOMAIN} 解析结果:${resolve}" + colorEcho ${RED} " 域名未解析到当前服务器IP(${IP})!" + exit 1 + fi fi + echo "" while true do - read -p "请输入伪装路径,以/开头:" path - if [ -z "${path}" ]; then - echo "请输入伪装路径,以/开头!" - elif [ "${path:0:1}" != "/" ]; then - echo "伪装路径必须以/开头!" - elif [ "${path}" = "/" ]; then - echo "不能使用根路径!" + read -p " 请输入伪装路径,以/开头(不懂请直接回车):" WSPATH + if [[ -z "${WSPATH}" ]]; then + len=`shuf -i5-12 -n1` + ws=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1` + WSPATH="/$ws" + break + elif [[ "${WSPATH:0:1}" != "/" ]]; then + colorEcho ${RED} " 伪装路径必须以/开头!" + elif [[ "${WSPATH}" = "/" ]]; then + colorEcho ${RED} " 不能使用根路径!" else break fi done -} + colorEcho ${BLUE} " 伪装路径:$WSPATH" -function preinstall() -{ - sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config - systemctl restart sshd - ret=`nginx -t` - if [ "$?" != "0" ]; then - echo "更新系统..." - apt update && apt -y upgrade + echo + read -p " 请输入Nginx端口[100-65535的一个数字,默认443]:" PORT + [ -z "${PORT}" ] && PORT=443 + if [ "${PORT:0:1}" = "0" ]; then + echo -e "${RED}端口不能以0开头${PLAIN}" + exit 1 + fi + colorEcho ${BLUE} " Nginx端口:$PORT" + + echo "" + colorEcho $BLUE " 请选择伪装站类型:" + echo " 1) 静态网站(位于/usr/share/nginx/html)" + echo " 2) 小说站(随机选择)" + echo " 3) 美女站(https://imeizi.me)" + echo " 4) 高清壁纸站(https://bing.imeizi.me)" + echo " 5) 自定义反代站点(需以http或者https开头)" + read -p " 请选择伪装网站类型[默认:高清壁纸站]" answer + if [[ -z "$answer" ]]; then + PROXY_URL="https://bing.imeizi.me" + else + case $answer in + 1) + PROXY_URL="" + ;; + 2) + len=${#SITES[@]} + ((len--)) + while true + do + index=`shuf -i0-${len} -n1` + PROXY_URL=${SITES[$index]} + host=`echo ${PROXY_URL} | cut -d/ -f3` + ip=`curl -sL https://hijk.art/hostip.php?d=${host}` + res=`echo -n ${ip} | grep ${host}` + if [[ "${res}" = "" ]]; then + echo "$ip $host" >> /etc/hosts + break + fi + done + ;; + 3) + PROXY_URL="https://imeizi.me" + ;; + 4) + PROXY_URL="https://bing.imeizi.me" + ;; + 5) + read -p " 请输入反代站点(以http或者https开头):" PROXY_URL + if [[ -z "$PROXY_URL" ]]; then + colorEcho $RED " 请输入反代网站!" + exit 1 + elif [[ "${PROXY_URL:0:4}" != "http" ]]; then + colorEcho $RED " 反代网站必须以http或https开头!" + exit 1 + fi + ;; + *) + colorEcho $RED " 请输入正确的选项!" + exit 1 + esac + fi + REMOTE_HOST=`echo ${PROXY_URL} | cut -d/ -f3` + echo "" + colorEcho $BLUE " 伪装网站:$PROXY_URL" + + echo "" + colorEcho $BLUE " 是否允许搜索引擎爬取网站?[默认:不允许]" + echo " y)允许,会有更多ip请求网站,但会消耗一些流量,vps流量充足情况下推荐使用" + echo " n)不允许,爬虫不会访问网站,访问ip比较单一,但能节省vps流量" + read -p " 请选择:[y/n]" answer + if [[ -z "$answer" ]]; then + ALLOW_SPIDER="n" + elif [[ "${answer,,}" = "y" ]]; then + ALLOW_SPIDER="y" + else + ALLOW_SPIDER="n" fi - echo "安装必要软件" + echo "" + colorEcho $BLUE " 允许搜索引擎:$ALLOW_SPIDER" + + echo "" + read -p " 是否安装BBR(安装请按y,不安装请输n,不输则默认安装):" NEED_BBR + [ -z "$NEED_BBR" ] && NEED_BBR=y + [ "$NEED_BBR" = "Y" ] && NEED_BBR=y + colorEcho $BLUE " 安装BBR:$NEED_BBR" +} + +preinstall() { + colorEcho $BLUE " 更新系统..." + apt clean all + apt update + #apt -y upgrade + colorEcho $BLUE " 安装必要软件" apt install -y telnet wget vim net-tools ntpdate unzip gcc g++ apt autoremove -y + res=`which wget` + [ "$?" != "0" ] && apt install -y wget + res=`which netstat` + [ "$?" != "0" ] && apt install -y net-tools } -function installV2ray() -{ - echo 安装v2ray... - bash <(curl -L -s https://install.direct/go.sh) +installV2ray() { + colorEcho $BLUE 安装v2ray... + bash <(curl -sL ${V6_PROXY}https://raw.githubusercontent.com/hijkpw/scripts/master/goV2.sh) - if [ ! -f /etc/v2ray/config.json ]; then - echo "安装失败,请到 https://www.hijk.pw 网站反馈" + if [ ! -f $CONFIG_FILE ]; then + colorEcho $RED " $OS 安装V2ray失败,请到 https://hijk.art 网站反馈" exit 1 fi - logsetting=`cat /etc/v2ray/config.json|grep loglevel` - if [ "${logsetting}" = "" ]; then - sed -i '1a\ "log": {\n "loglevel": "info",\n "access": "/var/log/v2ray/access.log",\n "error": "/var/log/v2ray/error.log"\n },' /etc/v2ray/config.json - fi - alterid=`shuf -i50-90 -n1` - sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" /etc/v2ray/config.json - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` - port=`cat /etc/v2ray/config.json | grep port | cut -d: -f2 | tr -d \",' '` + alterid=0 + sed -i -e "s/alterId\":.*[0-9]*/alterId\": ${alterid}/" $CONFIG_FILE + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + V2PORT=`grep port $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ntpdate -u time.nist.gov - res=`cat /etc/v2ray/config.json | grep streamSettings` + res=`grep streamSettings $CONFIG_FILE` if [ "$res" = "" ]; then - line=`grep -n '}]' /etc/v2ray/config.json | head -n1 | cut -d: -f1` + line=`grep -n '}]' $CONFIG_FILE | head -n1 | cut -d: -f1` line=`expr ${line} - 1` - sed -i "${line}s/}/},/" /etc/v2ray/config.json - sed -i "${line}a\ \"streamSettings\": {\n \"network\": \"ws\",\n \"wsSettings\": {\n \"path\": \"${path}\",\n \"headers\": {\n \"Host\": \"${domain}\"\n }\n }\n },\n \"listen\": \"127.0.0.1\"" /etc/v2ray/config.json + sed -i "${line}s/}/},/" $CONFIG_FILE + sed -i "${line}a\ \"streamSettings\": {\n \"network\": \"ws\",\n \"wsSettings\": {\n \"path\": \"${WSPATH}\",\n \"headers\": {\n \"Host\": \"${DOMAIN}\"\n }\n }\n },\n \"listen\": \"127.0.0.1\"" $CONFIG_FILE else - sed -i -e "s/path\":.*/path\": \"\\${path}\",/" /etc/v2ray/config.json + sed -i -e "s/path\":.*/path\": \"\\${WSPATH}\",/" $CONFIG_FILE fi - systemctl enable v2ray && systemctl restart v2ray + + systemctl enable v2ray + systemctl restart v2ray sleep 3 - res=`netstat -nltp | grep ${port} | grep v2ray` + res=`netstat -ntlp| grep ${V2PORT} | grep v2ray` if [ "${res}" = "" ]; then - echo "v2ray启动失败,请检查端口是否被占用!" + echo " $OS 端口号:${PORT},伪装路径:${WSPATH}, v2启动失败,请检查端口是否被占用或伪装路径是否有特殊字符!!" exit 1 fi - echo "v2ray安装成功!" + colorEcho $BLUE " v2ray安装成功!" } -function installNginx() -{ - apt install -y nginx - systemctl stop nginx - res=`netstat -ntlp| grep -E ':80|:443'` - if [ "${res}" != "" ]; then - echo " 其他进程占用了80或443端口,请先关闭再运行一键脚本" - echo " 端口占用信息如下:" - echo ${res} - exit 1 - fi - res=`which pip3` - if [ "$?" != "0" ]; then - apt install -y python3-pip python3-setuptools python3-dev - fi - res=`which pip3` - if [ "$?" != "0" ]; then - echo -e " pip3安装失败,请到 ${red}https://www.hijk.pw${plain} 反馈" - exit 1 - fi - pip3 install --upgrade pip - pip3 install wheel - pip3 install certbot - res=`which certbot` - if [ "$?" != "0" ]; then - export PATH=$PATH:/usr/local/bin +getCert() { + mkdir -p /etc/v2ray + if [[ -z ${CERT_FILE+x} ]]; then + systemctl stop nginx + systemctl stop v2ray + res=`netstat -ntlp| grep -E ':80 |:443 '` + if [[ "${res}" != "" ]]; then + colorEcho ${RED} " 其他进程占用了80或443端口,请先关闭再运行一键脚本" + echo " 端口占用信息如下:" + echo ${res} + exit 1 + fi + + apt install -y socat openssl cron + systemctl start cron + systemctl enable cron + curl -sL https://get.acme.sh | sh -s email=hijk.pw@protonmail.ch + source ~/.bashrc + ~/.acme.sh/acme.sh --upgrade --auto-upgrade + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "systemctl stop nginx" --post-hook "systemctl restart nginx" --standalone + [[ -f ~/.acme.sh/${DOMAIN}_ecc/ca.cer ]] || { + colorEcho $RED " 获取证书失败,请复制上面的红色文字到 https://hijk.art 反馈" + exit 1 + } + CERT_FILE="/etc/v2ray/${DOMAIN}.pem" + KEY_FILE="/etc/v2ray/${DOMAIN}.key" + ~/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \ + --key-file $KEY_FILE \ + --fullchain-file $CERT_FILE \ + --reloadcmd "service nginx force-reload" + [[ -f $CERT_FILE && -f $KEY_FILE ]] || { + colorEcho $RED " 获取证书失败,请到 https://hijk.art 反馈" + exit 1 + } + else + cp ~/v2ray.pem /etc/v2ray/${DOMAIN}.pem + cp ~/v2ray.key /etc/v2ray/${DOMAIN}.key fi - certbot certonly --standalone --agree-tos --register-unsafely-without-email -d ${domain} - if [ "$?" != "0" ]; then - echo -e " 获取证书失败,请到 ${red}https://www.hijk.pw${plain} 反馈" +} + +installNginx() { + apt install -y nginx + res=$(command -v nginx) + if [[ "$res" = "" ]]; then + colorEcho $RED " Nginx安装失败,请到 https://hijk.art 反馈" exit 1 fi + + getCert - res=`cat /usr/share/nginx/html/index.html| grep Flatfy` - if [ "${res}" = "" ]; then - mv /usr/share/nginx/html /usr/share/nginx/html.bak - wget 'https://github.com/hijkpw/scripts/raw/master/Flatfy%20V3.zip' -O theme.zip - unzip theme.zip - rm -rf __MACOSX/ - mv Flatfy\ V3 /usr/share/nginx/html - rm -rf theme.zip Flatfy\ V3 - fi if [ ! -f /etc/nginx/nginx.conf.bak ]; then mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak fi + if [[ "$ALLOW_SPIDER" = "n" ]]; then + echo 'User-Agent: *' > /usr/share/nginx/html/robots.txt + echo 'Disallow: /' >> /usr/share/nginx/html/robots.txt + fi + if [[ "$PROXY_URL" = "" ]]; then + action="" + else + action="proxy_ssl_server_name on; + proxy_pass $PROXY_URL; + proxy_set_header Accept-Encoding ''; + sub_filter \"$REMOTE_HOST\" \"$DOMAIN\"; + sub_filter_once off;" + fi cat > /etc/nginx/nginx.conf<<-EOF user www-data; worker_processes auto; @@ -217,41 +384,45 @@ http { } EOF - mkdir -p /etc/nginx/conf.d; - cat > /etc/nginx/conf.d/${domain}.conf<<-EOF + mkdir -p /etc/nginx/conf.d + cat > /etc/nginx/conf.d/${DOMAIN}.conf<<-EOF server { - listen 80 default_server; - server_name ${domain}; - rewrite ^(.*) https://\$server_name\$1 permanent; + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + rewrite ^(.*) https://\$server_name:${PORT}\$1 permanent; } server { - listen 443 ssl http2; - server_name ${domain}; + listen ${PORT} ssl http2; + listen [::]:${PORT} ssl http2; + server_name ${DOMAIN}; charset utf-8; # ssl配置 - ssl_protocols TLSv1.2; - ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_ecdh_curve secp384r1; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; - ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem; + ssl_certificate $CERT_FILE; + ssl_certificate_key $KEY_FILE; - access_log /var/log/nginx/${domain}.access.log; - error_log /var/log/nginx/${domain}.error.log; + access_log /var/log/nginx/${DOMAIN}.access.log; + error_log /var/log/nginx/${DOMAIN}.error.log; root /usr/share/nginx/html; location / { - index index.html; + $action + } + location = /robots.txt { } - location ${path} { + location ${WSPATH} { proxy_redirect off; - proxy_pass http://127.0.0.1:${port}; + proxy_pass http://127.0.0.1:${V2PORT}; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; @@ -262,103 +433,136 @@ server { } } EOF - res=`cat /etc/crontab | grep certbot` - if [ "${res}" = "" ]; then - echo '0 3 1 */2 0 root systemctl stop nginx && certbot renew && systemctl start nginx' >> /etc/crontab - fi + systemctl enable nginx && systemctl restart nginx + systemctl start v2ray sleep 3 - res=`netstat -nltp | grep 443 | grep nginx` + res=`netstat -nltp | grep ${PORT} | grep nginx` if [ "${res}" = "" ]; then - echo -e "nginx启动失败! 请到 ${red}https://www.hijk.pw${plain} 反馈" + echo -e " $OS nginx启动失败! 请到 ${RED}https://hijk.art${PLAIN} 反馈" exit 1 fi } -function setFirewall() -{ +setFirewall() { res=`ufw status | grep -i inactive` if [ "$res" = "" ];then ufw allow http/tcp ufw allow https/tcp + ufw allow ${PORT}/tcp fi } -function installBBR() -{ +installBBR() { + if [ "$NEED_BBR" != "y" ]; then + INSTALL_BBR=false + return + fi result=$(lsmod | grep bbr) if [ "$result" != "" ]; then - echo BBR模块已安装 - bbr=true - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf + colorEcho $YELLOW " BBR模块已安装" + INSTALL_BBR=false return; fi + + res=`hostnamectl | grep -i openvz` + if [ "$res" != "" ]; then + colorEcho $YELLOW " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi - echo 安装BBR模块... + colorEcho $BLUE " 安装BBR模块..." apt install -y --install-recommends linux-generic-hwe-16.04 grub-set-default 0 echo "tcp_bbr" >> /etc/modules-load.d/modules.conf - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - echo "3" > /proc/sys/net/ipv4/tcp_fastopen - echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf - bbr=false + INSTALL_BBR=true } -function info() -{ - ip=`curl -s -4 icanhazip.com` - port=443 +info() { + if [ ! -f $CONFIG_FILE ]; then + colorEcho $RED " v2ray未安装" + exit 1 + fi + res=`netstat -nltp | grep v2ray` - [ -z "$res" ] && v2status="${red}已停止${plain}" || v2status="${green}正在运行${plain}" + [ -z "$res" ] && v2status="${RED}已停止${PLAIN}" || v2status="${GREEN}正在运行${PLAIN}" + + uid=`grep id $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + alterid=`grep alterId $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + network=`grep network $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + domain=`grep Host $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + if [ -z "$domain" ]; then + colorEcho $RED " 不是伪装版本的v2ray" + exit 1 + fi + path=`grep path $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` + port=`cat /etc/nginx/conf.d/${domain}.conf | grep -i ssl | head -n1 | awk '{print $2}'` + security="none" res=`netstat -nltp | grep ${port} | grep nginx` - [ -z "$res" ] && ngstatus="${red}已停止${plain}" || ngstatus="${green}正在运行${plain}" - uid=`cat /etc/v2ray/config.json | grep id | cut -d: -f2 | tr -d \",' '` - alterid=`cat /etc/v2ray/config.json | grep alterId | cut -d: -f2 | tr -d \",' '` - network=`cat /etc/v2ray/config.json | grep network | cut -d: -f2 | tr -d \",' '` - domain=`cat /etc/v2ray/config.json | grep Host | cut -d: -f2 | tr -d \",' '` - path=`cat /etc/v2ray/config.json | grep path | cut -d: -f2 | tr -d \",' '` - security="auto" + [ -z "$res" ] && ngstatus="${RED}已停止${PLAIN}" || ngstatus="${GREEN}正在运行${PLAIN}" + + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"${network}\", + \"type\":\"none\", + \"host\":\"${domain}\", + \"path\":\"${path}\", + \"tls\":\"tls\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + echo ============================================ - echo -e " v2ray运行状态:${v2status}" - echo -e " v2ray配置文件:${red}/etc/v2ray/config.json${plain}" - echo -e " nginx运行状态:${ngstatus}" - echo -e " nginx配置文件:${red}/etc/nginx/conf.d/${domain}.conf${plain}" + echo -e " ${BLUE}v2ray运行状态:${PLAIN}${v2status}" + echo -e " ${BLUE}v2ray配置文件:${PLAIN}${RED}$CONFIG_FILE${PLAIN}" + echo -e " ${BLUE}nginx运行状态:${PLAIN}${ngstatus}" + echo -e " ${BLUE}nginx配置文件:${PLAIN}${RED}/etc/nginx/conf.d/${domain}.conf${PLAIN}" echo "" - echo -e "${red}v2ray配置信息:${plain} " - echo -e " IP(address): ${red}${ip}${plain}" - echo -e " 端口(port):${red}${port}${plain}" - echo -e " id(uuid):${red}${uid}${plain}" - echo -e " 额外id(alterid): ${red}${alterid}${plain}" - echo -e " 加密方式(security): ${red}$security${plain}" - echo -e " 传输协议(network): ${red}${network}${plain}" - echo -e " 主机名(host):${red}${domain}${plain}" - echo -e " 路径(path):${red}${path}${plain}" - echo -e " 安全传输(security):${red}TLS${plain}" + echo -e " ${RED}v2ray配置信息:${PLAIN} " + echo -e " ${BLUE}IP(address):${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}$security${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none${PLAIN}" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}路径(path):${PLAIN}${RED}${path}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" echo - echo ============================================ + echo -e " ${BLUE}vmess链接:${PLAIN} $link" } -function bbrReboot() -{ - if [ "${bbr}" == "false" ]; then +bbrReboot() { + if [ "${INSTALL_BBR}" == "true" ]; then echo - echo 为使BBR模块生效,系统将在30秒后重启 + colorEcho $BLUE " 为使BBR模块生效,系统将在30秒后重启" echo - echo -e "您可以按 ctrl + c 取消重启,稍后输入 ${red}reboot${plain} 重启系统" + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" sleep 30 reboot fi } -function install() -{ - echo -n "系统版本: " - lsb_release -a - +install() { checkSystem getData preinstall @@ -371,29 +575,35 @@ function install() bbrReboot } -function uninstall() -{ - read -p "您确定真的要卸载v2ray吗?(y/n)" answer +uninstall() { + echo "" + read -p " 确定卸载v2ray吗?(y/n)" answer [ -z ${answer} ] && answer="n" if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then systemctl stop v2ray systemctl disable v2ray + domain=`grep Host $CONFIG_FILE| cut -d: -f2 | tr -d \",' '` rm -rf /etc/v2ray/* rm -rf /usr/bin/v2ray/* rm -rf /var/log/v2ray/* rm -rf /etc/systemd/system/v2ray.service apt remove -y nginx + apt remove -y nginx-common apt autoremove -y if [ -d /usr/share/nginx/html.bak ]; then rm -rf /usr/share/nginx/html mv /usr/share/nginx/html.bak /usr/share/nginx/html fi - echo -e " ${red}卸载成功${plain}" + rm -rf /etc/nginx/conf.d/${domain}.conf + ~/.acme.sh/acme.sh --uninstall + echo -e " ${RED}卸载成功${PLAIN}" fi } +slogon + action=$1 [ -z $1 ] && action=install case "$action" in @@ -401,7 +611,7 @@ case "$action" in ${action} ;; *) - echo "参数错误" - echo "用法: `basename $0` [install|uninstall]" + echo " 参数错误" + echo " 用法: `basename $0` [install|uninstall|info]" ;; esac diff --git a/v2ray.sh b/v2ray.sh new file mode 100644 index 00000000..384ae6d5 --- /dev/null +++ b/v2ray.sh @@ -0,0 +1,1910 @@ +#!/bin/bash +# v2ray一键安装脚本 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +# 以下网站是随机从Google上找到的无广告小说网站,不喜欢请改成其他网址,以http或https开头 +# 搭建好后无法打开伪装域名,可能是反代小说网站挂了,请在网站留言,或者Github发issue,以便替换新的网站 +SITES=( +http://www.zhuizishu.com/ +http://xs.56dyc.com/ +#http://www.xiaoshuosk.com/ +#https://www.quledu.net/ +http://www.ddxsku.com/ +http://www.biqu6.com/ +https://www.wenshulou.cc/ +#http://www.auutea.com/ +http://www.55shuba.com/ +http://www.39shubao.com/ +https://www.23xsw.cc/ +https://www.huanbige.com/ +https://www.jueshitangmen.info/ +https://www.zhetian.org/ +http://www.bequgexs.com/ +http://www.tjwl.com/ +) + +CONFIG_FILE="/etc/v2ray/config.json" +SERVICE_FILE="/etc/systemd/system/v2ray.service" +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" +res=`which bt 2>/dev/null` +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +VLESS="false" +TROJAN="false" +TLS="false" +WS="false" +XTLS="false" +KCP="false" + +checkSystem() { + result=$(id | awk '{print $1}') + if [[ $result != "uid=0(root)" ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=`which yum 2>/dev/null` + if [[ "$?" != "0" ]]; then + res=`which apt 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + fi + res=`which systemctl 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +configNeedNginx() { + local ws=`grep wsSettings $CONFIG_FILE` + if [[ -z "$ws" ]]; then + echo no + return + fi + echo yes +} + +needNginx() { + if [[ "$WS" = "false" ]]; then + echo no + return + fi + echo yes +} + +status() { + if [[ ! -f /usr/bin/v2ray/v2ray ]]; then + echo 0 + return + fi + if [[ ! -f $CONFIG_FILE ]]; then + echo 1 + return + fi + port=`grep port $CONFIG_FILE| head -n 1| cut -d: -f2| tr -d \",' '` + res=`ss -nutlp| grep ${port} | grep -i v2ray` + if [[ -z "$res" ]]; then + echo 2 + return + fi + + if [[ `configNeedNginx` != "yes" ]]; then + echo 3 + else + res=`ss -nutlp|grep -i nginx` + if [[ -z "$res" ]]; then + echo 4 + else + echo 5 + fi + fi +} + +statusText() { + res=`status` + case $res in + 2) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 3) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}V2ray正在运行${PLAIN} + ;; + 4) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}V2ray正在运行${PLAIN}, ${RED}Nginx未运行${PLAIN} + ;; + 5) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}V2ray正在运行, Nginx正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +normalizeVersion() { + if [ -n "$1" ]; then + case "$1" in + v*) + echo "$1" + ;; + *) + echo "v$1" + ;; + esac + else + echo "" + fi +} + +# 1: new V2Ray. 0: no. 1: yes. 2: not installed. 3: check failed. +getVersion() { + VER="$(/usr/bin/v2ray/v2ray -version 2>/dev/null)" + RETVAL=$? + CUR_VER="$(normalizeVersion "$(echo "$VER" | head -n 1 | cut -d " " -f2)")" + TAG_URL="${V6_PROXY}https://api.github.com/repos/v2fly/v2ray-core/releases/latest" + NEW_VER="$(normalizeVersion "$(curl -s "${TAG_URL}" --connect-timeout 10| tr ',' '\n' | grep 'tag_name' | cut -d\" -f4)")" + if [[ "$XTLS" = "true" ]]; then + NEW_VER=v4.32.1 + fi + + if [[ $? -ne 0 ]] || [[ $NEW_VER == "" ]]; then + colorEcho $RED " 检查V2ray版本信息失败,请检查网络" + return 3 + elif [[ $RETVAL -ne 0 ]];then + return 2 + elif [[ $NEW_VER != $CUR_VER ]];then + return 1 + fi + return 0 +} + +archAffix(){ + case "$(uname -m)" in + i686|i386) + echo '32' + ;; + x86_64|amd64) + echo '64' + ;; + *armv7*) + echo 'arm32-v7a' + ;; + armv6*) + echo 'arm32-v6a' + ;; + *armv8*|aarch64) + echo 'arm64-v8a' + ;; + *mips64le*) + echo 'mips64le' + ;; + *mips64*) + echo 'mips64' + ;; + *mipsle*) + echo 'mipsle' + ;; + *mips*) + echo 'mips' + ;; + *s390x*) + echo 's390x' + ;; + ppc64le) + echo 'ppc64le' + ;; + ppc64) + echo 'ppc64' + ;; + *) + colorEcho $RED " 不支持的CPU架构!" + exit 1 + ;; + esac + + return 0 +} + +getData() { + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + echo "" + echo " V2ray一键脚本,运行之前请确认如下条件已经具备:" + colorEcho ${YELLOW} " 1. 一个伪装域名" + colorEcho ${YELLOW} " 2. 伪装域名DNS解析指向当前服务器ip(${IP})" + colorEcho ${BLUE} " 3. 如果/root目录下有 v2ray.pem 和 v2ray.key 证书密钥文件,无需理会条件2" + echo " " + read -p " 确认满足按y,按其他退出脚本:" answer + if [[ "${answer,,}" != "y" ]]; then + exit 0 + fi + + echo "" + while true + do + read -p " 请输入伪装域名:" DOMAIN + if [[ -z "${DOMAIN}" ]]; then + colorEcho ${RED} " 域名输入错误,请重新输入!" + else + break + fi + done + DOMAIN=${DOMAIN,,} + colorEcho ${BLUE} " 伪装域名(host):$DOMAIN" + + if [[ -f ~/v2ray.pem && -f ~/v2ray.key ]]; then + colorEcho ${BLUE} " 检测到自有证书,将使用其部署" + CERT_FILE="/etc/v2ray/${DOMAIN}.pem" + KEY_FILE="/etc/v2ray/${DOMAIN}.key" + else + resolve=`curl -sL https://hijk.art/hostip.php?d=${DOMAIN}` + res=`echo -n ${resolve} | grep ${IP}` + if [[ -z "${res}" ]]; then + colorEcho ${BLUE} "${DOMAIN} 解析结果:${resolve}" + colorEcho ${RED} " 域名未解析到当前服务器IP(${IP})!" + exit 1 + fi + fi + fi + + echo "" + if [[ "$(needNginx)" = "no" ]]; then + if [[ "$TLS" = "true" ]]; then + read -p " 请输入v2ray监听端口[强烈建议443,默认443]:" PORT + [[ -z "${PORT}" ]] && PORT=443 + else + read -p " 请输入v2ray监听端口[100-65535的一个数字]:" PORT + [[ -z "${PORT}" ]] && PORT=`shuf -i200-65000 -n1` + if [[ "${PORT:0:1}" = "0" ]]; then + colorEcho ${RED} " 端口不能以0开头" + exit 1 + fi + fi + colorEcho ${BLUE} " v2ray端口:$PORT" + else + read -p " 请输入Nginx监听端口[100-65535的一个数字,默认443]:" PORT + [[ -z "${PORT}" ]] && PORT=443 + if [ "${PORT:0:1}" = "0" ]; then + colorEcho ${BLUE} " 端口不能以0开头" + exit 1 + fi + colorEcho ${BLUE} " Nginx端口:$PORT" + V2PORT=`shuf -i10000-65000 -n1` + fi + + if [[ "$KCP" = "true" ]]; then + echo "" + colorEcho $BLUE " 请选择伪装类型:" + echo " 1) 无" + echo " 2) BT下载" + echo " 3) 视频通话" + echo " 4) 微信视频通话" + echo " 5) dtls" + echo " 6) wiregard" + read -p " 请选择伪装类型[默认:无]:" answer + case $answer in + 2) + HEADER_TYPE="utp" + ;; + 3) + HEADER_TYPE="srtp" + ;; + 4) + HEADER_TYPE="wechat-video" + ;; + 5) + HEADER_TYPE="dtls" + ;; + 6) + HEADER_TYPE="wireguard" + ;; + *) + HEADER_TYPE="none" + ;; + esac + colorEcho $BLUE " 伪装类型:$HEADER_TYPE" + SEED=`cat /proc/sys/kernel/random/uuid` + fi + + if [[ "$TROJAN" = "true" ]]; then + echo "" + read -p " 请设置trojan密码(不输则随机生成):" PASSWORD + [[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + colorEcho $BLUE " trojan密码:$PASSWORD" + fi + + if [[ "$XTLS" = "true" ]]; then + echo "" + colorEcho $BLUE " 请选择流控模式:" + echo -e " 1) xtls-rprx-direct [$RED推荐$PLAIN]" + echo " 2) xtls-rprx-origin" + read -p " 请选择流控模式[默认:direct]" answer + [[ -z "$answer" ]] && answer=1 + case $answer in + 1) + FLOW="xtls-rprx-direct" + ;; + 2) + FLOW="xtls-rprx-origin" + ;; + *) + colorEcho $RED " 无效选项,使用默认的xtls-rprx-direct" + FLOW="xtls-rprx-direct" + ;; + esac + colorEcho $BLUE " 流控模式:$FLOW" + fi + + if [[ "${WS}" = "true" ]]; then + echo "" + while true + do + read -p " 请输入伪装路径,以/开头(不懂请直接回车):" WSPATH + if [[ -z "${WSPATH}" ]]; then + len=`shuf -i5-12 -n1` + ws=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1` + WSPATH="/$ws" + break + elif [[ "${WSPATH:0:1}" != "/" ]]; then + colorEcho ${RED} " 伪装路径必须以/开头!" + elif [[ "${WSPATH}" = "/" ]]; then + colorEcho ${RED} " 不能使用根路径!" + else + break + fi + done + colorEcho ${BLUE} " ws路径:$WSPATH" + fi + + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + echo "" + colorEcho $BLUE " 请选择伪装站类型:" + echo " 1) 静态网站(位于/usr/share/nginx/html)" + echo " 2) 小说站(随机选择)" + echo " 3) 美女站(https://imeizi.me)" + echo " 4) 高清壁纸站(https://bing.imeizi.me)" + echo " 5) 自定义反代站点(需以http或者https开头)" + read -p " 请选择伪装网站类型[默认:高清壁纸站]" answer + if [[ -z "$answer" ]]; then + PROXY_URL="https://bing.imeizi.me" + else + case $answer in + 1) + PROXY_URL="" + ;; + 2) + len=${#SITES[@]} + ((len--)) + while true + do + index=`shuf -i0-${len} -n1` + PROXY_URL=${SITES[$index]} + host=`echo ${PROXY_URL} | cut -d/ -f3` + ip=`curl -sL https://hijk.art/hostip.php?d=${host}` + res=`echo -n ${ip} | grep ${host}` + if [[ "${res}" = "" ]]; then + echo "$ip $host" >> /etc/hosts + break + fi + done + ;; + 3) + PROXY_URL="https://imeizi.me" + ;; + 4) + PROXY_URL="https://bing.imeizi.me" + ;; + 5) + read -p " 请输入反代站点(以http或者https开头):" PROXY_URL + if [[ -z "$PROXY_URL" ]]; then + colorEcho $RED " 请输入反代网站!" + exit 1 + elif [[ "${PROXY_URL:0:4}" != "http" ]]; then + colorEcho $RED " 反代网站必须以http或https开头!" + exit 1 + fi + ;; + *) + colorEcho $RED " 请输入正确的选项!" + exit 1 + esac + fi + REMOTE_HOST=`echo ${PROXY_URL} | cut -d/ -f3` + colorEcho $BLUE " 伪装网站:$PROXY_URL" + + echo "" + colorEcho $BLUE " 是否允许搜索引擎爬取网站?[默认:不允许]" + echo " y)允许,会有更多ip请求网站,但会消耗一些流量,vps流量充足情况下推荐使用" + echo " n)不允许,爬虫不会访问网站,访问ip比较单一,但能节省vps流量" + read -p " 请选择:[y/n]" answer + if [[ -z "$answer" ]]; then + ALLOW_SPIDER="n" + elif [[ "${answer,,}" = "y" ]]; then + ALLOW_SPIDER="y" + else + ALLOW_SPIDER="n" + fi + colorEcho $BLUE " 允许搜索引擎:$ALLOW_SPIDER" + fi + + echo "" + read -p " 是否安装BBR(默认安装)?[y/n]:" NEED_BBR + [[ -z "$NEED_BBR" ]] && NEED_BBR=y + [[ "$NEED_BBR" = "Y" ]] && NEED_BBR=y + colorEcho $BLUE " 安装BBR:$NEED_BBR" +} + +installNginx() { + echo "" + colorEcho $BLUE " 安装nginx..." + if [[ "$BT" = "false" ]]; then + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ "$?" != "0" ]]; then + echo '[nginx-stable] +name=nginx stable repo +baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ +gpgcheck=1 +enabled=1 +gpgkey=https://nginx.org/keys/nginx_signing.key +module_hotfixes=true' > /etc/yum.repos.d/nginx.repo + fi + fi + $CMD_INSTALL nginx + if [[ "$?" != "0" ]]; then + colorEcho $RED " Nginx安装失败,请到 https://hijk.art 反馈" + exit 1 + fi + systemctl enable nginx + else + res=`which nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 您安装了宝塔,请在宝塔后台安装nginx后再运行本脚本" + exit 1 + fi + fi +} + +startNginx() { + if [[ "$BT" = "false" ]]; then + systemctl start nginx + else + nginx -c /www/server/nginx/conf/nginx.conf + fi +} + +stopNginx() { + if [[ "$BT" = "false" ]]; then + systemctl stop nginx + else + res=`ps aux | grep -i nginx` + if [[ "$res" != "" ]]; then + nginx -s stop + fi + fi +} + +getCert() { + mkdir -p /etc/v2ray + if [[ -z ${CERT_FILE+x} ]]; then + stopNginx + sleep 2 + res=`netstat -ntlp| grep -E ':80 |:443 '` + if [[ "${res}" != "" ]]; then + colorEcho ${RED} " 其他进程占用了80或443端口,请先关闭再运行一键脚本" + echo " 端口占用信息如下:" + echo ${res} + exit 1 + fi + + $CMD_INSTALL socat openssl + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL cronie + systemctl start crond + systemctl enable crond + else + $CMD_INSTALL cron + systemctl start cron + systemctl enable cron + fi + curl -sL https://get.acme.sh | sh -s email=hijk.pw@protonmail.ch + source ~/.bashrc + ~/.acme.sh/acme.sh --upgrade --auto-upgrade + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt + if [[ "$BT" = "false" ]]; then + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "systemctl stop nginx" --post-hook "systemctl restart nginx" --standalone + else + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "nginx -s stop || { echo -n ''; }" --post-hook "nginx -c /www/server/nginx/conf/nginx.conf || { echo -n ''; }" --standalone + fi + [[ -f ~/.acme.sh/${DOMAIN}_ecc/ca.cer ]] || { + colorEcho $RED " 获取证书失败,请复制上面的红色文字到 https://hijk.art 反馈" + exit 1 + } + CERT_FILE="/etc/v2ray/${DOMAIN}.pem" + KEY_FILE="/etc/v2ray/${DOMAIN}.key" + ~/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \ + --key-file $KEY_FILE \ + --fullchain-file $CERT_FILE \ + --reloadcmd "service nginx force-reload" + [[ -f $CERT_FILE && -f $KEY_FILE ]] || { + colorEcho $RED " 获取证书失败,请到 https://hijk.art 反馈" + exit 1 + } + else + cp ~/v2ray.pem /etc/v2ray/${DOMAIN}.pem + cp ~/v2ray.key /etc/v2ray/${DOMAIN}.key + fi +} + +configNginx() { + mkdir -p /usr/share/nginx/html; + if [[ "$ALLOW_SPIDER" = "n" ]]; then + echo 'User-Agent: *' > /usr/share/nginx/html/robots.txt + echo 'Disallow: /' >> /usr/share/nginx/html/robots.txt + ROBOT_CONFIG=" location = /robots.txt {}" + else + ROBOT_CONFIG="" + fi + + if [[ "$BT" = "false" ]]; then + if [[ ! -f /etc/nginx/nginx.conf.bak ]]; then + mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak + fi + res=`id nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + user="www-data" + else + user="nginx" + fi + cat > /etc/nginx/nginx.conf<<-EOF +user $user; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' + '\$status \$body_bytes_sent "\$http_referer" ' + '"\$http_user_agent" "\$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + server_tokens off; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + gzip on; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; +} +EOF + fi + + if [[ "$PROXY_URL" = "" ]]; then + action="" + else + action="proxy_ssl_server_name on; + proxy_pass $PROXY_URL; + proxy_set_header Accept-Encoding ''; + sub_filter \"$REMOTE_HOST\" \"$DOMAIN\"; + sub_filter_once off;" + fi + + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + mkdir -p $NGINX_CONF_PATH + # VMESS+WS+TLS + # VLESS+WS+TLS + if [[ "$WS" = "true" ]]; then + cat > ${NGINX_CONF_PATH}${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${PORT}\$request_uri; +} + +server { + listen ${PORT} ssl http2; + listen [::]:${PORT} ssl http2; + server_name ${DOMAIN}; + charset utf-8; + + # ssl配置 + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + ssl_ecdh_curve secp384r1; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_session_tickets off; + ssl_certificate $CERT_FILE; + ssl_certificate_key $KEY_FILE; + + root /usr/share/nginx/html; + location / { + $action + } + $ROBOT_CONFIG + + location ${WSPATH} { + proxy_redirect off; + proxy_pass http://127.0.0.1:${V2PORT}; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host \$host; + # Show real IP in v2ray access.log + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } +} +EOF + else + # VLESS+TCP+TLS + # VLESS+TCP+XTLS + # trojan + cat > ${NGINX_CONF_PATH}${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + listen 81 http2; + server_name ${DOMAIN}; + root /usr/share/nginx/html; + location / { + $action + } + $ROBOT_CONFIG +} +EOF + fi + fi +} + +setSelinux() { + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +setFirewall() { + res=`which firewall-cmd 2>/dev/null` + if [[ $? -eq 0 ]]; then + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-service=http + firewall-cmd --permanent --add-service=https + if [[ "$PORT" != "443" ]]; then + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp + fi + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + fi + fi + else + res=`which iptables 2>/dev/null` + if [[ $? -eq 0 ]]; then + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + fi + else + res=`which ufw 2>/dev/null` + if [[ $? -eq 0 ]]; then + res=`ufw status | grep -i inactive` + if [[ "$res" = "" ]]; then + ufw allow http/tcp + ufw allow https/tcp + if [[ "$PORT" != "443" ]]; then + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp + fi + fi + fi + fi + fi +} + +installBBR() { + if [[ "$NEED_BBR" != "y" ]]; then + INSTALL_BBR=false + return + fi + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $BLUE " BBR模块已安装" + INSTALL_BBR=false + return + fi + res=`hostnamectl | grep -i openvz` + if [[ "$res" != "" ]]; then + colorEcho $BLUE " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$PMT" = "yum" ]]; then + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + $CMD_INSTALL --enablerepo=elrepo-kernel kernel-ml + $CMD_REMOVE kernel-3.* + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi + else + $CMD_INSTALL --install-recommends linux-generic-hwe-16.04 + grub-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi +} + +installV2ray() { + rm -rf /tmp/v2ray + mkdir -p /tmp/v2ray + DOWNLOAD_LINK="${V6_PROXY}https://github.com/v2fly/v2ray-core/releases/download/${NEW_VER}/v2ray-linux-$(archAffix).zip" + colorEcho $BLUE " 下载V2Ray: ${DOWNLOAD_LINK}" + curl -L -H "Cache-Control: no-cache" -o /tmp/v2ray/v2ray.zip ${DOWNLOAD_LINK} + if [ $? != 0 ];then + colorEcho $RED " 下载V2ray文件失败,请检查服务器网络设置" + exit 1 + fi + mkdir -p '/etc/v2ray' '/var/log/v2ray' && \ + unzip /tmp/v2ray/v2ray.zip -d /tmp/v2ray + mkdir -p /usr/bin/v2ray + cp /tmp/v2ray/v2ctl /usr/bin/v2ray/; cp /tmp/v2ray/v2ray /usr/bin/v2ray/; cp /tmp/v2ray/geo* /usr/bin/v2ray/; + chmod +x '/usr/bin/v2ray/v2ray' '/usr/bin/v2ray/v2ctl' || { + colorEcho $RED " V2ray安装失败" + exit 1 + } + + cat >$SERVICE_FILE<<-EOF +[Unit] +Description=V2ray Service +Documentation=https://hijk.art +After=network.target nss-lookup.target + +[Service] +# If the version of systemd is 240 or above, then uncommenting Type=exec and commenting out Type=simple +#Type=exec +Type=simple +# This service runs as root. You may consider to run it as another user for security concerns. +# By uncommenting User=nobody and commenting out User=root, the service will run as user nobody. +# More discussion at https://github.com/v2ray/v2ray-core/issues/1011 +User=root +#User=nobody +NoNewPrivileges=true +ExecStart=/usr/bin/v2ray/v2ray -config /etc/v2ray/config.json +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable v2ray.service +} + +trojanConfig() { + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "trojan", + "settings": { + "clients": [ + { + "password": "$PASSWORD" + } + ], + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +trojanXTLSConfig() { + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "trojan", + "settings": { + "clients": [ + { + "password": "$PASSWORD", + "flow": "$FLOW" + } + ], + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "xtls", + "xtlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + local alterid=`shuf -i50-80 -n1` + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": $alterid + } + ] + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessKCPConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + local alterid=`shuf -i50-80 -n1` + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": $alterid + } + ] + }, + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "$HEADER_TYPE" + }, + "seed": "$SEED" + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessTLSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": 0 + } + ], + "disableInsecureEncryption": false + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessWSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $V2PORT, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": 0 + } + ], + "disableInsecureEncryption": false + }, + "streamSettings": { + "network": "ws", + "wsSettings": { + "path": "$WSPATH", + "headers": { + "Host": "$DOMAIN" + } + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessTLSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessXTLSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "flow": "$FLOW", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "xtls", + "xtlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessWSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $V2PORT, + "listen": "127.0.0.1", + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 0 + } + ], + "decryption": "none" + }, + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "path": "$WSPATH", + "headers": { + "Host": "$DOMAIN" + } + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessKCPConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 0 + } + ], + "decryption": "none" + }, + "streamSettings": { + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "$HEADER_TYPE" + }, + "seed": "$SEED" + } + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +configV2ray() { + mkdir -p /etc/v2ray + if [[ "$TROJAN" = "true" ]]; then + if [[ "$XTLS" = "true" ]]; then + trojanXTLSConfig + else + trojanConfig + fi + return 0 + fi + if [[ "$VLESS" = "false" ]]; then + # VMESS + kcp + if [[ "$KCP" = "true" ]]; then + vmessKCPConfig + return 0 + fi + # VMESS + if [[ "$TLS" = "false" ]]; then + vmessConfig + elif [[ "$WS" = "false" ]]; then + # VMESS+TCP+TLS + vmessTLSConfig + # VMESS+WS+TLS + else + vmessWSConfig + fi + #VLESS + else + if [[ "$KCP" = "true" ]]; then + vlessKCPConfig + return 0 + fi + # VLESS+TCP + if [[ "$WS" = "false" ]]; then + # VLESS+TCP+TLS + if [[ "$XTLS" = "false" ]]; then + vlessTLSConfig + # VLESS+TCP+XTLS + else + vlessXTLSConfig + fi + # VLESS+WS+TLS + else + vlessWSConfig + fi + fi +} + +install() { + getData + + $PMT clean all + [[ "$PMT" = "apt" ]] && $PMT update + #echo $CMD_UPGRADE | bash + $CMD_INSTALL wget vim unzip tar gcc openssl + $CMD_INSTALL net-tools + if [[ "$PMT" = "apt" ]]; then + $CMD_INSTALL libssl-dev g++ + fi + res=`which unzip 2>/dev/null` + if [[ $? -ne 0 ]]; then + colorEcho $RED " unzip安装失败,请检查网络" + exit 1 + fi + + installNginx + setFirewall + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + getCert + fi + configNginx + + colorEcho $BLUE " 安装V2ray..." + getVersion + RETVAL="$?" + if [[ $RETVAL == 0 ]]; then + colorEcho $BLUE " V2ray最新版 ${CUR_VER} 已经安装" + elif [[ $RETVAL == 3 ]]; then + exit 1 + else + colorEcho $BLUE " 安装V2Ray ${NEW_VER} ,架构$(archAffix)" + installV2ray + fi + + configV2ray + + setSelinux + installBBR + + start + showInfo + + bbrReboot +} + +bbrReboot() { + if [[ "${INSTALL_BBR}" == "true" ]]; then + echo + echo " 为使BBR模块生效,系统将在30秒后重启" + echo + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" + sleep 30 + reboot + fi +} + +update() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " V2ray未安装,请先安装!" + return + fi + + getVersion + RETVAL="$?" + if [[ $RETVAL == 0 ]]; then + colorEcho $BLUE " V2ray最新版 ${CUR_VER} 已经安装" + elif [[ $RETVAL == 3 ]]; then + exit 1 + else + colorEcho $BLUE " 安装V2Ray ${NEW_VER} ,架构$(archAffix)" + installV2ray + stop + start + + colorEcho $GREEN " 最新版V2ray安装成功!" + fi +} + +uninstall() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " V2ray未安装,请先安装!" + return + fi + + echo "" + read -p " 确定卸载V2ray?[y/n]:" answer + if [[ "${answer,,}" = "y" ]]; then + domain=`grep Host $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" = "" ]]; then + domain=`grep serverName $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + + stop + systemctl disable v2ray + rm -rf $SERVICE_FILE + rm -rf /etc/v2ray + rm -rf /usr/bin/v2ray + + if [[ "$BT" = "false" ]]; then + systemctl disable nginx + $CMD_REMOVE nginx + if [[ "$PMT" = "apt" ]]; then + $CMD_REMOVE nginx-common + fi + rm -rf /etc/nginx/nginx.conf + if [[ -f /etc/nginx/nginx.conf.bak ]]; then + mv /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf + fi + fi + if [[ "$domain" != "" ]]; then + rm -rf $NGINX_CONF_PATH${domain}.conf + fi + [[ -f ~/.acme.sh/acme.sh ]] && ~/.acme.sh/acme.sh --uninstall + colorEcho $GREEN " V2ray卸载成功" + fi +} + +start() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " V2ray未安装,请先安装!" + return + fi + stopNginx + startNginx + systemctl restart v2ray + sleep 2 + port=`grep port $CONFIG_FILE| head -n 1| cut -d: -f2| tr -d \",' '` + res=`ss -nutlp| grep ${port} | grep -i v2ray` + if [[ "$res" = "" ]]; then + colorEcho $RED " v2ray启动失败,请检查日志或查看端口是否被占用!" + else + colorEcho $BLUE " v2ray启动成功" + fi +} + +stop() { + stopNginx + systemctl stop v2ray + colorEcho $BLUE " V2ray停止成功" +} + + +restart() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " V2ray未安装,请先安装!" + return + fi + + stop + start +} + +getConfigFileInfo() { + vless="false" + tls="false" + ws="false" + xtls="false" + trojan="false" + protocol="VMess" + kcp="false" + + uid=`grep id $CONFIG_FILE | head -n1| cut -d: -f2 | tr -d \",' '` + alterid=`grep alterId $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + network=`grep network $CONFIG_FILE | tail -n1| cut -d: -f2 | tr -d \",' '` + [[ -z "$network" ]] && network="tcp" + domain=`grep serverName $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" = "" ]]; then + domain=`grep Host $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" != "" ]]; then + ws="true" + tls="true" + wspath=`grep path $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + else + tls="true" + fi + if [[ "$ws" = "true" ]]; then + port=`grep -i ssl $NGINX_CONF_PATH${domain}.conf| head -n1 | awk '{print $2}'` + else + port=`grep port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + res=`grep -i kcp $CONFIG_FILE` + if [[ "$res" != "" ]]; then + kcp="true" + type=`grep header -A 3 $CONFIG_FILE | grep 'type' | cut -d: -f2 | tr -d \",' '` + seed=`grep seed $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + + vmess=`grep vmess $CONFIG_FILE` + if [[ "$vmess" = "" ]]; then + trojan=`grep trojan $CONFIG_FILE` + if [[ "$trojan" = "" ]]; then + vless="true" + protocol="VLESS" + else + trojan="true" + password=`grep password $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + protocol="trojan" + fi + tls="true" + encryption="none" + xtls=`grep xtlsSettings $CONFIG_FILE` + if [[ "$xtls" != "" ]]; then + xtls="true" + flow=`grep flow $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + else + flow="无" + fi + fi +} + +outputVmess() { + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"tcp\", + \"type\":\"none\", + \"host\":\"\", + \"path\":\"\", + \"tls\":\"\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}auto${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo + echo -e " ${BLUE}vmess链接:${PLAIN} $RED$link$PLAIN" +} + +outputVmessKCP() { + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}auto${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN} ${RED}${type}${PLAIN}" + echo -e " ${BLUE}mkcp seed:${PLAIN} ${RED}${seed}${PLAIN}" +} + +outputTrojan() { + if [[ "$xtls" = "true" ]]; then + echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${domain}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}XTLS${PLAIN}" + else + echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${domain}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + fi +} + +outputVmessTLS() { + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"${network}\", + \"type\":\"none\", + \"host\":\"${domain}\", + \"path\":\"\", + \"tls\":\"tls\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + echo + echo -e " ${BLUE}vmess链接: ${PLAIN}$RED$link$PLAIN" +} + +outputVmessWS() { + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"${network}\", + \"type\":\"none\", + \"host\":\"${domain}\", + \"path\":\"${wspath}\", + \"tls\":\"tls\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}路径(path):${PLAIN}${RED}${wspath}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + echo + echo -e " ${BLUE}vmess链接:${PLAIN} $RED$link$PLAIN" +} + +showInfo() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " V2ray未安装,请先安装!" + return + fi + + echo "" + echo -n -e " ${BLUE}V2ray运行状态:${PLAIN}" + statusText + echo -e " ${BLUE}V2ray配置文件: ${PLAIN} ${RED}${CONFIG_FILE}${PLAIN}" + colorEcho $BLUE " V2ray配置信息:" + + getConfigFileInfo + + echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}" + if [[ "$trojan" = "true" ]]; then + outputTrojan + return 0 + fi + if [[ "$vless" = "false" ]]; then + if [[ "$kcp" = "true" ]]; then + outputVmessKCP + return 0 + fi + if [[ "$tls" = "false" ]]; then + outputVmess + elif [[ "$ws" = "false" ]]; then + outputVmessTLS + else + outputVmessWS + fi + else + if [[ "$kcp" = "true" ]]; then + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN} ${RED}${type}${PLAIN}" + echo -e " ${BLUE}mkcp seed:${PLAIN} ${RED}${seed}${PLAIN}" + return 0 + fi + if [[ "$xtls" = "true" ]]; then + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}XTLS${PLAIN}" + elif [[ "$ws" = "false" ]]; then + echo -e " ${BLUE}IP(address): ${PLAIN}${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + else + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}路径(path):${PLAIN}${RED}${wspath}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + fi + fi +} + +showLog() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " V2ray未安装,请先安装!" + return + fi + + journalctl -xen -u v2ray --no-pager +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}v2ray一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + + echo -e " ${GREEN}1.${PLAIN} 安装V2ray-VMESS" + echo -e " ${GREEN}2.${PLAIN} 安装V2ray-${BLUE}VMESS+mKCP${PLAIN}" + echo -e " ${GREEN}3.${PLAIN} 安装V2ray-VMESS+TCP+TLS" + echo -e " ${GREEN}4.${PLAIN} 安装V2ray-${BLUE}VMESS+WS+TLS${PLAIN}${RED}(推荐)${PLAIN}" + echo -e " ${GREEN}5.${PLAIN} 安装V2ray-${BLUE}VLESS+mKCP${PLAIN}" + echo -e " ${GREEN}6.${PLAIN} 安装V2ray-VLESS+TCP+TLS" + echo -e " ${GREEN}7.${PLAIN} 安装V2ray-${BLUE}VLESS+WS+TLS${PLAIN}${RED}(可过cdn)${PLAIN}" + echo -e " ${GREEN}8.${PLAIN} 安装V2ray-${BLUE}VLESS+TCP+XTLS${PLAIN}${RED}(推荐)${PLAIN}" + echo -e " ${GREEN}9.${PLAIN} 安装${BLUE}trojan${PLAIN}${RED}(推荐)${PLAIN}" + echo -e " ${GREEN}10.${PLAIN} 安装${BLUE}trojan+XTLS${PLAIN}${RED}(推荐)${PLAIN}" + echo " -------------" + echo -e " ${GREEN}11.${PLAIN} 更新V2ray" + echo -e " ${GREEN}12. ${RED}卸载V2ray${PLAIN}" + echo " -------------" + echo -e " ${GREEN}13.${PLAIN} 启动V2ray" + echo -e " ${GREEN}14.${PLAIN} 重启V2ray" + echo -e " ${GREEN}15.${PLAIN} 停止V2ray" + echo " -------------" + echo -e " ${GREEN}16.${PLAIN} 查看V2ray配置" + echo -e " ${GREEN}17.${PLAIN} 查看V2ray日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-17]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + KCP="true" + install + ;; + 3) + TLS="true" + install + ;; + 4) + TLS="true" + WS="true" + install + ;; + 5) + VLESS="true" + KCP="true" + install + ;; + 6) + VLESS="true" + TLS="true" + install + ;; + 7) + VLESS="true" + TLS="true" + WS="true" + install + ;; + 8) + VLESS="true" + TLS="true" + XTLS="true" + install + ;; + 9) + TROJAN="true" + TLS="true" + install + ;; + 10) + TROJAN="true" + TLS="true" + XTLS="true" + install + ;; + 11) + update + ;; + 12) + uninstall + ;; + 13) + start + ;; + 14) + restart + ;; + 15) + stop + ;; + 16) + showInfo + ;; + 17) + showLog + ;; + *) + colorEcho $RED " 请选择正确的操作!" + exit 1 + ;; + esac +} + +checkSystem + +action=$1 +[[ -z $1 ]] && action=menu +case "$action" in + menu|update|uninstall|start|restart|stop|showInfo|showLog) + ${action} + ;; + *) + echo " 参数错误" + echo " 用法: `basename $0` [menu|update|uninstall|start|restart|stop|showInfo|showLog]" + ;; +esac diff --git a/wordpress.sh b/wordpress.sh new file mode 100644 index 00000000..4ae700e1 --- /dev/null +++ b/wordpress.sh @@ -0,0 +1,585 @@ +#!/bin/bash +# v2ray/xray WordPress一键安装脚本 +# Author: hijk + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +V2_CONFIG_FILE="/etc/v2ray/config.json" +X_CONFIG_FILE="/usr/local/etc/xray/config.json" + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" +res=$(command -v bt) +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +VMESS="true" +WS="false" +TLS="false" + +checkSystem() { + uid=$(id -u) + if [[ $uid -ne 0 ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=$(command -v yum) + if [[ "$res" = "" ]]; then + res=$(command -v apt) + if [[ "$res" = "" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + PHP_SERVICE="php7.4-fpm" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + PHP_SERVICE="php-fpm" + result=`grep -oE "[0-9.]+" /etc/centos-release` + MAIN=${result%%.*} + fi + res=$(command -v systemctl) + if [[ "$res" = "" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +configNeedNginx() { + local ws=`grep wsSettings $V2_CONFIG_FILE` + if [[ -z "$ws" ]]; then + echo no + return + fi + echo yes +} + +checkV2() { + if [[ ! -f $V2_CONFIG_FILE ]]; then + if [[ ! -f $X_CONFIG_FILE ]]; then + colorEcho $RED " 未安装V2ray/Xray" + exit 1 + fi + SERVICE=xray + V2_CONFIG_FILE=$X_CONFIG_FILE + else + SERVICE=v2ray + fi + + res=`grep -i trojan $V2_CONFIG_FILE` + [[ "$res" != "" ]] && { + res=`grep -i fallbacks $V2_CONFIG_FILE` + [[ "$res" != "" ]] || { + colorEcho $RED " 检测到旧版trojan配置文件,请使用最新版一键脚本安装trojan后再运行此脚本" + exit 1 + } + } + + res=`grep vmess $V2_CONFIG_FILE` + [[ "$res" != "" ]] || { + VMESS="false" + V2PORT=`grep port $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + } + + res=`grep -i wsSettings $V2_CONFIG_FILE` + [[ "$res" != "" ]] && { + WS="true" + TLS="true" + DOMAIN=`grep Host $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + [[ "$1" = "install" ]] && colorEcho $BLUE " 伪装域名:$DOMAIN" + NGINX_CONFIG_FILE="$NGINX_CONF_PATH${DOMAIN}.conf" + [[ -f $NGINX_CONFIG_FILE ]] || { + colorEcho $RED " 未找到域名的nginx配置文件" + exit 1 + } + V2PORT=`grep port $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + WSPATH=`grep path $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + NGINX_PORT=`grep -i ssl $NGINX_CONFIG_FILE | grep listen | head -n1 | awk '{print $2}'` + [[ "$1" = "install" ]] && colorEcho $BLUE " Nginx端口:$NGINX_PORT" + CERT_FILE=`grep ssl_certificate $NGINX_CONFIG_FILE | grep -v _key` + KEY_FILE=`grep ssl_certificate_key $NGINX_CONFIG_FILE` + } + + res=`grep -i tlsSettings $V2_CONFIG_FILE` + [[ "$res" != "" ]] && { + TLS="true" + PORT=`grep port $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + DOMAIN=`grep serverName $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + [[ "$DOMAIN" = "" ]] && DOMAIN=`grep Host $V2_CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + [[ "$1" = "install" ]] && colorEcho $BLUE " 伪装域名:$DOMAIN" + [[ "$1" = "install" ]] && colorEcho $BLUE " V2ray/Xray监听端口:$PORT" + NGINX_CONFIG_FILE="$NGINX_CONF_PATH${DOMAIN}.conf" + } + + if [[ "$TLS" = "false" ]]; then + case "$1" in + install) + colorEcho $RED " 您未使用伪装域名安装V2ray/Xray" + read -p " 请输入您的域名:" DOMAIN + [[ -z "$DOMAIN" ]] && DOMAIN=$(curl -sL ip.sb) + ;; + info) + if [[ -z ${DBNAME+x} ]]; then + colorEcho $RED " 您未使用伪装域名安装V2ray/Xray,无法检测配置,请到 /var/www 目录下自行查看配置信息" + exit 1 + fi + ;; + uninstall) + colorEcho $RED " 您未使用伪装域名安装V2ray/Xray,无法检测配置,请到 /var/www 目录下自行删除网站文件" + colorEcho $GREEN " 卸载成功!" + exit 1 + ;; + *) + esac + fi +} + +statusText() { + res=$(command -v nginx) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}Nginx未安装${PLAIN} + else + res=`ps aux | grep nginx | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}Nginx未运行${PLAIN} || echo -e -n ${GREEN}Nginx正在运行${PLAIN} + fi + echo -n ", " + res=$(command -v php) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}PHP未安装${PLAIN} + else + res=`ps aux | grep php | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}PHP未运行${PLAIN} || echo -e -n ${GREEN}PHP正在运行${PLAIN} + fi + echo -n ", " + res=$(command -v mysql) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}Mysql未安装${PLAIN} + else + res=`ps aux | grep mysql | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}Mysql未运行${PLAIN} || echo -e -n ${GREEN}Mysql正在运行${PLAIN} + fi +} + +installPHP() { + [[ "$PMT" = "apt" ]] && $PMT update + $CMD_INSTALL curl wget ca-certificates + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ $MAIN -eq 7 ]]; then + rpm -iUh https://rpms.remirepo.net/enterprise/remi-release-7.rpm + sed -i '0,/enabled=0/{s/enabled=0/enabled=1/}' /etc/yum.repos.d/remi-php74.repo + else + dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm + sed -i '0,/enabled=0/{s/enabled=0/enabled=1/}' /etc/yum.repos.d/remi.repo + dnf module install -y php:remi-7.4 + fi + $CMD_INSTALL php-cli php-fpm php-bcmath php-gd php-mbstring php-mysqlnd php-pdo php-opcache php-xml php-pecl-zip php-pecl-imagick + else + $CMD_INSTALL lsb-release gnupg2 + wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add - + echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php7.list + $PMT update + $CMD_INSTALL php7.4-cli php7.4-fpm php7.4-bcmath php7.4-gd php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-xml php7.4-zip php7.4-json php7.4-imagick + update-alternatives --set php /usr/bin/php7.4 + fi + systemctl enable $PHP_SERVICE +} + +installMysql() { + if [[ "$PMT" = "yum" ]]; then + yum remove -y MariaDB-server + if [ ! -f /etc/yum.repos.d/mariadb.repo ]; then + if [ $MAIN -eq 7 ]; then + echo '# MariaDB 10.5 CentOS repository list - created 2019-11-23 15:00 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.5/centos7-amd64 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1' >> /etc/yum.repos.d/mariadb.repo + else + echo '# MariaDB 10.5 CentOS repository list - created 2020-03-11 16:29 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.5/centos8-amd64 +module_hotfixes=1 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1' >> /etc/yum.repos.d/mariadb.repo + fi + fi + yum install -y MariaDB-server + else + $PMT update + $CMD_INSTALL mariadb-server + fi + systemctl enable mariadb.service +} + +installWordPress() { + mkdir -p /var/www + wget https://cn.wordpress.org/latest-zh_CN.tar.gz + if [[ ! -f latest-zh_CN.tar.gz ]]; then + colorEcho $RED " 下载WordPress失败,请稍后重试" + exit 1 + fi + tar -zxf latest-zh_CN.tar.gz + rm -rf /var/www/$DOMAIN + mv wordpress /var/www/$DOMAIN + rm -rf latest-zh_CN.tar.gz +} + +config() { + # config mariadb + systemctl start mariadb + DBNAME="wordpress" + DBUSER="wordpress" + DBPASS=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + mysql -uroot <~\`+=,.;:/?|"; + sub salt { join "", map $chars[ rand @chars ], 1 .. 64 } + } + s/put your unique phrase here/salt()/ge +' wp-config.php + if [[ "$PMT" = "yum" ]]; then + user="apache" + # config nginx + [[ $MAIN -eq 7 ]] && upstream="127.0.0.1:9000" || upstream="php-fpm" + else + user="www-data" + upstream="unix:/run/php/php7.4-fpm.sock" + fi + chown -R $user:$user /var/www/${DOMAIN} + + configNginx +} + +configNginx() { + if [[ "$WS" = "true" ]]; then + cat > $NGINX_CONFIG_FILE<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${NGINX_PORT}\$request_uri; +} + +server { + listen ${NGINX_PORT} ssl http2; + server_name ${DOMAIN}; + charset utf-8; + + # ssl配置 + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + ssl_ecdh_curve secp384r1; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_session_tickets off; + $CERT_FILE + $KEY_FILE + + set \$host_path "/var/www/${DOMAIN}"; + access_log /var/log/nginx/${DOMAIN}.access.log main buffer=32k flush=30s; + error_log /var/log/nginx/${DOMAIN}.error.log; + root \$host_path; + location / { + index index.php; + try_files \$uri \$uri/ /index.php?\$args; + } + location ~ \.php\$ { + try_files \$uri =404; + fastcgi_index index.php; + fastcgi_pass $upstream; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + } + + location ${WSPATH} { + proxy_redirect off; + proxy_pass http://127.0.0.1:${V2PORT}; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + + location ~ \.(js|css|png|jpg|jpeg|gif|ico|swf|webp|pdf|txt|doc|docx|xls|xlsx|ppt|pptx|mov|fla|zip|rar)\$ { + expires max; + access_log off; + try_files \$uri =404; + } +} +EOF + return 0 + fi + + if [[ "$TLS" = "false" ]] || [[ "$TLS" = "true" && "$VMESS" = "true" ]]; then + cat > $NGINX_CONFIG_FILE<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + + charset utf-8; + + set \$host_path "/var/www/${DOMAIN}"; + access_log /var/log/nginx/${DOMAIN}.access.log main buffer=32k flush=30s; + error_log /var/log/nginx/${DOMAIN}.error.log; + root \$host_path; + location / { + index index.php; + try_files \$uri \$uri/ /index.php?\$args; + } + location ~ \.php\$ { + try_files \$uri =404; + fastcgi_index index.php; + fastcgi_pass $upstream; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + } + + location ~ \.(js|css|png|jpg|jpeg|gif|ico|swf|webp|pdf|txt|doc|docx|xls|xlsx|ppt|pptx|mov|fla|zip|rar)\$ { + expires max; + access_log off; + try_files \$uri =404; + } +} +EOF + return 0 + fi + + res=`grep -E 'dest.*8080' $V2_CONFIG_FILE` + [[ "$res" = "" ]] && sed -i 's/"dest": 80/"dest": 8080/' $V2_CONFIG_FILE + # VLESS + cat > $NGINX_CONFIG_FILE<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${PORT}\$request_uri; +} + +server { + listen 8080; + listen 81 http2; + server_name ${DOMAIN}; + charset utf-8; + + set \$host_path "/var/www/${DOMAIN}"; + access_log /var/log/nginx/${DOMAIN}.access.log main buffer=32k flush=30s; + error_log /var/log/nginx/${DOMAIN}.error.log; + root \$host_path; + location / { + index index.php; + try_files \$uri \$uri/ /index.php?\$args; + } + location ~ \.php\$ { + try_files \$uri =404; + fastcgi_index index.php; + fastcgi_pass $upstream; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + fastcgi_param SERVER_PORT ${PORT}; + fastcgi_param HTTPS "on"; + } + + location ~ \.(js|css|png|jpg|jpeg|gif|ico|swf|webp|pdf|txt|doc|docx|xls|xlsx|ppt|pptx|mov|fla|zip|rar)\$ { + expires max; + access_log off; + try_files \$uri =404; + } +} +EOF +} + +install() { + checkV2 "install" + installPHP + installMysql + installWordPress + colorEcho $BLUE " WordPress安装成功!" + + config + # restart service + systemctl restart $PHP_SERVICE mariadb nginx $SERVICE + sleep 2 + statusText + echo "" + + showInfo +} + +uninstall() { + echo "" + colorEcho $RED " 该操作会删除所有WordPress文件,清空数据库!" + read -p " 确认卸载WordPress?[y/n]" answer + [[ "$answer" != "y" && "$answer" != "Y" ]] && exit 0 + + systemctl stop mariadb + systemctl disable mariadb + if [[ "$PMT" = "yum" ]]; then + $CMD_REMOVE MariaDB-server + else + $CMD_REMOVE mariadb-* + fi + rm -rf /var/lib/mysql + + systemctl stop $PHP_SERVICE + systemctl disable $PHP_SERVICE + + checkV2 "uninstall" + [[ "$DOMAIN" != "" ]] && rm -rf /var/www/${DOMAIN} + + colorEcho $GREEN " 卸载成功!" +} + +showInfo() { + checkV2 "info" + + # VMESS/VLESS+WS+TLS + if [[ "$WS" = "true" ]]; then + if [[ "$NGINX_PORT" = "443" ]]; then + url="https://$DOMAIN" + else + url="https://$DOMAIN:$PORT" + fi + # pure VMESS/VLESS [+kcp] + elif [[ "$TLS" = "false" ]]; then + url="http://$DOMAIN" + else + # VMESS+TCP+TLS + if [[ "$VMESS" = "true" ]]; then + url="http://$DOMAIN" + else + # trojan/VLESS+TLS + if [[ "$V2PORT" = "443" ]]; then + url="https://$DOMAIN" + else + url="https://$DOMAIN:$V2PORT" + fi + fi + fi + + if [[ -z ${DBNAME+x} ]]; then + wpconfig="/var/www/${DOMAIN}/wp-config.php" + DBUSER=`grep DB_USER $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + DBNAME=`grep DB_NAME $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + DBPASS=`grep DB_PASSWORD $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + fi + colorEcho $BLUE " WordPress配置信息:" + echo "===============================" + echo -e " ${BLUE}WordPress安装路径:${PLAIN}${RED}/var/www/${DOMAIN}${PLAIN}" + echo -e " ${BLUE}WordPress数据库:${PLAIN}${RED}${DBNAME}${PLAIN}" + echo -e " ${BLUE}WordPress数据库用户名:${PLAIN}${RED}${DBUSER}${PLAIN}" + echo -e " ${BLUE}WordPress数据库密码:${PLAIN}${RED}${DBPASS}${PLAIN}" + echo -e " ${BLUE}WordPress网址:${PLAIN}${RED}$url${PLAIN}" + echo "===============================" +} + +help() { + echo "" + colorEcho $BLUE " Nginx操作:" + colorEcho $GREEN " 启动: systemctl start nginx" + colorEcho $GREEN " 停止:systemctl stop nginx" + colorEcho $GREEN " 重启:systemctl restart nginx" + echo " -------------" + colorEcho $BLUE " PHP操作:" + colorEcho $GREEN " 启动: systemctl start $PHP_SERVICE" + colorEcho $GREEN " 停止:systemctl stop $PHP_SERVICE" + colorEcho $GREEN " 重启:systemctl restart $PHP_SERVICE" + echo " -------------" + colorEcho $BLUE " Mysql操作:" + colorEcho $GREEN " 启动: systemctl start mariadb" + colorEcho $GREEN " 停止:systemctl stop mariadb" + colorEcho $GREEN " 重启:systemctl restart mariadb" +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}WordPress一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo + colorEcho $YELLOW " 该脚本仅适用于 https://hijk.art 网站上的V2ray/Xray一键脚本安装wordpress用!" + echo + echo -e " ${GREEN}1.${PLAIN} 安装WordPress" + echo -e " ${GREEN}2.${PLAIN} 卸载WordPress" + echo -e " ${GREEN}3.${PLAIN} 查看WordPress配置" + echo -e " ${GREEN}4.${PLAIN} 查看操作帮助" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo -n " 当前状态:" + statusText + echo + + echo "" + read -p " 请选择操作[0-17]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + uninstall + ;; + 3) + showInfo + ;; + 4) + help + ;; + *) + colorEcho $RED " 请选择正确的操作!" + exit 1 + ;; + esac +} + +checkSystem + +menu diff --git a/wordpress_trojan-go.sh b/wordpress_trojan-go.sh new file mode 100644 index 00000000..76492533 --- /dev/null +++ b/wordpress_trojan-go.sh @@ -0,0 +1,396 @@ +#!/bin/bash +# trojan-go WordPress一键安装脚本 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +CONFIG_FILE="/etc/trojan-go/config.json" + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" +res=$(command -v bt) +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { + uid=$(id -u) + if [[ $uid -ne 0 ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=$(command -v yum) + if [[ "$res" = "" ]]; then + res=$(command -v apt) + if [[ "$res" = "" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + PHP_SERVICE="php7.4-fpm" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + PHP_SERVICE="php-fpm" + result=`grep -oE "[0-9.]+" /etc/centos-release` + MAIN=${result%%.*} + fi + res=$(command -v systemctl) + if [[ "$res" = "" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +checkTrojan() { + if [[ ! -f ${CONFIG_FILE} ]]; then + colorEcho $RED " 未安装trojan-go" + exit 1 + fi + DOMAIN=`grep sni $CONFIG_FILE | cut -d\" -f4` + NGINX_CONFIG_FILE="$NGINX_CONF_PATH${DOMAIN}.conf" + if [[ ! -f $NGINX_CONFIG_FILE ]]; then + colorEcho $RED " 未找到域名的nginx配置文件" + exit 1 + fi + PORT=`grep local_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + [[ "$1" = "install" ]] && colorEcho $BLUE " 伪装域名:$DOMAIN" + [[ "$1" = "install" ]] && colorEcho $BLUE " trojan-go监听端口:$PORT" +} + +statusText() { + res=$(command -v nginx) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}Nginx未安装${PLAIN} + else + res=`ps aux | grep nginx | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}Nginx未运行${PLAIN} || echo -e -n ${GREEN}Nginx正在运行${PLAIN} + fi + echo -n ", " + res=$(command -v php) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}PHP未安装${PLAIN} + else + res=`ps aux | grep php | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}PHP未运行${PLAIN} || echo -e -n ${GREEN}PHP正在运行${PLAIN} + fi + echo -n ", " + res=$(command -v mysql) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}Mysql未安装${PLAIN} + else + res=`ps aux | grep mysql | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}Mysql未运行${PLAIN} || echo -e -n ${GREEN}Mysql正在运行${PLAIN} + fi +} + +installPHP() { + [[ "$PMT" = "apt" ]] && $PMT update + $CMD_INSTALL curl wget ca-certificates + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ $MAIN -eq 7 ]]; then + rpm -iUh https://rpms.remirepo.net/enterprise/remi-release-7.rpm + sed -i '0,/enabled=0/{s/enabled=0/enabled=1/}' /etc/yum.repos.d/remi-php74.repo + else + dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm + sed -i '0,/enabled=0/{s/enabled=0/enabled=1/}' /etc/yum.repos.d/remi.repo + dnf module install -y php:remi-7.4 + fi + $CMD_INSTALL php-cli php-fpm php-bcmath php-gd php-mbstring php-mysqlnd php-pdo php-opcache php-xml php-pecl-zip php-pecl-imagick + else + $CMD_INSTALL lsb-release gnupg2 + wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add - + echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php7.list + $PMT update + $CMD_INSTALL php7.4-cli php7.4-fpm php7.4-bcmath php7.4-gd php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-xml php7.4-zip php7.4-json php7.4-imagick + update-alternatives --set php /usr/bin/php7.4 + fi + systemctl enable $PHP_SERVICE +} + +installMysql() { + if [[ "$PMT" = "yum" ]]; then + yum remove -y MariaDB-server + if [ ! -f /etc/yum.repos.d/mariadb.repo ]; then + if [ $MAIN -eq 7 ]; then + echo '# MariaDB 10.5 CentOS repository list - created 2019-11-23 15:00 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.5/centos7-amd64 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1' >> /etc/yum.repos.d/mariadb.repo + else + echo '# MariaDB 10.5 CentOS repository list - created 2020-03-11 16:29 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.5/centos8-amd64 +module_hotfixes=1 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1' >> /etc/yum.repos.d/mariadb.repo + fi + fi + yum install -y MariaDB-server + else + $PMT update + $CMD_INSTALL mariadb-server + fi + systemctl enable mariadb.service +} + +installWordPress() { + mkdir -p /var/www + wget https://cn.wordpress.org/latest-zh_CN.tar.gz + if [[ ! -f latest-zh_CN.tar.gz ]]; then + colorEcho $RED " 下载WordPress失败,请稍后重试" + exit 1 + fi + tar -zxf latest-zh_CN.tar.gz + rm -rf /var/www/$DOMAIN + mv wordpress /var/www/$DOMAIN + rm -rf latest-zh_CN.tar.gz +} + +config() { + # config mariadb + systemctl start mariadb + DBNAME="wordpress" + DBUSER="wordpress" + DBPASS=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + mysql -uroot <~\`+=,.;:/?|"; + sub salt { join "", map $chars[ rand @chars ], 1 .. 64 } + } + s/put your unique phrase here/salt()/ge +' wp-config.php + + if [[ "$PMT" = "yum" ]]; then + user="apache" + # config nginx + [[ $MAIN -eq 7 ]] && upstream="127.0.0.1:9000" || upstream="php-fpm" + else + user="www-data" + upstream="unix:/run/php/php7.4-fpm.sock" + fi + chown -R $user:$user /var/www/${DOMAIN} + + # config nginx + cat > $NGINX_CONFIG_FILE<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${PORT}\$request_uri; +} +server { + listen 8080; + server_name ${DOMAIN}; + + charset utf-8; + + set \$host_path "/var/www/${DOMAIN}"; + access_log /var/log/nginx/${DOMAIN}.access.log main buffer=32k flush=30s; + error_log /var/log/nginx/${DOMAIN}.error.log; + root \$host_path; + location / { + index index.php index.html; + try_files \$uri \$uri/ /index.php?\$args; + } + location ~ \.php\$ { + try_files \$uri =404; + fastcgi_index index.php; + fastcgi_pass $upstream; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + fastcgi_param SERVER_PORT ${PORT}; + fastcgi_param HTTPS "on"; + } + location ~ \.(js|css|png|jpg|jpeg|gif|ico|swf|webp|pdf|txt|doc|docx|xls|xlsx|ppt|pptx|mov|fla|zip|rar)\$ { + expires max; + access_log off; + try_files \$uri =404; + } +} +EOF + + # config trojan-go + sed -i -e "s/remote_addr\":\s*\".*\",/remote_addr\": \"127.0.0.1\",/" $CONFIG_FILE + sed -i -e "s/remote_port\":\s*[0-9]*/remote_port\": 8080/" $CONFIG_FILE + sed -i -e "s/fallback_addr\":\s*\".*\",/fallback_addr\": \"127.0.0.1\",/" $CONFIG_FILE + sed -i -e "s/fallback_port\":\s*[0-9]*/fallback_port\": 8080/" $CONFIG_FILE + + # restart service + systemctl restart $PHP_SERVICE mariadb nginx trojan-go +} + +install() { + checkTrojan "install" + installPHP + installMysql + installWordPress + colorEcho $BLUE " WordPress安装成功!" + + config + # restart service + systemctl restart $PHP_SERVICE mariadb nginx + + sleep 2 + statusText + echo "" + + showInfo +} + +uninstall() { + echo "" + colorEcho $RED " 该操作会删除所有WordPress文件,清空数据库!" + read -p " 确认卸载WordPress?[y/n]" answer + [[ "$answer" != "y" && "$answer" != "Y" ]] && exit 0 + + checkTrojan + systemctl stop mariadb + systemctl disable mariadb + if [[ "$PMT" = "yum" ]]; then + $CMD_REMOVE MariaDB-server + else + apt-get purge -y mariadb-* + fi + rm -rf /var/lib/mysql + + systemctl stop $PHP_SERVICE + systemctl disable $PHP_SERVICE + + rm -rf /var/www/${DOMAIN} + + colorEcho $GREEN " 卸载成功!" +} + +showInfo() { + checkTrojan + + if [[ -z ${DBNAME+x} ]]; then + wpconfig="/var/www/${DOMAIN}/wp-config.php" + DBUSER=`grep DB_USER $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + DBNAME=`grep DB_NAME $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + DBPASS=`grep DB_PASSWORD $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + fi + if [[ "$PORT" = "443" ]]; then + url="https://$DOMAIN" + else + url="https://$DOMAIN:$PORT" + fi + colorEcho $BLUE " WordPress配置信息:" + echo "===============================" + echo -e " ${BLUE}WordPress安装路径:${PLAIN}${RED}/var/www/${DOMAIN}${PLAIN}" + echo -e " ${BLUE}WordPress数据库:${PLAIN}${RED}${DBNAME}${PLAIN}" + echo -e " ${BLUE}WordPress数据库用户名:${PLAIN}${RED}${DBUSER}${PLAIN}" + echo -e " ${BLUE}WordPress数据库密码:${PLAIN}${RED}${DBPASS}${PLAIN}" + echo -e " ${BLUE}WordPress网址:${PLAIN}${RED}$url${PLAIN}" + echo "===============================" +} + +help() { + echo "" + colorEcho $BLUE " Nginx操作:" + colorEcho $GREEN " 启动: systemctl start nginx" + colorEcho $GREEN " 停止:systemctl stop nginx" + colorEcho $GREEN " 重启:systemctl restart nginx" + echo " -------------" + colorEcho $BLUE " PHP操作:" + colorEcho $GREEN " 启动: systemctl start $PHP_SERVICE" + colorEcho $GREEN " 停止:systemctl stop $PHP_SERVICE" + colorEcho $GREEN " 重启:systemctl restart $PHP_SERVICE" + echo " -------------" + colorEcho $BLUE " Mysql操作:" + colorEcho $GREEN " 启动: systemctl start mariadb" + colorEcho $GREEN " 停止:systemctl stop mariadb" + colorEcho $GREEN " 重启:systemctl restart mariadb" +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}WordPress一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo + colorEcho $YELLOW " 该脚本仅适用于 https://hijk.art 网站上的trojan-go一键脚本安装wordpress用!" + echo + echo -e " ${GREEN}1.${PLAIN} 安装WordPress" + echo -e " ${GREEN}2.${PLAIN} 卸载WordPress" + echo -e " ${GREEN}3.${PLAIN} 查看WordPress配置" + echo -e " ${GREEN}4.${PLAIN} 查看操作帮助" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo -n " 当前状态:" + statusText + echo + + echo "" + read -p " 请选择操作[0-17]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + uninstall + ;; + 3) + showInfo + ;; + 4) + help + ;; + *) + colorEcho $RED " 请选择正确的操作!" + exit 1 + ;; + esac +} + +checkSystem + +menu diff --git a/wordpress_trojan.sh b/wordpress_trojan.sh new file mode 100644 index 00000000..22fe5950 --- /dev/null +++ b/wordpress_trojan.sh @@ -0,0 +1,393 @@ +#!/bin/bash +# trojan WordPress一键安装脚本 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +CONFIG_FILE=/usr/local/etc/trojan/config.json + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" +res=$(command -v bt) +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +checkSystem() { + uid=$(id -u) + if [[ $uid -ne 0 ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=$(command -v yum) + if [[ "$res" = "" ]]; then + res=$(command -v apt) + if [[ "$res" = "" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + PHP_SERVICE="php7.4-fpm" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + PHP_SERVICE="php-fpm" + result=`grep -oE "[0-9.]+" /etc/centos-release` + MAIN=${result%%.*} + fi + res=$(command -v systemctl) + if [[ "$res" = "" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +checkTrojan() { + if [ ! -f ${CONFIG_FILE} ]; then + colorEcho $RED " 未安装trojan" + exit 1 + fi + DOMAIN=`grep sni $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + NGINX_CONFIG_FILE="$NGINX_CONF_PATH${DOMAIN}.conf" + if [[ ! -f $NGINX_CONFIG_FILE ]]; then + colorEcho $RED " 未找到域名的nginx配置文件" + exit 1 + fi + PORT=`grep local_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + [[ "$1" = "install" ]] && colorEcho $BLUE " 伪装域名:$DOMAIN" + [[ "$1" = "install" ]] && colorEcho $BLUE " trojan监听端口:$PORT" +} + +statusText() { + res=$(command -v nginx) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}Nginx未安装${PLAIN} + else + res=`ps aux | grep nginx | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}Nginx未运行${PLAIN} || echo -e -n ${GREEN}Nginx正在运行${PLAIN} + fi + echo -n ", " + res=$(command -v php) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}PHP未安装${PLAIN} + else + res=`ps aux | grep php | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}PHP未运行${PLAIN} || echo -e -n ${GREEN}PHP正在运行${PLAIN} + fi + echo -n ", " + res=$(command -v mysql) + if [[ "$res" = "" ]]; then + echo -e -n ${RED}Mysql未安装${PLAIN} + else + res=`ps aux | grep mysql | grep -v grep` + [[ "$res" = "" ]] && echo -e -n ${RED}Mysql未运行${PLAIN} || echo -e -n ${GREEN}Mysql正在运行${PLAIN} + fi +} + +installPHP() { + [[ "$PMT" = "apt" ]] && $PMT update + $CMD_INSTALL curl wget ca-certificates + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ $MAIN -eq 7 ]]; then + rpm -iUh https://rpms.remirepo.net/enterprise/remi-release-7.rpm + sed -i '0,/enabled=0/{s/enabled=0/enabled=1/}' /etc/yum.repos.d/remi-php74.repo + else + dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm + sed -i '0,/enabled=0/{s/enabled=0/enabled=1/}' /etc/yum.repos.d/remi.repo + dnf module install -y php:remi-7.4 + fi + $CMD_INSTALL php-cli php-fpm php-bcmath php-gd php-mbstring php-mysqlnd php-pdo php-opcache php-xml php-pecl-zip php-pecl-imagick + else + $CMD_INSTALL lsb-release gnupg2 + wget -q https://packages.sury.org/php/apt.gpg -O- | apt-key add - + echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php7.list + $PMT update + $CMD_INSTALL php7.4-cli php7.4-fpm php7.4-bcmath php7.4-gd php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-xml php7.4-zip php7.4-json php7.4-imagick + update-alternatives --set php /usr/bin/php7.4 + fi + systemctl enable $PHP_SERVICE +} + +installMysql() { + if [[ "$PMT" = "yum" ]]; then + yum remove -y MariaDB-server + if [ ! -f /etc/yum.repos.d/mariadb.repo ]; then + if [ $MAIN -eq 7 ]; then + echo '# MariaDB 10.5 CentOS repository list - created 2019-11-23 15:00 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.5/centos7-amd64 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1' >> /etc/yum.repos.d/mariadb.repo + else + echo '# MariaDB 10.5 CentOS repository list - created 2020-03-11 16:29 UTC +# http://downloads.mariadb.org/mariadb/repositories/ +[mariadb] +name = MariaDB +baseurl = http://yum.mariadb.org/10.5/centos8-amd64 +module_hotfixes=1 +gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +gpgcheck=1' >> /etc/yum.repos.d/mariadb.repo + fi + fi + yum install -y MariaDB-server + else + $PMT update + $CMD_INSTALL mariadb-server + fi + systemctl enable mariadb.service +} + +installWordPress() { + mkdir -p /var/www + wget https://cn.wordpress.org/latest-zh_CN.tar.gz + if [[ ! -f latest-zh_CN.tar.gz ]]; then + colorEcho $RED " 下载WordPress失败,请稍后重试" + exit 1 + fi + tar -zxf latest-zh_CN.tar.gz + rm -rf /var/www/$DOMAIN + mv wordpress /var/www/$DOMAIN + rm -rf latest-zh_CN.tar.gz +} + +config() { + # config mariadb + systemctl start mariadb + DBNAME="wordpress" + DBUSER="wordpress" + DBPASS=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + mysql -uroot <~\`+=,.;:/?|"; + sub salt { join "", map $chars[ rand @chars ], 1 .. 64 } + } + s/put your unique phrase here/salt()/ge +' wp-config.php + if [[ "$PMT" = "yum" ]]; then + user="apache" + # config nginx + [[ $MAIN -eq 7 ]] && upstream="127.0.0.1:9000" || upstream="php-fpm" + else + user="www-data" + upstream="unix:/run/php/php7.4-fpm.sock" + fi + chown -R $user:$user /var/www/${DOMAIN} + # config nginx + cat > $NGINX_CONFIG_FILE<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${PORT}\$request_uri; +} +server { + listen 8080; + listen 81 http2; + server_name ${DOMAIN}; + + charset utf-8; + + set \$host_path "/var/www/${DOMAIN}"; + access_log /var/log/nginx/${DOMAIN}.access.log main buffer=32k flush=30s; + error_log /var/log/nginx/${DOMAIN}.error.log; + root \$host_path; + location / { + index index.php index.html; + try_files \$uri \$uri/ /index.php?\$args; + } + location ~ \.php\$ { + try_files \$uri =404; + fastcgi_index index.php; + fastcgi_pass $upstream; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + fastcgi_param SERVER_PORT ${PORT}; + fastcgi_param HTTPS "on"; + } + location ~ \.(js|css|png|jpg|jpeg|gif|ico|swf|webp|pdf|txt|doc|docx|xls|xlsx|ppt|pptx|mov|fla|zip|rar)\$ { + expires max; + access_log off; + try_files \$uri =404; + } +} +EOF + + # config trojan + sed -i -e "s/remote_addr\":\s*\".*\",/remote_addr\": \"127.0.0.1\",/" $CONFIG_FILE + sed -i -e "s/remote_port\":\s*[0-9]*/remote_port\": 8080/" $CONFIG_FILE + + # restart service + systemctl restart $PHP_SERVICE mariadb nginx trojan +} + +install() { + checkTrojan "install" + installPHP + installMysql + installWordPress + colorEcho $BLUE " WordPress安装成功!" + + config + # restart service + systemctl restart $PHP_SERVICE mariadb nginx + + sleep 2 + statusText + echo "" + + showInfo +} + +uninstall() { + echo "" + colorEcho $RED " 该操作会删除所有WordPress文件,清空数据库!" + read -p " 确认卸载WordPress?[y/n]" answer + [[ "$answer" != "y" && "$answer" != "Y" ]] && exit 0 + + checkTrojan + systemctl stop mariadb + systemctl disable mariadb + if [[ "$PMT" = "yum" ]]; then + $CMD_REMOVE MariaDB-server + else + apt-get purge -y mariadb-* + fi + rm -rf /var/lib/mysql + + systemctl stop $PHP_SERVICE + systemctl disable $PHP_SERVICE + + rm -rf /var/www/${DOMAIN} + + colorEcho $GREEN " 卸载成功!" +} + +showInfo() { + checkTrojan + + if [[ -z ${DBNAME+x} ]]; then + wpconfig="/var/www/${DOMAIN}/wp-config.php" + DBUSER=`grep DB_USER $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + DBNAME=`grep DB_NAME $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + DBPASS=`grep DB_PASSWORD $wpconfig | cut -d, -f2 | cut -d\) -f1 | tr -d \",\'' '` + fi + if [[ "$PORT" = "443" ]]; then + url="https://$DOMAIN" + else + url="https://$DOMAIN:$PORT" + fi + colorEcho $BLUE " WordPress配置信息:" + echo "===============================" + echo -e " ${BLUE}WordPress安装路径:${PLAIN}${RED}/var/www/${DOMAIN}${PLAIN}" + echo -e " ${BLUE}WordPress数据库:${PLAIN}${RED}${DBNAME}${PLAIN}" + echo -e " ${BLUE}WordPress数据库用户名:${PLAIN}${RED}${DBUSER}${PLAIN}" + echo -e " ${BLUE}WordPress数据库密码:${PLAIN}${RED}${DBPASS}${PLAIN}" + echo -e " ${BLUE}WordPress网址:${PLAIN}${RED}$url${PLAIN}" + echo "===============================" +} + +help() { + echo "" + colorEcho $BLUE " Nginx操作:" + colorEcho $GREEN " 启动: systemctl start nginx" + colorEcho $GREEN " 停止:systemctl stop nginx" + colorEcho $GREEN " 重启:systemctl restart nginx" + echo " -------------" + colorEcho $BLUE " PHP操作:" + colorEcho $GREEN " 启动: systemctl start $PHP_SERVICE" + colorEcho $GREEN " 停止:systemctl stop $PHP_SERVICE" + colorEcho $GREEN " 重启:systemctl restart $PHP_SERVICE" + echo " -------------" + colorEcho $BLUE " Mysql操作:" + colorEcho $GREEN " 启动: systemctl start mariadb" + colorEcho $GREEN " 停止:systemctl stop mariadb" + colorEcho $GREEN " 重启:systemctl restart mariadb" +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}WordPress一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo + colorEcho $YELLOW " 该脚本仅适用于 https://hijk.art 网站上的trojan一键脚本安装wordpress用!" + echo + echo -e " ${GREEN}1.${PLAIN} 安装WordPress" + echo -e " ${GREEN}2.${PLAIN} 卸载WordPress" + echo -e " ${GREEN}3.${PLAIN} 查看WordPress配置" + echo -e " ${GREEN}4.${PLAIN} 查看操作帮助" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo -n " 当前状态:" + statusText + echo + + echo "" + read -p " 请选择操作[0-17]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + uninstall + ;; + 3) + showInfo + ;; + 4) + help + ;; + *) + colorEcho $RED " 请选择正确的操作!" + exit 1 + ;; + esac +} + +checkSystem + +menu diff --git a/xray.sh b/xray.sh new file mode 100644 index 00000000..eb7cad83 --- /dev/null +++ b/xray.sh @@ -0,0 +1,1917 @@ +#!/bin/bash +# xray一键安装脚本 +# Author: hijk + + +RED="\033[31m" # Error message +GREEN="\033[32m" # Success message +YELLOW="\033[33m" # Warning message +BLUE="\033[36m" # Info message +PLAIN='\033[0m' + +# 以下网站是随机从Google上找到的无广告小说网站,不喜欢请改成其他网址,以http或https开头 +# 搭建好后无法打开伪装域名,可能是反代小说网站挂了,请在网站留言,或者Github发issue,以便替换新的网站 +SITES=( +http://www.zhuizishu.com/ +http://xs.56dyc.com/ +#http://www.xiaoshuosk.com/ +#https://www.quledu.net/ +http://www.ddxsku.com/ +http://www.biqu6.com/ +https://www.wenshulou.cc/ +#http://www.auutea.com/ +http://www.55shuba.com/ +http://www.39shubao.com/ +https://www.23xsw.cc/ +#https://www.huanbige.com/ +https://www.jueshitangmen.info/ +https://www.zhetian.org/ +http://www.bequgexs.com/ +http://www.tjwl.com/ +) + +CONFIG_FILE="/usr/local/etc/xray/config.json" +OS=`hostnamectl | grep -i system | cut -d: -f2` + +V6_PROXY="" +IP=`curl -sL -4 ip.sb` +if [[ "$?" != "0" ]]; then + IP=`curl -sL -6 ip.sb` + V6_PROXY="https://gh.hijk.art/" +fi + +BT="false" +NGINX_CONF_PATH="/etc/nginx/conf.d/" +res=`which bt 2>/dev/null` +if [[ "$res" != "" ]]; then + BT="true" + NGINX_CONF_PATH="/www/server/panel/vhost/nginx/" +fi + +VLESS="false" +TROJAN="false" +TLS="false" +WS="false" +XTLS="false" +KCP="false" + +checkSystem() { + result=$(id | awk '{print $1}') + if [[ $result != "uid=0(root)" ]]; then + colorEcho $RED " 请以root身份执行该脚本" + exit 1 + fi + + res=`which yum 2>/dev/null` + if [[ "$?" != "0" ]]; then + res=`which apt 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 不受支持的Linux系统" + exit 1 + fi + PMT="apt" + CMD_INSTALL="apt install -y " + CMD_REMOVE="apt remove -y " + CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y" + else + PMT="yum" + CMD_INSTALL="yum install -y " + CMD_REMOVE="yum remove -y " + CMD_UPGRADE="yum update -y" + fi + res=`which systemctl 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 系统版本过低,请升级到最新版本" + exit 1 + fi +} + +colorEcho() { + echo -e "${1}${@:2}${PLAIN}" +} + +configNeedNginx() { + local ws=`grep wsSettings $CONFIG_FILE` + if [[ -z "$ws" ]]; then + echo no + return + fi + echo yes +} + +needNginx() { + if [[ "$WS" = "false" ]]; then + echo no + return + fi + echo yes +} + +status() { + if [[ ! -f /usr/local/bin/xray ]]; then + echo 0 + return + fi + if [[ ! -f $CONFIG_FILE ]]; then + echo 1 + return + fi + port=`grep port $CONFIG_FILE| head -n 1| cut -d: -f2| tr -d \",' '` + res=`ss -nutlp| grep ${port} | grep -i xray` + if [[ -z "$res" ]]; then + echo 2 + return + fi + + if [[ `configNeedNginx` != "yes" ]]; then + echo 3 + else + res=`ss -nutlp|grep -i nginx` + if [[ -z "$res" ]]; then + echo 4 + else + echo 5 + fi + fi +} + +statusText() { + res=`status` + case $res in + 2) + echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN} + ;; + 3) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}Xray正在运行${PLAIN} + ;; + 4) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}Xray正在运行${PLAIN}, ${RED}Nginx未运行${PLAIN} + ;; + 5) + echo -e ${GREEN}已安装${PLAIN} ${GREEN}Xray正在运行, Nginx正在运行${PLAIN} + ;; + *) + echo -e ${RED}未安装${PLAIN} + ;; + esac +} + +normalizeVersion() { + if [ -n "$1" ]; then + case "$1" in + v*) + echo "$1" + ;; + http*) + echo "v1.4.2" + ;; + *) + echo "v$1" + ;; + esac + else + echo "" + fi +} + +# 1: new Xray. 0: no. 1: yes. 2: not installed. 3: check failed. +getVersion() { + VER=`/usr/local/bin/xray version|head -n1 | awk '{print $2}'` + RETVAL=$? + CUR_VER="$(normalizeVersion "$(echo "$VER" | head -n 1 | cut -d " " -f2)")" + TAG_URL="${V6_PROXY}https://api.github.com/repos/XTLS/Xray-core/releases/latest" + NEW_VER="$(normalizeVersion "$(curl -s "${TAG_URL}" --connect-timeout 10| grep 'tag_name' | cut -d\" -f4)")" + + if [[ $? -ne 0 ]] || [[ $NEW_VER == "" ]]; then + colorEcho $RED " 检查Xray版本信息失败,请检查网络" + return 3 + elif [[ $RETVAL -ne 0 ]];then + return 2 + elif [[ $NEW_VER != $CUR_VER ]];then + return 1 + fi + return 0 +} + +archAffix(){ + case "$(uname -m)" in + i686|i386) + echo '32' + ;; + x86_64|amd64) + echo '64' + ;; + armv5tel) + echo 'arm32-v5' + ;; + armv6l) + echo 'arm32-v6' + ;; + armv7|armv7l) + echo 'arm32-v7a' + ;; + armv8|aarch64) + echo 'arm64-v8a' + ;; + mips64le) + echo 'mips64le' + ;; + mips64) + echo 'mips64' + ;; + mipsle) + echo 'mips32le' + ;; + mips) + echo 'mips32' + ;; + ppc64le) + echo 'ppc64le' + ;; + ppc64) + echo 'ppc64' + ;; + ppc64le) + echo 'ppc64le' + ;; + riscv64) + echo 'riscv64' + ;; + s390x) + echo 's390x' + ;; + *) + colorEcho $RED " 不支持的CPU架构!" + exit 1 + ;; + esac + + return 0 +} + +getData() { + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + echo "" + echo " Xray一键脚本,运行之前请确认如下条件已经具备:" + colorEcho ${YELLOW} " 1. 一个伪装域名" + colorEcho ${YELLOW} " 2. 伪装域名DNS解析指向当前服务器ip(${IP})" + colorEcho ${BLUE} " 3. 如果/root目录下有 xray.pem 和 xray.key 证书密钥文件,无需理会条件2" + echo " " + read -p " 确认满足按y,按其他退出脚本:" answer + if [[ "${answer,,}" != "y" ]]; then + exit 0 + fi + + echo "" + while true + do + read -p " 请输入伪装域名:" DOMAIN + if [[ -z "${DOMAIN}" ]]; then + colorEcho ${RED} " 域名输入错误,请重新输入!" + else + break + fi + done + DOMAIN=${DOMAIN,,} + colorEcho ${BLUE} " 伪装域名(host):$DOMAIN" + + echo "" + if [[ -f ~/xray.pem && -f ~/xray.key ]]; then + colorEcho ${BLUE} " 检测到自有证书,将使用其部署" + CERT_FILE="/usr/local/etc/xray/${DOMAIN}.pem" + KEY_FILE="/usr/local/etc/xray/${DOMAIN}.key" + else + resolve=`curl -sL https://hijk.art/hostip.php?d=${DOMAIN}` + res=`echo -n ${resolve} | grep ${IP}` + if [[ -z "${res}" ]]; then + colorEcho ${BLUE} "${DOMAIN} 解析结果:${resolve}" + colorEcho ${RED} " 域名未解析到当前服务器IP(${IP})!" + exit 1 + fi + fi + fi + + echo "" + if [[ "$(needNginx)" = "no" ]]; then + if [[ "$TLS" = "true" ]]; then + read -p " 请输入xray监听端口[强烈建议443,默认443]:" PORT + [[ -z "${PORT}" ]] && PORT=443 + else + read -p " 请输入xray监听端口[100-65535的一个数字]:" PORT + [[ -z "${PORT}" ]] && PORT=`shuf -i200-65000 -n1` + if [[ "${PORT:0:1}" = "0" ]]; then + colorEcho ${RED} " 端口不能以0开头" + exit 1 + fi + fi + colorEcho ${BLUE} " xray端口:$PORT" + else + read -p " 请输入Nginx监听端口[100-65535的一个数字,默认443]:" PORT + [[ -z "${PORT}" ]] && PORT=443 + if [ "${PORT:0:1}" = "0" ]; then + colorEcho ${BLUE} " 端口不能以0开头" + exit 1 + fi + colorEcho ${BLUE} " Nginx端口:$PORT" + XPORT=`shuf -i10000-65000 -n1` + fi + + if [[ "$KCP" = "true" ]]; then + echo "" + colorEcho $BLUE " 请选择伪装类型:" + echo " 1) 无" + echo " 2) BT下载" + echo " 3) 视频通话" + echo " 4) 微信视频通话" + echo " 5) dtls" + echo " 6) wiregard" + read -p " 请选择伪装类型[默认:无]:" answer + case $answer in + 2) + HEADER_TYPE="utp" + ;; + 3) + HEADER_TYPE="srtp" + ;; + 4) + HEADER_TYPE="wechat-video" + ;; + 5) + HEADER_TYPE="dtls" + ;; + 6) + HEADER_TYPE="wireguard" + ;; + *) + HEADER_TYPE="none" + ;; + esac + colorEcho $BLUE " 伪装类型:$HEADER_TYPE" + SEED=`cat /proc/sys/kernel/random/uuid` + fi + + if [[ "$TROJAN" = "true" ]]; then + echo "" + read -p " 请设置trojan密码(不输则随机生成):" PASSWORD + [[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1` + colorEcho $BLUE " trojan密码:$PASSWORD" + fi + + if [[ "$XTLS" = "true" ]]; then + echo "" + colorEcho $BLUE " 请选择流控模式:" + echo -e " 1) xtls-rprx-direct [$RED推荐$PLAIN]" + echo " 2) xtls-rprx-origin" + read -p " 请选择流控模式[默认:direct]" answer + [[ -z "$answer" ]] && answer=1 + case $answer in + 1) + FLOW="xtls-rprx-direct" + ;; + 2) + FLOW="xtls-rprx-origin" + ;; + *) + colorEcho $RED " 无效选项,使用默认的xtls-rprx-direct" + FLOW="xtls-rprx-direct" + ;; + esac + colorEcho $BLUE " 流控模式:$FLOW" + fi + + if [[ "${WS}" = "true" ]]; then + echo "" + while true + do + read -p " 请输入伪装路径,以/开头(不懂请直接回车):" WSPATH + if [[ -z "${WSPATH}" ]]; then + len=`shuf -i5-12 -n1` + ws=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $len | head -n 1` + WSPATH="/$ws" + break + elif [[ "${WSPATH:0:1}" != "/" ]]; then + colorEcho ${RED} " 伪装路径必须以/开头!" + elif [[ "${WSPATH}" = "/" ]]; then + colorEcho ${RED} " 不能使用根路径!" + else + break + fi + done + colorEcho ${BLUE} " ws路径:$WSPATH" + fi + + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + echo "" + colorEcho $BLUE " 请选择伪装站类型:" + echo " 1) 静态网站(位于/usr/share/nginx/html)" + echo " 2) 小说站(随机选择)" + echo " 3) 美女站(https://imeizi.me)" + echo " 4) 高清壁纸站(https://bing.imeizi.me)" + echo " 5) 自定义反代站点(需以http或者https开头)" + read -p " 请选择伪装网站类型[默认:高清壁纸站]" answer + if [[ -z "$answer" ]]; then + PROXY_URL="https://bing.imeizi.me" + else + case $answer in + 1) + PROXY_URL="" + ;; + 2) + len=${#SITES[@]} + ((len--)) + while true + do + index=`shuf -i0-${len} -n1` + PROXY_URL=${SITES[$index]} + host=`echo ${PROXY_URL} | cut -d/ -f3` + ip=`curl -sL https://hijk.art/hostip.php?d=${host}` + res=`echo -n ${ip} | grep ${host}` + if [[ "${res}" = "" ]]; then + echo "$ip $host" >> /etc/hosts + break + fi + done + ;; + 3) + PROXY_URL="https://imeizi.me" + ;; + 4) + PROXY_URL="https://bing.imeizi.me" + ;; + 5) + read -p " 请输入反代站点(以http或者https开头):" PROXY_URL + if [[ -z "$PROXY_URL" ]]; then + colorEcho $RED " 请输入反代网站!" + exit 1 + elif [[ "${PROXY_URL:0:4}" != "http" ]]; then + colorEcho $RED " 反代网站必须以http或https开头!" + exit 1 + fi + ;; + *) + colorEcho $RED " 请输入正确的选项!" + exit 1 + esac + fi + REMOTE_HOST=`echo ${PROXY_URL} | cut -d/ -f3` + colorEcho $BLUE " 伪装网站:$PROXY_URL" + + echo "" + colorEcho $BLUE " 是否允许搜索引擎爬取网站?[默认:不允许]" + echo " y)允许,会有更多ip请求网站,但会消耗一些流量,vps流量充足情况下推荐使用" + echo " n)不允许,爬虫不会访问网站,访问ip比较单一,但能节省vps流量" + read -p " 请选择:[y/n]" answer + if [[ -z "$answer" ]]; then + ALLOW_SPIDER="n" + elif [[ "${answer,,}" = "y" ]]; then + ALLOW_SPIDER="y" + else + ALLOW_SPIDER="n" + fi + colorEcho $BLUE " 允许搜索引擎:$ALLOW_SPIDER" + fi + + echo "" + read -p " 是否安装BBR(默认安装)?[y/n]:" NEED_BBR + [[ -z "$NEED_BBR" ]] && NEED_BBR=y + [[ "$NEED_BBR" = "Y" ]] && NEED_BBR=y + colorEcho $BLUE " 安装BBR:$NEED_BBR" +} + +installNginx() { + echo "" + colorEcho $BLUE " 安装nginx..." + if [[ "$BT" = "false" ]]; then + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL epel-release + if [[ "$?" != "0" ]]; then + echo '[nginx-stable] +name=nginx stable repo +baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ +gpgcheck=1 +enabled=1 +gpgkey=https://nginx.org/keys/nginx_signing.key +module_hotfixes=true' > /etc/yum.repos.d/nginx.repo + fi + fi + $CMD_INSTALL nginx + if [[ "$?" != "0" ]]; then + colorEcho $RED " Nginx安装失败,请到 https://hijk.art 反馈" + exit 1 + fi + systemctl enable nginx + else + res=`which nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + colorEcho $RED " 您安装了宝塔,请在宝塔后台安装nginx后再运行本脚本" + exit 1 + fi + fi +} + +startNginx() { + if [[ "$BT" = "false" ]]; then + systemctl start nginx + else + nginx -c /www/server/nginx/conf/nginx.conf + fi +} + +stopNginx() { + if [[ "$BT" = "false" ]]; then + systemctl stop nginx + else + res=`ps aux | grep -i nginx` + if [[ "$res" != "" ]]; then + nginx -s stop + fi + fi +} + +getCert() { + mkdir -p /usr/local/etc/xray + if [[ -z ${CERT_FILE+x} ]]; then + stopNginx + systemctl stop xray + res=`netstat -ntlp| grep -E ':80 |:443 '` + if [[ "${res}" != "" ]]; then + colorEcho ${RED} " 其他进程占用了80或443端口,请先关闭再运行一键脚本" + echo " 端口占用信息如下:" + echo ${res} + exit 1 + fi + + $CMD_INSTALL socat openssl + if [[ "$PMT" = "yum" ]]; then + $CMD_INSTALL cronie + systemctl start crond + systemctl enable crond + else + $CMD_INSTALL cron + systemctl start cron + systemctl enable cron + fi + curl -sL https://get.acme.sh | sh -s email=hijk.pw@protonmail.sh + source ~/.bashrc + ~/.acme.sh/acme.sh --upgrade --auto-upgrade + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt + if [[ "$BT" = "false" ]]; then + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "systemctl stop nginx" --post-hook "systemctl restart nginx" --standalone + else + ~/.acme.sh/acme.sh --issue -d $DOMAIN --keylength ec-256 --pre-hook "nginx -s stop || { echo -n ''; }" --post-hook "nginx -c /www/server/nginx/conf/nginx.conf || { echo -n ''; }" --standalone + fi + [[ -f ~/.acme.sh/${DOMAIN}_ecc/ca.cer ]] || { + colorEcho $RED " 获取证书失败,请复制上面的红色文字到 https://hijk.art 反馈" + exit 1 + } + CERT_FILE="/usr/local/etc/xray/${DOMAIN}.pem" + KEY_FILE="/usr/local/etc/xray/${DOMAIN}.key" + ~/.acme.sh/acme.sh --install-cert -d $DOMAIN --ecc \ + --key-file $KEY_FILE \ + --fullchain-file $CERT_FILE \ + --reloadcmd "service nginx force-reload" + [[ -f $CERT_FILE && -f $KEY_FILE ]] || { + colorEcho $RED " 获取证书失败,请到 https://hijk.art 反馈" + exit 1 + } + else + cp ~/xray.pem /usr/local/etc/xray/${DOMAIN}.pem + cp ~/xray.key /usr/local/etc/xray/${DOMAIN}.key + fi +} + +configNginx() { + mkdir -p /usr/share/nginx/html; + if [[ "$ALLOW_SPIDER" = "n" ]]; then + echo 'User-Agent: *' > /usr/share/nginx/html/robots.txt + echo 'Disallow: /' >> /usr/share/nginx/html/robots.txt + ROBOT_CONFIG=" location = /robots.txt {}" + else + ROBOT_CONFIG="" + fi + + if [[ "$BT" = "false" ]]; then + if [[ ! -f /etc/nginx/nginx.conf.bak ]]; then + mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak + fi + res=`id nginx 2>/dev/null` + if [[ "$?" != "0" ]]; then + user="www-data" + else + user="nginx" + fi + cat > /etc/nginx/nginx.conf<<-EOF +user $user; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' + '\$status \$body_bytes_sent "\$http_referer" ' + '"\$http_user_agent" "\$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + server_tokens off; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + gzip on; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; +} +EOF + fi + + if [[ "$PROXY_URL" = "" ]]; then + action="" + else + action="proxy_ssl_server_name on; + proxy_pass $PROXY_URL; + proxy_set_header Accept-Encoding ''; + sub_filter \"$REMOTE_HOST\" \"$DOMAIN\"; + sub_filter_once off;" + fi + + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + mkdir -p ${NGINX_CONF_PATH} + # VMESS+WS+TLS + # VLESS+WS+TLS + if [[ "$WS" = "true" ]]; then + cat > ${NGINX_CONF_PATH}${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + server_name ${DOMAIN}; + return 301 https://\$server_name:${PORT}\$request_uri; +} + +server { + listen ${PORT} ssl http2; + listen [::]:${PORT} ssl http2; + server_name ${DOMAIN}; + charset utf-8; + + # ssl配置 + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + ssl_ecdh_curve secp384r1; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_session_tickets off; + ssl_certificate $CERT_FILE; + ssl_certificate_key $KEY_FILE; + + root /usr/share/nginx/html; + location / { + $action + } + $ROBOT_CONFIG + + location ${WSPATH} { + proxy_redirect off; + proxy_pass http://127.0.0.1:${XPORT}; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } +} +EOF + else + # VLESS+TCP+TLS + # VLESS+TCP+XTLS + # trojan + cat > ${NGINX_CONF_PATH}${DOMAIN}.conf<<-EOF +server { + listen 80; + listen [::]:80; + listen 81 http2; + server_name ${DOMAIN}; + root /usr/share/nginx/html; + location / { + $action + } + $ROBOT_CONFIG +} +EOF + fi + fi +} + +setSelinux() { + if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config + setenforce 0 + fi +} + +setFirewall() { + res=`which firewall-cmd 2>/dev/null` + if [[ $? -eq 0 ]]; then + systemctl status firewalld > /dev/null 2>&1 + if [[ $? -eq 0 ]];then + firewall-cmd --permanent --add-service=http + firewall-cmd --permanent --add-service=https + if [[ "$PORT" != "443" ]]; then + firewall-cmd --permanent --add-port=${PORT}/tcp + firewall-cmd --permanent --add-port=${PORT}/udp + fi + firewall-cmd --reload + else + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + fi + fi + else + res=`which iptables 2>/dev/null` + if [[ $? -eq 0 ]]; then + nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'` + if [[ "$nl" != "3" ]]; then + iptables -I INPUT -p tcp --dport 80 -j ACCEPT + iptables -I INPUT -p tcp --dport 443 -j ACCEPT + if [[ "$PORT" != "443" ]]; then + iptables -I INPUT -p tcp --dport ${PORT} -j ACCEPT + iptables -I INPUT -p udp --dport ${PORT} -j ACCEPT + fi + fi + else + res=`which ufw 2>/dev/null` + if [[ $? -eq 0 ]]; then + res=`ufw status | grep -i inactive` + if [[ "$res" = "" ]]; then + ufw allow http/tcp + ufw allow https/tcp + if [[ "$PORT" != "443" ]]; then + ufw allow ${PORT}/tcp + ufw allow ${PORT}/udp + fi + fi + fi + fi + fi +} + +installBBR() { + if [[ "$NEED_BBR" != "y" ]]; then + INSTALL_BBR=false + return + fi + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $BLUE " BBR模块已安装" + INSTALL_BBR=false + return + fi + res=`hostnamectl | grep -i openvz` + if [[ "$res" != "" ]]; then + colorEcho $BLUE " openvz机器,跳过安装" + INSTALL_BBR=false + return + fi + + echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf + echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf + sysctl -p + result=$(lsmod | grep bbr) + if [[ "$result" != "" ]]; then + colorEcho $GREEN " BBR模块已启用" + INSTALL_BBR=false + return + fi + + colorEcho $BLUE " 安装BBR模块..." + if [[ "$PMT" = "yum" ]]; then + if [[ "$V6_PROXY" = "" ]]; then + rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org + rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm + $CMD_INSTALL --enablerepo=elrepo-kernel kernel-ml + $CMD_REMOVE kernel-3.* + grub2-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi + else + $CMD_INSTALL --install-recommends linux-generic-hwe-16.04 + grub-set-default 0 + echo "tcp_bbr" >> /etc/modules-load.d/modules.conf + INSTALL_BBR=true + fi +} + +installXray() { + rm -rf /tmp/xray + mkdir -p /tmp/xray + DOWNLOAD_LINK="${V6_PROXY}https://github.com/XTLS/Xray-core/releases/download/${NEW_VER}/Xray-linux-$(archAffix).zip" + colorEcho $BLUE " 下载Xray: ${DOWNLOAD_LINK}" + curl -L -H "Cache-Control: no-cache" -o /tmp/xray/xray.zip ${DOWNLOAD_LINK} + if [ $? != 0 ];then + colorEcho $RED " 下载Xray文件失败,请检查服务器网络设置" + exit 1 + fi + systemctl stop xray + mkdir -p /usr/local/etc/xray /usr/local/share/xray && \ + unzip /tmp/xray/xray.zip -d /tmp/xray + cp /tmp/xray/xray /usr/local/bin + cp /tmp/xray/geo* /usr/local/share/xray + chmod +x /usr/local/bin/xray || { + colorEcho $RED " Xray安装失败" + exit 1 + } + + cat >/etc/systemd/system/xray.service<<-EOF +[Unit] +Description=Xray Service +Documentation=https://github.com/xtls https://hijk.art +After=network.target nss-lookup.target + +[Service] +User=root +#User=nobody +#CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE +#AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE +NoNewPrivileges=true +ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/config.json +Restart=on-failure +RestartPreventExitStatus=23 + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable xray.service +} + +trojanConfig() { + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "trojan", + "settings": { + "clients": [ + { + "password": "$PASSWORD" + } + ], + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +trojanXTLSConfig() { + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "trojan", + "settings": { + "clients": [ + { + "password": "$PASSWORD", + "flow": "$FLOW" + } + ], + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "xtls", + "xtlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + local alterid=`shuf -i50-80 -n1` + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": $alterid + } + ] + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessKCPConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + local alterid=`shuf -i50-80 -n1` + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": $alterid + } + ] + }, + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "$HEADER_TYPE" + }, + "seed": "$SEED" + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessTLSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": 0 + } + ], + "disableInsecureEncryption": false + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vmessWSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $XPORT, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 1, + "alterId": 0 + } + ], + "disableInsecureEncryption": false + }, + "streamSettings": { + "network": "ws", + "wsSettings": { + "path": "$WSPATH", + "headers": { + "Host": "$DOMAIN" + } + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessTLSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessXTLSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "flow": "$FLOW", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "alpn": "http/1.1", + "dest": 80 + }, + { + "alpn": "h2", + "dest": 81 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "xtls", + "xtlsSettings": { + "serverName": "$DOMAIN", + "alpn": ["http/1.1", "h2"], + "certificates": [ + { + "certificateFile": "$CERT_FILE", + "keyFile": "$KEY_FILE" + } + ] + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessWSConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $XPORT, + "listen": "127.0.0.1", + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 0 + } + ], + "decryption": "none" + }, + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "path": "$WSPATH", + "headers": { + "Host": "$DOMAIN" + } + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +vlessKCPConfig() { + local uuid="$(cat '/proc/sys/kernel/random/uuid')" + cat > $CONFIG_FILE<<-EOF +{ + "inbounds": [{ + "port": $PORT, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "$uuid", + "level": 0 + } + ], + "decryption": "none" + }, + "streamSettings": { + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "$HEADER_TYPE" + }, + "seed": "$SEED" + } + } + } + }], + "outbounds": [{ + "protocol": "freedom", + "settings": {} + },{ + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }] +} +EOF +} + +configXray() { + mkdir -p /usr/local/xray + if [[ "$TROJAN" = "true" ]]; then + if [[ "$XTLS" = "true" ]]; then + trojanXTLSConfig + else + trojanConfig + fi + return 0 + fi + if [[ "$VLESS" = "false" ]]; then + # VMESS + kcp + if [[ "$KCP" = "true" ]]; then + vmessKCPConfig + return 0 + fi + # VMESS + if [[ "$TLS" = "false" ]]; then + vmessConfig + elif [[ "$WS" = "false" ]]; then + # VMESS+TCP+TLS + vmessTLSConfig + # VMESS+WS+TLS + else + vmessWSConfig + fi + #VLESS + else + if [[ "$KCP" = "true" ]]; then + vlessKCPConfig + return 0 + fi + # VLESS+TCP + if [[ "$WS" = "false" ]]; then + # VLESS+TCP+TLS + if [[ "$XTLS" = "false" ]]; then + vlessTLSConfig + # VLESS+TCP+XTLS + else + vlessXTLSConfig + fi + # VLESS+WS+TLS + else + vlessWSConfig + fi + fi +} + +install() { + getData + + $PMT clean all + [[ "$PMT" = "apt" ]] && $PMT update + #echo $CMD_UPGRADE | bash + $CMD_INSTALL wget vim unzip tar gcc openssl + $CMD_INSTALL net-tools + if [[ "$PMT" = "apt" ]]; then + $CMD_INSTALL libssl-dev g++ + fi + res=`which unzip 2>/dev/null` + if [[ $? -ne 0 ]]; then + colorEcho $RED " unzip安装失败,请检查网络" + exit 1 + fi + + installNginx + setFirewall + if [[ "$TLS" = "true" || "$XTLS" = "true" ]]; then + getCert + fi + configNginx + + colorEcho $BLUE " 安装Xray..." + getVersion + RETVAL="$?" + if [[ $RETVAL == 0 ]]; then + colorEcho $BLUE " Xray最新版 ${CUR_VER} 已经安装" + elif [[ $RETVAL == 3 ]]; then + exit 1 + else + colorEcho $BLUE " 安装Xray ${NEW_VER} ,架构$(archAffix)" + installXray + fi + + configXray + + setSelinux + installBBR + + start + showInfo + + bbrReboot +} + +bbrReboot() { + if [[ "${INSTALL_BBR}" == "true" ]]; then + echo + echo " 为使BBR模块生效,系统将在30秒后重启" + echo + echo -e " 您可以按 ctrl + c 取消重启,稍后输入 ${RED}reboot${PLAIN} 重启系统" + sleep 30 + reboot + fi +} + +update() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " Xray未安装,请先安装!" + return + fi + + getVersion + RETVAL="$?" + if [[ $RETVAL == 0 ]]; then + colorEcho $BLUE " Xray最新版 ${CUR_VER} 已经安装" + elif [[ $RETVAL == 3 ]]; then + exit 1 + else + colorEcho $BLUE " 安装Xray ${NEW_VER} ,架构$(archAffix)" + installXray + stop + start + + colorEcho $GREEN " 最新版Xray安装成功!" + fi +} + +uninstall() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " Xray未安装,请先安装!" + return + fi + + echo "" + read -p " 确定卸载Xray?[y/n]:" answer + if [[ "${answer,,}" = "y" ]]; then + domain=`grep Host $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" = "" ]]; then + domain=`grep serverName $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + + stop + systemctl disable xray + rm -rf /etc/systemd/system/xray.service + rm -rf /usr/local/bin/xray + rm -rf /usr/local/etc/xray + + if [[ "$BT" = "false" ]]; then + systemctl disable nginx + $CMD_REMOVE nginx + if [[ "$PMT" = "apt" ]]; then + $CMD_REMOVE nginx-common + fi + rm -rf /etc/nginx/nginx.conf + if [[ -f /etc/nginx/nginx.conf.bak ]]; then + mv /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf + fi + fi + if [[ "$domain" != "" ]]; then + rm -rf ${NGINX_CONF_PATH}${domain}.conf + fi + [[ -f ~/.acme.sh/acme.sh ]] && ~/.acme.sh/acme.sh --uninstall + colorEcho $GREEN " Xray卸载成功" + fi +} + +start() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " Xray未安装,请先安装!" + return + fi + stopNginx + startNginx + systemctl restart xray + sleep 2 + + port=`grep port $CONFIG_FILE| head -n 1| cut -d: -f2| tr -d \",' '` + res=`ss -nutlp| grep ${port} | grep -i xray` + if [[ "$res" = "" ]]; then + colorEcho $RED " Xray启动失败,请检查日志或查看端口是否被占用!" + else + colorEcho $BLUE " Xray启动成功" + fi +} + +stop() { + stopNginx + systemctl stop xray + colorEcho $BLUE " Xray停止成功" +} + + +restart() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " Xray未安装,请先安装!" + return + fi + + stop + start +} + + +getConfigFileInfo() { + vless="false" + tls="false" + ws="false" + xtls="false" + trojan="false" + protocol="VMess" + kcp="false" + + uid=`grep id $CONFIG_FILE | head -n1| cut -d: -f2 | tr -d \",' '` + alterid=`grep alterId $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + network=`grep network $CONFIG_FILE | tail -n1| cut -d: -f2 | tr -d \",' '` + [[ -z "$network" ]] && network="tcp" + domain=`grep serverName $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" = "" ]]; then + domain=`grep Host $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + if [[ "$domain" != "" ]]; then + ws="true" + tls="true" + wspath=`grep path $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + else + tls="true" + fi + if [[ "$ws" = "true" ]]; then + port=`grep -i ssl $NGINX_CONF_PATH${domain}.conf| head -n1 | awk '{print $2}'` + else + port=`grep port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + res=`grep -i kcp $CONFIG_FILE` + if [[ "$res" != "" ]]; then + kcp="true" + type=`grep header -A 3 $CONFIG_FILE | grep 'type' | cut -d: -f2 | tr -d \",' '` + seed=`grep seed $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + fi + + vmess=`grep vmess $CONFIG_FILE` + if [[ "$vmess" = "" ]]; then + trojan=`grep trojan $CONFIG_FILE` + if [[ "$trojan" = "" ]]; then + vless="true" + protocol="VLESS" + else + trojan="true" + password=`grep password $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + protocol="trojan" + fi + tls="true" + encryption="none" + xtls=`grep xtlsSettings $CONFIG_FILE` + if [[ "$xtls" != "" ]]; then + xtls="true" + flow=`grep flow $CONFIG_FILE | cut -d: -f2 | tr -d \",' '` + else + flow="无" + fi + fi +} + +outputVmess() { + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"tcp\", + \"type\":\"none\", + \"host\":\"\", + \"path\":\"\", + \"tls\":\"\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}auto${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo + echo -e " ${BLUE}vmess链接:${PLAIN} $RED$link$PLAIN" +} + +outputVmessKCP() { + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}auto${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN} ${RED}${type}${PLAIN}" + echo -e " ${BLUE}mkcp seed:${PLAIN} ${RED}${seed}${PLAIN}" +} + +outputTrojan() { + if [[ "$xtls" = "true" ]]; then + echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${domain}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}XTLS${PLAIN}" + else + echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${domain}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}密码(password):${PLAIN}${RED}${password}${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + fi +} + +outputVmessTLS() { + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"${network}\", + \"type\":\"none\", + \"host\":\"${domain}\", + \"path\":\"\", + \"tls\":\"tls\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + echo + echo -e " ${BLUE}vmess链接: ${PLAIN}$RED$link$PLAIN" +} + +outputVmessWS() { + raw="{ + \"v\":\"2\", + \"ps\":\"\", + \"add\":\"$IP\", + \"port\":\"${port}\", + \"id\":\"${uid}\", + \"aid\":\"$alterid\", + \"net\":\"${network}\", + \"type\":\"none\", + \"host\":\"${domain}\", + \"path\":\"${wspath}\", + \"tls\":\"tls\" +}" + link=`echo -n ${raw} | base64 -w 0` + link="vmess://${link}" + + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}额外id(alterid):${PLAIN} ${RED}${alterid}${PLAIN}" + echo -e " ${BLUE}加密方式(security):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}路径(path):${PLAIN}${RED}${wspath}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + echo + echo -e " ${BLUE}vmess链接:${PLAIN} $RED$link$PLAIN" +} + +showInfo() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " Xray未安装,请先安装!" + return + fi + + echo "" + echo -n -e " ${BLUE}Xray运行状态:${PLAIN}" + statusText + echo -e " ${BLUE}Xray配置文件: ${PLAIN} ${RED}${CONFIG_FILE}${PLAIN}" + colorEcho $BLUE " Xray配置信息:" + + getConfigFileInfo + + echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}" + if [[ "$trojan" = "true" ]]; then + outputTrojan + return 0 + fi + if [[ "$vless" = "false" ]]; then + if [[ "$kcp" = "true" ]]; then + outputVmessKCP + return 0 + fi + if [[ "$tls" = "false" ]]; then + outputVmess + elif [[ "$ws" = "false" ]]; then + outputVmessTLS + else + outputVmessWS + fi + else + if [[ "$kcp" = "true" ]]; then + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN} ${RED}${type}${PLAIN}" + echo -e " ${BLUE}mkcp seed:${PLAIN} ${RED}${seed}${PLAIN}" + return 0 + fi + if [[ "$xtls" = "true" ]]; then + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}XTLS${PLAIN}" + elif [[ "$ws" = "false" ]]; then + echo -e " ${BLUE}IP(address): ${PLAIN}${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + else + echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}" + echo -e " ${BLUE}端口(port):${PLAIN}${RED}${port}${PLAIN}" + echo -e " ${BLUE}id(uuid):${PLAIN}${RED}${uid}${PLAIN}" + echo -e " ${BLUE}流控(flow):${PLAIN}$RED$flow${PLAIN}" + echo -e " ${BLUE}加密(encryption):${PLAIN} ${RED}none${PLAIN}" + echo -e " ${BLUE}传输协议(network):${PLAIN} ${RED}${network}${PLAIN}" + echo -e " ${BLUE}伪装类型(type):${PLAIN}${RED}none$PLAIN" + echo -e " ${BLUE}伪装域名/主机名(host)/SNI/peer名称:${PLAIN}${RED}${domain}${PLAIN}" + echo -e " ${BLUE}路径(path):${PLAIN}${RED}${wspath}${PLAIN}" + echo -e " ${BLUE}底层安全传输(tls):${PLAIN}${RED}TLS${PLAIN}" + fi + fi +} + +showLog() { + res=`status` + if [[ $res -lt 2 ]]; then + colorEcho $RED " Xray未安装,请先安装!" + return + fi + + journalctl -xen -u xray --no-pager +} + +menu() { + clear + echo "#############################################################" + echo -e "# ${RED}Xray一键安装脚本${PLAIN} #" + echo -e "# ${GREEN}作者${PLAIN}: 网络跳越(hijk) #" + echo -e "# ${GREEN}网址${PLAIN}: https://hijk.art #" + echo -e "# ${GREEN}论坛${PLAIN}: https://hijk.club #" + echo -e "# ${GREEN}TG群${PLAIN}: https://t.me/hijkclub #" + echo -e "# ${GREEN}Youtube频道${PLAIN}: https://youtube.com/channel/UCYTB--VsObzepVJtc9yvUxQ #" + echo "#############################################################" + echo -e " ${GREEN}1.${PLAIN} 安装Xray-VMESS" + echo -e " ${GREEN}2.${PLAIN} 安装Xray-${BLUE}VMESS+mKCP${PLAIN}" + echo -e " ${GREEN}3.${PLAIN} 安装Xray-VMESS+TCP+TLS" + echo -e " ${GREEN}4.${PLAIN} 安装Xray-${BLUE}VMESS+WS+TLS${PLAIN}${RED}(推荐)${PLAIN}" + echo -e " ${GREEN}5.${PLAIN} 安装Xray-${BLUE}VLESS+mKCP${PLAIN}" + echo -e " ${GREEN}6.${PLAIN} 安装Xray-VLESS+TCP+TLS" + echo -e " ${GREEN}7.${PLAIN} 安装Xray-${BLUE}VLESS+WS+TLS${PLAIN}${RED}(可过cdn)${PLAIN}" + echo -e " ${GREEN}8.${PLAIN} 安装Xray-${BLUE}VLESS+TCP+XTLS${PLAIN}${RED}(推荐)${PLAIN}" + echo -e " ${GREEN}9.${PLAIN} 安装${BLUE}trojan${PLAIN}${RED}(推荐)${PLAIN}" + echo -e " ${GREEN}10.${PLAIN} 安装${BLUE}trojan+XTLS${PLAIN}${RED}(推荐)${PLAIN}" + echo " -------------" + echo -e " ${GREEN}11.${PLAIN} 更新Xray" + echo -e " ${GREEN}12. ${RED}卸载Xray${PLAIN}" + echo " -------------" + echo -e " ${GREEN}13.${PLAIN} 启动Xray" + echo -e " ${GREEN}14.${PLAIN} 重启Xray" + echo -e " ${GREEN}15.${PLAIN} 停止Xray" + echo " -------------" + echo -e " ${GREEN}16.${PLAIN} 查看Xray配置" + echo -e " ${GREEN}17.${PLAIN} 查看Xray日志" + echo " -------------" + echo -e " ${GREEN}0.${PLAIN} 退出" + echo -n " 当前状态:" + statusText + echo + + read -p " 请选择操作[0-17]:" answer + case $answer in + 0) + exit 0 + ;; + 1) + install + ;; + 2) + KCP="true" + install + ;; + 3) + TLS="true" + install + ;; + 4) + TLS="true" + WS="true" + install + ;; + 5) + VLESS="true" + KCP="true" + install + ;; + 6) + VLESS="true" + TLS="true" + install + ;; + 7) + VLESS="true" + TLS="true" + WS="true" + install + ;; + 8) + VLESS="true" + TLS="true" + XTLS="true" + install + ;; + 9) + TROJAN="true" + TLS="true" + install + ;; + 10) + TROJAN="true" + TLS="true" + XTLS="true" + install + ;; + 11) + update + ;; + 12) + uninstall + ;; + 13) + start + ;; + 14) + restart + ;; + 15) + stop + ;; + 16) + showInfo + ;; + 17) + showLog + ;; + *) + colorEcho $RED " 请选择正确的操作!" + exit 1 + ;; + esac +} + +checkSystem + +action=$1 +[[ -z $1 ]] && action=menu +case "$action" in + menu|update|uninstall|start|restart|stop|showInfo|showLog) + ${action} + ;; + *) + echo " 参数错误" + echo " 用法: `basename $0` [menu|update|uninstall|start|restart|stop|showInfo|showLog]" + ;; +esac