标签:
这是jumpserver二次开发系列第三篇 ,前两篇是关于用户认证模块的,调用现有的认证接口认证并获取用户信息。
此篇是关于如何实现双机热备,要实现互备,就要确保用户及系统用户信息不只同步到另外一台数据库,还需要把用户及系统用户的秘钥信息同步到另外一台服务器,并创建用户,当然删除也需要同步。
ps:在原代码基础上添加的代码,在每个代码框内用绿色背景斜体标记,否则为整体添加。
一、修改setting,增加server_type配置,从jumpserver.conf配置文件读取主备服务器信息。
# master & slave host type HOST_TYPE = config.get(‘server_type‘, ‘host_type‘) MASTER_HOST = config.get(‘server_type‘, ‘master_host‘) SLAVE_HOST = config.get(‘server_type‘, ‘slave_host‘)
二、修改 install.py,以便安装时输入主备服务器信息,并写入配置文件jumpserver.conf
class PreSetup(object): def __init__(self): self.db_host = ‘127.0.0.1‘ self.db_port = 3306 self.db_user = ‘jumpserver‘ self.db_pass = ‘5Lov@wife‘ self.db = ‘jumpserver‘ self.mail_host = ‘smtp.qq.com‘ self.mail_port = 25 self.mail_addr = ‘hello@jumpserver.org‘ self.mail_pass = ‘‘ self.host_type = ‘master‘ self.master_host = ‘192.168.3.85‘ self.slave_host = ‘192.168.3.86‘
def _input_server_type(self): while True: self.host_type = raw_input(‘请输入服务器类型master或者slave:‘).strip() self.master_host = raw_input(‘请输入主服务器IP:‘).strip() self.slave_host = raw_input(‘请输入从服务器IP:‘).strip() print break
def start(self): color_print(‘请务必先查看手册‘) time.sleep(3) self.check_platform() self._rpm_repo() self._depend_rpm() self._require_pip() self._set_env() self._input_ip() self._input_mysql() self._input_smtp() self._input_server_type() self.write_conf() os.system(‘python %s‘ % os.path.join(jms_dir, ‘install/next.py‘))
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(‘base‘, ‘key‘, self.key) 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(‘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) conf.set(‘server_type‘, ‘host_type‘, self.host_type) conf.set(‘server_type‘, ‘master_host‘, self.master_host) conf.set(‘server_type‘, ‘slave_host‘, self.slave_host) with open(conf_file, ‘w‘) as f: conf.write(f)
三、修改juser下面的user_api.py 实现远程在另外一台服务器上创建用户和同步秘钥
定义ssh远程登录、执行函数
from jumpserver.settings import HOST_TYPE, MASTER_HOST, SLAVE_HOST import paramiko def ssh_login(cmd): """ 定义ssh远程登录、执行函数 """ ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) if ‘master‘ == HOST_TYPE.lower(): ssh.connect(SLAVE_HOST, 22, ‘root‘, key_filename=‘/root/.ssh/id_rsa‘) else: ssh.connect(MASTER_HOST, 22, ‘root‘, key_filename=‘/root/.ssh/id_rsa‘) stdin, stdout, stderr = ssh.exec_command(cmd) ssh.close()
修改函数gen_ssh_key ,同步key前先判定key目录是否存在,如不存在先创建
def gen_ssh_key(username, password=‘‘, key_dir=os.path.join(KEY_DIR, ‘user‘),authorized_keys=True, home="/home", length=2048): """ generate a user ssh key in a property dir 生成一个用户ssh密钥对 """ logger.debug(‘生成ssh key, 并设置authorized_keys‘) private_key_file = os.path.join(key_dir, username+‘.pem‘) mkdir(key_dir, mode=777) if os.path.isfile(private_key_file): os.unlink(private_key_file) ret = bash(‘echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"‘ % (private_key_file, length, password)) if authorized_keys: auth_key_dir = os.path.join(home, username, ‘.ssh‘) mkdir(auth_key_dir, username=username, mode=700) authorized_key_file = os.path.join(auth_key_dir, ‘authorized_keys‘) with open(private_key_file+‘.pub‘) as pub_f: with open(authorized_key_file, ‘w‘) as auth_f: auth_f.write(pub_f.read()) os.chmod(authorized_key_file, 0600)
if ‘master‘ == HOST_TYPE.lower(): cmd = "if ssh %s test -d %s ;then echo %s exists; else ssh %s mkdir -p %s;fi" % (SLAVE_HOST, key_dir, key_dir, SLAVE_HOST, key_dir) res = subprocess.call(cmd, shell=True) logger.info(res) bash(‘scp -P22 %s root@%s:%s‘ % (private_key_file, SLAVE_HOST, key_dir)) bash(‘scp -P22 %s root@%s:%s‘ % (private_key_file+‘.pub‘, SLAVE_HOST, key_dir)) bash(‘scp -P22 %s root@%s:/home/%s/.ssh/‘ % (authorized_key_file, SLAVE_HOST, username)) else: cmd = "if ssh %s test -d %s ;then echo %s exists; else ssh %s mkdir -p %s;fi" % (MASTER_HOST, key_dir, key_dir, MASTER_HOST, key_dir) res = subprocess.call(cmd, shell=True) logger.info(cmd) bash(‘scp -P22 %s root@%s:%s‘ % (private_key_file, MASTER_HOST, key_dir)) bash(‘scp -P22 %s root@%s:%s‘ % (private_key_file+‘.pub‘, MASTER_HOST, key_dir)) bash(‘scp -P22 %s root@%s:/home/%s/.ssh/‘ % (authorized_key_file, MASTER_HOST, username)) chown(authorized_key_file, username) ssh_login("chown -R %s:%s /home/%s/" % (username, username, username)) ssh_login("chmod 700 /home/%s/.ssh" % username)
def server_add_user(username, ssh_key_pwd=‘‘):
"""
add a system user in jumpserver
在jumpserver服务器上添加一个用户
"""
bash("adduser -s ‘%s‘ ‘%s‘" % (os.path.join(BASE_DIR, ‘init.sh‘), username))
ssh_login("adduser -s ‘%s‘ ‘%s‘" % (os.path.join(BASE_DIR, ‘init.sh‘), username))
ssh_login("mkdir -p /home/%s/.ssh" % username)
gen_ssh_key(username, ssh_key_pwd)
删除用户也需要在另外一台服务上同步删除
def server_del_user(username): """ delete a user from jumpserver linux system 删除系统上的某用户 """ bash(‘userdel -r -f %s‘ % username) ssh_login(‘userdel -rf %s‘ % username) logger.debug(‘rm -f %s/%s_*.pem‘ % (os.path.join(KEY_DIR, ‘user‘), username)) bash(‘rm -f %s/%s.pem*‘ % (os.path.join(KEY_DIR, ‘user‘), username)) ssh_login(‘rm -f %s/%s.pem*‘ % (os.path.join(KEY_DIR, ‘user‘), username))
四、修改 juser下面的views.py 用户下载秘钥文件后需要在另外一台服务器也同步删除
def down_key(request): if is_role_request(request, ‘super‘): uuid_r = request.GET.get(‘uuid‘, ‘‘) else: uuid_r = request.user.uuid if uuid_r: user = get_object(User, uuid=uuid_r) if user: username = user.username private_key_file = os.path.join(KEY_DIR, ‘user‘, username+‘.pem‘) print private_key_file if os.path.isfile(private_key_file): f = open(private_key_file) data = f.read() f.close() response = HttpResponse(data, content_type=‘application/octet-stream‘) response[‘Content-Disposition‘] = ‘attachment; filename=%s‘ % os.path.basename(private_key_file) if request.user.role == ‘CU‘: os.unlink(private_key_file) ssh_login(‘rm -rf %s‘ % private_key_file)
return response return HttpResponse(‘No Key File. Contact Admin.‘)
五、修改jperm 下面的 utils.py 主要是同步系统用户(role_user)的信息和秘钥
from jumpserver.settings import KEY_DIR from jumpserver.api import logger, bash from juser.user_api import ssh_login from jumpserver.settings import HOST_TYPE, MASTER_HOST, SLAVE_HOST
def gen_keys(key="", key_path_dir=""): """ 在KEY_DIR下创建一个 uuid命名的目录,并且在该目录下 生产一对秘钥 :return: 返回目录名(uuid) """ key_basename = "key-" + uuid4().hex if not key_path_dir: key_path_dir = os.path.join(KEY_DIR, ‘role_key‘, key_basename) private_key = os.path.join(key_path_dir, ‘id_rsa‘) public_key = os.path.join(key_path_dir, ‘id_rsa.pub‘) mkdir(key_path_dir, mode=755) ssh_login("mkdir -p ‘%s‘" % key_path_dir) if not key: key = RSAKey.generate(2048) key.write_private_key_file(private_key) else: key_file = os.path.join(key_path_dir, ‘id_rsa‘) with open(key_file, ‘w‘) as f: f.write(key) f.close() with open(key_file) as f: try: key = RSAKey.from_private_key(f) except SSHException, e: shutil.rmtree(key_path_dir, ignore_errors=True) raise SSHException(e) os.chmod(private_key, 0644) with open(public_key, ‘w‘) as content_file: for data in [key.get_name(), " ",key.get_base64(), " %s@%s" % ("jumpserver", os.uname()[1])]: content_file.write(data) if ‘master‘ == HOST_TYPE.lower(): bash(‘scp -P22 %s/* root@%s:%s‘ % (key_path_dir, SLAVE_HOST, key_path_dir)) else: bash(‘scp -P22 %s/* root@%s:%s‘ % (key_path_dir, MASTER_HOST, key_path_dir)) return key_path_dir
六、修改jperm下面的view.py
函数 perm_role_delete
# TODO: 判断返回结果,处理异常 # 删除存储的秘钥,以及目录 try: key_files = os.listdir(role_key) for key_file in key_files: os.remove(os.path.join(role_key, key_file)) os.rmdir(role_key) ssh_login(‘rm -rf %s‘ % role_key) except OSError, e: logger.warning(u"Delete Role: delete key error, %s" % e) raise ServerError(u"删除系统用户key失败: %s" % e) logger.info(u"delete role %s - delete role key directory: %s" % (role.name, role_key)) # 数据库里删除记录 role.delete() return HttpResponse(u"删除系统用户: %s" % role.name)
七、mysql数据库主主配置(Centos7)
1、master 配置
master:192.168.0.13
slave: 192.168.0.12
修改配置
[root@localhost ~]# systemctl restart mariadb.service
[root@localhost ~]# systemctl restart mariadb.service
主数据写入从数据库:
CHANGE MASTER TO MASTER_HOST=‘192.168.0.13‘,MASTER_PORT=3306,MASTER_USER=‘username‘,MASTER_PASSWORD=‘password‘,MASTER_LOG_FILE=‘mysql-bin.000002‘,MASTER_LOG_POS=245;
mysql主从配置后都要运行以下3条指令
stop slave; #停止同步
reset slave; #复位同步
start slave; #启动同步
二次开发Jumpserver实现主备,实现user&key,系统用户&key的同步
标签:
原文地址:http://www.cnblogs.com/mageguoshi/p/5765555.html