• 粉丝日志首页

Mongoose使用案例–让JSON数据直接入库MongoDB

为什么用Nodejs?为什么用MongoDB?从领域语言和代码简洁之道来看,这是我非常关心的问题。

Nodejs基于Javascript,MongoDB脚步同样也是基于Javascript。而且他们的数据存储格式都是JSON,这就是为什么要把他们放在一起的原因了。如果程序前后端能直接处理JSON,我想数据处理过程又可以极大的减化了,代码量又将低少1/5。多么的兴奋啊!让我们来动手验证一下想法吧。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javacript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-mongoose-json/

程序代码已经上传到github有需要的同学,自行下载。
https://github.com/bsspirit/nodejs-demo

本文重点介绍web前端通过JQuery发起POST提交JSON数据,通过Mongoose直接插入或更新到MongoDB。

工程目录沿用nodejs-demo,增加/mongoose路径及对应文件。

关于nodejs-demo项目介绍,请参考文章:

Nodejs开发框架Express3.0开发手记–从零开始
http://blog.fens.me/nodejs-express3/

nodejs2

从零开始nodejs系列文章

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

 

文章目录

  1. 配置Mongoose
  2. 创建目录及文件
  3. 插入数据,POST提交JSON增加一条记录
  4. 查询数据,取出刚增加的记录

1. 配置Mongoose

增加mongoose的类库


cd d:/workspace/project/nodejs-demo
npm install mongoose

D:\workspace\project\nodejs-demo\node_modules\mongoose\node_modules\mongodb\node_modu
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.InvalidPlatform.Targe
e_modules\mongodb\node_modules\bson\build\bson.vcxproj]
mongoose@3.6.10 node_modules\mongoose
├── muri@0.3.1
├── hooks@0.2.1
├── sliced@0.0.3
├── mpath@0.1.1
├── ms@0.1.0
├── mpromise@0.2.1 (sliced@0.0.4)
└── mongodb@1.3.3 (kerberos@0.0.2, bson@0.1.8)

安装时,有64位兼容性错误提示没关系,Mongoose类库安装完成。

增加models目录
mkdir models

在models目录,增加mongodb.js文件


var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/nodejs');
exports.mongoose = mongoose;

指定Mongo的数据库名为nodejs

2.创建目录及文件

在models目录,增加数据模型Movie.js


var mongodb = require('./mongodb');
var Schema = mongodb.mongoose.Schema;
var MovieSchema = new Schema({
name : String,
alias : [String],
publish : Date,
create_date : { type: Date, default: Date.now},
images :{
coverSmall:String,
coverBig:String,
},
source :[{
source:String,
link:String,
swfLink:String,
quality:String,
version:String,
lang:String,
subtitle:String,
create_date : { type: Date, default: Date.now }
}]
});
var Movie = mongodb.mongoose.model("Movie", MovieSchema);
var MovieDAO = function(){};
module.exports = new MovieDAO();

指定Mongo的数据库集为Movie

数据类型,包括了String,Date,Array,Mixed]

打开app.js增加访问路径


var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, movie = require('./routes/movie')
, http = require('http')
, path = require('path')
, ejs = require('ejs')
, SessionStore = require("session-mongoose")(express);
...
app.get('/movie/add',movie.movieAdd);//增加
app.post('/movie/add',movie.doMovieAdd);//提交
app.get('/movie/:name',movie.movieAdd);//编辑查询
app.get('/movie/json/:name',movie.movieJSON);//JSON数据

在routes目录,增加movie.js


var Movie = require('./../models/Movie.js');
exports.movieAdd = function(req, res) {
if(req.params.name){//update
return res.render('movie', {
title:req.params.name+'|电影|管理|moive.me',
label:'编辑电影:'+req.params.name,
movie:req.params.name
});
} else {
return res.render('movie',{
title:'新增加|电影|管理|moive.me',
label:'新增加电影',
movie:false
});
}
};
exports.doMovieAdd = function(req, res) {
res.send({'success':true});
};

在views目录,增加movie.html


<% include header.html %>
<div class="container-fluid">
<div class="row-fluid">
<div class="span8">
<form>
<fieldset>
<legend><%=label%></legend>
<textarea id="c_editor" name="c_editor" class="span12" rows="10"></textarea>
<button id="c_save" type="button" class="btn btn-primary">保存</button>
</fieldset>
<form>
</div>
</div>
</div>
<% include footer.html %>

网页效果:http://localhost:3000/movie/add

movieInsert

3. 插入数据,POST提交JSON增加一条记录

基础环境,都搭建好后,我们开台准备向mongodb中插入数据。

首先创建一个json数据文件,这样我们可以方便点,直接读入这个文件,创建JSON数据对象了。

在public/javascripts/目录,增加movie.json文件


{
"name": "未来警察",
"alias": ["Future X-Cops ","Mei loi ging chaat"],
"publish": "2010-04-29",
"images":{
"coverBig":"/img/movie/1_big.jpg",
"coverSmall":"/img/movie/1_small.jpg"
},
"source":[{
"source":"优酷",
"link":"http://www.youku.com",
"swfLink":"http://player.youku.com/player.php/sid/XMTY4NzM5ODc2/v.swf",
"quality":"高清",
"version":"正片",
"lang":"汉语",
"subtitle":"中文字幕"
},{
"source":"搜狐",
"link":"http://tv.sohu.com",
"swfLink":"http://share.vrs.sohu.com/75837/v.swf&topBar=1&autoplay=false&plid=3860&pub_catecode=",
"quality":"高清",
"version":"正片",
"lang":"汉语",
"subtitle":"中文字幕"
}]
}

在public/javascripts/目录,增加jquery.json-2.4.js类库


<script src="/javascripts/jquery-1.9.1.min.js"></script>
<script src="/javascripts/bootstrap.min.js"></script>
<script src="/javascripts/jquery.json-2.4.js"></script>
<script src="/javascripts/movie.js"></script>
</body>
</html>

在public/javascripts/目录,增加movie.js文件,作为前端脚本


$(function() {
var mdata={};
var url = '/javascripts/movie.json';
$.getJSON(url, function(data) {
mdata=data;
render_editor_form(mdata);
render_event_form(mdata);
});
var render_editor_form=function(data){
$('#c_editor').val($.toJSON(data));
};
var render_event_form=function(){
$('#c_save').on('click',function(event){
var data = {};
data['content'] = mdata;
$.ajax({
type: "POST",
url: '/movie/add',
data: data,
success: function (data, textStatus){
if(data.success){
$('#msg').html('成功保存!');
$('#msg').addClass('alert alert-success');
$(location).attr('href','/movie/'+mdata.name);
} else {
$('#msg').html(data.err);
$('#msg').addClass('alert alert-error');
}
}
});
});
};
});

