mirror of https://github.com/jumpserver/jumpserver
Merge pull request #106 from jumpserver/issue_57_bug_fix
1. 修复tonrado数据库连接bug 2. 修改定期处理长时间连接 3. 添加nginx文档 ref #57pull/108/head
commit
06aef8fb1a
|
@ -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判断的那三行)。
|
|
@ -19,7 +19,7 @@ from tempfile import NamedTemporaryFile
|
|||
from jinja2 import FileSystemLoader, Template
|
||||
from jinja2.environment import Environment
|
||||
|
||||
from jumpserver.api import BASE_DIR
|
||||
from jumpserver.api import BASE_DIR, logger
|
||||
from jlog.models import Log
|
||||
|
||||
|
||||
|
@ -80,27 +80,27 @@ def renderTemplate(script_path, time_file_path, dimensions=(24, 80), templatenam
|
|||
|
||||
|
||||
def kill_invalid_connection():
|
||||
long_time_logs = []
|
||||
unfinished_logs = Log.objects.filter(is_finished=False)
|
||||
now = datetime.datetime.now()
|
||||
now_timestamp = int(time.mktime(now.timetuple()))
|
||||
for log in unfinished_logs:
|
||||
if (now - log.start_time).days > 1:
|
||||
long_time_logs.append(log)
|
||||
|
||||
for log in long_time_logs:
|
||||
for log in unfinished_logs:
|
||||
try:
|
||||
log_file_mtime = int(os.stat(log.log_path).st_mtime)
|
||||
log_file_mtime = int(os.stat('%s.log' % log.log_path).st_mtime)
|
||||
except OSError:
|
||||
log_file_mtime = 0
|
||||
|
||||
if (now_timestamp - log_file_mtime) > 3600:
|
||||
try:
|
||||
os.kill(int(log.pid), 9)
|
||||
except OSError:
|
||||
pass
|
||||
if log.login_type == 'ssh':
|
||||
try:
|
||||
os.kill(int(log.pid), 9)
|
||||
except OSError:
|
||||
pass
|
||||
elif (now - log.start_time).days < 1:
|
||||
continue
|
||||
|
||||
log.is_finished = True
|
||||
log.end_time = now
|
||||
log.save()
|
||||
logger.warn('kill log %s' % log.log_path)
|
||||
|
||||
|
|
|
@ -155,5 +155,5 @@ BOOTSTRAP_COLUMN_COUNT = 10
|
|||
|
||||
CRONJOBS = [
|
||||
('0 1 * * *', 'jasset.asset_api.asset_ansible_update_all'),
|
||||
('1 * * * *', 'jlog.log_api.kill_invalid_connection'),
|
||||
('*/10 * * * *', 'jlog.log_api.kill_invalid_connection'),
|
||||
]
|
||||
|
|
|
@ -8,8 +8,10 @@ import os
|
|||
import sys
|
||||
import os.path
|
||||
import threading
|
||||
import datetime
|
||||
import re
|
||||
import functools
|
||||
|
||||
from django.core.signals import request_started, request_finished
|
||||
|
||||
import tornado.ioloop
|
||||
import tornado.options
|
||||
|
@ -21,10 +23,10 @@ import tornado.httpclient
|
|||
from tornado.websocket import WebSocketClosedError
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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 _deco(func):
|
||||
def _deco2(request, *args, **kwargs):
|
||||
|
@ -58,6 +70,7 @@ def require_auth(role='user'):
|
|||
request.user = user
|
||||
if role == 'admin':
|
||||
if user.role in ['SU', 'GA']:
|
||||
request_finished.send_robust()
|
||||
return func(request, *args, **kwargs)
|
||||
logger.debug('Websocket: user [ %s ] is not admin.' % user.username)
|
||||
else:
|
||||
|
@ -69,6 +82,7 @@ def require_auth(role='user'):
|
|||
except AttributeError:
|
||||
pass
|
||||
logger.warning('Websocket: Request auth failed.')
|
||||
|
||||
return _deco2
|
||||
return _deco
|
||||
|
||||
|
@ -129,6 +143,7 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
|
|||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
@django_request_support
|
||||
@require_auth('admin')
|
||||
def open(self):
|
||||
# 获取监控的path
|
||||
|
@ -180,6 +195,7 @@ class WebTty(Tty):
|
|||
|
||||
|
||||
class WebTerminalKillHandler(tornado.web.RequestHandler):
|
||||
@django_request_support
|
||||
@require_auth('admin')
|
||||
def get(self):
|
||||
ws_id = self.get_argument('id')
|
||||
|
@ -209,6 +225,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
|
|||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
@django_request_support
|
||||
@require_auth('user')
|
||||
def open(self):
|
||||
logger.debug('Websocket: Open exec request')
|
||||
|
@ -289,6 +306,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
|
|||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
@django_request_support
|
||||
@require_auth('user')
|
||||
def open(self):
|
||||
logger.debug('Websocket: Open request')
|
||||
|
|
Loading…
Reference in New Issue