pull/109/head
midoks 8 years ago
parent 6978b7a421
commit 0845a7d5fe
  1. 34
      plugins/beta/beta_main.py
  2. 86
      plugins/beta/index.html
  3. 16
      plugins/beta/info.json
  4. 56
      plugins/beta/install.sh
  5. 22
      plugins/btyw/btyw_main.py
  6. BIN
      plugins/btyw/ico-btyw.png
  7. BIN
      plugins/btyw/ico-hot.png
  8. BIN
      plugins/btyw/icon.png
  9. 74
      plugins/btyw/index.html
  10. 19
      plugins/btyw/info.json
  11. 52
      plugins/btyw/install.sh
  12. BIN
      plugins/safelogin/icon.png
  13. 550
      plugins/safelogin/index.html
  14. 16
      plugins/safelogin/info.json
  15. 40
      plugins/safelogin/install.sh
  16. 276
      plugins/safelogin/safelogin_main.py

@ -1,34 +0,0 @@
#!/usr/bin/python
#coding: utf-8
#-----------------------------
# 宝塔Linux面板内测插件
#-----------------------------
import sys,os
reload(sys)
sys.setdefaultencoding('utf-8')
os.chdir('/www/server/panel');
sys.path.append("class/")
import public,db,time
class beta_main:
__setupPath = '/www/server/panel/plugin/beta';
#设置内测
def SetConfig(self,get):
data = {}
data['username'] = get.bbs_name
data['qq'] = get.qq
data['email'] = get.email
result = public.httpPost('https://www.bt.cn/Api/LinuxBeta',data);
import json;
data = json.loads(result);
if data['status']:
public.writeFile(self.__setupPath + '/config.conf',get.bbs_name + '|' + get.qq + '|' + get.email);
return data;
#取内测资格状态
def GetConfig(self,get):
try:
cfile = self.__setupPath + '/config.conf'
if not os.path.exists(cfile): cfile = 'data/beta.pl'
return public.readFile(cfile).strip();
except:
return 'False';

@ -1,86 +0,0 @@
<div id="beta-1" class="bt-form pd20 pb55" style="padding-top:0">
<div class="neice_con">
<div class="tit">注意事项</div>
<div class="nc_con">
<p style="color:red">1、注意,请不要在正式商用网站及自己生产环境的面板申请测试版。</p>
<p>2、所有新功能做完内部初审后都会第一时间向所有内测用户推送。</p>
<p>3、内测版会有诸多小Bug,如遇到,可以论坛或QQ找我们,我们一定负责到底。</p>
<p>4、内测意义在于为广大宝塔用户找Bug,宝塔团队再一次感谢您的积极参与。</p>
<p>5、如果你不是愿意付出及肯折腾学习的人,我们不建议申请内测。</p>
</div>
<div class="nc_opt"><label><input type="checkbox" name="yes" value="yes" />以上5句我已阅读并知晓</label></div>
<div class="tit">联系方式</div>
<div class="nc_con nc_con_user">
<p><span>论坛用户名</span><input id="ename" name="name" value=""></p>
<p style="line-height: 10px; margin-left: 80px; position: relative; top: -5px;">请如实填写宝塔论坛账号,提交后我们会审核,如未有,<a style="color:#20a53a" href="http://www.bt.cn/bbs/member.php?mod=register" target="_blank">去注册宝塔论坛账户</a></p>
<p><span>QQ号码</span><input id="qq" name="qq" value=""></p>
<p><span>邮箱</span><input id="email" name="email" value=""></p>
</div>
</div>
<div class="bt-form-submit-btn">
<button type="button" class="btn btn-danger btn-sm" onclick="layer.closeAll()">取消</button>
<button type="button" class="btn btn-success btn-sm" onclick="neice()">提交</button>
</div>
</div>
<div id="beta-2" class="nc-tips" style="display:none;">
<p style="font-size: 16px; margin-bottom: 10px;">恭喜您,成为内测组的一员!</p>
<p>您的宝塔论坛认证用户为:<span id="bbs_user"></span></p>
<p>您可以用这个账号在内测专用版块反馈交流,<a href="http://www.bt.cn/bbs/forum.php?mod=forumdisplay&fid=39" target="_blank">宝塔论坛内测专用版块</a></p>
<p>如果您想返回正式版,则直接SSH里再执行安装代码即可</p>
</div>
<script type="javascript/text">
$(function(){
$(".nc_con_user input").addClass("disabled").attr({"disabled":"disabled","placeholder":"阅读注意事项并确认"});
$.get('/plugin?action=a&name=beta&s=GetConfig',function(rdata){
if(rdata.status === false){
layer.closeAll();
layer.msg(rdata.msg,{icon:5});
return;
}
if(rdata != 'False'){
$("#beta-1").hide();
$("#beta-2").show();
$("#bbs_user").text(rdata.split('|')[0]);
}else{
$("#beta-2").hide();
$("#beta-1").show();
}
});
});
$(".nc_opt label").click(function(){
var check = $(".nc_opt input").prop("checked");
if(!check){
$(".nc_con_user input").addClass("disabled").attr({"disabled":"disabled","placeholder":"阅读注意事项并确认"});
}
else{
$(".nc_con_user input").removeClass("disabled").removeAttr("disabled").removeAttr("placeholder");
}
});
$('#qq').on('input', function() {
var str = $(this).val();
$("#email").val(str+"@qq.com");
});
function neice(){
var bbs_name = $("#ename").val();
var qq = $("#qq").val();
var email = $("#email").val();
if(bbs_name == '' || qq == '' || email == ''){
layer.msg('论坛用户名/QQ/邮箱不能为空!',{icon:2});
return;
}
var data = 'bbs_name=' + bbs_name + '&qq=' + qq + '&email=' + email;
var loadT = layer.msg("正在提交,请稍候...",{icon:16,time:0,shade:[0.3,'#000']});
$.post('/plugin?action=a&name=beta&s=SetConfig',data,function(rdata){
layer.close(loadT);
if(rdata.status) layer.closeAll();
layer.msg(rdata.msg,{icon:rdata.status?1:2});
});
}
</script>

