码迷,mamicode.com
首页 > 其他好文 > 详细

二次开发Jumpserver实现主备,实现user&key,系统用户&key的同步

时间:2016-08-12 19:49:22      阅读:536      评论:0      收藏:0      [点我收藏+]

标签:

  这是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 ~]# vim /etc/my.cnf 
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-ignore-db=mysql  #  同步除mysql库之外所有库
slave_skip_errors = 1062
 
主服务器上创建用于同步的账号: 
GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.* TO ‘username‘@‘192.168.0.12‘ IDENTIFIED BY ‘password‘; 
GRANT REPLICATION SLAVE ON *.* TO ‘username‘@‘192.168.0.13‘ IDENTIFIED BY ‘password‘; 
重启服务

 [root@localhost ~]# systemctl restart mariadb.service

查看是否启动日志记录: 
MariaDB [mysql]> show master status; 
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    2
Current database: mysql
+------------------+----------+----------------+------------------+
| File             | Position | Binlog_Do_DB   | Binlog_Ignore_DB |
+------------------+----------+----------------+------------------+
| mysql-bin.000002 |      245 | jumpserver |                  |
+------------------+----------+----------------+------------------+
1 row in set (0.01 sec)
 
从数据写入主数据库:(当从数据库设置后再运行,注意:mysql-bin.000002是个变量,请根据show master status;显示出来的实际值填写) 
CHANGE MASTER TO MASTER_HOST=‘192.168.0.12‘,MASTER_PORT=3306,MASTER_USER=‘username‘,MASTER_PASSWORD=‘password‘,MASTER_LOG_FILE=‘mysql-bin.000002‘,MASTER_LOG_POS=245; 
 
2、从数据库配置
[root@localhost ~]# vim /etc/my.cnf 
[mysqld]
server-id=2  # 不能与master一样
log-bin=mysql-bin
binlog-ignore-db=mysql  #  同步除mysql库之外所有库
slave_skip_errors = 1062
 
主服务器上创建用于同步的账号: 
GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.* TO ‘username‘@‘192.168.0.13‘ IDENTIFIED BY ‘password‘; 
GRANT REPLICATION SLAVE ON *.* TO ‘username‘@‘192.168.0.12‘ IDENTIFIED BY ‘password‘; 
重启服务

 [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;   #启动同步 

检查状态 
 
MariaDB [mysql]>  show slave status\G; 
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.12
                  Master_User: username
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 245
               Relay_Log_File: mariadb-relay-bin.000003
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

二次开发Jumpserver实现主备,实现user&key,系统用户&key的同步

标签:

原文地址:http://www.cnblogs.com/mageguoshi/p/5765555.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!