码迷,mamicode.com
首页 > 数据库 > 详细

使用数据库统一管理ssh登陆用户密钥信息

时间:2015-09-23 01:30:37      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:ssh key authorizedkeyscommand mysql linux

使用数据库统一管理ssh登陆用户密钥信息

    需求是由一个开发部门提出的,他们需要在他们的测试服务器上开放root权限给所有的开发人员,同时要给每个开发人员配置无密码登录,由于使用ssh默认的认证文件存储公钥不方便人员信息的管理(例如一个人离职后不方便在大量的key中找到他的key,且需要在大量的服务器上全部删除)。

    基于上述需求,我们决定将所有人员的key和其对应的fingerprint保存在数据库中,而且每个fingerprint都对应一个真实用户名,在用户登录的时候,虽然都是使用root用户登录,但是,其登录的时候不会再到autherized_keys文件中查找key,而是根据用户传递的fingerprint去数据库中查找对应的公钥。

    为了实现上述的需求,我们需要用户在使用ssh登录的时候首先去执行一个取公钥的脚本,然后再根据脚本取回的key来验证用户。这里需要用到两个ssh的配置参数AuthorizedKeysCommand和AuthorizedKeysCommandUser,第一个参数用来指定登录时执行的脚本文件,第二个参数用来指定这个脚本的用户,这里要注意,这个脚本权限必须是700且属组属主必须是root。这两个配置参数在低版本的openssh中无法使用,需要首先升级openssh的版本,而且在升级时需要我们修改一部分openssh的源码,本文中升级到了ssh 6.6p1这个版本。

    一、升级openssh

    准备升级openssh的源码包,在官网上找到6.6版本的源码包并下载:

[root@localhost ~]# wget http://ftp.jaist.ac.jp/pub/OpenBSD/OpenSSH/portable/openssh-6.6p1.tar.gz
[root@localhost ~]# tar -zxf openssh-6.6p1.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/openssh-6.6p1

    解包完成后,我们要更改一下其源码,更改解压后目录下的auth2-pubkey.c文件

//512行左右
 struct passwd *pw;
        struct stat st;
        int status, devnull, p[2], i;
        pid_t pid;
        //char *username, errmsg[512];    注释掉此行代码
        char *username, *fp, errmsg[512];    添加此行代码

        if (options.authorized_keys_command == NULL ||
            options.authorized_keys_command[0] != ‘/‘)
                return 0;
//552行左右

        if (pipe(p) != 0) {
                error("%s: pipe: %s", __func__, strerror(errno));
                goto out;
        }

//      debug3("Running AuthorizedKeysCommand: \"%s %s\" as \"%s\"",    注释掉这行
//          options.authorized_keys_command, user_pw->pw_name, pw->pw_name);  注释掉这行
        fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);    添加这行
        debug3("Running AuthorizedKeysCommand: \"%s %s %s\" as \"%s\"",
            options.authorized_keys_command, user_pw->pw_name, fp, pw->pw_name);
        /*
         * Don‘t want to call this in the child, where it can fatal() and
         * run cleanup_exit() code.
         */
        restore_uid();

        switch ((pid = fork())) {
        case -1: /* error */
//602行左右
/* stdin is pointed to /dev/null at this point */
           if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
                    error("%s: dup2: %s", __func__, strerror(errno));
                    _exit(1);
            }

            execl(options.authorized_keys_command,
            //    options.authorized_keys_command, user_pw->pw_name, NULL); 注释掉此行  
                  options.authorized_keys_command, user_pw->pw_name, fp, NULL); 添加此行

             error("AuthorizedKeysCommand %s exec failed: %s",
                 options.authorized_keys_command, strerror(errno));
             _exit(127);
        default: /* parent */
                break;
        }

        free(fp);    添加此行
        temporarily_use_uid(pw);

    改完上述源码后,我们将更改后的源码打成rpm包来升级:

[root@localhost ~]# cd /usr/src/openssh-6.6p1/contrib/redhat    #本文系统为CentOS 6.5
[root@localhost ~]# vim openssh.spec    #更改spec文档,关闭一些用不到的参数
# Do we want to disable building of x11-askpass? (1=yes 0=no)
%define no_x11_askpass 1        #此处设置为1,不构建x11-askpass

# Do we want to disable building of gnome-askpass? (1=yes 0=no)
%define no_gnome_askpass 1      #此处设置为1,不构建gnome-askpass
[root@localhost ~]# cd /usr/src/
[root@localhost ~]# tar -zcf openssh-6.6p1.tar.gz openssh-6.6p1/
注意:此处必须在/usr/src/目录下打包,否则制作rpm包时会报错,且文件名必须如上所示
[root@localhost ~]# cd /usr/src/openssh-6.6p1/contrib/redhat
[root@localhost ~]# rpmbuild -bb openssh.spec    #开始制作rpm包
注意:制作rpm包的时候可能会遇到依赖包不全的问题,常见的有pam pam-devel glibc glibc-devel tcp_wrappers-devel openssl098e gcc等,此处不再一一赘述。

    打包完成后,在/usr/src/redhat/RPMS/x86_64目录下有打好的rpm包。用rpm方式升级安装。我在安装的时候遇到了版本冲突的问题,然后直接强制安装。

    安装完成后,修改/etc/ssh/sshd_config配置文件:

#AuthorizedKeysFile	.ssh/authorized_keys        //注释掉这一行

#AuthorizedPrincipalsFile none

AuthorizedKeysCommand /bin/ssh-zhy.sh            //添加这一行,指定查找ssh-key的脚本
AuthorizedKeysCommandUser root                       //添加这一行,指定运行脚本的用户,必须是root

     AuthorizedKeysCommand回向ssh-key脚本传递两个位置参数,$1是登陆用户名,$2是登陆用户的fingerprint,在脚本中可以直接用$2来获取fingerprint。

     准备取ssh-key的脚本,该脚本可以是shell脚本,也可以是其他脚本,只要能从数据库中取到对应的key就可以了,此处我使用的是shell脚本。数据库中保存各用户的key和fingerprint,根据fingerprint来取对应的key值,这样就保证所有用户即使都使用root登陆,也可以根据其fingerprint值来对应查找到对应的登陆人员从而完成人员记录。

    准备好脚本后,放到配置文件中配置的位置,改脚本文件属主和属组为root,脚本权限为700,这两步是必须设置的。配置完成后准备好存储key的数据库,然后重启sshd服务。此时再登陆的时候就会去数据库中查找key信息,如果在数据库中找不到对应的key,依然会去authorized_keys文件中找。

    配置好后,我们只需要通过管理数据库,就可以很方便的管理所有人的key。也可以方便后期的管理界面的开发。

本文出自 “手艺人” 博客,请务必保留此出处http://8838848.blog.51cto.com/8828848/1697188

使用数据库统一管理ssh登陆用户密钥信息

标签:ssh key authorizedkeyscommand mysql linux

原文地址:http://8838848.blog.51cto.com/8828848/1697188

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