@ -1,16 +0,0 @@
{
"title":"申请内测",
"tip":"lib",
"name":"beta",
"type":"扩展",
"ps":"申请内测资格,审核完成后将会获得内测版本更新推送,并可在宝塔论坛内测专用版块参与讨论",
"versions":"1.2",
"shell":"beta.sh",
"checks":"/www/server/panel/plugin/beta",
"author":"宝塔",
"home":"http://www.bt.cn/bbs",
"date":"2017-10-16",
"default":false,
"display":0,
"pid":"2"
}

@ -1,56 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
install_tmp='/tmp/bt_install.pl'
CN='125.88.182.172'
HK='download.bt.cn'
HK2='103.224.251.67'
US='128.1.164.196'
sleep 0.5;
CN_PING=`ping -c 1 -w 1 $CN|grep time=|awk '{print $7}'|sed "s/time=//"`
HK_PING=`ping -c 1 -w 1 $HK|grep time=|awk '{print $7}'|sed "s/time=//"`
HK2_PING=`ping -c 1 -w 1 $HK2|grep time=|awk '{print $7}'|sed "s/time=//"`
US_PING=`ping -c 1 -w 1 $US|grep time=|awk '{print $7}'|sed "s/time=//"`
echo "$HK_PING $HK" > ping.pl
echo "$HK2_PING $HK2" >> ping.pl
echo "$US_PING $US" >> ping.pl
echo "$CN_PING $CN" >> ping.pl
nodeAddr=`sort -V ping.pl|sed -n '1p'|awk '{print $2}'`
if [ "$nodeAddr" == "" ];then
nodeAddr=$HK2
fi
download_Url=http://$nodeAddr:5880
Install_Beta()
{
mkdir -p /www/server/panel/plugin/beta
f1=/www/server/panel/data/beta.pl
if [ ! -f "$f1" ];then
echo 'False' > $f1
fi
f2=/www/server/panel/plugin/beta/config.conf
if [ ! -f "$f2" ];then
echo 'False' > $f2
fi
echo '正在安装脚本文件...' > $install_tmp
wget -O /www/server/panel/plugin/beta/beta_main.py $download_Url/install/lib/plugin/beta/beta_main.py -T 5
wget -O /www/server/panel/plugin/beta/index.html $download_Url/install/lib/plugin/beta/index.html -T 5
wget -O /www/server/panel/plugin/beta/info.json $download_Url/install/lib/plugin/beta/info.json -T 5
echo '安装完成' > $install_tmp
}
Uninstall_Beta()
{
rm -rf /www/server/panel/plugin/beta
rm -f /www/server/panel/data/beta.pl
}
action=$1
if [ "${1}" == 'install' ];then
Install_Beta
else
Uninstall_Beta
fi

@ -1,22 +0,0 @@
#!/usr/bin/python
#coding: utf-8
#-----------------------------
# 宝塔Linux面板网站备份工具 - ALIOSS
#-----------------------------
import sys,os
reload(sys)
sys.setdefaultencoding('utf-8')
os.chdir('/www/server/panel');
sys.path.append("class/")
import public,web
class btyw_main:
def GetIndex(self,get):
try:
if hasattr(web.ctx.session,'btyw'): return False;
result = public.httpGet('https://www.bt.cn/lib/btyw.html');
public.writeFile('/www/server/panel/plugin/btyw/index.html',result);
web.ctx.session.btyw = True;
return True;
except:
return False;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

@ -1,74 +0,0 @@
<style>
.btyw .table td,.btyw .table th {
height: 50px;
vertical-align: middle;
}
.btyw .ico-hot{
background: url(/static/images/ico-hot.png) no-repeat 0 0/26px auto;
}
.btyw .bgf6{
background-color: #f9f9f9;
}
</style>
<div class="pd15 btyw divtable">
<p style="margin-bottom:15px;font-size:14px;color:red">宝塔运维,一对一技术服务,承诺如解决不好,款项立即全额原路退回,请放心付费后咨询。</p>
<table class="table table-hover">
<thead>
<tr>
<th>服务类型</th>
<th>服务范围</th>
<th>服务价格</th>
<th>购买服务</th>
</tr>
</thead>
<tbody>
<tr>
<td>企业托管运维</td>
<td class="text-left">定制化企业托管服务,如有需要可咨询技术</td>
<td>5000元/年起</td>
<td><a class="btlink" href="https://www.bt.cn/admin/yunwei" target="_blank">立即前往</a></td>
</tr>
<tr class="bgf6">
<td>宝塔面板安装</td>
<td class="text-left">安装好宝塔面板及指定环境,并做好服务器安全设置</td>
<td style="line-height: 20px;"><s>原价200元起</s><br><span style="color:red">限时特价80元</span></td>
<td><a class="btlink" href="https://www.bt.cn/admin/yunwei" target="_blank">立即前往</a></td>
</tr>
<tr>
<td>系统优化加速</td>
<td class="text-left">网站加速、系统优化、环境优化,让性能更上一台阶</td>
<td>300元/次起</td>
<td><a class="btlink" href="https://www.bt.cn/admin/yunwei" target="_blank">立即前往</a></td>
</tr>
<tr class="bgf6">
<td>数据同步服务</td>
<td class="text-left">部署SQL SERVER或MySQL数据库实时热备功能</td>
<td>300元/次起 </td>
<td><a class="btlink" href="https://www.bt.cn/admin/yunwei" target="_blank">立即前往</a></td>
</tr>
<tr>
<td>网站挂马清理</td>
<td class="text-left">手工查找并清理网站的各种挂马代码</td>
<td>500元/次起</td>
<td><a class="btlink" href="https://www.bt.cn/admin/yunwei" target="_blank">立即前往</a></td>
</tr>
<tr class="bgf6">
<td class="ico-hot">面板问题处理</td>
<td class="text-left">解决面板打不开、部分功能无法正常使用等问题</td>
<td style="line-height: 20px;"><s>原价200元起</s><br><span style="color:red">限时特价80元</span></td>
<td><a class="btlink" href="https://www.bt.cn/admin/yunwei" target="_blank">立即前往</a></td>
</tr>
</tbody>
</table>
</div>
<script type="javascript/text">
function GetIndex(){
$.get('/plugin?action=a&name=btyw&s=GetIndex',function(rdata){
if(rdata === true){
layer.closeAll();
PluginMan('btyw','宝塔运维');
}
});
}
GetIndex();
</script>

