Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
M
micro-remote
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tarak.li
micro-remote
Commits
55ade2f1
Commit
55ade2f1
authored
Feb 03, 2021
by
BH
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
远程出金3期,容器打包脚本
parent
fa6e8a60
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
2096 additions
and
238 deletions
+2096
-238
app_env.py
server/www/teleport/webroot/app/app_env.py
+7
-6
plugin.py
server/www/teleport/webroot/app/controller/plugin.py
+2
-2
demo_alipay.py
server/www/teleport/webroot/app/plugin/demo_alipay.py
+0
-75
Dockerfile
...r/www/teleport/webroot/app/plugin/docker_build/Dockerfile
+22
-8
api-redir.conf
...w/teleport/webroot/app/plugin/docker_build/api-redir.conf
+1
-27
cache-redir.conf
...teleport/webroot/app/plugin/docker_build/cache-redir.conf
+0
-47
http.lua
server/www/teleport/webroot/app/plugin/docker_build/http.lua
+1143
-0
http_headers.lua
...teleport/webroot/app/plugin/docker_build/http_headers.lua
+44
-0
small_web.py
...www/teleport/webroot/app/plugin/docker_build/small_web.py
+118
-53
supervisord.conf
...teleport/webroot/app/plugin/docker_build/supervisord.conf
+1
-1
token_check.lua
.../teleport/webroot/app/plugin/docker_build/token_check.lua
+120
-0
vnc-redir.conf
...w/teleport/webroot/app/plugin/docker_build/vnc-redir.conf
+2
-17
remote.py
server/www/teleport/webroot/app/plugin/remote.py
+4
-2
install.sh
server/www/teleport/webroot/app/plugin/shop_build/install.sh
+632
-0
No files found.
server/www/teleport/webroot/app/app_env.py
View file @
55ade2f1
...
...
@@ -44,9 +44,10 @@ if _ext_path not in sys.path:
sys
.
path
.
append
(
_ext_path
)
# 确定一些路径
if
os
.
path
.
exists
(
os
.
path
.
join
(
os
.
path
.
dirname
(
sys
.
executable
),
'dev_mode'
)):
# 开发调试模式
PATH_DATA
=
os
.
path
.
abspath
(
os
.
path
.
join
(
PATH_APP_ROOT
,
'..'
,
'..'
,
'share'
))
else
:
PATH_DATA
=
os
.
path
.
abspath
(
os
.
path
.
join
(
PATH_APP_ROOT
,
'..'
,
'..'
,
'data'
))
PATH_DATA
=
os
.
path
.
abspath
(
os
.
path
.
join
(
PATH_APP_ROOT
,
'..'
,
'..'
,
'share'
))
# if os.path.exists(os.path.join(os.path.dirname(sys.executable), 'dev_mode')):
# # 开发调试模式
# PATH_DATA = os.path.abspath(os.path.join(PATH_APP_ROOT, '..', '..', 'share'))
#
# else:
# PATH_DATA = os.path.abspath(os.path.join(PATH_APP_ROOT, '..', '..', 'data'))
server/www/teleport/webroot/app/controller/plugin.py
View file @
55ade2f1
...
...
@@ -589,8 +589,8 @@ class BindPayAccountHandler(TPBasePluginHandler):
self
.
parse
=
reqparse
.
RequestParser
()
self
.
parse
.
add_argument
(
"comp_id"
,
type
=
int
,
required
=
True
,
help
=
''
,
)
self
.
parse
.
add_argument
(
"host_id"
,
type
=
int
,
required
=
True
,
help
=
''
,
)
self
.
parse
.
add_argument
(
"mch_no"
,
type
=
str
,
help
=
''
,
)
self
.
parse
.
add_argument
(
"biz_id"
,
type
=
int
,
help
=
''
,
)
#
self.parse.add_argument("mch_no", type=str, help='', )
#
self.parse.add_argument("biz_id", type=int, help='', )
self
.
parse
.
add_argument
(
"account"
,
type
=
str
,
required
=
True
,
help
=
''
,
)
self
.
parse
.
add_argument
(
"password"
,
type
=
str
,
required
=
True
,
help
=
''
,
)
# 绑定账户类型
...
...
server/www/teleport/webroot/app/plugin/demo_alipay.py
deleted
100644 → 0
View file @
fa6e8a60
# coding: utf-8
import
os
from
selenium
import
webdriver
options
=
webdriver
.
ChromeOptions
()
options
.
add_argument
(
"--no-sandbox"
)
# options.add_argument('--disable-dev-shm-usage')
options
.
add_experimental_option
(
"excludeSwitches"
,
[
'enable-automation'
])
# options.add_argument("--remote-debugging-port=9222")
# options.headless = True
command_executor
=
"http://localhost:4444/wd/hub"
driver
=
webdriver
.
Remote
(
command_executor
,
desired_capabilities
=
options
.
to_capabilities
())
import
time
# time.sleep(5)
driver
.
get
(
"https://b.alipay.com/index2.htm"
)
driver
.
get_screenshot_as_file
(
'screenshot1.png'
)
import
random
def
do_tool
(
k
):
os
.
system
(
"xdotool key {}"
.
format
(
k
))
time
.
sleep
(
random
.
randint
(
1
,
10
)
*
0.1
)
[
do_tool
(
k
)
for
k
in
'18826140775'
]
do_tool
(
"Tab"
)
[
do_tool
(
k
)
for
k
in
'v4f8169l'
]
do_tool
(
"Tab"
)
do_tool
(
"Tab"
)
do_tool
(
"Tab"
)
do_tool
(
"Shift+Tab"
)
do_tool
(
"Shift+Tab"
)
# 获取截图
driver
.
get_screenshot_as_file
(
'screenshot.png'
)
import
cv2
def
crop_code
(
img_path
):
img
=
cv2
.
pyrDown
(
cv2
.
imread
(
img_path
,
cv2
.
IMREAD_UNCHANGED
))
img2
=
cv2
.
imread
(
img_path
)
ret
,
thresh
=
cv2
.
threshold
(
cv2
.
cvtColor
(
img
.
copy
(),
cv2
.
COLOR_BGR2GRAY
),
127
,
255
,
cv2
.
THRESH_BINARY
)
contours
,
hier
=
cv2
.
findContours
(
thresh
,
cv2
.
RETR_EXTERNAL
,
cv2
.
CHAIN_APPROX_SIMPLE
)
for
c
in
contours
:
x
,
y
,
w
,
h
=
cv2
.
boundingRect
(
c
)
if
w
<
30
or
h
<
20
or
w
*
h
>
1000
:
continue
cv2
.
rectangle
(
img
,
(
x
,
y
),
(
x
+
w
,
y
+
h
),
(
0
,
255
,
0
),
2
)
cropImg
=
img2
[
y
*
2
:(
y
+
h
)
*
2
,
x
*
2
:(
x
+
w
)
*
2
]
cv2
.
imwrite
(
"code.png"
,
cropImg
)
return
"code.png"
path
=
crop_code
(
"screenshot0.png"
)
from
example
import
FateadmApi
pd_id
=
"122334"
pd_key
=
"CvSAzmpNTCk953nPqrciORQ5LaMmwsSZ"
app_id
=
"322334"
app_key
=
"ZVZG1lpunkJrrGA0xPJJgfRHHa384ycQ"
pred_type
=
"30400"
# 初始化api接口
other_api
=
FateadmApi
(
app_id
,
app_key
,
pd_id
,
pd_key
)
rsp
=
other_api
.
PredictFromFile
(
"30400"
,
"code.png"
,
"demo"
)
code
=
rsp
.
pred_rsp
.
value
print
(
code
)
[
do_tool
(
k
)
for
k
in
code
]
do_tool
(
"KP_Enter"
)
server/www/teleport/webroot/app/plugin/docker_build/Dockerfile
View file @
55ade2f1
...
...
@@ -20,6 +20,7 @@ RUN mkdir -p /run/systemd \
&&
echo
'docker'
>
/run/systemd/container
CMD
["/bin/bash"]
ENV
HOME=/root
#ENV DEBIAN_FRONTEND=noninteractive
#ENV LC_ALL=C.UTF-8
#ENV LANG=zh_CN.UTF-8
...
...
@@ -58,6 +59,7 @@ RUN mkdir -p /root/.config/fcitx && \
RUN
mkdir
-p
/etc/opt
COPY
google-chrome-stable_current_amd64.deb /etc/opt/google-chrome-stable_current_amd64.deb
RUN
apt
install
-fy
/etc/opt/google-chrome-stable_current_amd64.deb
#RUN wget http://172.30.20.148:8888/google-chrome-stable_current_amd64.deb && apt install -fy google-chrome-stable_current_amd64.deb
RUN
apt-get autoclean
WORKDIR
/root
...
...
@@ -106,8 +108,8 @@ ENV CHROME_DRIVER_BASE="chromedriver.storage.googleapis.com" \
ENV
CHROME_DRIVER_FILE="chromedriver_linux${CPU_ARCH}.zip"
ENV
CHROME_DRIVER_URL="https://${CHROME_DRIVER_BASE}/${CHROME_DRIVER_VERSION}/${CHROME_DRIVER_FILE}"
# Gets latest chrome driver version. Or you can hard-code it, e.g. 2.15
RUN
wget
-nv
-O
chromedriver_linux
${
CPU_ARCH
}
.zip
${
CHROME_DRIVER_URL
}
#
RUN wget -nv -O chromedriver_linux${CPU_ARCH}.zip ${CHROME_DRIVER_URL}
COPY
chromedriver_linux64.zip /root/chromedriver_linux64.zip
RUN
unzip chromedriver_linux
${
CPU_ARCH
}
.zip
RUN
rm
chromedriver_linux
${
CPU_ARCH
}
.zip
\
&&
mv
chromedriver
\
...
...
@@ -159,22 +161,28 @@ RUN apt-get update && apt-get install -y \
ruby
\
zlib1g
\
zlib1g.dev
ARG
LOCALIP
RUN
cd
/root
&&
wget https://openresty.org/download/openresty-1.13.6.2.tar.gz
&&
tar
xzvf openresty-1.13.6.2.tar.gz
\
COPY
openresty-1.13.6.2.tar.gz /root/openresty-1.13.6.2.tar.gz
#RUN cd /root &&wget https://openresty.org/download/openresty-1.13.6.2.tar.gz && tar xzvf openresty-1.13.6.2.tar.gz \
RUN
cd
/root
&&
tar
xzvf openresty-1.13.6.2.tar.gz
\
&&
cd
openresty-1.13.6.2/
\
&&
./configure
\
&&
make
\
&&
make
install
\
&&
ln
/usr/local/openresty/nginx/sbin/nginx /usr/bin/nginx
\
&&
var
=
" lua_package_path '/usr/local/openresty/nginx/mylua/?.lua;;';"
\
&&
sed
-i
"/gzip on;/ a
\\
$var
"
/usr/local/openresty/nginx/conf/nginx.conf
\
&&
var
=
" include /usr/local/openresty/nginx/conf/conf.d/*.conf;"
\
&&
sed
-i
"/gzip on;/ a
\\
$var
"
/usr/local/openresty/nginx/conf/nginx.conf
\
&&
var
=
" lua_shared_dict my_cache 64m;"
\
&&
sed
-i
"/gzip on;/ a
\\
$var
"
/usr/local/openresty/nginx/conf/nginx.conf
\
&&
var
=
" set
\$
client_ip '
${
LOCALIP
}
';"
\
&&
sed
-i
"/charset koi8-r;/ a
\\
$var
"
/usr/local/openresty/nginx/conf/nginx.conf
\
&&
mkdir
-p
/usr/local/openresty/nginx/conf/conf.d
\
&&
mkdir
-p
/var/log/nginx
COPY
api-redir.conf /usr/local/openresty/nginx/conf/conf.d/api-redir.conf
COPY
cache-redir.conf /usr/local/openresty/nginx/conf/conf.d/cache-redir.conf
#==================
# xdotool 自动化工具
...
...
@@ -182,15 +190,14 @@ COPY cache-redir.conf /usr/local/openresty/nginx/conf/conf.d/cache-redir.conf
RUN
apt-get update
&&
apt-get
install
-y
\
xdotool
\
cmake
RUN
pip3
install
scikit-build
&&
pip3
install
opencv-python requests flask rsa
#todo 优化安装 opencv-python pycryptodome
RUN
pip3
install
scikit-build
&&
pip3
install
requests flask pycrypto
-i
http://mirrors.aliyun.com/pypi/simple/
--trusted-host
mirrors.aliyun.com
COPY
vnc-redir.conf /usr/local/openresty/nginx/conf/conf.d/vnc-redir.conf
RUN
mkdir
-p
/root/main
COPY
public.pem /root/main/public.pem
COPY
small_web.py /root/main/small_web.py
RUN
pip3
install
pyDes
#==================
# 调试用工具
...
...
@@ -199,6 +206,11 @@ RUN apt-get update && apt-get install -y \
lsof
\
vim
RUN
mkdir
-p
/usr/local/openresty/nginx/mylua/resty
COPY
token_check.lua /usr/local/openresty/nginx/mylua/token_check.lua
COPY
http.lua /usr/local/openresty/nginx/mylua/resty/http.lua
COPY
http_headers.lua /usr/local/openresty/nginx/mylua/resty/http_headers.lua
ENV
\
# 時區
...
...
@@ -215,7 +227,7 @@ ENV \
DISPLAY=:0 \
SCREEN_RESOLUTION=1280x900
COPY
private.pem /root/main/private.pem
COPY
supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ENV
DISPLAY=:0
...
...
@@ -237,3 +249,4 @@ CMD ["/usr/bin/supervisord"]
#/usr/local/bin/x11vnc
#/usr/bin/x11vnc
#docker run -d -p 8083:8083 -p 5900:5900 oldiy/chrome-novnc:latest
#docker build -t sandbox .
\ No newline at end of file
server/www/teleport/webroot/app/plugin/docker_build/api-redir.conf
View file @
55ade2f1
...
...
@@ -34,34 +34,8 @@ server {
break
;
}
# 对 / 访问进行控制
location
/
token
{
proxy_pass
http
://
127
.
0
.
0
.
1
:
8000
;
proxy_set_header
Referer
$
http_referer
;
proxy_set_header
Host
$
http_host
;
proxy_buffers
256
4
k
;
proxy_set_header
Upgrade
$
http_upgrade
;
proxy_set_header
Connection
"upgrade"
;
}
location
/ {
access_by_lua
'
local
cache_ngx
=
ngx
.
shared
.
my_cache
local
token
=
ngx
.
var
.
cookie_token
if
not
token
then
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
token
)
ngx
.
exit
(
200
)
end
local
token2
=
cache_ngx
:
get
(
token
)
if
not
token2
then
local
errs
=
"requests check fail"
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
errs
)
ngx
.
exit
(
200
)
end
return
'
;
access_by_lua_file
mylua
/
token_check
.
lua
;
proxy_pass
http
://
127
.
0
.
0
.
1
:
8000
;
proxy_set_header
Referer
$
http_referer
;
proxy_set_header
Host
$
http_host
;
...
...
server/www/teleport/webroot/app/plugin/docker_build/cache-redir.conf
deleted
100644 → 0
View file @
fa6e8a60
server
{
listen
10086
;
charset
utf
-
8
;
server_name
_
;
gzip
on
;
location
/
set
{
access_by_lua
'
local
cache_ngx
=
ngx
.
shared
.
my_cache
local
args
=
ngx
.
req
.
get_headers
();
local
token1
=
args
[
"appid"
];
cache_ngx
:
set
(
token1
,
token1
,
30
*
60
)
local
msg
=
"ok"
ngx
.
say
(
msg
)
ngx
.
exit
(
200
)
return
'
;
}
location
/
check
{
access_by_lua
'
local
cache_ngx
=
ngx
.
shared
.
my_cache
local
args
=
ngx
.
req
.
get_headers
();
local
token1
=
args
[
"appid"
];
local
token2
=
cache_ngx
:
get
(
token1
)
local
errs
=
"oh,Only token1 Request will be Processe"
if
not
token1
then
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
errs
)
ngx
.
exit
(
200
)
end
local
errs
=
"oh,Only token2 Request will be Processe"
if
not
token2
then
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
errs
)
ngx
.
exit
(
200
)
end
local
errs
=
"oh,Only token Request will be Processe"
if
token1
~=
token2
then
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
errs
)
ngx
.
exit
(
200
)
else
return
end
'
;
}
}
server/www/teleport/webroot/app/plugin/docker_build/http.lua
0 → 100644
View file @
55ade2f1
local
http_headers
=
require
"resty.http_headers"
local
ngx
=
ngx
local
ngx_socket_tcp
=
ngx
.
socket
.
tcp
local
ngx_req
=
ngx
.
req
local
ngx_req_socket
=
ngx_req
.
socket
local
ngx_req_get_headers
=
ngx_req
.
get_headers
local
ngx_req_get_method
=
ngx_req
.
get_method
local
str_lower
=
string.lower
local
str_upper
=
string.upper
local
str_find
=
string.find
local
str_sub
=
string.sub
local
tbl_concat
=
table.concat
local
tbl_insert
=
table.insert
local
ngx_encode_args
=
ngx
.
encode_args
local
ngx_re_match
=
ngx
.
re
.
match
local
ngx_re_gmatch
=
ngx
.
re
.
gmatch
local
ngx_re_sub
=
ngx
.
re
.
sub
local
ngx_re_gsub
=
ngx
.
re
.
gsub
local
ngx_re_find
=
ngx
.
re
.
find
local
ngx_log
=
ngx
.
log
local
ngx_DEBUG
=
ngx
.
DEBUG
local
ngx_ERR
=
ngx
.
ERR
local
ngx_var
=
ngx
.
var
local
ngx_print
=
ngx
.
print
local
ngx_header
=
ngx
.
header
local
co_yield
=
coroutine.yield
local
co_create
=
coroutine.create
local
co_status
=
coroutine.status
local
co_resume
=
coroutine.resume
local
setmetatable
=
setmetatable
local
tonumber
=
tonumber
local
tostring
=
tostring
local
unpack
=
unpack
local
rawget
=
rawget
local
select
=
select
local
ipairs
=
ipairs
local
pairs
=
pairs
local
pcall
=
pcall
local
type
=
type
-- http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
local
HOP_BY_HOP_HEADERS
=
{
[
"connection"
]
=
true
,
[
"keep-alive"
]
=
true
,
[
"proxy-authenticate"
]
=
true
,
[
"proxy-authorization"
]
=
true
,
[
"te"
]
=
true
,
[
"trailers"
]
=
true
,
[
"transfer-encoding"
]
=
true
,
[
"upgrade"
]
=
true
,
[
"content-length"
]
=
true
,
-- Not strictly hop-by-hop, but Nginx will deal
-- with this (may send chunked for example).
}
local
EXPECTING_BODY
=
{
POST
=
true
,
PUT
=
true
,
PATCH
=
true
,
}
-- Reimplemented coroutine.wrap, returning "nil, err" if the coroutine cannot
-- be resumed. This protects user code from infinite loops when doing things like
-- repeat
-- local chunk, err = res.body_reader()
-- if chunk then -- <-- This could be a string msg in the core wrap function.
-- ...
-- end
-- until not chunk
local
co_wrap
=
function
(
func
)
local
co
=
co_create
(
func
)
if
not
co
then
return
nil
,
"could not create coroutine"
else
return
function
(
...
)
if
co_status
(
co
)
==
"suspended"
then
return
select
(
2
,
co_resume
(
co
,
...
))
else
return
nil
,
"can't resume a "
..
co_status
(
co
)
..
" coroutine"
end
end
end
end
-- Returns a new table, recursively copied from the one given.
--
-- @param table table to be copied
-- @return table
local
function
tbl_copy
(
orig
)
local
orig_type
=
type
(
orig
)
local
copy
if
orig_type
==
"table"
then
copy
=
{}
for
orig_key
,
orig_value
in
next
,
orig
,
nil
do
copy
[
tbl_copy
(
orig_key
)]
=
tbl_copy
(
orig_value
)
end
else
-- number, string, boolean, etc
copy
=
orig
end
return
copy
end
local
_M
=
{
_VERSION
=
'0.14'
,
}
_M
.
_USER_AGENT
=
"lua-resty-http/"
..
_M
.
_VERSION
..
" (Lua) ngx_lua/"
..
ngx
.
config
.
ngx_lua_version
local
mt
=
{
__index
=
_M
}
local
HTTP
=
{
[
1
.
0
]
=
" HTTP/1.0\r\n"
,
[
1
.
1
]
=
" HTTP/1.1\r\n"
,
}
local
DEFAULT_PARAMS
=
{
method
=
"GET"
,
path
=
"/"
,
version
=
1
.
1
,
}
local
DEBUG
=
false
function
_M
.
new
(
_
)
local
sock
,
err
=
ngx_socket_tcp
()
if
not
sock
then
return
nil
,
err
end
return
setmetatable
({
sock
=
sock
,
keepalive
=
true
},
mt
)
end
function
_M
.
debug
(
d
)
DEBUG
=
(
d
==
true
)
end
function
_M
.
set_timeout
(
self
,
timeout
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
return
sock
:
settimeout
(
timeout
)
end
function
_M
.
set_timeouts
(
self
,
connect_timeout
,
send_timeout
,
read_timeout
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
return
sock
:
settimeouts
(
connect_timeout
,
send_timeout
,
read_timeout
)
end
function
_M
.
ssl_handshake
(
self
,
...
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
self
.
ssl
=
true
return
sock
:
sslhandshake
(
...
)
end
function
_M
.
connect
(
self
,
...
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
self
.
host
=
select
(
1
,
...
)
self
.
port
=
select
(
2
,
...
)
-- If port is not a number, this is likely a unix domain socket connection.
if
type
(
self
.
port
)
~=
"number"
then
self
.
port
=
nil
end
self
.
keepalive
=
true
return
sock
:
connect
(
...
)
end
function
_M
.
set_keepalive
(
self
,
...
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
if
self
.
keepalive
==
true
then
return
sock
:
setkeepalive
(
...
)
else
-- The server said we must close the connection, so we cannot setkeepalive.
-- If close() succeeds we return 2 instead of 1, to differentiate between
-- a normal setkeepalive() failure and an intentional close().
local
res
,
err
=
sock
:
close
()
if
res
then
return
2
,
"connection must be closed"
else
return
res
,
err
end
end
end
function
_M
.
get_reused_times
(
self
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
return
sock
:
getreusedtimes
()
end
function
_M
.
close
(
self
)
local
sock
=
self
.
sock
if
not
sock
then
return
nil
,
"not initialized"
end
return
sock
:
close
()
end
local
function
_should_receive_body
(
method
,
code
)
if
method
==
"HEAD"
then
return
nil
end
if
code
==
204
or
code
==
304
then
return
nil
end
if
code
>=
100
and
code
<
200
then
return
nil
end
return
true
end
function
_M
.
parse_uri
(
_
,
uri
,
query_in_path
)
if
query_in_path
==
nil
then
query_in_path
=
true
end
local
m
,
err
=
ngx_re_match
(
uri
,
[[^(?:(http[s]?):)?//([^:/\?]+)(?::(\d+))?([^\?]*)\??(.*)]]
,
"jo"
)
if
not
m
then
if
err
then
return
nil
,
"failed to match the uri: "
..
uri
..
", "
..
err
end
return
nil
,
"bad uri: "
..
uri
else
-- If the URI is schemaless (i.e. //example.com) try to use our current
-- request scheme.
if
not
m
[
1
]
then
local
scheme
=
ngx_var
.
scheme
if
scheme
==
"http"
or
scheme
==
"https"
then
m
[
1
]
=
scheme
else
return
nil
,
"schemaless URIs require a request context: "
..
uri
end
end
if
m
[
3
]
then
m
[
3
]
=
tonumber
(
m
[
3
])
else
if
m
[
1
]
==
"https"
then
m
[
3
]
=
443
else
m
[
3
]
=
80
end
end
if
not
m
[
4
]
or
""
==
m
[
4
]
then
m
[
4
]
=
"/"
end
if
query_in_path
and
m
[
5
]
and
m
[
5
]
~=
""
then
m
[
4
]
=
m
[
4
]
..
"?"
..
m
[
5
]
m
[
5
]
=
nil
end
return
m
,
nil
end
end
local
function
_format_request
(
params
)
local
version
=
params
.
version
local
headers
=
params
.
headers
or
{}
local
query
=
params
.
query
or
""
if
type
(
query
)
==
"table"
then
query
=
"?"
..
ngx_encode_args
(
query
)
elseif
query
~=
""
and
str_sub
(
query
,
1
,
1
)
~=
"?"
then
query
=
"?"
..
query
end
-- Initialize request
local
req
=
{
str_upper
(
params
.
method
),
" "
,
params
.
path
,
query
,
HTTP
[
version
],
-- Pre-allocate slots for minimum headers and carriage return.
true
,
true
,
true
,
}
local
c
=
6
-- req table index it's faster to do this inline vs table.insert
-- Append headers
for
key
,
values
in
pairs
(
headers
)
do
key
=
tostring
(
key
)
if
type
(
values
)
==
"table"
then
for
_
,
value
in
pairs
(
values
)
do
req
[
c
]
=
key
..
": "
..
tostring
(
value
)
..
"
\r\n
"
c
=
c
+
1
end
else
req
[
c
]
=
key
..
": "
..
tostring
(
values
)
..
"
\r\n
"
c
=
c
+
1
end
end
-- Close headers
req
[
c
]
=
"
\r\n
"
return
tbl_concat
(
req
)
end
local
function
_receive_status
(
sock
)
local
line
,
err
=
sock
:
receive
(
"*l"
)
if
not
line
then
return
nil
,
nil
,
nil
,
err
end
return
tonumber
(
str_sub
(
line
,
10
,
12
)),
tonumber
(
str_sub
(
line
,
6
,
8
)),
str_sub
(
line
,
14
)
end
local
function
_receive_headers
(
sock
)
local
headers
=
http_headers
.
new
()
repeat
local
line
,
err
=
sock
:
receive
(
"*l"
)
if
not
line
then
return
nil
,
err
end
local
m
,
err
=
ngx_re_match
(
line
,
"([^:\\s]+):\\s*(.*)"
,
"jo"
)
if
err
then
ngx_log
(
ngx_ERR
,
err
)
end
if
not
m
then
break
end
local
key
=
m
[
1
]
local
val
=
m
[
2
]
if
headers
[
key
]
then
if
type
(
headers
[
key
])
~=
"table"
then
headers
[
key
]
=
{
headers
[
key
]
}
end
tbl_insert
(
headers
[
key
],
tostring
(
val
))
else
headers
[
key
]
=
tostring
(
val
)
end
until
ngx_re_find
(
line
,
"^\\s*$"
,
"jo"
)
return
headers
,
nil
end
local
function
_chunked_body_reader
(
sock
,
default_chunk_size
)
return
co_wrap
(
function
(
max_chunk_size
)
local
remaining
=
0
local
length
max_chunk_size
=
max_chunk_size
or
default_chunk_size
repeat
-- If we still have data on this chunk
if
max_chunk_size
and
remaining
>
0
then
if
remaining
>
max_chunk_size
then
-- Consume up to max_chunk_size
length
=
max_chunk_size
remaining
=
remaining
-
max_chunk_size
else
-- Consume all remaining
length
=
remaining
remaining
=
0
end
else
-- This is a fresh chunk
-- Receive the chunk size
local
str
,
err
=
sock
:
receive
(
"*l"
)
if
not
str
then
co_yield
(
nil
,
err
)
end
length
=
tonumber
(
str
,
16
)
if
not
length
then
co_yield
(
nil
,
"unable to read chunksize"
)
end
if
max_chunk_size
and
length
>
max_chunk_size
then
-- Consume up to max_chunk_size
remaining
=
length
-
max_chunk_size
length
=
max_chunk_size
end
end
if
length
>
0
then
local
str
,
err
=
sock
:
receive
(
length
)
if
not
str
then
co_yield
(
nil
,
err
)
end
max_chunk_size
=
co_yield
(
str
)
or
default_chunk_size
-- If we're finished with this chunk, read the carriage return.
if
remaining
==
0
then
sock
:
receive
(
2
)
-- read \r\n
end
else
-- Read the last (zero length) chunk's carriage return
sock
:
receive
(
2
)
-- read \r\n
end
until
length
==
0
end
)
end
local
function
_body_reader
(
sock
,
content_length
,
default_chunk_size
)
return
co_wrap
(
function
(
max_chunk_size
)
max_chunk_size
=
max_chunk_size
or
default_chunk_size
if
not
content_length
and
max_chunk_size
then
-- We have no length, but wish to stream.
-- HTTP 1.0 with no length will close connection, so read chunks to the end.
repeat
local
str
,
err
,
partial
=
sock
:
receive
(
max_chunk_size
)
if
not
str
and
err
==
"closed"
then
co_yield
(
partial
,
err
)
end
max_chunk_size
=
tonumber
(
co_yield
(
str
)
or
default_chunk_size
)
if
max_chunk_size
and
max_chunk_size
<
0
then
max_chunk_size
=
nil
end
if
not
max_chunk_size
then
ngx_log
(
ngx_ERR
,
"Buffer size not specified, bailing"
)
break
end
until
not
str
elseif
not
content_length
then
-- We have no length but don't wish to stream.
-- HTTP 1.0 with no length will close connection, so read to the end.
co_yield
(
sock
:
receive
(
"*a"
))
elseif
not
max_chunk_size
then
-- We have a length and potentially keep-alive, but want everything.
co_yield
(
sock
:
receive
(
content_length
))
else
-- We have a length and potentially a keep-alive, and wish to stream
-- the response.
local
received
=
0
repeat
local
length
=
max_chunk_size
if
received
+
length
>
content_length
then
length
=
content_length
-
received
end
if
length
>
0
then
local
str
,
err
=
sock
:
receive
(
length
)
if
not
str
then
co_yield
(
nil
,
err
)
end
received
=
received
+
length
max_chunk_size
=
tonumber
(
co_yield
(
str
)
or
default_chunk_size
)
if
max_chunk_size
and
max_chunk_size
<
0
then
max_chunk_size
=
nil
end
if
not
max_chunk_size
then
ngx_log
(
ngx_ERR
,
"Buffer size not specified, bailing"
)
break
end
end
until
length
==
0
end
end
)
end
local
function
_no_body_reader
()
return
nil
end
local
function
_read_body
(
res
)
local
reader
=
res
.
body_reader
if
not
reader
then
-- Most likely HEAD or 304 etc.
return
nil
,
"no body to be read"
end
local
chunks
=
{}
local
c
=
1
local
chunk
,
err
repeat
chunk
,
err
=
reader
()
if
err
then
return
nil
,
err
,
tbl_concat
(
chunks
)
-- Return any data so far.
end
if
chunk
then
chunks
[
c
]
=
chunk
c
=
c
+
1
end
until
not
chunk
return
tbl_concat
(
chunks
)
end
local
function
_trailer_reader
(
sock
)
return
co_wrap
(
function
()
co_yield
(
_receive_headers
(
sock
))
end
)
end
local
function
_read_trailers
(
res
)
local
reader
=
res
.
trailer_reader
if
not
reader
then
return
nil
,
"no trailers"
end
local
trailers
=
reader
()
setmetatable
(
res
.
headers
,
{
__index
=
trailers
})
end
local
function
_send_body
(
sock
,
body
)
if
type
(
body
)
==
'function'
then
repeat
local
chunk
,
err
,
partial
=
body
()
if
chunk
then
local
ok
,
err
=
sock
:
send
(
chunk
)
if
not
ok
then
return
nil
,
err
end
elseif
err
~=
nil
then
return
nil
,
err
,
partial
end
until
chunk
==
nil
elseif
body
~=
nil
then
local
bytes
,
err
=
sock
:
send
(
body
)
if
not
bytes
then
return
nil
,
err
end
end
return
true
,
nil
end
local
function
_handle_continue
(
sock
,
body
)
local
status
,
version
,
reason
,
err
=
_receive_status
(
sock
)
--luacheck: no unused
if
not
status
then
return
nil
,
nil
,
err
end
-- Only send body if we receive a 100 Continue
if
status
==
100
then
local
ok
,
err
=
sock
:
receive
(
"*l"
)
-- Read carriage return
if
not
ok
then
return
nil
,
nil
,
err
end
_send_body
(
sock
,
body
)
end
return
status
,
version
,
err
end
function
_M
.
send_request
(
self
,
params
)
-- Apply defaults
setmetatable
(
params
,
{
__index
=
DEFAULT_PARAMS
})
local
sock
=
self
.
sock
local
body
=
params
.
body
local
headers
=
http_headers
.
new
()
local
params_headers
=
params
.
headers
if
params_headers
then
-- We assign one by one so that the metatable can handle case insensitivity
-- for us. You can blame the spec for this inefficiency.
for
k
,
v
in
pairs
(
params_headers
)
do
headers
[
k
]
=
v
end
end
-- Ensure minimal headers are set
if
not
headers
[
"Content-Length"
]
then
if
type
(
body
)
==
'string'
then
headers
[
"Content-Length"
]
=
#
body
elseif
body
==
nil
and
EXPECTING_BODY
[
str_upper
(
params
.
method
)]
then
headers
[
"Content-Length"
]
=
0
end
end
if
not
headers
[
"Host"
]
then
if
(
str_sub
(
self
.
host
,
1
,
5
)
==
"unix:"
)
then
return
nil
,
"Unable to generate a useful Host header for a unix domain socket. Please provide one."
end
-- If we have a port (i.e. not connected to a unix domain socket), and this
-- port is non-standard, append it to the Host header.
if
self
.
port
then
if
self
.
ssl
and
self
.
port
~=
443
then
headers
[
"Host"
]
=
self
.
host
..
":"
..
self
.
port
elseif
not
self
.
ssl
and
self
.
port
~=
80
then
headers
[
"Host"
]
=
self
.
host
..
":"
..
self
.
port
else
headers
[
"Host"
]
=
self
.
host
end
else
headers
[
"Host"
]
=
self
.
host
end
end
if
not
headers
[
"User-Agent"
]
then
headers
[
"User-Agent"
]
=
_M
.
_USER_AGENT
end
if
params
.
version
==
1
.
0
and
not
headers
[
"Connection"
]
then
headers
[
"Connection"
]
=
"Keep-Alive"
end
params
.
headers
=
headers
-- Format and send request
local
req
=
_format_request
(
params
)
if
DEBUG
then
ngx_log
(
ngx_DEBUG
,
"
\n
"
,
req
)
end
local
bytes
,
err
=
sock
:
send
(
req
)
if
not
bytes
then
return
nil
,
err
end
-- Send the request body, unless we expect: continue, in which case
-- we handle this as part of reading the response.
if
headers
[
"Expect"
]
~=
"100-continue"
then
local
ok
,
err
,
partial
=
_send_body
(
sock
,
body
)
if
not
ok
then
return
nil
,
err
,
partial
end
end
return
true
end
function
_M
.
read_response
(
self
,
params
)
local
sock
=
self
.
sock
local
status
,
version
,
reason
,
err
-- If we expect: continue, we need to handle this, sending the body if allowed.
-- If we don't get 100 back, then status is the actual status.
if
params
.
headers
[
"Expect"
]
==
"100-continue"
then
local
_status
,
_version
,
_err
=
_handle_continue
(
sock
,
params
.
body
)
if
not
_status
then
return
nil
,
_err
elseif
_status
~=
100
then
status
,
version
,
err
=
_status
,
_version
,
_err
-- luacheck: no unused
end
end
-- Just read the status as normal.
if
not
status
then
status
,
version
,
reason
,
err
=
_receive_status
(
sock
)
if
not
status
then
return
nil
,
err
end
end
local
res_headers
,
err
=
_receive_headers
(
sock
)
if
not
res_headers
then
return
nil
,
err
end
-- keepalive is true by default. Determine if this is correct or not.
local
ok
,
connection
=
pcall
(
str_lower
,
res_headers
[
"Connection"
])
if
ok
then
if
(
version
==
1
.
1
and
str_find
(
connection
,
"close"
,
1
,
true
))
or
(
version
==
1
.
0
and
not
str_find
(
connection
,
"keep-alive"
,
1
,
true
))
then
self
.
keepalive
=
false
end
else
-- no connection header
if
version
==
1
.
0
then
self
.
keepalive
=
false
end
end
local
body_reader
=
_no_body_reader
local
trailer_reader
,
err
local
has_body
=
false
-- Receive the body_reader
if
_should_receive_body
(
params
.
method
,
status
)
then
has_body
=
true
local
te
=
res_headers
[
"Transfer-Encoding"
]
-- Handle duplicate headers
-- This shouldn't happen but can in the real world
if
type
(
te
)
==
"table"
then
te
=
tbl_concat
(
te
,
""
)
end
local
ok
,
encoding
=
pcall
(
str_lower
,
te
)
if
not
ok
then
encoding
=
""
end
if
version
==
1
.
1
and
str_find
(
encoding
,
"chunked"
,
1
,
true
)
~=
nil
then
body_reader
,
err
=
_chunked_body_reader
(
sock
)
else
local
ok
,
length
=
pcall
(
tonumber
,
res_headers
[
"Content-Length"
])
if
not
ok
then
-- No content-length header, read until connection is closed by server
length
=
nil
end
body_reader
,
err
=
_body_reader
(
sock
,
length
)
end
end
if
res_headers
[
"Trailer"
]
then
trailer_reader
,
err
=
_trailer_reader
(
sock
)
end
if
err
then
return
nil
,
err
else
return
{
status
=
status
,
reason
=
reason
,
headers
=
res_headers
,
has_body
=
has_body
,
body_reader
=
body_reader
,
read_body
=
_read_body
,
trailer_reader
=
trailer_reader
,
read_trailers
=
_read_trailers
,
}
end
end
function
_M
.
request
(
self
,
params
)
params
=
tbl_copy
(
params
)
-- Take by value
local
res
,
err
=
self
:
send_request
(
params
)
if
not
res
then
return
res
,
err
else
return
self
:
read_response
(
params
)
end
end
function
_M
.
request_pipeline
(
self
,
requests
)
requests
=
tbl_copy
(
requests
)
-- Take by value
for
_
,
params
in
ipairs
(
requests
)
do
if
params
.
headers
and
params
.
headers
[
"Expect"
]
==
"100-continue"
then
return
nil
,
"Cannot pipeline request specifying Expect: 100-continue"
end
local
res
,
err
=
self
:
send_request
(
params
)
if
not
res
then
return
res
,
err
end
end
local
responses
=
{}
for
i
,
params
in
ipairs
(
requests
)
do
responses
[
i
]
=
setmetatable
({
params
=
params
,
response_read
=
false
,
},
{
-- Read each actual response lazily, at the point the user tries
-- to access any of the fields.
__index
=
function
(
t
,
k
)
local
res
,
err
if
t
.
response_read
==
false
then
res
,
err
=
_M
.
read_response
(
self
,
t
.
params
)
t
.
response_read
=
true
if
not
res
then
ngx_log
(
ngx_ERR
,
err
)
else
for
rk
,
rv
in
pairs
(
res
)
do
t
[
rk
]
=
rv
end
end
end
return
rawget
(
t
,
k
)
end
,
})
end
return
responses
end
function
_M
.
request_uri
(
self
,
uri
,
params
)
params
=
tbl_copy
(
params
or
{})
-- Take by value
local
parsed_uri
,
err
=
self
:
parse_uri
(
uri
,
false
)
if
not
parsed_uri
then
return
nil
,
err
end
local
scheme
,
host
,
port
,
path
,
query
=
unpack
(
parsed_uri
)
if
not
params
.
path
then
params
.
path
=
path
end
if
not
params
.
query
then
params
.
query
=
query
end
-- See if we should use a proxy to make this request
local
proxy_uri
=
self
:
get_proxy_uri
(
scheme
,
host
)
-- Make the connection either through the proxy or directly
-- to the remote host
local
c
,
err
if
proxy_uri
then
local
proxy_authorization
if
scheme
==
"https"
then
if
params
.
headers
and
params
.
headers
[
"Proxy-Authorization"
]
then
proxy_authorization
=
params
.
headers
[
"Proxy-Authorization"
]
else
proxy_authorization
=
self
.
proxy_opts
.
https_proxy_authorization
end
end
c
,
err
=
self
:
connect_proxy
(
proxy_uri
,
scheme
,
host
,
port
,
proxy_authorization
)
else
c
,
err
=
self
:
connect
(
host
,
port
)
end
if
not
c
then
return
nil
,
err
end
if
proxy_uri
then
if
scheme
==
"http"
then
-- When a proxy is used, the target URI must be in absolute-form
-- (RFC 7230, Section 5.3.2.). That is, it must be an absolute URI
-- to the remote resource with the scheme, host and an optional port
-- in place.
--
-- Since _format_request() constructs the request line by concatenating
-- params.path and params.query together, we need to modify the path
-- to also include the scheme, host and port so that the final form
-- in conformant to RFC 7230.
if
port
==
80
then
params
.
path
=
scheme
..
"://"
..
host
..
path
else
params
.
path
=
scheme
..
"://"
..
host
..
":"
..
port
..
path
end
if
self
.
proxy_opts
.
http_proxy_authorization
then
if
not
params
.
headers
then
params
.
headers
=
{}
end
if
not
params
.
headers
[
"Proxy-Authorization"
]
then
params
.
headers
[
"Proxy-Authorization"
]
=
self
.
proxy_opts
.
http_proxy_authorization
end
end
elseif
scheme
==
"https"
then
-- don't keep this connection alive as the next request could target
-- any host and re-using the proxy tunnel for that is not possible
self
.
keepalive
=
false
end
-- self:connect_uri() set the host and port to point to the proxy server. As
-- the connection to the proxy has been established, set the host and port
-- to point to the actual remote endpoint at the other end of the tunnel to
-- ensure the correct Host header added to the requests.
self
.
host
=
host
self
.
port
=
port
end
if
scheme
==
"https"
then
local
verify
=
true
if
params
.
ssl_verify
==
false
then
verify
=
false
end
local
ok
,
err
=
self
:
ssl_handshake
(
nil
,
host
,
verify
)
if
not
ok
then
self
:
close
()
return
nil
,
err
end
end
local
res
,
err
=
self
:
request
(
params
)
if
not
res
then
self
:
close
()
return
nil
,
err
end
local
body
,
err
=
res
:
read_body
()
if
not
body
then
self
:
close
()
return
nil
,
err
end
res
.
body
=
body
if
params
.
keepalive
==
false
then
local
ok
,
err
=
self
:
close
()
if
not
ok
then
ngx_log
(
ngx_ERR
,
err
)
end
else
local
ok
,
err
=
self
:
set_keepalive
(
params
.
keepalive_timeout
,
params
.
keepalive_pool
)
if
not
ok
then
ngx_log
(
ngx_ERR
,
err
)
end
end
return
res
,
nil
end
function
_M
.
get_client_body_reader
(
_
,
chunksize
,
sock
)
chunksize
=
chunksize
or
65536
if
not
sock
then
local
ok
,
err
ok
,
sock
,
err
=
pcall
(
ngx_req_socket
)
if
not
ok
then
return
nil
,
sock
-- pcall err
end
if
not
sock
then
if
err
==
"no body"
then
return
nil
else
return
nil
,
err
end
end
end
local
headers
=
ngx_req_get_headers
()
local
length
=
headers
.
content_length
local
encoding
=
headers
.
transfer_encoding
if
length
then
return
_body_reader
(
sock
,
tonumber
(
length
),
chunksize
)
elseif
encoding
and
str_lower
(
encoding
)
==
'chunked'
then
-- Not yet supported by ngx_lua but should just work...
return
_chunked_body_reader
(
sock
,
chunksize
)
else
return
nil
end
end
function
_M
.
proxy_request
(
self
,
chunksize
)
return
self
:
request
({
method
=
ngx_req_get_method
(),
path
=
ngx_re_gsub
(
ngx_var
.
uri
,
"
\\
s"
,
"%20"
,
"jo"
)
..
ngx_var
.
is_args
..
(
ngx_var
.
query_string
or
""
),
body
=
self
:
get_client_body_reader
(
chunksize
),
headers
=
ngx_req_get_headers
(),
})
end
function
_M
.
proxy_response
(
_
,
response
,
chunksize
)
if
not
response
then
ngx_log
(
ngx_ERR
,
"no response provided"
)
return
end
ngx
.
status
=
response
.
status
-- Filter out hop-by-hop headeres
for
k
,
v
in
pairs
(
response
.
headers
)
do
if
not
HOP_BY_HOP_HEADERS
[
str_lower
(
k
)]
then
ngx_header
[
k
]
=
v
end
end
local
reader
=
response
.
body_reader
repeat
local
chunk
,
err
=
reader
(
chunksize
)
if
err
then
ngx_log
(
ngx_ERR
,
err
)
break
end
if
chunk
then
local
res
,
err
=
ngx_print
(
chunk
)
if
not
res
then
ngx_log
(
ngx_ERR
,
err
)
break
end
end
until
not
chunk
end
function
_M
.
set_proxy_options
(
self
,
opts
)
self
.
proxy_opts
=
tbl_copy
(
opts
)
-- Take by value
end
function
_M
.
get_proxy_uri
(
self
,
scheme
,
host
)
if
not
self
.
proxy_opts
then
return
nil
end
-- Check if the no_proxy option matches this host. Implementation adapted
-- from lua-http library (https://github.com/daurnimator/lua-http)
if
self
.
proxy_opts
.
no_proxy
then
if
self
.
proxy_opts
.
no_proxy
==
"*"
then
-- all hosts are excluded
return
nil
end
local
no_proxy_set
=
{}
-- wget allows domains in no_proxy list to be prefixed by "."
-- e.g. no_proxy=.mit.edu
for
host_suffix
in
ngx_re_gmatch
(
self
.
proxy_opts
.
no_proxy
,
"
\\
.?([^,]+)"
)
do
no_proxy_set
[
host_suffix
[
1
]]
=
true
end
-- From curl docs:
-- matched as either a domain which contains the hostname, or the
-- hostname itself. For example local.com would match local.com,
-- local.com:80, and www.local.com, but not www.notlocal.com.
--
-- Therefore, we keep stripping subdomains from the host, compare
-- them to the ones in the no_proxy list and continue until we find
-- a match or until there's only the TLD left
repeat
if
no_proxy_set
[
host
]
then
return
nil
end
-- Strip the next level from the domain and check if that one
-- is on the list
host
=
ngx_re_sub
(
host
,
"^[^.]+\\."
,
""
)
until
not
ngx_re_find
(
host
,
"
\\
."
)
end
if
scheme
==
"http"
and
self
.
proxy_opts
.
http_proxy
then
return
self
.
proxy_opts
.
http_proxy
end
if
scheme
==
"https"
and
self
.
proxy_opts
.
https_proxy
then
return
self
.
proxy_opts
.
https_proxy
end
return
nil
end
function
_M
.
connect_proxy
(
self
,
proxy_uri
,
scheme
,
host
,
port
,
proxy_authorization
)
-- Parse the provided proxy URI
local
parsed_proxy_uri
,
err
=
self
:
parse_uri
(
proxy_uri
,
false
)
if
not
parsed_proxy_uri
then
return
nil
,
err
end
-- Check that the scheme is http (https is not supported for
-- connections between the client and the proxy)
local
proxy_scheme
=
parsed_proxy_uri
[
1
]
if
proxy_scheme
~=
"http"
then
return
nil
,
"protocol "
..
proxy_scheme
..
" not supported for proxy connections"
end
-- Make the connection to the given proxy
local
proxy_host
,
proxy_port
=
parsed_proxy_uri
[
2
],
parsed_proxy_uri
[
3
]
local
c
,
err
=
self
:
connect
(
proxy_host
,
proxy_port
)
if
not
c
then
return
nil
,
err
end
if
scheme
==
"https"
then
-- Make a CONNECT request to create a tunnel to the destination through
-- the proxy. The request-target and the Host header must be in the
-- authority-form of RFC 7230 Section 5.3.3. See also RFC 7231 Section
-- 4.3.6 for more details about the CONNECT request
local
destination
=
host
..
":"
..
port
local
res
,
err
=
self
:
request
({
method
=
"CONNECT"
,
path
=
destination
,
headers
=
{
[
"Host"
]
=
destination
,
[
"Proxy-Authorization"
]
=
proxy_authorization
,
}
})
if
not
res
then
return
nil
,
err
end
if
res
.
status
<
200
or
res
.
status
>
299
then
return
nil
,
"failed to establish a tunnel through a proxy: "
..
res
.
status
end
end
return
c
,
nil
end
return
_M
server/www/teleport/webroot/app/plugin/docker_build/http_headers.lua
0 → 100644
View file @
55ade2f1
local
rawget
,
rawset
,
setmetatable
=
rawget
,
rawset
,
setmetatable
local
str_lower
=
string.lower
local
_M
=
{
_VERSION
=
'0.14'
,
}
-- Returns an empty headers table with internalised case normalisation.
function
_M
.
new
()
local
mt
=
{
normalised
=
{},
}
mt
.
__index
=
function
(
t
,
k
)
return
rawget
(
t
,
mt
.
normalised
[
str_lower
(
k
)])
end
mt
.
__newindex
=
function
(
t
,
k
,
v
)
local
k_normalised
=
str_lower
(
k
)
-- First time seeing this header field?
if
not
mt
.
normalised
[
k_normalised
]
then
-- Create a lowercased entry in the metatable proxy, with the value
-- of the given field case
mt
.
normalised
[
k_normalised
]
=
k
-- Set the header using the given field case
rawset
(
t
,
k
,
v
)
else
-- We're being updated just with a different field case. Use the
-- normalised metatable proxy to give us the original key case, and
-- perorm a rawset() to update the value.
rawset
(
t
,
mt
.
normalised
[
k_normalised
],
v
)
end
end
return
setmetatable
({},
mt
)
end
return
_M
server/www/teleport/webroot/app/plugin/docker_build/small_web.py
View file @
55ade2f1
...
...
@@ -9,23 +9,47 @@ import random
import
time
import
requests
from
flask
import
Flask
,
request
import
rsa
from
pyDes
import
des
,
CBC
,
PAD_PKCS5
import
binascii
import
traceback
from
flask
import
Flask
,
request
,
jsonify
from
selenium
import
webdriver
# import cv2
from
Crypto.PublicKey
import
RSA
from
Crypto.Cipher
import
PKCS1_v1_5
logging
.
basicConfig
(
level
=
logging
.
DEBUG
)
import
cv2
from
selenium.common.exceptions
import
NoSuchWindowException
,
WebDriverException
logging
.
basicConfig
(
level
=
logging
.
INFO
)
app
=
Flask
(
__name__
)
with
open
(
'public.pem'
,
'r'
)
as
f
:
pubkey_s
=
f
.
read
()
pubkey
=
rsa
.
PublicKey
.
load_pkcs1
(
pubkey_s
.
encode
())
with
open
(
'private.pem'
,
'r'
)
as
f
:
private_key
=
f
.
read
()
FATEA_PRED_URL
=
"http://pred.fateadm.com"
# private_key = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALBiT+CFXy3xpe+SSZjf3tYp1POdheHj2Wr/kQa4Fnrmnw+MqhqyNNSCdnY7vVNuvAHvUFtpH1yRgO/dCwjmNQHeANC0odJFjAzX7UkpDVW6RGw/GC2tXs5+nckx2a+5j7JNLoFHZi9YjSKwtwgLf0cXcqzfjq2quvoj8vvaUzdZAgMBAAECgYAuFOFNhUrClBmIJ632tLZhOXibVRI/W+nXnIFlQf8NiOcRhuyCIQDQbG1KonzqKUoRL1bNKv+4jYMkJ5nUb2B1d1JPWhh3BR5V5qrAYEpbL5IQh05Sk0igfT+k/b1TYOydWs7Wa7oholFMLnqpy9az4UqP3hV6LSBPM8L5tmOb6QJBANwoYEEboF8MTXXkDD0W4JXpw4Ja3R+JoRMraKMPdsDvD4e5lP29UFU/40A6SSQGSyNpllvYmI8akTUlduiActcCQQDNGY7bSl9FAJWnONP58kdr3RCZlzhO/Qqk8sb8JAEywlUXggCNtfLFqFrdJHAaJpsB9rXMYq3QUs57hh5i/JFPAkEAzxmkQlsMp5zZGTdnU+g7aIq4gd2b+Vjsjy3chte7LI82GsU3JOJ7uVYaHoc12o+ZCzz+VnQQPz4MruQJUXnTjQJBAKFe9pN7VLIJ37WOdNo30hIAAUuXO2qKlZFqoz1HZtn1JNY2JxFYkwcJi1RrkvhAX72Py0JgcblzLZrqz4W6iukCQQDN1TfsS2qyJ/7gX1pU6rV1JvnU7ckXz+/mxS6k2G0yz65P6W1k1mCrRyp+Ul5t5VCyhF7eF+4BiaNRg9jQDaDX"
# private_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIsyzM8WRLiiQ1nm0NTNMWEccNVa5XYLYm1qG0Oa6W9mIQ+oMGbn2IYH/j5XJduQ+AKeyMN8v6vmaJku2/X1CbwXM0K/uWtkPMg8wk7OEKsmmdA5Z0SO0R56InT77xSYdJyPh5SSE+pewtKrjnvR5jCwLW+BsnPIRbN7YliMq8NJAgMBAAECgYAAl7PFgevC+XXd8Ryce08lgbB9SAjICt5dZuE81XD+92lWnrmuBnimgWw0qbxQhfp4UGK8alCKk82IMWngTy2+bKEbP94b2HgpATAm9o5m3pfB5Td8dCnl4+cay2KOk0GYFUYY4JTAQ5mzjHQR1VW7PKwzTeGF/ajaAnV6ZubA3QJBANHEf3p6C+SZ7zkWuD7zSmARrVVq8qxIzm+CwIyWvUvy6GrosjXy08nUv3KWHX7fRIqxWCrMsgn6A/p1DBaQOYMCQQCp4KbZkGG4hQz+8EQ+87JxinDoOS5r2BdV3mB8yTzcaJ4+JaCXMb8XQW/BHqSa/w6kn+W3ZlVNlHoABUhxYJJDAkEAxvY6959lQmnjZmGvVj4KsH5zys4K6PCRpWD+Yxri53O5kRWvWs48pXY+NGBAD8OTTn2Ro97Ni/rw5RE56vjXIwJAAhA0dpgGV9Nl4QLSEWGsXSytSmTHZ4/sWKKm0V0wXAz5Pw/971gvVfz5eoMAxNEsQFug0qVvi82t3aoyww3FOQJBAMAtrqdy/BYTepdxgrg3H9JDdoHVHFHKrYKHgsKC1a1OIQXG6IqM+cCFXHjZZfVHiOXlC6aNN6vlGSwcLsbxSKQ="
def
rsa_long_decrypt
(
priv_key_str
,
msg
):
msg
=
base64
.
b64decode
(
msg
)
length
=
len
(
msg
)
default_length
=
128
# 私钥解密
priobj
=
PKCS1_v1_5
.
new
(
RSA
.
importKey
(
base64
.
b64decode
(
priv_key_str
)))
# 长度不用分段
if
length
<
default_length
:
return
b
''
.
join
(
priobj
.
decrypt
(
msg
,
b
'xyz'
))
.
decode
()
# 需要分段
offset
=
0
res
=
[]
while
length
-
offset
>
0
:
if
length
-
offset
>
default_length
:
res
.
append
(
priobj
.
decrypt
(
msg
[
offset
:
offset
+
default_length
],
b
'xyz'
))
else
:
res
.
append
(
priobj
.
decrypt
(
msg
[
offset
:],
b
'xyz'
))
offset
+=
default_length
return
b
''
.
join
(
res
)
.
decode
()
class
TmpObj
():
...
...
@@ -139,26 +163,6 @@ class FateadmApi():
return
self
.
Predict
(
pred_type
,
data
,
src_url
)
def
des_descrypt
(
s
,
key
=
None
):
"""
DES 解密
:param s: 加密后的字符串,16进制
:return: 解密后的字符串
"""
secret_key
=
key
iv
=
secret_key
k
=
des
(
secret_key
,
CBC
,
iv
,
pad
=
None
,
padmode
=
PAD_PKCS5
)
de
=
k
.
decrypt
(
binascii
.
a2b_hex
(
s
),
padmode
=
PAD_PKCS5
)
return
de
def
md5
(
str
):
m
=
hashlib
.
md5
()
b
=
str
.
encode
(
encoding
=
'utf-8'
)
m
.
update
(
b
)
return
m
.
hexdigest
()
class
Driver
(
object
):
def
__init__
(
self
):
self
.
_driver
=
self
.
create_driver
()
...
...
@@ -176,6 +180,22 @@ class Driver(object):
def
driver
(
self
):
return
self
.
_driver
def
switch
(
self
):
pass
def
new_page
(
self
,
url
):
js
=
'window.open("{}");'
.
format
(
url
)
self
.
driver
.
execute_script
(
js
)
def
check
(
self
):
# https://authet2.alipay.com/login/checkSecurity.htm
prop
=
{
"auth"
:
"https://authet2.alipay.com/login/checkSecurity.htm"
,
"login"
:
"https://b.alipay.com/index2.htm"
}
for
k
,
url
in
prop
.
items
():
if
self
.
driver
.
current_url
in
url
:
return
k
return
'unknown'
def
get_driver
():
"""
...
...
@@ -187,6 +207,7 @@ def get_driver():
def
do_tool
(
k
):
logging
.
info
(
"xdotool key {}"
.
format
(
k
))
os
.
system
(
"xdotool key {}"
.
format
(
k
))
time
.
sleep
(
random
.
randint
(
1
,
10
)
*
0.1
)
...
...
@@ -209,8 +230,10 @@ def crop_code(img_path):
def
try_login
(
account
,
password
):
# todo 多次登录处理
# xdotool mousemove x y click 1 click 1
driver
=
get_driver
()
.
driver
driver
.
get
(
"https://b.alipay.com/index2.htm"
)
time
.
sleep
(
1
)
[
do_tool
(
k
)
for
k
in
account
]
do_tool
(
"Tab"
)
[
do_tool
(
k
)
for
k
in
password
]
...
...
@@ -234,22 +257,43 @@ def try_login(account, password):
# do_tool("KP_Enter")
@app.route
(
'/token'
,
methods
=
[
'GET'
,
'POST'
])
def
token
():
ip
=
request
.
form
[
'ip'
]
timestamp
=
request
.
form
[
'timestamp'
]
msg
=
request
.
form
[
'msg'
]
user_agent
=
request
.
headers
.
environ
[
'HTTP_USER_AGENT'
]
token
=
md5
(
user_agent
+
ip
+
str
(
timestamp
))
crypto_email_text
=
base64
.
b64decode
(
msg
)
if
rsa
.
verify
(
token
.
encode
(),
crypto_email_text
,
pubkey
)
==
'SHA-1'
:
# 容器加载token
url
=
'http://127.0.0.1:10086/set'
headers
=
{
"appid"
:
token
}
resp
=
requests
.
get
(
url
,
headers
=
headers
)
print
(
resp
.
text
)
return
'ok'
return
'fail'
def
md5
(
s
):
m
=
hashlib
.
md5
()
b
=
s
.
encode
(
encoding
=
'utf-8'
)
m
.
update
(
b
)
return
m
.
hexdigest
()
def
check_driver
(
key
=
'alipay'
):
browser
=
get_driver
()
driver
=
browser
.
driver
try
:
window_handle
=
driver
.
current_window_handle
res
=
False
for
handles
in
driver
.
window_handles
:
driver
.
switch_to
.
window
(
handles
)
if
key
in
driver
.
current_url
:
res
=
True
break
driver
.
switch_to
.
window
(
window_handle
)
if
not
res
:
browser
.
new_page
(
"https://b.alipay.com/index2.htm"
)
return
res
except
NoSuchWindowException
as
e
:
# 页面被关闭
logging
.
error
(
"test test ******** no such window: window was already closed ********"
)
if
driver
.
window_handles
:
driver
.
switch_to
.
window
(
driver
.
window_handles
[
0
])
browser
.
new_page
(
"https://b.alipay.com/index2.htm"
)
except
WebDriverException
as
e
:
# unknown error: session deleted because of page crash
logging
.
error
(
"test test ******** chrome not reachable ********"
)
builtins
.
__dict__
[
'driver'
]
=
Driver
()
browser
.
new_page
(
"https://b.alipay.com/index2.htm"
)
except
Exception
as
e
:
err
=
str
(
traceback
.
format_exc
())
logging
.
error
(
err
)
# 接收账户密码接口
...
...
@@ -257,24 +301,45 @@ def token():
def
login_alipay
():
try
:
logging
.
info
(
"demo"
)
body
=
request
.
form
[
'body'
]
body
=
json
.
loads
(
request
.
data
.
decode
())
t
=
body
[
't'
]
m
=
body
[
'm'
]
body
=
rsa_long_decrypt
(
private_key
,
m
)
logging
.
info
(
body
)
body
=
des_descrypt
(
base64
.
b64decode
(
body
),
md5
(
pubkey_s
)[:
8
])
if
not
body
:
return
"fail"
body
=
json
.
loads
(
body
.
decode
()
)
return
jsonify
({
"code"
:
300
})
body
=
json
.
loads
(
body
)
account
=
body
.
get
(
"account"
,
""
)
password
=
body
.
get
(
"password"
,
""
)
if
account
and
password
:
# try_login(account, password)
return
'ok'
return
'disenable param'
return
jsonify
({
"code"
:
200
})
return
jsonify
({
"code"
:
201
})
except
:
import
traceback
logging
.
error
(
traceback
.
format_exc
())
# todo 定时任务检查
# 定时任务配置类
class
SchedulerConfig
(
object
):
JOBS
=
[
{
'id'
:
'check_driver'
,
# 任务id
'func'
:
'__main__:check_driver'
,
# 任务执行程序
'args'
:
(),
# 执行程序参数
'trigger'
:
'interval'
,
# 任务执行类型,定时器
'seconds'
:
6
,
# 任务执行时间,单位秒
}
]
app
.
config
.
from_object
(
SchedulerConfig
())
if
__name__
==
'__main__'
:
app
.
run
(
port
=
8000
)
# from flask_apscheduler import APScheduler
# scheduler = APScheduler()
# scheduler.init_app(app)
# scheduler.start()
app
.
run
(
host
=
"0.0.0.0"
,
port
=
8000
)
# try_login(account, password)
# check_driver()
server/www/teleport/webroot/app/plugin/docker_build/supervisord.conf
View file @
55ade2f1
...
...
@@ -26,7 +26,7 @@ command=/usr/bin/java -jar /root/selenium.jar
autorestart
=
true
[
program
:
nginx
]
command
=/
usr
/
bin
/
nginx
command
=/
usr
/
bin
/
nginx
-
g
'daemon off;'
autorestart
=
true
[
program
:
fcitx
]
...
...
server/www/teleport/webroot/app/plugin/docker_build/token_check.lua
0 → 100644
View file @
55ade2f1
--
-- Created by IntelliJ IDEA.
-- User: nanda
-- Date: 2021/1/25
-- Time: 14:29
-- To change this template use File | Settings | File Templates.
--
local
n_err
=
ngx
.
ERR
local
n_warn
=
ngx
.
WARN
local
n_info
=
ngx
.
INFO
local
n_log
=
ngx
.
log
local
http
=
require
(
"resty.http"
)
local
httpc
=
http
.
new
()
local
cjson
=
require
(
"cjson"
)
local
token
=
nil
local
args
=
nil
-- security 权限校验接口
local
url
=
"http://172.30.20.128:6016/access/jwt/check/host/token"
;
local
rep
;
local
resStr
=
{
code
=
500
,
message
=
"token is wrong"
}
local
resStrJson
=
cjson
.
encode
(
resStr
)
n_log
(
n_err
,
"resStrJson == "
,
resStrJson
)
--获取参数的值
if
"GET"
==
ngx
.
req
.
get_method
()
then
args
=
ngx
.
req
.
get_uri_args
()
elseif
"POST"
==
ngx
.
req
.
get_method
()
then
ngx
.
req
.
read_body
()
args
=
ngx
.
req
.
get_post_args
()
end
if
args
==
nil
then
n_log
(
n_err
,
"args 校验失败== 请求终止"
)
ngx
.
exit
(
ngx
.
HTTP_FORBIDDEN
)
return
resStrJson
;
end
--local headers_tab = ngx.req.get_headers()
--if headers_tab and token == nil then
-- n_log(n_err,"token == ",headers_tab["token"])
-- token = headers_tab["token"];
--end
function
get_client_ip
()
local
headers
=
ngx
.
req
.
get_headers
()
local
ip
=
headers
[
"X-REAL-IP"
]
or
headers
[
"X_FORWARDED_FOR"
]
or
ngx
.
var
.
remote_addr
or
"0.0.0.0"
return
ip
end
local
request_ip
=
get_client_ip
()
token
=
args
[
"token"
]
if
token
==
nil
then
token
=
ngx
.
var
.
cookie_token
end
--local getip = httpGet("http://ip.chinaz.com/getip.aspx")
local
ip
,
err
=
httpc
:
request_uri
(
"https://api.ip.sb/ip"
,
{
method
=
"GET"
})
n_log
(
n_err
,
"token == "
,
token
)
n_log
(
n_err
,
"ip == "
,
ip
)
n_log
(
n_err
,
"err == "
,
err
)
local
reqStr
=
{
token
=
token
,
productId
=
"host_ip="
..
ngx
.
var
.
client_ip
}
local
reqStrJson
=
cjson
.
encode
(
reqStr
)
n_log
(
n_err
,
"reqStrJson == "
,
reqStrJson
)
-- http 请求
local
res
,
err
=
httpc
:
request_uri
(
url
,
{
method
=
"POST"
,
body
=
reqStrJson
,
headers
=
{
[
"Content-Type"
]
=
"application/json"
,
}
})
-- local res = ngx.location.capture("/public_api",{method=ngx.HTTP_GET,body="token="..token,args={token=token}})
if
not
res
then
n_log
(
n_warn
,
"failed to request: "
,
err
)
ngx
.
exit
(
ngx
.
HTTP_FORBIDDEN
)
return
resStrJson
end
n_log
(
n_err
,
"res.body == "
,
res
.
body
)
rep
=
res
.
body
;
local
rep_json
=
cjson
.
decode
(
rep
);
if
rep_json
.
code
~=
0
then
n_log
(
n_err
,
"token 校验失败== 请求终止"
)
ngx
.
exit
(
ngx
.
HTTP_FORBIDDEN
)
return
resStrJson
;
end
--请求之后,状态码
ngx
.
status
=
res
.
status
if
ngx
.
status
~=
200
then
n_log
(
n_err
,
"非200状态,ngx.status:"
..
ngx
.
status
)
ngx
.
exit
(
ngx
.
HTTP_FORBIDDEN
)
return
resStrJson
end
server/www/teleport/webroot/app/plugin/docker_build/vnc-redir.conf
View file @
55ade2f1
...
...
@@ -4,23 +4,8 @@ server {
server_name
_
;
gzip
on
;
location
/ {
access_by_lua
'
local
cache_ngx
=
ngx
.
shared
.
my_cache
local
token
=
ngx
.
var
.
cookie_token
if
not
token
then
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
token
)
ngx
.
exit
(
200
)
end
local
token2
=
cache_ngx
:
get
(
token
)
if
not
token2
then
local
errs
=
"requests check fail"
ngx
.
status
=
ngx
.
HTTP_FORBIDDEN
ngx
.
say
(
errs
)
ngx
.
exit
(
200
)
end
return
'
;
access_by_lua_file
mylua
/
token_check
.
lua
;
# 转发至 VNC 服务
proxy_pass
http
://
127
.
0
.
0
.
1
:
8084
;
proxy_set_header
Referer
$
http_referer
;
proxy_set_header
Host
$
http_host
;
...
...
server/www/teleport/webroot/app/plugin/remote.py
View file @
55ade2f1
...
...
@@ -188,12 +188,14 @@ def install_docker(ip, username, password, pubkey):
f
.
write
(
pubkey
)
push_file
(
ip
,
username
,
password
,
{
"{path}/api-redir.conf"
:
'/root/build/api-redir.conf'
,
"{path}/cache-redir.conf"
:
"/root/build/cache-redir.conf"
,
"{path}/token_check.lua"
:
"/root/build/token_check.lua"
,
"{path}/http.lua"
:
"/root/build/http.lua"
,
"{path}/http_headers.lua"
:
"/root/build/http_headers.lua"
,
"{path}/vnc-redir.conf"
:
"/root/build/vnc-redir.conf"
,
"{path}/Dockerfile"
:
"/root/build/Dockerfile"
,
"{path}/supervisord.conf"
:
"/root/build/supervisord.conf"
,
"{path}/small_web.py"
:
"/root/build/small_web.py"
,
temp_file
:
"/root/build/p
ublic
.pem"
},
"docker_build"
)
temp_file
:
"/root/build/p
rivate
.pem"
},
"docker_build"
)
if
__name__
==
'__main__'
:
...
...
server/www/teleport/webroot/app/plugin/shop_build/install.sh
0 → 100644
View file @
55ade2f1
#!/bin/bash
PATH
=
/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export
PATH
LANG
=
en_US.UTF-8
setup_path
=
"/www"
if
[
"
$1
"
]
;
then
IDC_CODE
=
$1
fi
Red_Error
(){
echo
'================================================='
;
printf
'\033[1;31;40m%b\033[0m\n'
"
$1
"
;
exit
0
;
}
is64bit
=
$(
getconf LONG_BIT
)
if
[
"
${
is64bit
}
"
!=
'64'
]
;
then
Red_Error
"抱歉, 7.x不支持32位系统, 请使用64位系统或安装宝塔5.9!"
;
fi
isPy26
=
$(
python
-V
2>&1|grep
'2.6.'
)
if
[
"
${
isPy26
}
"
]
;
then
Red_Error
"抱歉, 7.x不支持Centos6.x,请安装Centos7或安装宝塔5.9"
;
fi
Lock_Clear
(){
if
[
-f
"/etc/bt_crack.pl"
]
;
then
chattr
-R
-ia
/www
chattr
-ia
/etc/init.d/bt
\c
p
-rpa
/www/backup/panel/vhost/
*
/www/server/panel/vhost/
mv
/www/server/panel/BTPanel/__init__.bak /www/server/panel/BTPanel/__init__.py
rm
-f
/etc/bt_crack.pl
fi
}
Install_Check
(){
while
[
"
$yes
"
!=
'yes'
]
&&
[
"
$yes
"
!=
'n'
]
do
echo
-e
"----------------------------------------------------"
echo
-e
"已有Web环境,安装宝塔可能影响现有站点"
echo
-e
"Web service is alreday installed,Can't install panel"
echo
-e
"----------------------------------------------------"
read
-p
"输入yes强制安装/Enter yes to force installation (yes/n): "
yes
;
done
if
[
"
$yes
"
==
'n'
]
;
then
exit
;
fi
}
System_Check
(){
for
serviceS
in
nginx httpd mysqld
do
if
[
-f
"/etc/init.d/
${
serviceS
}
"
]
;
then
if
[
"
${
serviceS
}
"
=
"httpd"
]
;
then
serviceCheck
=
$(
cat
/etc/init.d/
${
serviceS
}
|grep /www/server/apache
)
elif
[
"
${
serviceS
}
"
=
"mysqld"
]
;
then
serviceCheck
=
$(
cat
/etc/init.d/
${
serviceS
}
|grep /www/server/mysql
)
else
serviceCheck
=
$(
cat
/etc/init.d/
${
serviceS
}
|grep /www/server/
${
serviceS
})
fi
[
-z
"
${
serviceCheck
}
"
]
&&
Install_Check
fi
done
}
Get_Pack_Manager
(){
if
[
-f
"/usr/bin/yum"
]
&&
[
-d
"/etc/yum.repos.d"
]
;
then
PM
=
"yum"
elif
[
-f
"/usr/bin/apt-get"
]
&&
[
-f
"/usr/bin/dpkg"
]
;
then
PM
=
"apt-get"
fi
}
Auto_Swap
()
{
swap
=
$(
free |grep Swap|awk
'{print $2}'
)
if
[
"
${
swap
}
"
-gt
1
]
;
then
echo
"Swap total sizse:
$swap
"
;
return
;
fi
if
[
!
-d
/www
]
;
then
mkdir
/www
fi
swapFile
=
"/www/swap"
dd
if
=
/dev/zero
of
=
$swapFile
bs
=
1M
count
=
1025
mkswap
-f
$swapFile
swapon
$swapFile
echo
"
$swapFile
swap swap defaults 0 0"
>>
/etc/fstab
swap
=
`
free |grep Swap|awk
'{print $2}'
`
if
[
$swap
-gt
1
]
;
then
echo
"Swap total sizse:
$swap
"
;
return
;
fi
sed
-i
"/
\/
www
\/
swap/d"
/etc/fstab
rm
-f
$swapFile
}
Service_Add
(){
if
[
"
${
PM
}
"
==
"yum"
]
||
[
"
${
PM
}
"
==
"dnf"
]
;
then
chkconfig
--add
bt
chkconfig
--level
2345 bt on
elif
[
"
${
PM
}
"
==
"apt-get"
]
;
then
update-rc.d bt defaults
fi
}
get_node_url
(){
echo
'---------------------------------------------'
;
echo
"Selected download node..."
;
nodes
=(
http://183.235.223.101:3389 http://119.188.210.21:5880 http://125.88.182.172:5880 http://103.224.251.67 http://45.32.116.160 http://download.bt.cn
)
;
i
=
1
;
if
[
!
-f
/bin/curl
]
;
then
if
[
"
${
PM
}
"
=
"yum"
]
;
then
yum
install
curl
-y
elif
[
"
${
PM
}
"
=
"apt-get"
]
;
then
apt-get
install
curl
-y
fi
fi
for
node
in
${
nodes
[@]
}
;
do
start
=
`
date
+%s.%N
`
result
=
`
curl
-sS
--connect-timeout
3
-m
60
$node
/check.txt
`
if
[
$result
=
'True'
]
;
then
end
=
`
date
+%s.%N
`
start_s
=
`
echo
$start
|
cut
-d
'.'
-f
1
`
start_ns
=
`
echo
$start
|
cut
-d
'.'
-f
2
`
end_s
=
`
echo
$end
|
cut
-d
'.'
-f
1
`
end_ns
=
`
echo
$end
|
cut
-d
'.'
-f
2
`
time_micro
=
$((
(
10
#$end_s-10#$start_s)*1000000 + (10#$end_ns/1000 - 10#$start_ns/1000) ))
time_ms
=
$((
$time_micro
/
1000
))
values[
$i
]=
$time_ms
;
urls[
$time_ms
]=
$node
i
=
$((
$i
+
1
))
fi
done
j
=
5000
for
n
in
${
values
[@]
}
;
do
if
[
$j
-
gt
$n
]
;
then
j
=
$n
fi
done
if
[
$j
=
5000
]
;
then
NODE_URL
=
'http://download.bt.cn'
;
else
NODE_URL
=
${
urls
[
$j
]
}
fi
download_Url
=
$NODE_URL
echo
"Download node:
$download_Url
"
;
echo
'---------------------------------------------'
;
}
Remove_Package
(){
local
PackageNmae
=
$1
if
[
"
${
PM
}
"
==
"yum"
]
;
then
isPackage
=
$(
rpm
-q
${
PackageNmae
}
|grep
"not installed"
)
if
[
-
z
"
${
isPackage
}
"
]
;
then
yum remove
${
PackageNmae
}
-
y
fi
elif
[
"
${
PM
}
"
==
"apt-get"
]
;
then
isPackage
=
$(
dpkg
-l
|grep
${
PackageNmae
})
if
[
"
${
PackageNmae
}
"
]
;
then
apt-get remove
${
PackageNmae
}
-
y
fi
fi
}
Install_RPM_Pack
(){
yumPath
=/
etc/yum.conf
Centos8Check
=
$(
cat
/etc/redhat-release |
grep
' 8.'
|
grep
-iE
'centos|Red Hat'
)
isExc
=
$(
cat
$yumPath
|grep httpd
)
if
[
"
$isExc
"
=
""
]
;
then
echo
"exclude=httpd nginx php mysql mairadb python-psutil python2-psutil"
>>
$yumPath
fi
yumBaseUrl
=
$(
cat
/etc/yum.repos.d/CentOS-Base.repo|grep
baseurl
=
http|cut
-d
'='
-f
2|cut
-d
'$'
-f
1|head
-n
1
)
[
"
${
yumBaseUrl
}
"
]
&&
checkYumRepo
=
$(
curl
--connect-timeout
5
--head
-s
-o
/dev/null
-w
%
{
http_code
}
${
yumBaseUrl
})
if
[
"
${
checkYumRepo
}
"
!=
"200"
]
;
then
curl
-
Ss
--
connect-timeout
3
-
m
60
http://download.bt.cn/install/yumRepo_select.sh|bash
fi
#尝试同步时间(从bt.cn)
echo
'Synchronizing system time...'
getBtTime
=
$(
curl
-sS
--connect-timeout
3
-m
60 http://www.bt.cn/api/index/get_time
)
if
[
"
${
getBtTime
}
"
]
;
then
date
-
s
"
$(
date
-d
@
$getBtTime
+
"%Y-%m-%d %H:%M:%S"
)
"
fi
if
[
-
z
"
${
Centos8Check
}
"
]
;
then
yum
install
ntp
-
y
rm
-
rf
/
etc/localtime
ln
-
s
/
usr/share/zoneinfo/Asia/Shanghai
/
etc/localtime
#尝试同步国际时间(从ntp服务器)
ntpdate
0
.asia.pool.ntp.org
setenforce
0
fi
startTime
=
`
date
+%s
`
sed
-
i
's/SELINUX=enforcing/SELINUX=disabled/'
/
etc/selinux/config
#yum remove -y python-requests python3-requests python-greenlet python3-greenlet
yumPacks
=
"wget python-devel python-imaging tar zip unzip openssl openssl-devel gcc libxml2 libxml2-devel libxslt* zlib zlib-devel libjpeg-devel libpng-devel libwebp libwebp-devel freetype freetype-devel lsof pcre pcre-devel vixie-cron crontabs icu libicu-devel c-ares"
yum
install
-
y
${
yumPacks
}
for
yumPack
in
${
yumPacks
}
do
rpmPack
=
$(
rpm
-q
${
yumPack
})
packCheck
=
$(
echo
${
rpmPack
}
|grep not
)
if
[
"
${
packCheck
}
"
]
;
then
yum
install
${
yumPack
}
-
y
fi
done
if
[
-
f
"/usr/bin/dnf"
]
;
then
dnf
install
-
y redhat-rpm-config
fi
yum
install
epel-release
-
y
if
[
-
z
"
${
Centos8Check
}
"
]
;
then
yum
install
python-devel
-
y
else
yum
install
python3 python3-devel
-
y
ln
-
sf
/
usr/bin/python3
/
usr/bin/python
fi
}
Install_Deb_Pack
(){
ln
-
sf bash
/
bin/sh
apt-get update
-
y
apt-get
install
ruby
-
y
apt-get
install
lsb-release
-
y
#apt-get install ntp ntpdate -y
#/etc/init.d/ntp stop
#update-rc.d ntp remove
#cat >>~/.profile<<EOF
#TZ='Asia/Shanghai'; export TZ
#EOF
#rm -rf /etc/localtime
#cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#echo 'Synchronizing system time...'
#ntpdate 0.asia.pool.ntp.org
#apt-get upgrade -y
for
pace
in
wget curl python python-dev python-imaging zip unzip openssl libssl-dev gcc libxml2 libxml2-dev libxslt zlib1g zlib1g-dev libjpeg-dev libpng-dev lsof libpcre3 libpcre3-dev cron
;
do
apt-get
-
y
install
$pace
--
force-yes
;
done
apt-get
-
y
install
python-dev
tmp
=
$(
python
-V
2>&1|awk
'{print $2}'
)
pVersion
=
${
tmp
:0:3
}
if
[
"
${
pVersion
}
"
==
'2.7'
]
;
then
apt-get
-
y
install
python2.7-dev
fi
if
[
!
-
d
'/etc/letsencrypt'
]
;
then
mkdir
-
p
/
etc/letsencryp
mkdir
-
p
/
var/spool/cron
if
[
!
-
f
'/var/spool/cron/crontabs/root'
]
;
then
echo
''
>
/
var/spool/cron/crontabs/root
chmod
600
/
var/spool/cron/crontabs/root
fi
fi
}
Install_Bt
(){
panelPort
=
"8888"
if
[
-
f
${
setup_path
}
/
server/panel/data/port.pl
]
;
then
panelPort
=
$(
cat
${
setup_path
}
/server/panel/data/port.pl
)
fi
mkdir
-
p
${
setup_path
}
/
server/panel/logs
mkdir
-
p
${
setup_path
}
/
server/panel/vhost/apache
mkdir
-
p
${
setup_path
}
/
server/panel/vhost/nginx
mkdir
-
p
${
setup_path
}
/
server/panel/vhost/rewrite
mkdir
-
p
${
setup_path
}
/
server/panel/install
mkdir
-
p
/
www/server
mkdir
-
p
/
www/wwwroot
mkdir
-
p
/
www/wwwlogs
mkdir
-
p
/
www/backup/database
mkdir
-
p
/
www/backup/site
if
[
!
-
f
"/usr/bin/unzip"
]
;
then
if
[
"
${
PM
}
"
=
"yum"
]
;
then
yum
install
unzip
-
y
elif
[
"
${
PM
}
"
=
"apt-get"
]
;
then
apt-get
install
unzip
-
y
fi
fi
if
[
-
f
"/etc/init.d/bt"
]
;
then
/
etc/init.d/bt stop
sleep
1
fi
wget
-
O panel.zip
${
download_Url
}
/
install
/
src/panel6.zip
-
T
10
wget
-
O
/
etc/init.d/bt
${
download_Url
}
/
install
/
src/bt6.init
-
T
10
wget
-
O
/
www/server/panel/install/public.sh http://download.bt.cn/install/public.sh
-
T
10
if
[
-
f
"
${
setup_path
}
/server/panel/data/default.db"
]
;
then
if
[
-
d
"/
${
setup_path
}
/server/panel/old_data"
]
;
then
rm
-
rf
${
setup_path
}
/
server/panel/old_data
fi
mkdir
-
p
${
setup_path
}
/
server/panel/old_data
mv
-
f
${
setup_path
}
/
server/panel/data/default.db
${
setup_path
}
/
server/panel/old_data/default.db
mv
-
f
${
setup_path
}
/
server/panel/data/system.db
${
setup_path
}
/
server/panel/old_data/system.db
mv
-
f
${
setup_path
}
/
server/panel/data/port.pl
${
setup_path
}
/
server/panel/old_data/port.pl
mv
-
f
${
setup_path
}
/
server/panel/data/admin_path.pl
${
setup_path
}
/
server/panel/old_data/admin_path.pl
fi
unzip
-
o panel.zip
-
d
${
setup_path
}
/
server/
>
/
dev/null
if
[
-
d
"
${
setup_path
}
/server/panel/old_data"
]
;
then
mv
-
f
${
setup_path
}
/
server/panel/old_data/default.db
${
setup_path
}
/
server/panel/data/default.db
mv
-
f
${
setup_path
}
/
server/panel/old_data/system.db
${
setup_path
}
/
server/panel/data/system.db
mv
-
f
${
setup_path
}
/
server/panel/old_data/port.pl
${
setup_path
}
/
server/panel/data/port.pl
mv
-
f
${
setup_path
}
/
server/panel/old_data/admin_path.pl
${
setup_path
}
/
server/panel/data/admin_path.pl
if
[
-
d
"/
${
setup_path
}
/server/panel/old_data"
]
;
then
rm
-
rf
${
setup_path
}
/
server/panel/old_data
fi
fi
rm
-
f panel.zip
if
[
!
-
f
${
setup_path
}
/
server/panel/tools.py
]
;
then
Red_Error
"ERROR: Failed to download, please try install again!"
fi
rm
-
f
${
setup_path
}
/
server/panel/class/
*
.pyc
rm
-
f
${
setup_path
}
/
server/panel/
*
.pyc
chmod
+
x
/
etc/init.d/bt
chmod
-
R
600
${
setup_path
}
/
server/panel
chmod
-
R
+
x
${
setup_path
}
/
server/panel/script
ln
-
sf
/
etc/init.d/bt
/
usr/bin/bt
echo
"
${
panelPort
}
"
>
${
setup_path
}
/
server/panel/data/port.pl
}
Install_Pip
(){
curl
-
Ss
--
connect-timeout
3
-
m
60
http://download.bt.cn/install/pip_select.sh|bash
isPip
=
$(
pip
-V
|grep python
)
if
[
-
z
"
${
isPip
}
"
]
;
then
wget
-
O get-pip.py
${
download_Url
}
/
src/get-pip.py
python get-pip.py
rm
-
f get-pip.py
isPip
=
$(
pip
-V
|grep python
)
if
[
-
z
"
${
isPip
}
"
]
;
then
if
[
"
${
PM
}
"
=
"yum"
]
;
then
if
[
-
z
"
${
Centos8Check
}
"
]
;
then
yum
install
python-pip
-
y
pip
install
--
upgrade pip
else
yum
install
python3-pip
-
y
pip3
install
--
upgrade pip
fi
elif
[
"
${
PM
}
"
=
"apt-get"
]
;
then
apt-get
install
python-pip
-
y
pip
install
--
upgrade pip
fi
fi
fi
pipVersion
=
$(
pip
-V
|awk
'{print $2}'
|cut
-d
'.'
-f
1
)
if
[
"
${
pipVersion
}
"
-
lt
"9"
]
;
then
pip
install
--
upgrade pip
fi
}
Install_Pillow
()
{
isSetup
=
$(
python
-m
PIL 2>&1|grep package
)
if
[
"
$isSetup
"
=
""
]
;
then
isFedora
=
`
cat
/etc/redhat-release |grep Fedora
`
if
[
"
${
isFedora
}
"
]
;
then
pip
install
Pillow
return
;
fi
wget
-
O Pillow-3.2.0.zip
$download_Url
/
install
/
src/Pillow-3.2.0.zip
-
T
10
unzip Pillow-3.2.0.zip
rm
-
f Pillow-3.2.0.zip
cd
Pillow-3.2.0
python setup.py
install
cd
..
rm
-
rf Pillow-3.2.0
fi
isSetup
=
$(
python
-m
PIL 2>&1|grep package
)
if
[
-
z
"
${
isSetup
}
"
]
;
then
Red_Error
"Pillow installation failed."
fi
}
Install_psutil
()
{
isSetup
=
`
python
-m
psutil 2>&1|grep package
`
if
[
"
$isSetup
"
=
""
]
;
then
wget
-
O psutil-5.2.2.tar.gz
$download_Url
/
install
/
src/psutil-5.2.2.tar.gz
-
T
10
tar
xvf psutil-5.2.2.tar.gz
rm
-
f psutil-5.2.2.tar.gz
cd
psutil-5.2.2
python setup.py
install
cd
..
rm
-
rf psutil-5.2.2
fi
isSetup
=
$(
python
-m
psutil 2>&1|grep package
)
if
[
"
${
isSetup
}
"
=
""
]
;
then
Red_Error
"Psutil installation failed."
fi
}
Install_chardet
()
{
isSetup
=
$(
python
-m
chardet 2>&1|grep package
)
if
[
"
${
isSetup
}
"
=
""
]
;
then
wget
-
O chardet-2.3.0.tar.gz
$download_Url
/
install
/
src/chardet-2.3.0.tar.gz
-
T
10
tar
xvf chardet-2.3.0.tar.gz
rm
-
f chardet-2.3.0.tar.gz
cd
chardet-2.3.0
python setup.py
install
cd
..
rm
-
rf chardet-2.3.0
fi
isSetup
=
$(
python
-m
chardet 2>&1|grep package
)
if
[
-
z
"
${
isSetup
}
"
]
;
then
Red_Error
"chardet installation failed."
fi
}
Install_Python_Lib
(){
isPsutil
=
$(
python
-m
psutil 2>&1|grep package
)
if
[
"
${
isPsutil
}
"
]
;
then
PSUTIL_VERSION
=
`
python
-c
'import psutil;print psutil.__version__;'
|grep
'5.'
`
if
[
-
z
"
${
PSUTIL_VERSION
}
"
]
;
then
pip uninstall psutil
-
y
fi
fi
if
[
"
${
PM
}
"
=
"yum"
]
;
then
yum
install
libffi-devel
-
y
elif
[
"
${
PM
}
"
=
"apt-get"
]
;
then
apt
install
libffi-dev
-
y
fi
pip
install
--
upgrade setuptools
isPy27
=
$(
python
-V
2>&1|grep
'2.7.'
)
[
"
${
isPy27
}
"
]
&&
pip
install
gunicorn
==
19
.0
pip
install
-
r
${
setup_path
}
/
server/panel/requirements.txt
isGevent
=
$(
pip list|grep gevent
)
if
[
"
$isGevent
"
=
""
]
;
then
if
[
"
${
PM
}
"
=
"yum"
]
;
then
yum
install
python-gevent
-
y
elif
[
"
${
PM
}
"
=
"apt-get"
]
;
then
apt-get
install
python-gevent
-
y
fi
fi
pip
install
psutil chardet virtualenv Flask Flask-Session Flask-SocketIO flask-sqlalchemy Pillow gunicorn gevent-websocket paramiko
pip
install
qiniu oss2 upyun cos-python-sdk-v5
Install_Pillow
Install_psutil
Install_chardet
[
"
${
isPy27
}
"
]
&&
pip
install
gunicorn
==
19
.0
}
Set_Bt_Panel
(){
password
=
$(
cat
/dev/urandom |
head
-n
16 |
md5sum
|
head
-c
8
)
sleep
1
admin_auth
=
"/www/server/panel/data/admin_path.pl"
if
[
!
-
f
${
admin_auth
}
]
;
then
auth_path
=
$(
cat
/dev/urandom |
head
-n
16 |
md5sum
|
head
-c
8
)
echo
"/
${
auth_path
}
"
>
${
admin_auth
}
fi
auth_path
=
$(
cat
${
admin_auth
})
cd
${
setup_path
}
/
server/panel/
/
etc/init.d/bt start
python
-
m py_compile tools.py
python tools.py username
username
=
$(
python tools.py panel
${
password
})
cd
~
echo
"
${
password
}
"
>
${
setup_path
}
/
server/panel/default.pl
chmod
600
${
setup_path
}
/
server/panel/default.pl
/
etc/init.d/bt restart
sleep
3
isStart
=
$(
ps aux |grep
'BT-Panel'
|grep
-v
grep
|awk
'{print $2}'
)
if
[
-
z
"
${
isStart
}
"
]
;
then
Red_Error
"ERROR: The BT-Panel service startup failed."
fi
}
Set_Firewall
(){
sshPort
=
$(
cat
/etc/ssh/sshd_config |
grep
'Port '
|awk
'{print $2}'
)
if
[
"
${
PM
}
"
=
"apt-get"
]
;
then
apt-get
install
-
y ufw
if
[
-
f
"/usr/sbin/ufw"
]
;
then
ufw allow
888
,20,21,22,80,
${
panelPort
}
,
${
sshPort
}
/
tcp
ufw allow
39000
:40000/tcp
ufw_status
=
`
ufw status
`
echo
y|ufw
enable
ufw default deny
ufw reload
fi
else
if
[
-
f
"/etc/init.d/iptables"
]
;
then
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
20
-
j ACCEPT
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
21
-
j ACCEPT
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
22
-
j ACCEPT
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
80
-
j ACCEPT
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
${
panelPort
}
-
j ACCEPT
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
${
sshPort
}
-
j ACCEPT
iptables
-
I INPUT
-
p tcp
-
m state
--
state NEW
-
m tcp
--
dport
39000
:40000
-
j ACCEPT
#iptables -I INPUT -p tcp -m state --state NEW -m udp --dport 39000:40000 -j ACCEPT
iptables
-
A INPUT
-
p icmp
--
icmp-type any
-
j ACCEPT
iptables
-
A INPUT
-
s localhost
-
d localhost
-
j ACCEPT
iptables
-
A INPUT
-
m state
--
state ESTABLISHED,RELATED
-
j ACCEPT
iptables
-
P INPUT DROP
service iptables save
sed
-
i
"s#IPTABLES_MODULES=
\"\"
#IPTABLES_MODULES=
\"
ip_conntrack_netbios_ns ip_conntrack_ftp ip_nat_ftp
\"
#"
/
etc/sysconfig/iptables-config
iptables_status
=
$(
service iptables status |
grep
'not running'
)
if
[
"
${
iptables_status
}
"
==
''
]
;
then
service iptables restart
fi
else
AliyunCheck
=
$(
cat
/etc/redhat-release|grep
"Aliyun Linux"
)
[
"
${
AliyunCheck
}
"
]
&&
return
yum
install
firewalld
-
y
[
"
${
Centos8Check
}
"
]
&&
yum reinstall python3-six
-
y
systemctl
enable
firewalld
systemctl start firewalld
firewall-cmd
--
set-default-zone
=
public
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
20
/
tcp
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
21
/
tcp
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
22
/
tcp
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
80
/
tcp
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
${
panelPort
}
/
tcp
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
${
sshPort
}
/
tcp
>
/
dev/null
2
>&
1
firewall-cmd
--
permanent
--
zone
=
public
--
add-port
=
39000
-
40000
/
tcp
>
/
dev/null
2
>&
1
#firewall-cmd --permanent --zone=public --add-port=39000-40000/udp > /dev/null 2>&1
firewall-cmd
--
reload
fi
fi
}
Get_Ip_Address
(){
getIpAddress
=
""
getIpAddress
=
$(
curl
-sS
--connect-timeout
10
-m
60 https://www.bt.cn/Api/getIpAddress
)
if
[
-
z
"
${
getIpAddress
}
"
]
||
[
"
${
getIpAddress
}
"
=
"0.0.0.0"
]
;
then
isHosts
=
$(
cat
/etc/hosts|grep
'www.bt.cn'
)
if
[
-
z
"
${
isHosts
}
"
]
;
then
echo
""
>>
/
etc/hosts
echo
"103.224.251.67 www.bt.cn"
>>
/
etc/hosts
getIpAddress
=
$(
curl
-sS
--connect-timeout
10
-m
60 https://www.bt.cn/Api/getIpAddress
)
if
[
-
z
"
${
getIpAddress
}
"
]
;
then
sed
-
i
"/bt.cn/d"
/
etc/hosts
fi
fi
fi
ipv4Check
=
$(
python
-c
"import re; print(re.match('^(?:[0-9]{1,3}
\.
){3}[0-9]{1,3}
$'
,'
${
getIpAddress
}
'))"
)
if
[
"
${
ipv4Check
}
"
==
"None"
]
;
then
ipv6Address
=
$(
echo
${
getIpAddress
}
|tr
-d
"[]"
)
ipv6Check
=
$(
python
-c
"import re; print(re.match('^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}
$'
,'
${
ipv6Address
}
'))"
)
if
[
"
${
ipv6Check
}
"
==
"None"
]
;
then
getIpAddress
=
"SERVER_IP"
else
echo
"True"
>
${
setup_path
}
/
server/panel/data/ipv6.pl
sleep
1
/
etc/init.d/bt restart
fi
fi
if
[
"
${
getIpAddress
}
"
!=
"SERVER_IP"
]
;
then
echo
"
${
getIpAddress
}
"
>
${
setup_path
}
/
server/panel/data/iplist.txt
fi
}
Setup_Count
(){
curl
-
sS
--
connect-timeout
10
-
m
60
https://www.bt.cn/Api/SetupCount?type
=
Linux
\&
o
=
$1
>
/
dev/null
2
>&
1
if
[
"
$1
"
!=
""
]
;
then
echo
$1
>
/
www/server/panel/data/o.pl
cd
/
www/server/panel
python tools.py o
fi
echo
/
www
>
/
var/bt_setupPath.conf
}
Install_Main
(){
Lock_Clear
System_Check
Get_Pack_Manager
get_node_url
#Auto_Swap
startTime
=
`
date
+%s
`
if
[
"
${
PM
}
"
=
"yum"
]
;
then
Install_RPM_Pack
elif
[
"
${
PM
}
"
=
"apt-get"
]
;
then
Install_Deb_Pack
fi
Install_Bt
Install_Pip
Install_Python_Lib
Set_Bt_Panel
Service_Add
Set_Firewall
Get_Ip_Address
Setup_Count
${
IDC_CODE
}
}
echo
"
+----------------------------------------------------------------------
| Bt-WebPanel 7.0 FOR CentOS/Ubuntu/Debian
+----------------------------------------------------------------------
| Copyright © 2015-2099 BT-SOFT(http://www.bt.cn) All rights reserved.
+----------------------------------------------------------------------
| The WebPanel URL will be http://SERVER_IP:8888 when installed.
+----------------------------------------------------------------------
"
while
[
"
$go
"
!=
'y'
]
&&
[
"
$go
"
!=
'n'
]
do
read
-
p
"Do you want to install Bt-Panel to the
$setup_path
directory now?(y/n): "
go
;
done
if
[
"
$go
"
==
'n'
]
;
then
exit
;
fi
Install_Main
echo
-
e
"=================================================================="
echo
-
e
"
\0
33[32mCongratulations! Installed successfully!
\0
33[0m"
echo
-
e
"=================================================================="
echo
"Bt-Panel: http://
${
getIpAddress
}
:
${
panelPort
}
$auth_path
"
echo
-
e
"username:
$username
"
echo
-
e
"password:
$password
"
echo
-
e
"
\0
33[33mWarning:
\0
33[0m"
echo
-
e
"
\0
33[33mIf you cannot access the panel,
\0
33[0m"
echo
-
e
"
\0
33[33mrelease the following port (8888|888|80|443|20|21) in the security group
\0
33[0m"
echo
-
e
"=================================================================="
endTime
=
`
date
+%s
`
((
outTime
=(
$endTime
-
$startTime
)/
60
))
echo
-e
"Time consumed:
\0
33[32m
$outTime
\0
33[0mMinute!"
rm
-f
new_install.sh
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment