i.sh 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #!/usr/bin/env bash
  2. { # this ensures the entire script is downloaded #
  3. JSPROXY_VER=0.1.0
  4. OPENRESTY_VER=1.15.8.1
  5. SRC_URL=https://raw.githubusercontent.com/EtherDream/jsproxy/$JSPROXY_VER
  6. BIN_URL=https://raw.githubusercontent.com/EtherDream/jsproxy-bin/master
  7. ZIP_URL=https://codeload.github.com/EtherDream/jsproxy/tar.gz
  8. SUPPORTED_OS="Linux-x86_64"
  9. OS="$(uname)-$(uname -m)"
  10. USER=$(whoami)
  11. INSTALL_DIR=/home/jsproxy
  12. NGX_DIR=$INSTALL_DIR/openresty
  13. DOMAIN_SUFFIX=(
  14. xip.io
  15. nip.io
  16. sslip.io
  17. )
  18. GET_IP_API=(
  19. https://api.ipify.org
  20. https://bot.whatismyipaddress.com/
  21. )
  22. COLOR_RESET="\033[0m"
  23. COLOR_RED="\033[31m"
  24. COLOR_GREEN="\033[32m"
  25. COLOR_YELLOW="\033[33m"
  26. output() {
  27. local color=$1
  28. shift 1
  29. local sdata=$@
  30. local stime=$(date "+%H:%M:%S")
  31. printf "$color[jsproxy $stime]$COLOR_RESET $sdata\n"
  32. }
  33. log() {
  34. output $COLOR_GREEN $1
  35. }
  36. warn() {
  37. output $COLOR_YELLOW $1
  38. }
  39. err() {
  40. output $COLOR_RED $1
  41. }
  42. gen_cert() {
  43. local ip=""
  44. for i in ${GET_IP_API[@]}; do
  45. log "服务器公网 IP 获取中,通过接口 $i"
  46. ip=$(curl -s $i)
  47. if [[ ! $ip ]]; then
  48. warn "获取失败"
  49. continue
  50. fi
  51. if ! grep -qP "^\d+\.\d+\.\d+\.\d+$" <<< $ip; then
  52. warn "无效 IP:$ip"
  53. continue
  54. fi
  55. break
  56. done
  57. if [[ $ip ]]; then
  58. log "服务器公网 IP: $ip"
  59. else
  60. err "服务器公网 IP 获取失败,无法申请证书"
  61. exit 1
  62. fi
  63. log "安装 acme.sh 脚本 ..."
  64. curl https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh | INSTALLONLINE=1 sh
  65. local acme=~/.acme.sh/acme.sh
  66. local domains=()
  67. if [[ $@ ]]; then
  68. for i in $@; do
  69. domains+=($i)
  70. done
  71. else
  72. warn "未指定域名,使用公共测试域名"
  73. for i in ${DOMAIN_SUFFIX[@]}; do
  74. domains+=($ip.$i)
  75. done
  76. fi
  77. for domain in ${domains[@]}; do
  78. echo "校验域名 $domain ..."
  79. local ret=$(getent ahosts $domain | head -n1 | awk '{print $1}')
  80. if [[ $ret != $ip ]]; then
  81. err "域名 $domain 解析结果: $ret,非本机公网 IP: $ip"
  82. continue
  83. fi
  84. log "尝试为域名 $domain 申请证书 ..."
  85. local dist=server/cert/$domain
  86. mkdir -p $dist
  87. $acme \
  88. --issue \
  89. -d $domain \
  90. --keylength ec-256 \
  91. --webroot server/acme
  92. $acme \
  93. --install-cert \
  94. -d $domain \
  95. --ecc \
  96. --key-file $dist/ecc.key \
  97. --fullchain-file $dist/ecc.cer
  98. if [ -s $dist/ecc.key ] && [ -s $dist/ecc.cer ]; then
  99. echo "# generated by i.sh
  100. listen 8443 ssl http2;
  101. ssl_certificate cert/$domain/ecc.cer;
  102. ssl_certificate_key cert/$domain/ecc.key;
  103. " > server/cert/cert.conf
  104. local url=https://$domain:8443
  105. echo "
  106. $url 'mysite';" >> server/allowed-sites.conf
  107. log "证书申请完成,重启服务 ..."
  108. server/run.sh reload
  109. log "在线预览: $url"
  110. break
  111. fi
  112. err "证书申请失败!(80 端口是否添加到防火墙)"
  113. rm -rf $dist
  114. done
  115. }
  116. install() {
  117. cd $INSTALL_DIR
  118. log "下载 nginx 程序 ..."
  119. curl -O $BIN_URL/$OS/openresty-$OPENRESTY_VER.tar.gz
  120. tar zxf openresty-$OPENRESTY_VER.tar.gz
  121. rm -f openresty-$OPENRESTY_VER.tar.gz
  122. local ngx_exe=$NGX_DIR/nginx/sbin/nginx
  123. local ngx_ver=$($ngx_exe -v 2>&1)
  124. if [[ "$ngx_ver" != *"nginx version:"* ]]; then
  125. err "$ngx_exe 无法执行!尝试编译安装"
  126. exit 1
  127. fi
  128. log "$ngx_ver"
  129. log "nginx path: $NGX_DIR"
  130. log "下载代理服务 ..."
  131. curl -o jsproxy.tar.gz $ZIP_URL/$JSPROXY_VER
  132. tar zxf jsproxy.tar.gz
  133. rm -f jsproxy.tar.gz
  134. log "下载静态资源 ..."
  135. curl -o www.tar.gz $ZIP_URL/gh-pages
  136. tar zxf www.tar.gz -C jsproxy-$JSPROXY_VER/www --strip-components=1
  137. rm -f www.tar.gz
  138. if [ -x server/run.sh ]; then
  139. warn "尝试停止当前服务 ..."
  140. server/run.sh quit
  141. fi
  142. if [ -d server ]; then
  143. local backup="$INSTALL_DIR/bak/$(date +%Y_%m_%d_%H_%M_%S)"
  144. warn "当前 server 目录备份到 $backup"
  145. mkdir -p $backup
  146. mv server $backup
  147. fi
  148. mv jsproxy-$JSPROXY_VER server
  149. log "启动服务 ..."
  150. server/run.sh
  151. log "服务已开启"
  152. shift 1
  153. gen_cert $@
  154. }
  155. main() {
  156. log "自动安装脚本开始执行"
  157. if [[ "$SUPPORTED_OS" != *"$OS"* ]]; then
  158. err "当前系统 $OS 不支持自动安装。尝试编译安装"
  159. exit 1
  160. fi
  161. if [[ "$USER" != "root" ]]; then
  162. err "自动安装需要 root 权限。如果无法使用 root,尝试编译安装"
  163. exit 1
  164. fi
  165. local cmd
  166. if [[ $0 == *"i.sh" ]]; then
  167. warn "本地调试模式"
  168. local dst=/home/jsproxy/i.sh
  169. cp $0 $dst
  170. chown jsproxy:nobody $dst
  171. if [[ $1 == "-s" ]]; then
  172. shift 1
  173. fi
  174. cmd="bash $dst install $@"
  175. else
  176. cmd="curl -s $SRC_URL/i.sh | bash -s install $@"
  177. fi
  178. iptables \
  179. -t nat \
  180. -I PREROUTING 1 \
  181. -p tcp --dport 80 \
  182. -j REDIRECT \
  183. --to-ports 8080
  184. if ! id -u jsproxy > /dev/null 2>&1 ; then
  185. log "创建用户 jsproxy ..."
  186. groupadd nobody > /dev/null 2>&1
  187. useradd jsproxy -g nobody --create-home
  188. fi
  189. log "切换到 jsproxy 用户,执行安装脚本 ..."
  190. su - jsproxy -c "$cmd"
  191. local line=$(iptables -t nat -nL --line-numbers | grep "tcp dpt:80 redir ports 8080")
  192. iptables -t nat -D PREROUTING ${line%% *}
  193. log "安装完成。后续维护参考 https://github.com/EtherDream/jsproxy"
  194. }
  195. if [[ $1 == "install" ]]; then
  196. install $@
  197. else
  198. main $@
  199. fi
  200. } # this ensures the entire script is downloaded #