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

使用数据库统一管理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版本的源码包并下载:

1
2
3
[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文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//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包来升级:

1
2
3
4
5
6
7
[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
1
2
3
4
5
6
[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配置文件:

1
2
3
4
5
6
#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。也可以方便后期的管理界面的开发。

    想了解更多相关资讯,可以查看传智播客java教程,了解更多。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值