Merge remote-tracking branch 'origin/issue_57_bug_fix' into dev

pull/106/head
ibuler 2016-02-29 18:15:31 +08:00
commit c418f142ba
2 changed files with 96 additions and 3 deletions

View File

@ -0,0 +1,75 @@
# 使用Nginx搭建SSL配置
跳板机是所有服务器的入口,所以,它的安全至关重要。因此,建议把`Jumpserver`搭建在内网环境中并且加上SSL证书保证数据传输的安全。
## nginx的安装
不同的操作系统及版本,安装方法都不太一样。我们以`Debian`为例。
```
apt-get update
apt-get install -y nginx
```
更多安装示例请参考 [Nginx官方安装指南](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/)
## Nginx中的SSL的配置
* 编辑 `/etc/nginx/sites-enabled/default` 或者指定的`Jumpserver`的配置文件
* 示例如下
```
server {
listen 443;
listen 80;
server_name YOUR_DOMAIN;
ssl_certificate YOUR_DOMAIN_CRT;
ssl_certificate_key YOUR_DOMAIN_KEY;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl on ;
if ($ssl_protocol = "") {
rewrite ^ https://$host$request_uri? permanent;
}
location / {
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://JUMPSERVER_HOST:WEB_PORT;
}
location /_ws/ {
keepalive_timeout 600s;
send_timeout 600s;
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
rewrite ^/_ws(/.*)$ $1 break;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://JUMPSERVER_HOST:WS_PORT;
}
}
```
* 请替换如下表格的关键字
关键字 | 示例 | 说明
------------- | ------------- |-------
`YOUR_DOMAIN` | example.com | `Jumpserver`的域名
`YOUR_DOMAIN_CRT` | /etc/nginx/certs/example.crt | SSL证书的CRT文件
`YOUR_DOMAIN_KEY` | /etc/nginx/certs/example.key | SSL证书的KEY文件
`JUMPSERVER_HOST` | 127.0.0.1 | `Jumpserver`服务器IP
`WEB_PORT ` | 80 | `Jumpserver`网页监听端口
`WS_PORT ` | 3000 | websocket端口`Jumpserver` 默认为3000
* 此配置会强制使用`https`, 建议加上(即if判断的那三行)。

View File

@ -8,8 +8,10 @@ import os
import sys import sys
import os.path import os.path
import threading import threading
import datetime
import re import re
import functools
from django.core.signals import request_started, request_finished
import tornado.ioloop import tornado.ioloop
import tornado.options import tornado.options
@ -21,10 +23,10 @@ import tornado.httpclient
from tornado.websocket import WebSocketClosedError from tornado.websocket import WebSocketClosedError
from tornado.options import define, options from tornado.options import define, options
from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE, IN_MODIFY, AsyncNotifier from pyinotify import WatchManager, ProcessEvent, IN_DELETE, IN_CREATE, IN_MODIFY, AsyncNotifier
import select import select
from connect import Tty, User, Asset, PermRole, logger, get_object, PermRole, gen_resource from connect import Tty, User, Asset, PermRole, logger, get_object, gen_resource
from connect import TtyLog, Log, Session, user_have_perm, get_group_user_perm, MyRunner, ExecLog from connect import TtyLog, Log, Session, user_have_perm, get_group_user_perm, MyRunner, ExecLog
try: try:
@ -38,6 +40,16 @@ define("port", default=PORT, help="run on the given port", type=int)
define("host", default=IP, help="run port on given host", type=str) define("host", default=IP, help="run port on given host", type=str)
def django_request_support(func):
@functools.wraps(func)
def _deco(*args, **kwargs):
request_started.send_robust(func)
response = func(*args, **kwargs)
request_finished.send_robust(func)
return response
return _deco
def require_auth(role='user'): def require_auth(role='user'):
def _deco(func): def _deco(func):
def _deco2(request, *args, **kwargs): def _deco2(request, *args, **kwargs):
@ -58,6 +70,7 @@ def require_auth(role='user'):
request.user = user request.user = user
if role == 'admin': if role == 'admin':
if user.role in ['SU', 'GA']: if user.role in ['SU', 'GA']:
request_finished.send_robust()
return func(request, *args, **kwargs) return func(request, *args, **kwargs)
logger.debug('Websocket: user [ %s ] is not admin.' % user.username) logger.debug('Websocket: user [ %s ] is not admin.' % user.username)
else: else:
@ -69,6 +82,7 @@ def require_auth(role='user'):
except AttributeError: except AttributeError:
pass pass
logger.warning('Websocket: Request auth failed.') logger.warning('Websocket: Request auth failed.')
return _deco2 return _deco2
return _deco return _deco
@ -129,6 +143,7 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin): def check_origin(self, origin):
return True return True
@django_request_support
@require_auth('admin') @require_auth('admin')
def open(self): def open(self):
# 获取监控的path # 获取监控的path
@ -180,6 +195,7 @@ class WebTty(Tty):
class WebTerminalKillHandler(tornado.web.RequestHandler): class WebTerminalKillHandler(tornado.web.RequestHandler):
@django_request_support
@require_auth('admin') @require_auth('admin')
def get(self): def get(self):
ws_id = self.get_argument('id') ws_id = self.get_argument('id')
@ -209,6 +225,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin): def check_origin(self, origin):
return True return True
@django_request_support
@require_auth('user') @require_auth('user')
def open(self): def open(self):
logger.debug('Websocket: Open exec request') logger.debug('Websocket: Open exec request')
@ -289,6 +306,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin): def check_origin(self, origin):
return True return True
@django_request_support
@require_auth('user') @require_auth('user')
def open(self): def open(self):
logger.debug('Websocket: Open request') logger.debug('Websocket: Open request')