Skip to content

Commit

Permalink
merge with dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuler committed Dec 19, 2015
1 parent c103738 commit 7b79290
Show file tree
Hide file tree
Showing 99 changed files with 17,772 additions and 0 deletions.
127 changes: 127 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
快速安装
------
####环境
CentOS 6.x x86_64
iptables stop
selinux disable


####开始
**1. 安装git**

> yum -y install git
**2. 下载jumpserver**

> git clone https://github.com/ibuler/jumpserver.git
**3. 执行快速安装脚本**

> cd jumpserver/install && python install.py

*根据提示输入相关信息,完成安装,完成安装后,请访问web,继续查看后续文档*



名词解释
------


* **用户** 用户是授权和登陆的主体,将来为每个员工建立一个账户,用来登录跳板机,
将资产授权给该用户,查看用户登陆记录命令历史等

* **用户组** 多个用户可以组合成用户组,为了方便进行授权,可以将一个部门或几个用户
组建成用户组,在授权中使用组授权,该组中的用户拥有所有授权的主机权限

* **资产** 资产通常是我们的服务器、网络设备等,将资产授权给用户,用户则会有权限登
录资产,执行命令等

* **管理账户** 添加资产时需要添加一个管理账户,该账户是该资产上已有的有管理权限的用户,
如root,或者有 NOPASSWD: ALL sudo权限的用户,该管理账户用来向资产推送系统用户,
为系统用户添加sudo,获取资产的一些硬件信息

* **资产组** 同用户组,是资产组成的集合,为了方便授权

* **机房** 又称IDC,不解释

* **Sudo** 这里的sudo其实是Linux中的sudo命令别名,一个sudo别名包含多个命令,
系统用户关联sudo就代表该系统用户有权限sudo执行这些命令

* **系统用户** 系统用户是服务器上建立的一些真实存在的可以ssh登陆的用户,如 dev,
sa, dba等,系统用户可使用jumpserver推送到服务器上,也可以利用自己公司
的工具进行推送,授权时将用户、资产、系统用户关联起来则表明用户有权限登陆该资产的
这个系统用户 如:用户 **小明****dev** 系统用户登陆 **172.16.1.1**资产

* **授权规则** 授权规则是将 **资产** **系统用户****用户** 关联起来,用来完成授权。
这样用户就可以以某个系统用户账号登陆资产

* **日志审计**
* **在线** 查看当前在线的用户(非web在线),可以监控用户的命令执行,强制结束用户
登录。
* **登录历史** 查看以往用户的登录历史,可以查看用户登陆操作的命令,可以回放用户
执行命令的录像
* **命令记录** 查看用户批量执行命令的历史,包含执行命令的主机,执行的命令,执行的结果

* **上传下载** 查看用户上传下载文件的记录


快速开始
------

##### 1. 添加用户
**用户管理 - 查看用户 - 添加用户** 填写基本信息,完成用户添加

用户添加完成后,根据提示记住用户账号密码,换个浏览器登录下载key,
ssh登录jumpserver测试

##### 2. 添加资产
**资产管理 - 查看资产 - 添加资产** 填写基本信息,完成资产添加

##### 3. 添加sudo
**授权管理 - Sudo - 添加别名** 输入别名名称和命令,完成sudo添加

##### 4. 添加系统用户
**授权管理 - 系统用户 - 添加** 输入基本信息,完成系统用户添加

##### 5. 推送系统用户
**授权管理 - 推送** - 选择需要推送的资产或资产组完成推送

推送只支持服务器,使用密钥是指用户从跳板机跳转时使用key,反之使用密码,
授权时会检查推送记录,如果没有推送过则无法完成系统用户在该资产上的授权。
如果资产时网络设备,请不要选择密码和秘钥,模拟一下推送,目的是为了生成
推送记录。

##### 6. 添加授权规则
**授权管理 - 授权规则 - 添加规则** 选择刚才添加的用户,资产,系统用户完成授权

##### 7. 测试登录
**用户下载key** 登录跳板机,会自动运行connect.py,根据提示登录服务器

**用户登陆web** 查看授权的主机,点击后面的链接,测试是否可以登录服务器

##### 8. 监控和结束会话
**日志审计 - 在线** 查看当前登录的用户登录情况,点击监控查看用户执行的命令,
点击阻断,结束用户的会话

##### 9. 查看历史记录
**日志审计 - 登录历史** 查看登录历史,点击统计查看命令历史,点击回放查看录像