修改views/footer.html,增加movie.js文件引用,同时增加jquery.json包


<script src="/javascripts/jquery-1.9.1.min.js"></script>
<script src="/javascripts/bootstrap.min.js"></script>
<script src="/javascripts/jquery.json-2.4.js"></script>
<script src="/javascripts/movie.js"></script>
</body>
</html>

网页效果:http://localhost:3000/movie/add

movieInsert2

在models/Movie.js,增加save方法


MovieDAO.prototype.save = function(obj, callback) {
var instance = new Movie(obj);
instance.save(function(err){
callback(err);
});
};

在routes/movie.js,调用save方法


exports.doMovieAdd = function(req, res) {
console.log(req.body.content);
var json = req.body.content;
if(json._id){//update
} else {//insert
Movie.save(json, function(err){
if(err) {
res.send({'success':false,'err':err});
} else {
res.send({'success':true});
}
});
}
};

控制台日志


Express server listening on port 3000
{ name: '未来警察',
alias: [ 'Future X-Cops ', 'Mei loi ging chaat' ],
publish: '2010-04-29',
images:
{ coverBig: '/img/movie/1_big.jpg',
coverSmall: '/img/movie/1_small.jpg' },
source:
[ { source: '优酷',
link: 'http://www.youku.com',
swfLink: 'http://player.youku.com/player.php/sid/XMTY4NzM5ODc2/v.swf',
quality: '高清',
version: '正片',
lang: '汉语',
subtitle: '中文字幕' },
{ source: '搜狐',
link: 'http://tv.sohu.com',
swfLink: 'http://share.vrs.sohu.com/75837/v.swf&topBar=1&autoplay=false&plid=3860&pub_ca
quality: '高清',
version: '正片',
lang: '汉语',
subtitle: '中文字幕' } ] }
POST /movie/add 200 57ms - 21b

数据已插入MongoDB

movieInsert3

4. 查询数据,取出刚增加的记录

models/Movie.js,增加findByName方法


MovieDAO.prototype.findByName = function(name, callback) {
Movie.findOne({name:name}, function(err, obj){
callback(err, obj);
});
};

routes/movies.js,增加movieJSON


exports.movieJSON = function(req, res) {
Movie.findByName(req.params.name,function(err, obj){
res.send(obj);
});
}

前端javascripts/movie.js,从/movie/json/xxx处取数据


var mdata={};
var url = '/javascripts/movie.json';
var movie=$('#c_editor').attr('movie')
if(movie){
url = '/movie/json/'+movie;
}

修改 views/movie.html


<textarea id="c_editor" name="c_editor" rows="10" <%= (movie?'"movie='+movie+'"':'') %>></textarea>

访问我们的网页

http://localhost:3000/movie/未来警察

movieInsert4

数据从/movie/json/未来警察,处读取。完成尝试。

修改操作与插入的操作类似,我就不做演示了。

希望此文对大家有所帮助。

以上程序代码,我已经上传到github有需要的同学,自行下载。
https://github.com/bsspirit/nodejs-demo

转载请注明出处:
http://blog.fens.me/nodejs-mongoose-json/

打赏作者

Nodejs开发框架Express3.0开发手记–从零开始

前言

Nodejs给Javascript赋予了服务端应用的生命,Jquery让Javascript成为浏览中开发的利器。 最近学习了Nodejs的Express3.0的开发框架,本来是按照“node.js开发指南”书中介绍,但“node.js开发指南”讲的是Express2.x的,从Express2.x到Express3.0自己模索中还是走了不少弯路的。写篇文章总结一下。

关于作者

张丹(Conan), 程序员Java,R,PHP,Javacript
weibo:@Conan_Z
blog: http://blog.fens.me
email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-express3/

程序代码已经上传到github有需要的同学,自行下载。
https://github.com/bsspirit/nodejs-demo

nodejs intro

从零开始nodejs系列文章

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

目录

此文重点介绍Express3.0的开发框架,其中还会涉及到Mongoose,Ejs,Bootstrap等相关内容。
Express已经升级到4.x,请同时参考文章,Node.js开发框架Express4.x

  1. 建立工程
  2. 目录结构
  3. Express3.0配置文件
  4. Ejs模板使用
  5. Bootstrap界面框架
  6. 路由功能
  7. Session使用
  8. 页面提示
  9. 页面访问控制

开发环境:

Win7旗舰版 64bit

MonogoDB: v2.4.3


Tue May 14 09:24:50.118 [initandlisten] MongoDB starting : pid=1716 port=27017 dbpath=./data 64-bit host=PC201304202140
Tue May 14 09:24:50.119 [initandlisten] db version v2.4.3
Tue May 14 09:24:50.119 [initandlisten] git version: fe1743177a5ea03e91e0052fb5e2cb2945f6d95f
Tue May 14 09:24:50.119 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1') BOOST_LIB_VERSION=1_49
Tue May 14 09:24:50.119 [initandlisten] allocator: system
Tue May 14 09:24:50.119 [initandlisten] options: { dbpath: "./data" }
Tue May 14 09:24:50.188 [initandlisten] journal dir=./data\journal
Tue May 14 09:24:50.189 [initandlisten] recover : no journal files present, no recovery needed
Tue May 14 09:24:50.441 [initandlisten] preallocateIsFaster=true 3.26
Tue May 14 09:24:50.778 [initandlisten] preallocateIsFaster=true 5.88
Tue May 14 09:24:51.827 [initandlisten] waiting for connections on port 27017
Tue May 14 09:24:51.827 [websvr] admin web console waiting for connections on port 28017

nodejs: v0.10.5, npm 1.2.19

node -v
v0.10.5
npm -v
1.2.19

1. 建立工程

进入工程目录


cd D:\workspace\project

全局安装express,express作为命令被安装到了系统中


npm install -g express

查看express版本


express -V
3.2.2

使用express命令创建工程,并支持ejs


D:\workspace\project>express -e nodejs-demo

create : nodejs-demo
create : nodejs-demo/package.json
create : nodejs-demo/app.js
create : nodejs-demo/public
create : nodejs-demo/public/javascripts
create : nodejs-demo/public/images
create : nodejs-demo/public/stylesheets
create : nodejs-demo/public/stylesheets/style.css
create : nodejs-demo/routes
create : nodejs-demo/routes/index.js
create : nodejs-demo/routes/user.js
create : nodejs-demo/views
create : nodejs-demo/views/index.ejs