@ -1,19 +0,0 @@
{
"pid":9,
"title":"宝塔运维",
"tip":"lib",
"name":"btyw",
"type":"插件",
"id":2,
"sort":1001,
"ps":"宝塔付费运维服务",
"versions":"1.0",
"shell":"btyw.sh",
"checks":"/www/server/panel/plugin/btyw",
"author":"宝塔",
"home":"https://www.bt.cn/yunwei",
"date":"2017-10-18",
"default":false,
"display":0,
"pid":"2"
}

@ -1,52 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
install_tmp='/tmp/bt_install.pl'
CN='125.88.182.172'
HK='download.bt.cn'
HK2='103.224.251.67'
US='174.139.221.74'
sleep 0.5;
CN_PING=`ping -c 1 -w 1 $CN|grep time=|awk '{print $7}'|sed "s/time=//"`
HK_PING=`ping -c 1 -w 1 $HK|grep time=|awk '{print $7}'|sed "s/time=//"`
HK2_PING=`ping -c 1 -w 1 $HK2|grep time=|awk '{print $7}'|sed "s/time=//"`
US_PING=`ping -c 1 -w 1 $US|grep time=|awk '{print $7}'|sed "s/time=//"`
echo "$HK_PING $HK" > ping.pl
echo "$HK2_PING $HK2" >> ping.pl
echo "$US_PING $US" >> ping.pl
echo "$CN_PING $CN" >> ping.pl
nodeAddr=`sort -V ping.pl|sed -n '1p'|awk '{print $2}'`
if [ "$nodeAddr" == "" ];then
nodeAddr=$HK2
fi
download_Url=http://$nodeAddr:5880
Install_btyw()
{
mkdir -p /www/server/panel/plugin/btyw
echo '正在安装脚本文件...' > $install_tmp
wget -O /www/server/panel/plugin/btyw/btyw_main.py $download_Url/install/lib/plugin/btyw/btyw_main.py -T 5
wget -O /www/server/panel/plugin/btyw/index.html $download_Url/install/lib/plugin/btyw/index.html -T 5
wget -O /www/server/panel/plugin/btyw/info.json $download_Url/install/lib/plugin/btyw/info.json -T 5
wget -O /www/server/panel/plugin/btyw/icon.png $download_Url/install/lib/plugin/btyw/icon.png -T 5
wget -O /www/server/panel/static/img/soft_ico/ico-btyw.png $download_Url/install/lib/plugin/btyw/icon.png -T 5
wget -O /www/server/panel/static/images/ico-hot.png $download_Url/install/lib/plugin/btyw/ico-hot.png -T 5
echo '安装完成' > $install_tmp
}
Uninstall_btyw()
{
rm -rf /www/server/panel/plugin/btyw
pip uninstall btyw -y
}
action=$1
if [ "${1}" == 'install' ];then
Install_btyw
else
Uninstall_btyw
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