##### 10. 执行命令
同7 测试命令的执行,命令记录查看 批量执行命令的日志

##### 11. 上传下载
同7 测试文件的上传下载,日志审计 - 上传下载 查看上传下载记录













36 changes: 36 additions & 0 deletions install/developer_doc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# coding: utf8

Jumpserver开发者文档

开发规范:
1. 遵守PE8规范 1) 命名规范 2) 导入模块规范 3) 空行规范 4) 长度规范
2. 缩进统一4个空格
3. 变量命名明了易懂多个单词下划线隔开
4. 注释到位


框架说明:
1. 项目名称 Jumpserver
2. APP:
juser 用户管理
jasset 资产管理(设备管理)
jpermission 授权管理
jlog 日志管理
3. connect.py 用户登录入口程序
4. logs 日志保存目录
5. jumpserver.conf 配置文件
6. docs 文档目录
7. static 静态文件目录
8. templates 模板目录


connect.py逻辑说明:
用户登录系统,运行该脚本,p调用get_user_host函数查看有权限的服务器ip
输入部分IP,verify_connect匹配该部分ip,如果是匹配到多个,就显示ip
匹配到0了就显示没有权限或者主机,
匹配到1个则继续
查询该服务器是否支持ldap 如果是,获得ldap用户密码登陆
如果否,查询授权表,查看该服务器授权的系统用户,并返回对应账号密码,登陆
connect函数是登陆函数,采用paramiko 使用channel登陆,posix_shell 来完成交互,并记录日志
signal模块来完成窗口改变导致的tty大小随之改变
PyCrypt是对称加密类
9 changes: 9 additions & 0 deletions install/initial_data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- model: juser.user
pk: 5000
fields:
username: admin
name: admin
password: pbkdf2_sha256$20000$jBIDGPB2j5JT$orxqGgzzjzykColYm1BswPjgHOiERjZkcgkuVIkD2Hc=
email: [email protected]
role: SU
is_active: 1
215 changes: 215 additions & 0 deletions install/install.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#!/usr/bin/python
# coding: utf-8

import subprocess
import time
import os
import sys
import smtplib
import MySQLdb
from smtplib import SMTP, SMTPAuthenticationError, SMTPConnectError
import ConfigParser
import socket
import fcntl
import struct

jms_dir = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
sys.path.append(jms_dir)


def bash(cmd):
"""
run a bash shell command
执行bash命令
"""
return subprocess.call(cmd, shell=True)


def color_print(msg, color='red', exits=False):
"""
Print colorful string.
颜色打印字符或者退出
"""
color_msg = {'blue': '\033[1;36m%s\033[0m',
'green': '\033[1;32m%s\033[0m',
'yellow': '\033[1;33m%s\033[0m',
'red': '\033[1;31m%s\033[0m',
'title': '\033[30;42m%s\033[0m',
'info': '\033[32m%s\033[0m'}
msg = color_msg.get(color, 'red') % msg
print msg
if exits:
time.sleep(2)
sys.exit()
return msg


def get_ip_addr(ifname='eth0'):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915,
struct.pack('256s', ifname[:15])
)[20:24])
except:
ips = os.popen("LANG=C ifconfig | grep \"inet addr\" | grep -v \"127.0.0.1\" | awk -F \":\" '{print $2}' | awk '{print $1}'").readlines()
if len(ips) > 0:
return ips[0]
return ''


class PreSetup(object):
def __init__(self):
self.db_host = '127.0.0.1'
self.db_port = 3306
self.db_user = 'jumpserver'
self.db_pass = 'mysql234'
self.db = 'jumpserver'
self.mail_host = 'smtp.qq.com'
self.mail_port = 25
self.mail_addr = '[email protected]'
self.mail_pass = ''
self.ip = ''

def write_conf(self, conf_file=os.path.join(jms_dir, 'jumpserver.conf')):
color_print('开始写入配置文件', 'green')
conf = ConfigParser.ConfigParser()
conf.read(conf_file)
conf.set('base', 'url', 'http://%s' % self.ip)
conf.set('db', 'host', self.db_host)
conf.set('db', 'port', self.db_port)
conf.set('db', 'user', self.db_user)
conf.set('db', 'password', self.db_pass)
conf.set('db', 'database', self.db)
conf.set('websocket', 'web_socket_host', '%s:3000' % self.ip)
conf.set('mail', 'email_host', self.mail_host)
conf.set('mail', 'email_port', self.mail_port)
conf.set('mail', 'email_host_user', self.mail_addr)
conf.set('mail', 'email_host_password', self.mail_pass)