install dependencies:
$ cd nodejs-demo && npm install
run the app:
$ node app

根据提示,下载依赖包


cd nodejs-demo && npm install

express@3.2.2 node_modules\express
├── methods@0.0.1
├── fresh@0.1.0
├── buffer-crc32@0.2.1
├── range-parser@0.0.4
├── cookie-signature@1.0.1
├── cookie@0.0.5
├── qs@0.6.3
├── commander@0.6.1
├── debug@0.7.2
├── mkdirp@0.3.4
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.8 (pause@0.0.1, bytes@0.2.0, formidable@1.0.13)

模板项目建立成功,启动模板项目。


D:\workspace\project\nodejs-demo>node app.js
Express server listening on port 3000

本地的3000端口被打开,通过浏览器访问: localhost:3000

通过node启动程序,每次代码修改都需要重新启动。 有一个工具supervisor,每次修改代码后会自动重启,会我们开发省很多的时间。


npm install supervisor

再启动服务


D:\workspace\project\nodejs-demo>supervisor app.js

DEBUG: Running node-supervisor with
DEBUG: program 'app.js'
DEBUG: --watch '.'
DEBUG: --ignore 'undefined'
DEBUG: --extensions 'node|js'
DEBUG: --exec 'node'

DEBUG: Starting child process with 'node app.js'
DEBUG: Watching directory 'D:\workspace\project\nodejs-demo' for changes.
Express server listening on port 3000

 

2. 目录结构

D:\workspace\project\nodejs-demo>dir

2013/05/14 09:42 877 app.js
2013/05/14 09:48 <DIR> node_modules
2013/05/14 09:42 184 package.json
2013/05/14 09:42 <DIR> public
2013/05/14 09:42 <DIR> routes
2013/05/14 09:42 <DIR> views

目录介绍:

  • node_modules, 存放所有的项目依赖库。(每个项目管理自己的依赖,与Maven,Gradle等不同)
  • package.json,项目依赖配置及开发者信息
  • app.js,程序启动文件
  • public,静态文件(css,js,img)
  • routes,路由文件(MVC中的C,controller)
  • Views,页面文件(Ejs模板)

3. Express3.0配置文件

打开app.js文件