@ -1,550 +0,0 @@
<style>
/*危险按钮*/
.bts-danger:hover{
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
#whiteList a{
color: red;
}
/*弹窗*/
.Add_view{
height: 100px;
padding-left: 35px;
padding-top: 35px;
}
.Add_view label{
margin-right: 10px;
font-size: 15px;
font-weight: 100;
}
.Add_view input{
width: 230px;
}
.Add_view .error{
border: 1px solid red;
}
.Add_view .correct{
border: 1px solid #20a53a;
}
/*日志管理*/
.btnTitle{
font-weight: 100;
font-size: 16px;
line-height: 34px;
height: 34px;
margin-right: 15px;
position: relative;
top: 2px;
}
.whiteList-table{
margin-top: 10px;
}
/*登录日志表单*/
.viewTwo .whiteList-table{
overflow-x: hidden;
height: 500px;
}
.maks{
background: rgba(39, 39, 39, 0.4);
position: absolute;
width: 700px;
height: 555px;
z-index: 999;
overflow: hidden;
}
.boxshow{
position: absolute;
height: 150px;
width: 400px;
margin-left: -200px;
margin-top: -75px;
left: 50%;
top: 50%;
z-index: 1000;
background: #fff;
padding: 25px 20px;
overflow: hidden;
}
.btPayment {
float: left;
padding: 8px 10px;
width: 190px;
height: 100px;
line-height: 33px;
text-align: center;
border-left: 1px solid #ececec;
}
.btPayment .t2{
display: block;
width: 100%;
text-align: center;
font-size: 16px;
margin-bottom: 5px;
}
.btPayment .price{
color: #20A53A;
font-size: 22px;
margin: 0 5px;
}
.bt-form{
overflow: hidden;
}
.boxtext{
line-height: 32px;
margin-top: -17px;
text-align: center;
border-bottom: #eee 1px solid;
height: 39px;
font-size: 14px;
}
</style>
<div class="maks" style="display: none"></div>
<div class="boxshow" style="display: none;">
<div>
<div class="boxtext">
<span>未开通此服务,如需使用请开通企业运维版。</span>
</div>
<div class="btvipinfo" style="width: 170px;padding-left: 20px">
<p style="height: 25px">1、一对一运维人员对接</p>
<p style="height: 25px">2、提供每月3次运维服务</p>
<p style="height: 25px">3、双重安全隔离登录</p>
</div>
<div class="btPayment">
<span class="t2">企业运维版<span class="price">98</span>元/月</span>
<button class="btn btn-success btn-sm" style="width:80%" onclick="window.open('https://www.bt.cn/admin/index.html')">立即开通</button>
</div>
</div>
</div>
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw">密钥</p>
<p>面板设置</p>
<p>面板登录日志</p>
<p>SSH设置</p>
<p>SSH日志管理</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con viewZoo">
<p class="status" style="margin-top:10px;margin-left:10px;height: 80px;margin-bottom:15px;">
<span style="float:left;margin-top:-5px">密钥:</span>
<textarea class="bt-input-text" name="token" readonly="readonly" style="background-color: #eee;width:400px;height:80px;padding: 8px 15px;" placeholder="密钥已隐藏..."></textarea>
</p>
<input type="button" class="btn btn-success btn-sm" name="ButtonShow" style="margin-left:52px;width:100px" onclick="sagelogin.tokenShow()" value="显示密钥" />
<ul style="margin: 15px 5px;padding-left: 70px;list-style-type: disc;line-height: 25px;">
<li>宝塔企业运维后台连接您的服务器需要此密钥,请妥善记录并保存</li>
<li>一但密钥丢失,可能导致您无法登录服务器</li>
</ul>
</div>
<div class="soft-man-con viewOne" style="display: none;">
<p class="status">当前状态:
<span>开启</span>
<span style="color: #20a53a; margin-left: 3px;" class="glyphicon glyphicon glyphicon-play"></span>
<span style="color: red; margin-left: 3px; display: none" class="glyphicon glyphicon-pause"></span>
</p>
<div class="sfm-opt">
<button class="btn btn-default btn-sm bts-danger" onclick="sagelogin.Panel_Admin()">清除面板登录限制IP</button>
<button class="btn btn-default btn-sm bts-safety" onclick="sagelogin.Add_view('面板白名单',true)">添加白名单</button>
</div>
<div class="whiteList-table divtable" style="overflow-x: hidden;height: 420px">
<table class="table table-hover" style="max-height: 380px; overflow: auto;">
<thead>
<tr>
<th>IP地址</th>
<th style="text-align: right;">操作</th>
</tr>
</thead>
<tbody id="whiteListOne"></tbody>
</table>
</div>
</div>
<div class="soft-man-con viewTwo" style="display: none">
<div class="whiteList-table divtable">
<table class="table table-hover" style=" max-height: 380px; overflow: auto;">
<thead>
<tr>
<th>操作记录</th>
<th>操作时间</th>
</tr>
</thead>
<tbody id="whiteListTwo"></tbody>
</table>
</div>
</div>
<div class="soft-man-con viewThree" style="display: none">
<p class="status">当前状态:
<span>开启</span>
<span style="color: #20a53a; margin-left: 3px;" class="glyphicon glyphicon glyphicon-play">
</span>
<span style="color: red; margin-left: 3px; display: none" class="glyphicon glyphicon-pause"></span>
</p>
<div class="sfm-opt">
<button class="btn btn-default btn-sm bts-danger" onclick="sagelogin.Panel_Admin()">清除SSH登录限制IP</button>
<button class="btn btn-default btn-sm bts-safety" onclick="sagelogin.Add_view('SSH白名单',false)">添加白名单</button>
</div>
<div class="whiteList-table divtable" style="overflow-x: hidden;height: 420px">
<table class="table table-hover" style="max-height: 380px; overflow: auto;">
<thead>
<tr>
<th>IP地址</th>
<th style="text-align: right;">操作</th>
</tr>
</thead>
<tbody id="whiteListThree"></tbody>
</table>
</div>
</div>
<div class="soft-man-con viewFour" style="display: none">
<div class="btnclick">
<label class="btnTitle">日志分类</label>
<div class="btn-group">
<input type="submit" name="btnOne" class="btn btn-success" onclick="sagelogin.SSH_Defense_List(0)" value="已防御" />
<input type="submit" name="btnTwo" class="btn btn-default" onclick="sagelogin.SSH_Defense_List(1)" value="入侵日志"/>
<input type="submit" name="btnThree" class="btn btn-default" onclick="sagelogin.SSH_Defense_List(2)" value="登录日志"/>
</div>
</div>
<div class="whiteList-table divtable" style="overflow-x: hidden;height: 470px;">
<table class="table table-hover" style="max-height: 380px; overflow: auto;">
<thead>
<tr>
<th>源IP地址</th>
<th>用户</th>
<th style="text-align: right;">登录时间</th>
</tr>
</thead>
<tbody id="whiteListFour"></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script type="javascript/text">
//宝塔安全登录
$(function(){
$(".bt-w-menu p").click(function(){
$(this).addClass("bgw").siblings().removeClass("bgw");
$('.bt-w-con .soft-man-con').hide().eq($(this).index()).show();
switch($(this).index()) {
case 0:
break;
case 1:
sagelogin.Panel_White_List();
break;
case 2:
sagelogin.Panel_journal();
break;
case 3:
sagelogin.SSH_White_List();
break;
case 4:
sagelogin.SSH_Defense_List(0);
break;
}
});
layer.load();
$.get('/plugin?action=a&name=safelogin&s=GetServerInfo',function(data) {
layer.closeAll('loading');
if (data.status) {
$('.boxshow').hide();
$('.maks').hide();
}else{
$('.boxshow').show();
$('.maks').show();
}
});
});
var sagelogin = new Object();
sagelogin = {
Addview:'',
SSHlogList:'',
PanelLogList:'',
// SSH管理
SSH_Admin:function(){
var confirm = layer.confirm('确定清除面板登录限制IP地址?',{icon: 1}, {
btn: ['确认','取消'],
}, function(){
$.get('/plugin?action=a&name=safelogin&s=close_ssh_limit',function(data) {
if (data.status) {
layer.msg(data.msg,{icon:1});
sagelogin.SSH_White_List();
}else{
layer.msg(data.msg,{icon:2});
}
});
}, function(){
layer.close(confirm);
});
},
tokenShow:function(){
var inputPwd = layer.open({
type: 1,
title: '验证面板密码',
shadeClose: true,
shade: 0.3,
area: ['380px', '190px'],
btn:['确定','取消'],
content:'<div class="Add_view" style="height:90px"><label>面板密码:</label><input name="panel_pwd" class=" bt-input-text" type="password"></div>',
yes:function(){
var passwordStr = $("input[name='panel_pwd']").val();
var index = layer.load(0, {shade: false});
$.post('/plugin?action=a&name=safelogin&s=GetServerToken',{password:passwordStr},function(token) {
layer.close(index);
if(token.status === false){
layer.msg(token.msg,{icon:2});
return;
}
layer.close(inputPwd);
$("textarea[name='token']").val(token);
});
},
btn2:function(){
layer.close(inputPwd);
}
});
},
// SSH白名单——列表
SSH_White_List:function(){
var index = layer.load(0, {shade: false});
$.get('/plugin?action=a&name=safelogin&s=get_ssh_limit','',function(data){
$('#whiteListThree').empty();
var List = '';
if (data.length == 0){
$('.viewThree .status span:eq(0)').html('关闭');
$('.viewThree .glyphicon-pause').show();
$('.viewThree .glyphicon-play').hide();
}else {
$('.viewThree .status span:eq(0)').html('开启');
$('.viewThree .glyphicon-pause').hide();
$('.viewThree .glyphicon-play').show();
}
for (var i = 0; i < data.length; i++) {
List = List + '<tr><td>'+ data[i] +'</td><td style="text-align:right;"><a href="javascript:;" ip-val="'+ data[i] +'" onclick="sagelogin.SSH_Del_White_List(event)" style="color:red">删除</a></td></tr>'
}
$('#whiteListThree').append(List);
layer.close(index);
});
},
// SSH白名单——删除
SSH_Del_White_List:function(ev){
var ip = ev.currentTarget.getAttribute('ip-val');
var confirm = layer.confirm('确定删除IP['+ ip +']限制地址?', {
btn: ['确认','取消'] //按钮
}, function(){
$.get('/plugin?action=a&name=safelogin&s=remove_ssh_limit',{ip:ip},function(data){
if (data.status) {
sagelogin.SSH_White_List();
layer.msg(data.msg,{icon:1});
}else {
layer.msg(data.msg,{icon:2});
}
});
}, function(){
layer.close(confirm);
});
},
// SSH白名单——添加
SSH_Add_White_List:function(ip){
$.post('/plugin?action=a&name=safelogin&s=add_ssh_limit',{ip:ip},function(data){
layer.close(sagelogin.Addview);
if (data.status) {
sagelogin.SSH_White_List();
layer.msg(data.msg,{icon:1});
}else{
layer.msg(data.msg,{icon:2});
}
});
},
// SSH日志管理
SSH_Defense_List:function(status){
$('.btnclick input').removeClass('btn-success').addClass('btn-default');
$('.btnclick input').eq(status).addClass('btn-success').removeClass('btn-default');
if (sagelogin.SSHlogList == '') {
$.get('/plugin?action=a&s=get_ssh_errorlogin&name=safelogin',function(data){
sagelogin.SSHlogList = data;
sagelogin.DefenseFor(sagelogin.SSHlogList.defense);
});
}else{
switch(status) {
case 0:
sagelogin.DefenseFor(sagelogin.SSHlogList.defense);
break;
case 1:
sagelogin.DefenseFor(sagelogin.SSHlogList.intrusion);
break;
case 2:
sagelogin.DefenseFor(sagelogin.SSHlogList.success);
break;
}
}
},
// SSH日志渲染模板
DefenseFor:function(data){
var List = '';
$('#whiteListFour').empty();
for (var i = data.length - 1; i >= 0; i--) {
List = List + '<tr><td>'+data[i].address+'</td><td>' + data[i].user + '</td><td style="text-align:right">'+ data[i].date+'</td></tr>'
}
$('#whiteListFour').append(List);
},
// 面板管理
Panel_Admin:function(){
var confirm = layer.confirm('确定清除面板登录限制IP地址?', {
btn: ['确认','取消'] //按钮
}, function(){
$.get('/plugin?action=a&name=safelogin&s=close_panel_limit',function(data) {
if (data.status) {
layer.msg(data.msg,{icon:1});
sagelogin.Panel_White_List();
}else{
layer.msg(data.msg,{icon:2});
}
});
}, function(){
layer.close(confirm);
});
},
// 面板白名单——列表
Panel_White_List:function(){
$.get('/plugin?action=a&name=safelogin&s=get_panel_limit','',function(data){
$('#whiteListOne').empty();
var List = '';
if (data.length == 0){
$('.viewOne .status span:eq(0)').html('关闭');
$('.viewOne .glyphicon-pause').show();
$('.viewOne .glyphicon-play').hide();
}else {
$('.viewOne .status span:eq(0)').html('开启');
$('.viewOne .glyphicon-pause').hide();
$('.viewOne .glyphicon-play').show();
}
for (var i = 0; i < data.length; i++) {
List = List + '<tr><td>'+ data[i] +'</td><td style="text-align:right;"><a href="javascript:;" ip-val="'+ data[i] +'" onclick="sagelogin.Panel_Del_White_List(event)" style="color:red">删除</a></td></tr>'
}
$('#whiteListOne').append(List);
});
},
// 面板白名单——删除
Panel_Del_White_List:function(ev){
var ip = ev.currentTarget.getAttribute('ip-val');
var confirm = layer.confirm('确定删除IP['+ ip +']限制地址?', {
btn: ['确认','取消'] //按钮
}, function(){
$.get('/plugin?action=a&name=safelogin&s=remove_ssh_limit',{ip:ip},function(data){
if (data.status) {
sagelogin.Panel_White_List();
layer.msg(data.msg,{icon:1});
}else {
layer.msg(data.msg,{icon:2});
}
});
}, function(){
layer.close(confirm);
});
},
// 面板白名单——添加
Panel_Add_White_List:function(ip){
$.post('/plugin?action=a&name=safelogin&s=add_panel_limit', {ip: ip}, function(data) {
layer.close(sagelogin.Addview);
if (data.status) {
sagelogin.Panel_White_List();
layer.msg(data.msg,{icon:1});
}else{
layer.msg(data.msg,{icon:2});
}
});
},
// 面板日志——列表
Panel_journal:function(){
var index = layer.load(0, {shade: false});
$.get('/plugin?action=a&name=safelogin&s=get_login_log',function(data){
$('#whiteListTwo').empty();
var List = '';
sagelogin.PanelLogList = data;
for (var i = sagelogin.PanelLogList.length - 1; i >= 0; i--) {
List = List + '<tr><td>'+ sagelogin.PanelLogList[i].log +'</td><td style="text-align:right;">'+ sagelogin.PanelLogList[i].addtime +'</tr>';
}
$('#whiteListTwo').append(List);
layer.close(index);
});
},
// IP正则:192.168.1.0/24
CheckIP:function(ip) {
var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\/\d{1,2})?$/;
return reg.test(ip);
},
CheckIPTwo:function(ip) {
var reg = /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/gi;
return reg.test(ip);
},
// 添加表单效验
addViewVul:function(status){
var ip = $('.addViewVul');
if (status) {
console.log(sagelogin.CheckIP(ip.val()));
if(sagelogin.CheckIPTwo(ip.val())){
ip.addClass('correct').removeClass('error');
return true;
}else {
ip.addClass('error').removeClass('correct');
return false;
}
}else{
if(sagelogin.CheckIP(ip.val())){
ip.addClass('correct').removeClass('error');
return true;
}else {
ip.addClass('error').removeClass('correct');
return false;
}
}
},
// 添加界面
Add_view:function(title,status){
var _this = this;
var text = ''
var statuss = true;
if (status) {
text = '';
statuss = true;
}else{
text = '<p style="color:red;margin: 5px 0px 0px 67px;font-size: 14px;">支持IP段,如:192.168.1.0/24</p>';
statuss = false;
}
sagelogin.Addview = layer.open({
type: 1,
title: title,
shadeClose: true,
shade: 0.1,
area: ['380px', '200px'],
btn:['确定','取消'],
content:'<div class="Add_view"><label>IP地址:</label><input class="addViewVul bt-input-text" onchange="sagelogin.addViewVul('+ statuss +')" type="text">'+ text +'</div>',
yes:function(){
if (sagelogin.addViewVul(statuss)) {
if(status){
sagelogin.Panel_Add_White_List($('.addViewVul').val());
}else{
sagelogin.SSH_Add_White_List($('.addViewVul').val());
}
}else{
layer.msg('请输入合法的IP地址',{icon:2})
}
},
btn2:function(){
layer.close(sagelogin.Addview);
}
});
$('.addViewVul').focus();
}
}
</script>

