forked from jumpserver/jumpserver
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
99 changed files
with
17,772 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 测试文件的上传下载,日志审计 - 上传下载 查看上传下载记录 | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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是对称加密类 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
|
||
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 | ||
|
||
@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() |
Oops, something went wrong.