with open(conf_file, 'w') as f:
conf.write(f)

def _setup_mysql(self):
color_print('开始安装设置mysql (请手动设置mysql安全)', 'green')
bash('yum -y install mysql-server')
bash('service mysqld start')
bash('mysql -e "create database %s default charset=utf8"' % self.db)
bash('mysql -e "grant all on %s.* to \'%s\'@\'%s\' identified by \'%s\'"' % (self.db,
self.db_user,
self.db_host,
self.db_pass))

@staticmethod
def _set_env():
color_print('开始关闭防火墙和selinux', 'green')
bash('service iptables stop && chkconfig iptables off && setenforce 0')

def _test_db_conn(self):
try:
MySQLdb.connect(host=self.db_host, port=self.db_port,
user=self.db_user, passwd=self.db_pass, db=self.db)
color_print('连接数据库成功', 'green')
return True
except MySQLdb.OperationalError, e:
color_print('数据库连接失败 %s' % e, 'red')
return False

def _test_mail(self):
try:
smtp = SMTP(self.mail_host, port=self.mail_port, timeout=2)
smtp.login(self.mail_addr, self.mail_pass)
smtp.sendmail(self.mail_addr, (self.mail_addr, ),
'''From:%s\r\nTo:%s\r\nSubject:Jumpserver Mail Test!\r\n\r\n Mail test passed!\r\n''' %
(self.mail_addr, self.mail_addr))
smtp.quit()
return True

except (SMTPAuthenticationError, socket.timeout, socket.gaierror), e:
color_print(e, 'red')
return False

@staticmethod
def _rpm_repo():
color_print('开始安装epel源', 'green')
bash('yum -y install epel-release')

@staticmethod
def _depend_rpm():
color_print('开始安装依赖rpm包', 'green')
bash('yum -y install git python-pip mysql-devel gcc automake autoconf python-devel vim sshpass')

@staticmethod
def _require_pip():
color_print('开始安装依赖pip包', 'green')
bash('pip install -r requirements.txt')

def _input_ip(self):
ip = raw_input('\n请输入您服务器的IP地址,用户浏览器可以访问 [%s]: ' % get_ip_addr())
self.ip = ip if ip else get_ip_addr()

def _input_mysql(self):
while True:
db_host = raw_input('请输入数据库服务器IP [127.0.0.1]: ')
db_port = raw_input('请输入数据库服务器端口 [3306]: ')
db_user = raw_input('请输入数据库服务器用户 [root]: ')
db_pass = raw_input('请输入数据库服务器密码: ')
db = raw_input('请输入使用的数据库 [jumpserver]: ')

if db_host: self.db_host = db_host
if db_port: self.db_port = db_port
if db_user: self.db_user = db_user
if db_pass: self.db_pass = db_pass
if db: self.db = db

mysql = raw_input('是否使用已经存在的数据库服务器? (y/n) [n]: ')

if mysql != 'y':
self._setup_mysql()

if self._test_db_conn():
break

print

def _input_smtp(self):
while True:
self.mail_host = raw_input('请输入SMTP地址: ').strip()
self.mail_port = int(raw_input('请输入SMTP端口: ').strip())
self.mail_addr = raw_input('请输入账户: ').strip()
self.mail_pass = raw_input('请输入密码: ').strip()

if self._test_mail():
color_print('\n\t请登陆邮箱查收邮件, 然后确认是否继续安装\n', 'green')
smtp = raw_input('是否继续? (y/n) [y]: ')
if smtp == 'n':
continue
else:
break
print

@staticmethod
def _pull():
color_print('开始更新jumpserver', 'green')
bash('git pull')
os.chdir(jms_dir)
os.chmod('logs', 0777)
os.chmod('keys', 0777)

def start(self):
self._rpm_repo()
self._depend_rpm()
self._require_pip()
self._set_env()
self._pull()
self._input_ip()
self._input_mysql()
self._input_smtp()
self.write_conf()
os.system('python %s' % os.path.join(jms_dir, 'install/next.py'))


if __name__ == '__main__':
pre_setup = PreSetup()
pre_setup.start()
Loading

0 comments on commit 7b79290

Please sign in to comment.