@ -1,16 +0,0 @@
{
"title":"宝塔安全登录",
"tip":"lib",
"name":"safelogin",
"type":"扩展",
"ps":"宝塔企业版安全登陆插件!",
"versions":"1.3",
"shell":"safelogin.sh",
"checks":"/www/server/panel/plugin/safelogin",
"author":"宝塔",
"home":"http://www.bt.cn/bbs",
"date":"2017-11-24",
"default":false,
"display":0,
"pid":"3"
}

@ -1,40 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
install_tmp='/tmp/bt_install.pl'
public_file=/www/server/panel/install/public.sh
if [ ! -f $public_file ];then
wget -O $public_file http://download.bt.cn/install/public.sh -T 5;
fi
. $public_file
download_Url=$NODE_URL
Install_safelogin()
{
mkdir -p /www/server/panel/plugin/safelogin
echo '正在安装脚本文件...' > $install_tmp
wget -O /www/server/panel/plugin/safelogin/safelogin_main.py $download_Url/install/lib/plugin/safelogin/safelogin_main.py -T 5
wget -O /www/server/panel/plugin/safelogin/index.html $download_Url/install/lib/plugin/safelogin/index.html -T 5
wget -O /www/server/panel/plugin/safelogin/info.json $download_Url/install/lib/plugin/safelogin/info.json -T 5
wget -O /www/server/panel/plugin/safelogin/icon.png $download_Url/install/lib/plugin/safelogin/icon.png -T 5
echo '安装完成' > $install_tmp
}
Uninstall_safelogin()
{
chattr -i /www/server/panel/plugin/safelogin/token.pl
rm -f /www/server/panel/data/limitip.conf
sed -i "/ALL/d" /etc/hosts.deny
rm -rf /www/server/panel/plugin/safelogin
}
action=$1
host=$2;
if [ "${1}" == 'install' ];then
Install_safelogin
else
Uninstall_safelogin
fi