/**
* 模块依赖
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');

var app = express();

//环境变量
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// 开发模式
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}

// 路径解析
app.get('/', routes.index);
app.get('/users', user.list);

// 启动及端口
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

 

4. Ejs模板使用

让ejs模板文件,使用扩展名为html的文件。

修改:app.js


app.engine('.html', ejs.__express);
app.set('view engine', 'html');// app.set('view engine', 'ejs');

修改后,ejs变量没有定义,supervisor的程序会一直报错


ReferenceError: ejs is not defined
at Object. (D:\workspace\project\nodejs-demo\app.js:17:21)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
DEBUG: Program node app.js exited with code 8

在app.js中增加ejs变量


var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, ejs = require('ejs');

访问localhost:3000,程序报错


Error: Failed to lookup view "index"
at Function.app.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\application.js:495:17)
at ServerResponse.res.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\response.js:756:7)
at exports.index (D:\workspace\project\nodejs-demo\routes\index.js:7:7)
at callbacks (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:161:37)
at param (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:135:11)
at pass (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:142:5)
at Router._dispatch (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:170:5)
at Object.router (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:33:10)
at next (D:\workspace\project\nodejs-demo\node_modules\express\node_modules\connect\lib\proto.js:190:15)
at Object.methodOverride [as handle] (D:\workspace\project\nodejs-demo\node_modules\express\node_modules\connect\lib\middleware\methodOverride.js:37:5)
GET / 500 26ms

重命名:views/indes.ejs 为 views/index.html

访问localhost:3000正确

 

5. 增加Bootstrap界面框架

其实就是把js,css文件复制到项目中对应该的目录里。 包括4个文件:

复制到public/stylesheets目录


bootstrap.min.css
bootstrap-responsive.min.css

复制到public/javascripts目录


bootstrap.min.js
jquery-1.9.1.min.js

接下来,我们把index.html页面切分成3个部分:header.html, index.html, footer.html

header.html, 为html页面的头部区域
index.html, 为内容显示区域
footer.html,为页面底部区域

header.html


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><%=: title %></title>
<!-- Bootstrap -->
<link href="/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen">
<!-- <link href="css/bootstrap-responsive.min.css" rel="stylesheet" media="screen"> -->
</head>
<body screen_capture_injected="true">

index.html


<% include header.html %>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<% include footer.html %>

注:express3.0时,ejs嵌入其他页面时使用include,express2.x用法不一样。

footer.html


<script src="/javascripts/jquery-1.9.1.min.js"></script>
<script src="/javascripts/bootstrap.min.js"></script>
</body>
</html>

访问localhost:3000正确。

我们已经成功的使用了EJS模板的功能,把公共的头部和底部从页面中分离出来了。

并已经引入了bootstrap界面框架,后面讲到“登陆界面”的时候,就会看到bootstrap界面效果了。

 

6. 路由功能

我们设计一下用户登陆业务需求。

访问路径:/,页面:index.html,不需要登陆,可以直接访问。
访问路径:/home,页面:home.html,必须用户登陆后,才可以访问。
访问路径:/login,页面:login.html,登陆页面,用户名密码输入正确,自动跳转到home.html
访问路径:/logout,页面:无,退出登陆后,自动回到index.html页面
打开app.js文件,在增加路由配置


app.get('/', routes.index);
app.get('/login', routes.login);
app.post('/login', routes.doLogin);
app.get('/logout', routes.logout);
app.get('/home', routes.home);

注:get为get请求,post为post请求,all为所有针对这个路径的请求

我们打开routes/index.js文件,增加对应的方法。


exports.index = function(req, res){
res.render('index', { title: 'Index' });
};
exports.login = function(req, res){
res.render('login', { title: '用户登陆'});
};
exports.doLogin = function(req, res){
var user={
username:'admin',
password:'admin'
}
if(req.body.username===user.username && req.body.password===user.password){
res.redirect('/home');
}
res.redirect('/login');
};
exports.logout = function(req, res){
res.redirect('/');
};
exports.home = function(req, res){
var user={
username:'admin',
password:'admin'
}
res.render('home', { title: 'Home',user: user});
};

创建views/login.html和views/home.html两个文件

login.html


<% include header.html %>
<div class="container-fluid">
<form class="form-horizontal" method="post">
<fieldset>
<legend>用户登陆</legend>
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input type="text" class="input-xlarge" id="username" name="username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">登陆</button>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>

login
注:使用了bootstrap界面框架,效果还不错吧.

home.html


<% include header.html %>
<h1>Welcome <%= user.username %>, 欢迎登陆!!</h1>
<a claa="btn" href="/logout">退出</a>
<% include footer.html %>

修改index.html,增加登陆链接
index.html


<% include header.html %>
<h1>Welcome to <%= title %></h1>
<p><a href="/login">登陆</a></p>
<% include footer.html %>

路由及页面我们都写好了,快去网站上试试吧。

 

7. Session使用

从刚来的例子上面看,执行exports.doLogin时,如果用户名和密码正确,我们使用redirect方法跳转到的home

res.redirect('/home');

执行exports.home时,我们又用render渲染页面,并把user对象传给home.html页面

res.render('home', { title: 'Home',user: user});

为什么不能在doLogin时,就把user对象赋值给session,每个页面就不再传值了。

session这个问题,其实是涉及到服务器的底层处理方式。

像Java的web服务器,是多线程调用模型。每用户请求会打开一个线程,每个线程在内容中维护着用户的状态。

像PHP的web服务器,是交行CGI的程序处理,CGI是无状态的,所以一般用cookie在客户的浏览器是维护用户的状态。但cookie在客户端维护的信息是不够的,所以CGI应用要模仿用户session,就需要在服务器端生成一个session文件存储起来,让原本无状态的CGI应用,通过中间文件的方式,达到session的效果。

Nodejs的web服务器,也是CGI的程序无状态的,与PHP不同的地方在于,单线程应用,所有请求都是异步响应,通过callback方式返回数据。如果我们想保存session数据,也是需要找到一个存储,通过文件存储,redis,Mongdb都可以。

接下来,我将演示如何通过mongodb来保存session,并实现登陆后用户对象传递。

app.js文件


var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, ejs = require('ejs')
, SessionStore = require("session-mongoose")(express);
var store = new SessionStore({
url: "mongodb://localhost/session",
interval: 120000
});
....
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.cookieSession({secret : 'fens.me'}));
app.use(express.session({
secret : 'fens.me',
store: store,
cookie: { maxAge: 900000 }
}));
app.use(function(req, res, next){
res.locals.user = req.session.user;
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

注:app.js文件有顺序要求,一定要注意!!!

安装session-mongoose依赖库


D:\workspace\project\nodejs-demo>npm install session-mongoose
D:\workspace\project\nodejs-demo\node_modules\session-mongoose\node_modules\mongoose\node_modules\mongodb\node_modules\bson>node "D:\toolkit\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.InvalidPlatform.Targets(23,7): error MSB8007: 项目“kerberos.vcxproj”的平台无效。平台为“x64”。您会看到此消息的可能原因是,您尝试在没有解决方案文件的情况下生成项目,并且为
oose\node_modules\mongoose\node_modules\mongodb\node_modules\bson\build\bson.vcxproj]
session-mongoose@0.2.2 node_modules\session-mongoose
└── mongoose@3.6.10 (mpath@0.1.1, ms@0.1.0, hooks@0.2.1, sliced@0.0.3, muri@0.3.1, mpromise@0.2.1, mongodb@1.3.3)

安装有错误但是没关系。

访问:http://localhost:3000/login,正常

修改routes/index.js文件

exports.doLogin方法


exports.doLogin = function(req, res){
var user={
username:'admin',
password:'admin'
}
if(req.body.username===user.username && req.body.password===user.password){
req.session.user=user;
return res.redirect('/home');
} else {
return res.redirect('/login');
}
};

exports.logout方法


exports.logout = function(req, res){
req.session.user=null;
res.redirect('/');
};

exports.home方法


exports.home = function(req, res){
res.render('home', { title: 'Home'});
};

这个时候session已经起作用了,exports.home的user显示传值已经被去掉了。 是通过app.js中app.use的res.locals变量,通过框架进行的赋值。


app.use(function(req, res, next){
res.locals.user = req.session.user;
next();
});

注:这个session是express3.0的写法,与express2.x是不一样的。原理是在框架内每次赋值,把我们刚才手动传值的过程,让框架去完成了。

 

8. 页面提示

登陆的大体我们都已经讲完了,最后看一下登陆失败的情况。

我们希望如果用户登陆时,用户名或者密码出错了,会给用户提示,应该如何去实现。

打开app.js的,增加res.locals.message


app.use(function(req, res, next){
res.locals.user = req.session.user;
var err = req.session.error;
delete req.session.error;
res.locals.message = '';
if (err) res.locals.message = '<div class="alert alert-error">' + err + '</div>';
next();
});

修改login.html页面,<%- message %>


<% include header.html %>
<div class="container-fluid">
<form class="form-horizontal" method="post">
<fieldset>
<legend>用户登陆</legend>
<%- message %>
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input type="text" class="input-xlarge" id="username" name="username" value="admin">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password" value="admin">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">登陆</button>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>

修改routes/index.js,增加req.session.error


exports.doLogin = function(req, res){
var user={
username:'admin',
password:'admin'
}
if(req.body.username===user.username && req.body.password===user.password){
req.session.user=user;
return res.redirect('/home');
} else {
req.session.error='用户名或密码不正确';
return res.redirect('/login');
}
};

让我们来看看效果: http://localhost:3000/login 输入错误的和密码, 用户名:adminfe,密码:12121

loginErr

 

9. 页面访问控制

网站登陆部分按照我们的求已经完成了,但网站并不安全。

localhost:3000/home,页面本来是登陆以后才访问的,现在我们不要登陆,直接在浏览器输入也可访问。

页面报错了,提示<%= user.username %> 变量出错。


GET /home?user==a 500 15ms
TypeError: D:\workspace\project\nodejs-demo\views\home.html:2
1| <% include header.html %>
>> 2| <h1>Welcome <%= user.username %>, 欢迎登陆!!</h1>
3| <a claa="btn" href="/logout">退出</a>
4| <% include header.html %>
Cannot read property 'username' of null
at eval (eval at <anonymous> (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:
at eval (eval at <anonymous> (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:
at D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:249:15
at Object.exports.render (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:287:
at View.exports.renderFile [as engine] (D:\workspace\project\nodejs-demo\node_modules\ejs\l
at View.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\view.js:75:8)
at Function.app.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\applicati
at ServerResponse.res.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\res
at exports.home (D:\workspace\project\nodejs-demo\routes\index.js:36:8)
at callbacks (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:161

这个页面被打开发,因为没有user.username参数。我们避免这样的错误发生。

还记录路由部分里说的get,post,all的作用吗?我现在要回到路由配置中,再做点事情。

修改app.js文件


app.all('/login', notAuthentication);
app.get('/login', routes.login);
app.post('/login', routes.doLogin);
app.get('/logout', authentication);
app.get('/logout', routes.logout);
app.get('/home', authentication);
app.get('/home', routes.home);

访问控制:

  • / ,谁访问都行,没有任何控制
  • /login,用all拦截所有访问/login的请求,先调用authentication,用户登陆检查
  • /logout,用get拦截访问/login的请求,先调用notAuthentication,用户不登陆检查
  • /home,用get拦截访问/home的请求,先调用Authentication,用户登陆检查

修改app.js文件,增加authentication,notAuthentication两个方法


function authentication(req, res, next) {
if (!req.session.user) {
req.session.error='请先登陆';
return res.redirect('/login');
}
next();
}
function notAuthentication(req, res, next) {
if (req.session.user) {
req.session.error='已登陆';
return res.redirect('/');
}
next();
}

配置好后,我们未登陆,直接访问localhost:3000/home时,就会跳到/login页面

loginHome

如果你也出现图片显示的内容,那么恭喜你了。

Nodejs使用Express3.0框架的第一步你已经完成了,并且还使用了ejs,bootstrap,mongoose库的使用。

希望此文对大家有所帮助。

Express已经升级到4.x,请同时参考文章,Node.js开发框架Express4.x

转载请注明出处:
http://blog.fens.me/nodejs-express3/

程序代码已经上传到github有需要的同学,自行下载。
https://github.com/bsspirit/nodejs-demo

打赏作者

在Ubuntu上安装PPTP VPN服务

1

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/ubuntu-vpn-pptp/

此图完整的阐述了身为帝国平民的必备技能之一,VPN服务则是此种技能的技术实现,虚拟专用网络(Virtual Private Network ,简称VPN)指的是在公用网络上建立专用网络的技术。它涵盖了跨共享网络或公共网络的封装、加密和身份验证链接的专用网络的扩展。VPN主要采用了彩隧道技术、加解密技术、密钥管理技术和使用者与设备身份认证技术。

点对点隧道协议(PPTP)是VPN服务的一种最简单的实现协议,其它常见的VPN类型还有:使用IPsec的第2层隧道协议(L2TP/IPsec)、安全套接字隧道协议(SSL VPN)。本文主要讨论PPTP VPN服务在Ubuntu上的安装和配置。

A.使用apt源服务来安装PPTPD服务


sudo apt-get update
sudo apt-get install pptpd

B.安装完成之后编辑pptpd.conf配置文件


sudo vi /etc/pptpd.conf

#确保如下选项的配置
option /etc/ppp/pptpd-option                    #指定PPP选项文件的位置
debug                                           #启用调试模式
localip 192.168.0.1                             #VPN服务器的虚拟ip
remoteip 192.168.0.200-238,192.168.0.245        #分配给VPN客户端的虚拟ip

C.编辑PPP选项配置文件

sudo vi /etc/ppp/pptpd-options

#确保如下选项的配置
name pptpd                      #pptpd服务的名称
refuse-pap                      #拒绝pap身份认证模式
refuse-chap                     #拒绝chap身份认证模式
refuse-mschap                   #拒绝mschap身份认证模式
require-mschap-v2               #允许mschap-v2身份认证模式
require-mppe-128                #允许mppe 128位加密身份认证模式
ms-dns 8.8.8.8                  #使用Google DNS
ms-dns 8.8.4.4                  #使用Google DNS
proxyarp                        #arp代理
debug                           #调试模式
dump                            #服务启动时打印出所有配置信息
lock                            #锁定TTY设备
nobsdcomp                       #禁用BSD压缩模式
logfile /var/log/pptpd.log      #输出日志文件位置

D.编辑用户配置文件来添加用户

sudo vi /etc/ppp/chap-secrets

#格式:用户名   服务类型   密码   分配的ip地址
test    *    1234    *
#第一个*代表服务可以是PPTPD也可以是L2TPD,第二个*代表随机分配ip

E.重启PPTPD服务


sudo service pptpd restart

F.配置网络和路由规则 设置ipv4转发


sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
sudo sysctl -p

设置iptables NAT转发

#注意这里eth0代表你的外网网卡,请用ifconfig查看或者咨询网络管理员
sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
#如果上面的命令报错,那么可以尝试以下的命令,其中xxx.xxx.xxx.xxx代表你的VPS外网ip地址
sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT --to-source xxx.xxx.xxx.xxx

设置MTU来确保过大的包不会被丢弃(这个可以不做)


sudo iptables -I FORWARD -s 192.168.0.0/24 -p tcp --syn -i ppp+ -j TCPMSS --set-mss 1300

iptables的设置重启之后会取消,所以可以将上面的命令加入到/etc/rc.local来确保每次重启都会执行设置。

G.至此设置全部完成,可以用任意一个客户端机器如MAC、PC或者手机来新建一个VPN连接使用用户test,密码1234进行测试。另外网上提供一种自动安装脚本,可以参见如下操作:


wget -c http://small-script.googlecode.com/files/debian-pptpd.tar.gz
tar -zxf debian-pptpd.tar.gz
sudo sh pptpd.sh

最后,如果想要实现更便利的用户管理,请参见在Ubuntu上安装FreeRADIUS服务

转载请注明出处:
http://blog.fens.me/ubuntu-vpn-pptp/

打赏作者

昨日终于找到攻击服务器的黑手了

近期服务器,总是收到IO,CPU的报警。

每天某一时刻,IO,CPU, 网络负载值非常高,并不是我的应用流量大。唯一的原因就是服务器被攻击了。

下面4幅图为服务器异常时的状态。

traffic

traffic IPV6

IO

CPU

 

应用软件设置:

  • Open-SSH:    SSH登陆
  • MySQL:         数据库服务器
  • Tomcat:        Java Web服务器
  • Nginx:           Http服务器
  • php-cgi:       PHP脚本解析服务

 

服务器的端口设置:

~# netstat -nlt

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:1723 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 127.0.0.1:8005 :::* LISTEN
tcp6 0 0 :::8009 :::* LISTEN
tcp6 0 0 :::8080 :::* LISTEN

 

找到攻击源:

发现在tomcat7/webapps下面,部署了一个我不认识的应用。

找到tomcat7/logs日志,查看是否有使用过Tomcat管理后台


~ tomcat7/logs# ls manager*

manager.2012-07-01.log  manager.2013-04-01.log  manager.2013-04-25.log
manager.2012-08-21.log  manager.2013-04-05.log  manager.2013-04-26.log
manager.2012-10-31.log  manager.2013-04-08.log  manager.2013-04-30.log
manager.2012-11-01.log  manager.2013-04-09.log  manager.2013-05-01.log
manager.2012-12-26.log  manager.2013-04-16.log  manager.2013-05-06.log
manager.2013-01-23.log  manager.2013-04-17.log  manager.2013-05-07.log
manager.2013-03-01.log  manager.2013-04-23.log

真被我发现了!!这么多文件操作,我自己并没有这么多的使用。

我们看一下黑客在管理后台干了什么。


~ /tomcat7/logs# vi manager.2013-05-06.log

May 6, 2013 2:20:48 PM org.apache.catalina.core.ApplicationContext log
INFO: HTMLManager: list: Listing contexts for virtual host 'localhost'
May 6, 2013 2:33:45 PM org.apache.catalina.core.ApplicationContext log
INFO: HTMLManager: list: Listing contexts for virtual host 'localhost'
May 6, 2013 2:34:00 PM org.apache.catalina.core.ApplicationContext log
SEVERE: HTMLManager: FAIL - Deploy Upload Failed, Exception: java.io.FileNotFoundException: /root/toolkit/tomcat7/webapps/51.war (Permission denied)
java.io.IOException: java.io.FileNotFoundException: /root/toolkit/tomcat7/webapps/51.war (Permission denied)
	at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:123)
	at org.apache.catalina.manager.HTMLManagerServlet.upload(HTMLManagerServlet.java:332)
	at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:211)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:186)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.FileNotFoundException: /root/toolkit/tomcat7/webapps/51.war (Permission denied)
	at java.io.FileOutputStream.open(Native Method)
	at java.io.FileOutputStream.(FileOutputStream.java:194)
	at java.io.FileOutputStream.(FileOutputStream.java:145)
	at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.write(DiskFileItem.java:457)
	at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:121)
	... 26 more
May 6, 2013 2:34:00 PM org.apache.catalina.core.ApplicationContext log
INFO: HTMLManager: list: Listing contexts for virtual host 'localhost'

上传名叫 51.war 的包程序在到tomcat/webapps目录。

再来找到黑客是如何获得后台访问权限的


~ vi localhost_access_log.2013-05-06.txt

218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - tomcat [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 200 19009
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:20:49 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - - [06/May/2013:14:33:39 +0000] "GET /manager/html HTTP/1.1" 401 2486
218.15.154.174 - tomcat [06/May/2013:14:33:45 +0000] "GET /manager/html HTTP/1.1" 200 17513
218.15.154.174 - tomcat [06/May/2013:14:33:46 +0000] "GET /manager/images/tomcat.gif HTTP/1.1" 200 2066
218.15.154.174 - tomcat [06/May/2013:14:33:46 +0000] "GET /manager/images/asf-logo.gif HTTP/1.1" 200 7279
218.15.154.174 - tomcat [06/May/2013:14:34:00 +0000] "POST /manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=64E6C202103BF3113A72485F80F5133F HTTP/1.1" 200 17638
218.15.154.174 - - [06/May/2013:14:34:11 +0000] "GET /doc HTTP/1.1" 302 -
218.15.154.174 - - [06/May/2013:14:34:11 +0000] "GET /doc/ HTTP/1.1" 200 3309

黑客的扫描程序实验多次后,终于发现了管理后台的密码,并成功登陆
218.15.154.174 – tomcat [06/May/2013:14:20:49 +0000] “GET /manager/html HTTP/1.1” 200 19009

上传自己的程序包
218.15.154.174 – tomcat [06/May/2013:14:34:00 +0000] “POST /manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=64E6C202103BF3113A72485F80F5133F HTTP/1.1” 200 17638

发现黑客的手段后,果断采取防御措施

1. 暂停tomcat的运行
2. 进入webapps目录,删除黑客上传的文件和文件包
3. 分析日志找到攻击者的IP
4. 把这些IP加到iptabls黑名单中
5. 关闭Tomcat管理控制台

分析日志找到攻击者的IP

183.191.4.235
58.180.70.160
113.30.74.125
113.30.106.92
124.160.217.200
218.15.154.174
61.187.94.66
180.179.206.10
187.188.175.49
65.126.238.4
61.167.33.222
54.228.209.57
95.211.121.136
77.79.125.2
218.15.154.174
222.184.121.15
182.140.241.19
121.199.27.236
116.55.226.215
124.129.18.178
109.186.134.160
61.187.94.66
101.226.33.208
101.226.51.226
112.64.235.89
14.63.196.181
113.30.106.90
109.186.134.160
58.180.70.160
49.156.145.2
61.191.31.27
14.17.18.152
113.30.106.95
61.187.94.66
61.187.94.66
101.226.65.106
180.153.163.191
110.4.89.42
61.187.94.66
109.186.134.160
80.241.209.155
85.17.156.16
218.15.154.174
121.199.27.236
61.187.94.66
113.30.74.125
61.191.31.27
121.189.59.207
82.80.248.188
203.174.60.2
182.140.241.19
124.129.18.178
14.63.196.181
49.156.145.2
199.254.238.207
206.172.16.30
61.167.33.222
203.174.60.2
65.126.238.4
59.188.29.254
118.180.7.60
221.12.174.123
46.32.254.6
59.188.29.254
223.16.9.122

把这些IP加到黑名单中


iptables -I INPUT -s 183.191.4.235 -j DROP
iptables -I INPUT -s 58.180.70.160 -j DROP
iptables -I INPUT -s 113.30.74.125 -j DROP
iptables -I INPUT -s 113.30.106.92 -j DROP
iptables -I INPUT -s 124.160.217.200 -j DROP
iptables -I INPUT -s 218.15.154.174 -j DROP
iptables -I INPUT -s 61.187.94.66 -j DROP
iptables -I INPUT -s 180.179.206.10 -j DROP
iptables -I INPUT -s 187.188.175.49 -j DROP
iptables -I INPUT -s 65.126.238.4 -j DROP
iptables -I INPUT -s 61.167.33.222 -j DROP
iptables -I INPUT -s 54.228.209.57 -j DROP
iptables -I INPUT -s 95.211.121.136 -j DROP
iptables -I INPUT -s 77.79.125.2 -j DROP
iptables -I INPUT -s 222.184.121.15 -j DROP
iptables -I INPUT -s 182.140.241.19 -j DROP
iptables -I INPUT -s 121.199.27.236 -j DROP
iptables -I INPUT -s 116.55.226.215 -j DROP
iptables -I INPUT -s 124.129.18.178 -j DROP
iptables -I INPUT -s 109.186.134.160 -j DROP
iptables -I INPUT -s 101.226.33.208 -j DROP
iptables -I INPUT -s 101.226.51.226 -j DROP
iptables -I INPUT -s 112.64.235.89 -j DROP
iptables -I INPUT -s 14.63.196.181 -j DROP
iptables -I INPUT -s 113.30.106.90 -j DROP
iptables -I INPUT -s 49.156.145.2 -j DROP
iptables -I INPUT -s 61.191.31.27 -j DROP
iptables -I INPUT -s 14.17.18.152 -j DROP
iptables -I INPUT -s 113.30.106.95 -j DROP
iptables -I INPUT -s 101.226.65.106 -j DROP
iptables -I INPUT -s 180.153.163.191 -j DROP
iptables -I INPUT -s 110.4.89.42 -j DROP
iptables -I INPUT -s 80.241.209.155 -j DROP
iptables -I INPUT -s 85.17.156.16 -j DROP
iptables -I INPUT -s 121.189.59.207 -j DROP
iptables -I INPUT -s 82.80.248.188 -j DROP
iptables -I INPUT -s 203.174.60.2 -j DROP
iptables -I INPUT -s 14.63.196.181 -j DROP
iptables -I INPUT -s 199.254.238.207 -j DROP
iptables -I INPUT -s 206.172.16.30 -j DROP
iptables -I INPUT -s 59.188.29.254 -j DROP
iptables -I INPUT -s 118.180.7.60 -j DROP
iptables -I INPUT -s 221.12.174.123 -j DROP
iptables -I INPUT -s 46.32.254.6 -j DROP
iptables -I INPUT -s 223.16.9.122 -j DROP

iptables -I INPUT -s 50.23.210.133 -j DROP
iptables -I INPUT -s 208.109.219.192 -j DROP
iptables -I INPUT -s 50.87.248.103 -j DROP
iptables -I INPUT -s 182.50.130.77 -j DROP
iptables -I INPUT -s 50.87.248.181 -j DROP
iptables -I INPUT -s 50.87.90.193 -j DROP
iptables -I INPUT -s 220.177.198.84 -j DROP
iptables -I INPUT -s 50.62.208.135 -j DROP
iptables -I INPUT -s 162.218.210.232 -j DROP
iptables -I INPUT -s 184.168.193.131 -j DROP
iptables -I INPUT -s 50.63.197.206 -j DROP
iptables -I INPUT -s 174.143.240.181 -j DROP
iptables -I INPUT -s 205.144.171.18 -j DROP
iptables -I INPUT -s 205.144.171.18 -j DROP
iptables -I INPUT -s 108.168.219.178 -j DROP
iptables -I INPUT -s 203.198.63.60 -j DROP
iptables -I INPUT -s 119.18.52.114 -j DROP
iptables -I INPUT -s 91.237.52.5 -j DROP
iptables -I INPUT -s 14.102.254.210 -j DROP
iptables -I INPUT -s 108.168.219.178 -j DROP
iptables -I INPUT -s 173.201.196.146 -j DROP
iptables -I INPUT -s 114.215.113.131 -j DROP
iptables -I INPUT -s 184.168.200.185 -j DROP
iptables -I INPUT -s 139.223.200.149 -j DROP
iptables -I INPUT -s 184.168.27.57 -j DROP
iptables -I INPUT -s 122.155.3.113 -j DROP
iptables -I INPUT -s 113.11.250.65 -j DROP
iptables -I INPUT -s 123.30.209.152 -j DROP
iptables -I INPUT -s 184.168.27.57 -j DROP
iptables -I INPUT -s 122.155.3.113 -j DROP
iptables -I INPUT -s 113.11.250.65 -j DROP
iptables -I INPUT -s 123.30.209.152 -j DROP
iptables -I INPUT -s 103.254.12.144 -j DROP
iptables -I INPUT -s 184.168.27.164 -j DROP
iptables -I INPUT -s 107.170.218.152 -j DROP
iptables -I INPUT -s 72.167.232.144 -j DROP
iptables -I INPUT -s 184.168.200.133 -j DROP
iptables -I INPUT -s 175.102.35.39 -j DROP
iptables -I INPUT -s 184.168.193.208 -j DROP

iptables -I INPUT -s 193.0.61.97 -j DROP
iptables -I INPUT -s 184.168.152.201 -j DROP
iptables -I INPUT -s 31.24.128.43 -j DROP
iptables -I INPUT -s 184.168.193.169 -j DROP
iptables -I INPUT -s 185.76.77.160 -j DROP
iptables -I INPUT -s 208.64.62.17 -j DROP
iptables -I INPUT -s 50.62.176.218 -j DROP
iptables -I INPUT -s 50.76.12.242 -j DROP
iptables -I INPUT -s 208.180.34.230  -j DROP
iptables -I INPUT -s 157.7.188.28 -j DROP
iptables -I INPUT -s 184.168.46.193  -j DROP
iptables -I INPUT -s 184.168.27.26 -j DROP
iptables -I INPUT -s 109.2.222.226 -j DROP
iptables -I INPUT -s 50.62.177.130 -j DROP
iptables -I INPUT -s 188.132.236.186 -j DROP
iptables -I INPUT -s 50.97.138.113 -j DROP
iptables -I INPUT -s 72.167.232.225  -j DROP
iptables -I INPUT -s 182.50.132.104  -j DROP
iptables -I INPUT -s 184.168.193.122 -j DROP
iptables -I INPUT -s 184.168.27.144  -j DROP
iptables -I INPUT -s 63.251.175.215  -j DROP
iptables -I INPUT -s 88.208.252.228  -j DROP
iptables -I INPUT -s 101.50.1.11 -j DROP
iptables -I INPUT -s 218.5.79.103 -j DROP
iptables -I INPUT -s 184.168.193.59  -j DROP
iptables -I INPUT -s 97.74.24.214 -j DROP
iptables -I INPUT -s 50.63.196.134 -j DROP
iptables -I INPUT -s 113.10.222.214  -j DROP
iptables -I INPUT -s 184.168.46.92 -j DROP
iptables -I INPUT -s 50.63.197.67 -j DROP
iptables -I INPUT -s 184.168.192.45  -j DROP
iptables -I INPUT -s 182.50.130.111  -j DROP
iptables -I INPUT -s 37.77.3.133 -j DROP
iptables -I INPUT -s 182.50.130.14 -j DROP
iptables -I INPUT -s 184.168.193.121 -j DROP
iptables -I INPUT -s 182.50.130.114  -j DROP
iptables -I INPUT -s 69.16.197.227 -j DROP
iptables -I INPUT -s 97.74.24.172 -j DROP
iptables -I INPUT -s 50.62.208.191 -j DROP
iptables -I INPUT -s 50.62.161.7 -j DROP
iptables -I INPUT -s 82.200.247.241  -j DROP
iptables -I INPUT -s 216.245.192.26  -j DROP
iptables -I INPUT -s 122.155.16.127  -j DROP
iptables -I INPUT -s 50.62.177.161 -j DROP
iptables -I INPUT -s 50.22.62.68 -j DROP
iptables -I INPUT -s 5.101.157.89 -j DROP
iptables -I INPUT -s 70.32.98.71 -j DROP
iptables -I INPUT -s 50.62.176.42 -j DROP
iptables -I INPUT -s 50.62.161.74 -j DROP
iptables -I INPUT -s 106.186.125.120 -j DROP
iptables -I INPUT -s 94.103.47.8 -j DROP
iptables -I INPUT -s 23.101.136.55 -j DROP
iptables -I INPUT -s 185.50.196.214  -j DROP
iptables -I INPUT -s 184.168.200.12  -j DROP
iptables -I INPUT -s 103.233.98.157  -j DROP
iptables -I INPUT -s 50.62.161.38 -j DROP
iptables -I INPUT -s 50.206.14.7 -j DROP
iptables -I INPUT -s 118.186.240.109 -j DROP
iptables -I INPUT -s 182.50.130.114 -j DROP
iptables -I INPUT -s 173.230.136.186 -j DROP
iptables -I INPUT -s 50.63.197.69 -j DROP
iptables -I INPUT -s 194.247.174.66 -j DROP


~ iptables-save > /etc/iptables.up.rules

~ iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  223.16.9.122         anywhere
DROP       all  --  327458.vps-10.com    anywhere
DROP       all  --  221.12.174.123       anywhere
DROP       all  --  118.180.7.60         anywhere
DROP       all  --  smtp.efaxonline.com  anywhere
DROP       all  --  van-router-01.boats.com  anywhere
DROP       all  --  seattle207.riseup.net  anywhere
DROP       all  --  14.63.196.181        anywhere
DROP       all  --  203.174.60.2         anywhere
DROP       all  --  bzq-82-80-248-188.static.dcenter.bezeqint.net  anywhere      
DROP       all  --  121.189.59.207       anywhere
DROP       all  --  hosted-by.leaseweb.com  anywhere
DROP       all  --  ip-155-209-241-80.static.contabo.net  anywhere
DROP       all  --  110.4.89.42          anywhere
DROP       all  --  180.153.163.191      anywhere
DROP       all  --  101.226.65.106       anywhere
DROP       all  --  113.30.106.95        anywhere
DROP       all  --  14.17.18.152         anywhere
DROP       all  --  61.191.31.27         anywhere
DROP       all  --  smtpmail8102.brixmail.com  anywhere
DROP       all  --  113.30.106.90        anywhere
DROP       all  --  14.63.196.181        anywhere
DROP       all  --  112.64.235.89        anywhere
DROP       all  --  101.226.51.226       anywhere
DROP       all  --  101.226.33.208       anywhere
DROP       all  --  109-186-134-160.bb.netvision.net.il  anywhere
DROP       all  --  124.129.18.178       anywhere
DROP       all  --  215.226.55.116.broad.km.yn.dynamic.163data.com.cn  anywhere  
DROP       all  --  121.199.27.236       anywhere
DROP       all  --  182.140.241.19       anywhere
DROP       all  --  222.184.121.15       anywhere
DROP       all  --  reverse-77-79-125-2.grid.com.tr  anywhere
DROP       all  --  95.211.121.136       anywhere
DROP       all  --  ec2-54-228-209-57.eu-west-1.compute.amazonaws.com  anywhere  
DROP       all  --  61.167.33.222        anywhere
DROP       all  --  wickedgoodcharcoal.com  anywhere
DROP       all  --  fixed-188-175-49.iusacell.net  anywhere
DROP       all  --  180.179.206.10       anywhere
DROP       all  --  61.187.94.66         anywhere
DROP       all  --  218.15.154.174       anywhere
DROP       all  --  124.160.217.200      anywhere
DROP       all  --  113.30.106.92        anywhere
DROP       all  --  113.30.74.125        anywhere
DROP       all  --  58.180.70.160        anywhere
DROP       all  --  235.4.191.183.adsl-pool.sx.cn  anywhere
DROP       all  --  124.115.0.199        anywhere
DROP       all  --  cust.static.62-202-18-26.swisscomdata.ch  anywhere           
DROP       all  --  60-199-223-196.static.tfn.net.tw  anywhere
DROP       all  --  148.208.222.7        anywhere
DROP       all  --  woman22.ru           anywhere

关闭Tomcat管理控制台

把tomcat-users.xml文件的内容都注释掉。

vi ~/tomcat7/conf/tomcat-users.xml

<tomcat-users>

<!–
<role rolename=”manager-gui”/>
<user username=”tomcat” password=”bsspirit” roles=”manager-gui”/>
<user username=”both” password=”tomcat” roles=”tomcat,role1″/>
<user username=”role1″ password=”tomcat” roles=”role1″/>
–>

</tomcat-users>

重启Tomcat服务器!完成Tomcat防御。

服务器的root账号,并没有被破解。为了安全还是换一个吧,攻击手段并不高明,只是我们疏于防范了。

再次给使用TOMCAT的用户提个醒,平时不要打开管理控制台,会被黑客当枪用的。

打赏作者

R利剑NoSQL系列文章 之 Redis

R利剑NoSQL系列文章,主要介绍通过R语言连接使用nosql数据库。涉及的NoSQL产品,包括Redis,MongoDBHBaseHiveCassandra, Neo4j。希望通过我的介绍让广大的R语言爱好者,有更多的开发选择,做出更多地激动人心的应用。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

由于文章篇幅有限,均跳过NoSQL的安装过程,请自行参考文档安装。

转载请注明:
http://blog.fens.me/nosql-r-redis/

r-nosql-redis

第二篇 R利剑Redis,分为4个章节。

  1. Redis环境准备
  2. rredis函数库
  3. rredis基本使用操作
  4. rredis使用案例

每一章节,都会分为”文字说明部分”和”代码部分”,保持文字说明与代码的连贯性。

第一章 Redis环境准备

文字说明部分:

首先环境准备,这里我选择了Linux Ubuntu操作系统12.04的64位服务器版本,大家可以根据自己的使用习惯选择顺手的Linux。
(more…)