@ -1,276 +0,0 @@
#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Linux面板 x3
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
#+--------------------------------------------------------------------
#| 宝塔安全登陆插件
#+--------------------------------------------------------------------
import sys;
sys.path.append('class/');
reload(sys);
import public,json,os,time,binascii,urllib,re,web;
class safelogin_main:
__PANEL_SSL = None;
__PDATA = None;
__APIURL = 'http://www.bt.cn/api/Auth';
__UPATH = 'data/userInfo.json';
__DENY = '/etc/hosts.deny';
__ALLOW = '/etc/hosts.allow';
__LIMIT_CONF = 'data/limitip.conf';
__userInfo = None;
def __init__(self):
pdata = {}
data = {}
if os.path.exists(self.__UPATH):
self.__userInfo = json.loads(public.readFile(self.__UPATH));
if self.__userInfo:
pdata['access_key'] = self.__userInfo['access_key'];
data['secret_key'] = self.__userInfo['secret_key'];
else:
pdata['access_key'] = 'test';
data['secret_key'] = '123456';
pdata['data'] = data;
self.__PDATA = pdata;
#生成并发送Token
def SendToken(self,get = None):
return False;
#获取服务器密钥
def GetServerToken(self,get):
password = public.M('users').where('id=?',(1,)).getField('password');
if password != public.md5(get.password): return public.returnMsg(False,'密码验证失败!');
tokenFile = '/www/server/panel/plugin/safelogin/token.pl';
if not os.path.exists(tokenFile):
tokenStr = public.GetRandomString(64);
public.writeFile(tokenFile,tokenStr);
else:
tokenStr = public.readFile(tokenFile);
public.ExecShell('chattr +i ' + tokenFile);
return tokenStr.strip();
#获取服务器信息
def GetServerInfo(self,get):
#self.SendToken();
self.__init__();
self.__PDATA['data'] = self.De_Code(self.__PDATA['data']);
result = json.loads(public.httpPost(self.__APIURL + '/GetServerInfo',self.__PDATA));
result['data'] = self.En_Code(result['data']);
return result;
#获取Token
def GetToken(self,get):
data = {}
data['username'] = get.username;
data['password'] = public.md5(get.password);
pdata = {}
pdata['data'] = self.De_Code(data);
result = json.loads(public.httpPost(self.__APIURL+'/GetToken',pdata));
result['data'] = self.En_Code(result['data']);
if result['data']: public.writeFile(self.__UPATH,json.dumps(result['data']));
del(result['data']);
return result;
#获取节点列表
def get_node_list(self,get):
self.__PDATA['data'] = self.De_Code(self.__PDATA['data']);
result = json.loads(public.httpPost(self.__APIURL + '/GetNodeList',self.__PDATA));
result['data'] = self.En_Code(result['data']);
return result;
#添加SSH许可IP
def add_ssh_limit(self,get):
ip = get.ip;
denyConf = public.readFile(self.__DENY);
if denyConf.find('sshd:ALL') == -1:
while denyConf[-1:] == "\n" or denyConf[-1:] == " ": denyConf = denyConf[:-1];
denyConf += "\nsshd:ALL\n";
public.writeFile(self.__DENY,denyConf);
if ip in self.get_ssh_limit(): return public.returnMsg(True,'指定IP白名单已存在!');
allowConf = public.readFile(self.__ALLOW).strip();
while allowConf[-1:] == "\n" or allowConf[-1:] == " ": allowConf = allowConf[:-1];
allowConf += "\nsshd:" + ip+":allow\n";
public.writeFile(self.__ALLOW,allowConf);
if ip in self.get_ssh_limit(): return public.returnMsg(True,'添加成功!');
return public.returnMsg(False,'添加失败!');
#删除SSH许可IP
def remove_ssh_limit(self,get):
ip = get.ip;
if not ip in self.get_ssh_limit(): return public.returnMsg(True,'指定白名单不存在!');
allowConf = public.readFile(self.__ALLOW).strip();
while allowConf[-1:] == "\n" or allowConf[-1:] == " ": allowConf = allowConf[:-1];
allowConf = re.sub("\nsshd:"+ip+":allow\n?","\n",allowConf);
public.writeFile(self.__ALLOW,allowConf+"\n");
return public.returnMsg(True,'删除成功!');
#获取当前SSH许可IP
def get_ssh_limit(self,get = None):
allowConf = public.readFile(self.__ALLOW);
return re.findall("sshd:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):allow",allowConf);
#获取登陆记录
def get_login_log(self,get):
return public.M('logs').where('type=?',(u'用户登录',)).field('log,addtime').select();
#取当前面板登陆许可
def get_panel_limit(self,get = None):
conf = public.readFile(self.__LIMIT_CONF)
if not conf: conf = '';
limitIp = conf.split(',');
if '' in limitIp: limitIp.remove('');
return limitIp;
#添加面板许可登陆IP
def add_panel_limit(self,get):
limitIp = self.get_panel_limit();
if get.ip in limitIp: return public.returnMsg(True,'指定IP白名单已存在!');
limitIp.append(get.ip);
public.writeFile(self.__LIMIT_CONF,','.join(limitIp));
return public.returnMsg(True,'添加成功!');
#删除面板许可登陆IP
def remove_panel_limit(self,get):
limitIp = self.get_panel_limit();
if not get.ip in limitIp: return public.returnMsg(True,'指定IP白名单不存在!');
limitIp.remove(get.ip);
public.writeFile(self.__LIMIT_CONF,','.join(limitIp));
return public.returnMsg(True,'删除成功!');
#清除SSH许可限制
def close_ssh_limit(self,get):
#清除白名单
allowConf = public.readFile(self.__ALLOW);
allowConf = re.sub("\n\s*sshd:\w{1,3}\.\w{1,3}\.\w{1,3}\.\w{1,3}:allow",'',allowConf);
public.writeFile(self.__ALLOW,allowConf);
#关闭限制
denyConf = public.readFile(self.__DENY);
denyConf = re.sub("sshd:ALL\s*","",denyConf);
public.writeFile(self.__DENY,denyConf);
return public.returnMsg(True,'清除成功!');
#清除面板登陆许可
def close_panel_limit(self,get):
if os.path.exists(self.__LIMIT_CONF): os.remove(self.__LIMIT_CONF);
return public.returnMsg(True,'已关闭IP限制!');
#获取操作系统信息
def get_system_info(self,get):
import system;
s = system.system();
data = s.GetSystemTotal(get,0.1);
data['disk'] = s.GetDiskInfo2();
return data;
#获取环境信息
def get_service_info(self,get):
import system;
serviceInfo = system.system().GetConcifInfo(get);
del(serviceInfo['mysql_root']);
return serviceInfo;
#获取用户绑定信息
def get_user_info(self,get):
return self.__userInfo;
#设置用户绑定信息
def set_user_info(self,get):
data = {}
data['username'] = get.username;
data['password'] = public.md5(get.password);
pdata = {}
pdata['data'] = self.De_Code(data);
result = json.loads(public.httpPost(self.__APIURL+'/GetToken',pdata));
result['data'] = self.En_Code(result['data']);
if result['data']: public.writeFile(self.__UPATH,json.dumps(result['data']));
del(result['data']);
return result;
#获取SSH爆破次数
def get_ssh_errorlogin(self,get):
path = '/var/log/secure'
if not os.path.exists(path): public.writeFile(path,'');
fp = open(path,'r');
l = fp.readline();
data = {};
data['intrusion'] = [];
data['intrusion_total'] = 0;
data['defense'] = [];
data['defense_total'] = 0;
data['success'] = [];
data['success_total'] = 0;
limit = 100;
while l:
if l.find('Failed password for root') != -1:
if len(data['intrusion']) > limit: del(data['intrusion'][0]);
data['intrusion'].append(l);
data['intrusion_total'] += 1;
elif l.find('Accepted') != -1:
if len(data['success']) > limit: del(data['success'][0]);
data['success'].append(l);
data['success_total'] += 1;
elif l.find('refused') != -1:
if len(data['defense']) > limit: del(data['defense'][0]);
data['defense'].append(l);
data['defense_total'] += 1;
l = fp.readline();
months = {'Jan':'01','Feb':'02','Mar':'03','Apr':'04','May':'05','Jun':'06','Jul':'07','Aug':'08','Sept':'09','Oct':'10','Nov':'11','Dec':'12'}
intrusion = [];
for g in data['intrusion']:
tmp = {}
tmp1 = g.split();
tmp['date'] = months[tmp1[0]] + '/' + tmp1[1] + ' ' + tmp1[2];
tmp['user'] = tmp1[8];
tmp['address'] = tmp1[10];
intrusion.append(tmp);
data['intrusion'] = intrusion;
success = [];
for g in data['success']:
tmp = {}
tmp1 = g.split();
tmp['date'] = months[tmp1[0]] + '/' + tmp1[1] + ' ' + tmp1[2];
tmp['user'] = tmp1[8];
tmp['address'] = tmp1[10];
success.append(tmp);
data['success'] = success;
defense = []
for g in data['defense']:
tmp = {}
tmp1 = g.split();
tmp['date'] = months[tmp1[0]] + '/' + tmp1[1] + ' ' + tmp1[2];
tmp['user'] = '-';
tmp['address'] = tmp1[8];
defense.append(tmp);
data['defense'] = defense;
import firewalls;
data['ssh'] = firewalls.firewalls().GetSshInfo(get);
return data;
#加密数据
def De_Code(self,data):
pdata = urllib.urlencode(data);
return binascii.hexlify(pdata);
#解密数据
def En_Code(self,data):
result = urllib.unquote(binascii.unhexlify(data));
return json.loads(result);
Loading…
Cancel
Save