基于openldap+Kerberos+google authenticator动态口令实现的运维跳板机

出于安全考虑,大多数公司的办公环境和业务环境在网络层面基本上是隔离开的,在办公环境是无法直接连到业务生产环境的,只有做过特定白名单通行的情况下才会允许这么做。这样做了,开发人员需要访问生产环境服务器排查问题或者运维人员通过办公网络对生产环境进行维护就不太方便,但是网络一旦开通又会出现安全风险。

在这种情况下,就需要一种可以控制网络入口,能够统一授权,认证的系统,这样运维跳板机,也就是比较严格意义上的AAAA认证系统就出现了。

所谓的4A认证系统其实是指:
统一用户账号(Account)
统一认证(Authentication)
统一授权(Authorization)
统一安全审计(Audit)

我们公司使用的是openldap(管理用户信息,同时实现资源访问控制),Kerberos(网络鉴权),google authenticator(二次认证的动态口令),bash (修改源码,实现账户远程登录操作
日志记录)

dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01DVXlSakpCSlRKR01UTWxNa1ozUzJsdlRERlBRMWhPUkZGNGNHdFBRVUZKY1RSSVpVRnJja2t6TlRBdWFuQm4=

统环境: 64位 CentOS linux 6.3

openldap+bdb+phpldapadmin

openldap:
master端:yum 安装
openldap
openldap-clients
openldap-servers
nss_ldap

客户端:yum方式
openldap
nss_ldap

slapd.conf配置文件修改:

database        bdb
suffix          "dc=dianpinng,dc=com"
rootdn          "cn=ldapadmin,dc=dianpinng,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw          
hehenimei # The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory       /usr/local/openldap/var/openldap-data
# Indices to maintain
index   objectClass     eq
# index uidNumber       eq
serverid    3 ldap://server1
serverid    5 ldap://server2
cachesize 50000
checkpoint 1024 5
idletimeout 20
syncrepl rid=005
  provider=ldap://server2
  binddn="cn=ldapadmin,dc=dianpinng,dc=com"
  bindmethod=simple
  credentials=hehehehhe,qunying.liu
  searchbase="dc=dianpinng,dc=com"
  type=refreshAndPersist
  interval=00:00:00:10
  retry="5 5 300 5"
  timeout=1
mirrormode true
overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100
sizelimit 700
timelimit 20
database monitor

系统加入ldap认证:

vi /etc/nsswitch.conf
        passwd: files ldap
        shadow: files ldap
        group: files ldap

打开ldap服务日志:
syslog中加入ldap日志文件

vi /etc/syslog.conf
# save OpenLDAP log
local4.* /var/log/ldap.log

客户端修改 /etc/ldap.conf

host  server1
# The distinguished name of the search base.
base ou=ldap,ou=auth,dc=dianpinng,dc=com

Openldapadmin配置

Tar zxvf openldapadmin-x.x.x.tar.gz
Cd openldapadmin-x.x.x.x
 mv phpldapadmin-x.x.x /var/www/localhost/htdocs/phpldapadmin –r
cd /var/www/localhost/htdocs/phpldapadmin
cp config/config.php.example config/config.php

修改config.php文件

登录phpldapadmins,设置的登录密码(hehehehhe,qunying.liu)登录

Kerberos:
Kerberos认证协议

Kerberos是一种网络认证协议,其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。

使用Kerberos时,一个客户端需要经过三个步骤来获取服务:

认证:客户端向认证服务器发送一条报文,并获取一个含时间戳的Ticket-Granting Ticket(TGT)。
授权:客户端使用TGT向Ticket-Granting Server(TGS)请求一个服务Ticket。
服务请求:客户端向服务器出示服务Ticket,以证实自己的合法性。该服务器提供客户端所需服务,在Hadoop应用中,服务器可以是namenode或jobtracker。

为此,Kerberos需要The Key Distribution Centers(KDC)来进行认证。KDC只有一个Master,可以带多个slaves机器。slaves机器仅进行普通验证。Mater上做的修改需要自动同步到slaves。
另外,KDC需要一个admin,来进行日常的管理操作。这个admin可以通过远程或者本地方式登录。

搭建Kerberos

1.安装:通过yum安装即可,组成KDC。

yum install -y krb5-server krb5-lib krb5-workstation

2.配置:Kerberos的配置文件只有两个。在server1中创建以下两个文件,并同步/etc/krb5.conf到所有机器。
/var/kerberos/krb5kdc/kdc.conf:包括KDC的配置信息。默认放在 /usr/local/var/krb5kdc。或者通过覆盖KRB5_KDC_PROFILE环境变量修改配置文件位置。

配置示例:

[kdcdefaults]
 kdc_ports = 88
 kdc_tcp_ports = 88
[realms]
 Qunying.liu = {
  master_key_type = aes128-cts
  acl_file = /var/kerberos/krb5kdc/kadm5.acl
  dict_file = /usr/share/dict/words
  admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
  max_renewable_life = 7d
  supported_enctypes = aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
 }

说明:
QUNYING.LIU:是设定的realms。名字随意。Kerberos可以支持多个realms,会增加复杂度。大小写敏感,一般为了识别使用全部大写。这个realms跟机器的host没有大关系。
max_renewable_life = 7d 涉及到是否能进行ticket的renwe必须配置。
master_key_type:和supported_enctypes默认使用aes256-cts。由于,JAVA使用aes256-cts验证方式需要安装额外的jar包。推荐不使用。
acl_file:标注了admin的用户权限,需要用户自己创建。文件格式是

Kerberos_principal permissions [target_principal]  [restrictions]

支持通配符等。最简单的写法是

*/admin@QUNYING.LIU    *

代表名称匹配*/admin@QUNYING.LIU 都认为是admin,权限是 *。代表全部权限。
admin_keytab:KDC进行校验的keytab。后文会提及如何创建。
supported_enctypes:支持的校验方式。注意把aes256-cts去掉。

/etc/krb5.conf:包含Kerberos的配置信息。例如,KDC的位置,Kerberos的admin的realms 等。需要所有使用的Kerberos的机器上的配置文件都同步。这里仅列举需要的基本配置。详细介绍参考:krb5conf:http://web.mit.edu/~kerberos/krb5-devel/doc/admin/conf_files/krb5_conf.html

配置示例:

logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log
[libdefaults]
 default_realm = QUNYING.LIU
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 max_life = 12h 0m 0s
 forwardable = true
 udp_preference_limit = 1
[realms]
 QUNYING.LIU = {
  kdc = server1:88
  admin_server = server1:749
  default_domain = DIANPINNG.COM
 }
[appdefaults]

说明:
[logging]:表示server端的日志的打印位置
[libdefaults]:每种连接的默认配置,需要注意以下几个关键的小配置
default_realm = QUNYING.LIU 默认的realm,必须跟要配置的realm的名称一致。
udp_preference_limit = 1 禁止使用udp可以防止一个Hadoop中的错误
[realms]:列举使用的realm。
kdc:代表要kdc的位置。格式是 机器:端口
admin_server:代表admin的位置。格式是 机器:端口
default_domain:代表默认的域名
[appdefaults]:可以设定一些针对特定应用的配置,覆盖默认配置。
初始化并启动:完成上面两个配置文件后,就可以进行初始化并启动了。

A.初始化数据库:在server1上运行命令。其中-r指定对应realm。

kdb5_util create -r QUNYING>LIU -s

如果遇到数据库已经存在的提示,可以把/var/kerberos/krb5kdc/目录下的principal的相关文件都删除掉。默认的数据库名字都是principal。可以使用-d指定数据库名字。(尚未测试多数据库的情况)。

B.启动kerberos。如果想开机自启动,需要stash文件。

/usr/local/sbin/krb5kdc
 /usr/local/sbin/kadmind

至此kerberos,搭建完毕。

测试kerberos,搭建完毕后,进行以下步骤测试Kerberos是否可用。
A. 进入kadmin在kadmin上添加一个超级管理员账户,需要输入passwd

kadmin.local
addprinc admin/admin

B. 在其它机器尝试通过kadmin连接,需要输入密码

kinit admin/admin
kadmin

如果能成功进入,则搭建成功。

kerberos日常操作

管理员操作

登录到管理员账户: 如果在本机上,可以通过kadmin.local直接登录。其它机器的,先使用kinit进行验证。

kadmin.local  
kinit admin/admin
kadmin

增删改查账户:在管理员的状态下使用addprinc,delprinc,modprinc,listprincs命令。使用?可以列出所有的命令。

kamdin:addprinc -randkey hdfs/hadoop1
kamdin:delprinc hdfs/hadoop1
kamdin:listprincs命令
生成keytab:使用xst命令或者ktadd命令
kadmin:xst -k /xxx/xxx/kerberos.keytab hdfs/server1
用户操作

查看当前的认证用户:klist

认证用户:kinit -kt /xx/xx/kerberos.keytab hdfs/server1
删除当前的认证的缓存: kdestroy

google authenticator:

基于TOTP(Time-based One-time Password,基于时间的一次性密码)
TOTP(基于时间的一次性密码算法)是支持时间作为动态因素基于HMAC一次性密码算法的扩展。
http://tools.ietf.org/html/rfc6238

条件:
1)Prover与Verifier之间必须时钟同步;
2)Prover与Verifier之间必须共享密钥;
3)Prover与Verifier之间必须使用相同的时间步长

算法:
K 共享密钥
T 时间
T0 开始计数的时间步长
X 时间步长

TOTP = Truncate(HMAC-SHA-1(K, (T - T0) / X))

使用Google Authenticator的步骤:

1. 服务器端对每个用户生成一个唯一的密钥SecretKey。
2. 用户在手机上安装Google Authenticator。首次使用需要将密钥输入到Google Authenticator。可通过手动和扫描系统生成的二维码等两种方式输入密钥信息。
3. Google Authenticator每隔一段时间为系统自动生成一个新的密码。用户在输入口令前需先输入生成的动态验证码。

客户端实现
python实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import hmac, base64, struct, hashlib, time ,sys , os
 
def get_hotp_token(secret, intervals_no):
        key = base64.b32decode(secret)
        msg = struct.pack(">Q", intervals_no)
        h = hmac.new(key, msg, hashlib.sha1).digest()
        o = ord(h[19]) & 15
        h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
        return h
 
def get_totp_token(secret):
        return get_hotp_token(secret, intervals_no=int(time.time())//30)
 
        #Sec = str(sys.argv[1])
Sec = 'xxxxxxx'
validation_code = str(get_totp_token(Sec))
print  validation_code

ruby实现:

#!/usr/bin/ruby
 
require 'rubygems'
require 'base32'
require 'openssl'
 
int = 30
 
now = Time.now.to_i / int
key = Base32.decode 'xxxxxxxx'
sha = OpenSSL::Digest::Digest.new('sha1')
 
(-1..1).each do |x|
  bytes  = [ now + x ].pack('>q').reverse
  hmac   = OpenSSL::HMAC.digest(sha, key.to_s, bytes)
  offset = hmac[-1] & 0x0F
  hash   = hmac[offset...offset + 4]
 
  code   = hash.reverse.unpack('L')[0]
  code  &= 0x7FFFFFFF
  code  %= 1000000
 
  puts code
end

跳板机登录增加谷歌二次认证

Google Authenticator模块安装:
EPEL源安装:

yum install  libpam-google-authenticator

2.源码安装:

yum -y install wget gcc make pam-devel libpng-devel
 
    # cd /tmp
    # wget http://google-authenticator.googlecode.com/files/libpam-google-authenticator-1.0-source.tar.bz2
    # bunzip2 libpam-google-authenticator-1.0-source.tar.bz2
    # tar xf libpam-google-authenticator-1.0-source.tar
    # cd libpam-google-authenticator-1.0
    # make
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o google-authenticator.o google-authenticator.c
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o base32.o base32.c
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o hmac.o hmac.c
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o sha1.o sha1.c
    gcc -g   -o google-authenticator google-authenticator.o base32.o hmac.o sha1.o  -ldl
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o pam_google_authenticator.o pam_google_authenticator.c
    gcc -shared -g   -o pam_google_authenticator.so pam_google_authenticator.o base32.o hmac.o sha1.o -lpam
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o demo.o demo.c
    gcc -DDEMO --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o pam_google_authenticator_demo.o pam_google_authenticator.c
    gcc -g   -rdynamic -o demo demo.o pam_google_authenticator_demo.o base32.o hmac.o sha1.o  -ldl
    gcc -DTESTING --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden        \
                  -o pam_google_authenticator_testing.o pam_google_authenticator.c
    gcc -shared -g   -o pam_google_authenticator_testing.so pam_google_authenticator_testing.o base32.o hmac.o sha1.o -lpam
    gcc --std=gnu99 -Wall -O2 -g -fPIC -c  -fvisibility=hidden  -o pam_google_authenticator_unittest.o pam_google_authenticator_unittest.c
    gcc -g   -rdynamic -o pam_google_authenticator_unittest pam_google_authenticator_unittest.o base32.o hmac.o sha1.o -lc  -ldl
 
    # make install
    cp pam_google_authenticator.so /lib64/security
    cp google-authenticator /usr/local/bin

设置Google Authenticator

运行 /usr/local/bin/google-authenticator
会在当前帐号home目录下生成相关配置文件。
安装完成之后运行google-authenticator命令
首先会提示你,是否要基于时间生成令牌,选择Y,然后它会生成密钥,以及紧急状态使用的验证码(有5个,谨当无法获取验证码时使用,注意这些紧急验证码用一次就少一个的哟,所以这几个紧急验证码一定要保存好。

Do you want me to update your "~/.google_authenticator" file (y/n) y
 
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@server%3Fsecret%3DABCD12E3FGHIJKLMN
Your new secret key is: ABCD12E3FGHIJKLMN
Your verification code is 98765432
Your emergency scratch codes are:
  01234567
  89012345
  67890123
  45678901
  23456789
 
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y
 
By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) y
 
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y

sshd配置加入谷歌认证模块:

/etc/pam.d/sshd 
#%PAM-1.0
auth       required     pam_google_authenticator.so 
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    required     pam_loginuid.so

修改 /etc/ssh/sshd_config

ChallengeResponseAuthentication no
修改为
ChallengeResponseAuthentication yes
修改完成之后重启SSH服务,下次登录就要输入动态验证码:

本地网络登录帐号跳过谷歌认证模块设置:

/etc/pam.d/sshd 增加

auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/access-local.conf
auth       required     pam_google_authenticator.so
在/etc/security/access-local.conf文件中增加:
# Google Authenticator can be skipped on local network
+ : ALL : 192.168.0.0/24
+ : ALL : LOCAL
- : ALL : ALL

允许192.196.0.0网段的用户登录帐号时跳过谷歌认证步骤。

整个跳板机部署完毕后,用户如何登录对于很多开发人员完全未知,站在用户的角度我们进行了一次内部分享,对如何登录跳板机做了简要说明。

dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01TVXlSakpCSlRKR01USWxNa1ozUzJsdmJURlBRMkpTZVZGeExXdzJRVUZJTnpkT2NHOUVRamczTnpVdWFuQm4=

 


dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01TVXlSakpCSlRKR01UTWxNa1ozUzJsdlRERlBRMkpRUTBOR1VrMTBRVUZMWkRObk1FeHVkSGN3TnpNdWFuQm4=


dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01DVXlSakpCSlRKR01UTWxNa1ozUzJsdlRERlBRMkpRUkVSNE5VcGxRVUZIY1VadU9UVm5TR015TURVdWFuQm4=


dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01DVXlSakpCSlRKR01USWxNa1ozUzJsdmJURlBRMkpTZWtKU2VUSXlRVUZMT0RWd1oxcEpZa1V4TlRFdWFuQm4=


dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01pVXlSakpCSlRKR01USWxNa1ozUzJsdmJURlBRMkpTTW5sbFNtNURRVUZHZWxoVVJVZE5iekEwT1RrdWFuQm4=


dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01pVXlSakpCSlRKR01UTWxNa1ozUzJsdlRERlBRMkpRUjFJMWFrNVNRVUZNT1dwVVEyUTVORVU0TURFdWFuQm4=


dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJuTXpMalV4WTNSdkxtTnZiU1V5Um5kNVpuTXdNaVV5Umswd01TVXlSakpCSlRKR01UTWxNa1ozUzJsdlRERlBRMkpRU0doeVZrTllRVUZLYTBnM1FXSnpNM2N3TnpndWFuQm4=

当然较于现在出现的比较高大上的堡垒机而言,运维跳板机的功能还是相当简单,只实现了用户信息和权限管理的统一,同时也只是事后的安全审计,目前还不能事前控制以避免人员的误操作。堡垒机一般支持的协议有图形(RDP/VNC/X11)、字符(SSH/TELNET)、文件(FTP/SFTP)和一些数据库协议(MySQL、Oracle)等等。除此之外,除了未实现高端的图形界面显示和一些比较人性化的交互功能外,目前大部分的功能(比如单点登录,审计,帐号管理,操作也可以定位到来源和人员)我们都是具有的。

基于信息安全考虑,必要信息做了修改处理,仅供参考,请勿直接黏贴使用。
时间同步,与权限信息同步未做说明。

相关参考:
http://www.howtogeek.com/121650/how-to-secure-ssh-with-google-authenticators-two-factor-authentication/
有关ldap与ad同步问题讨论:
http://bbs.csdn.net/topics/340139712

还没有评论,快来抢沙发!

发表评论

  • 😉
  • 😐
  • 😡
  • 😈
  • 🙂
  • 😯
  • 🙁
  • 🙄
  • 😛
  • 😳
  • 😮
  • emoji-mrgree
  • 😆
  • 💡
  • 😀
  • 👿
  • 😥
  • 😎
  • ➡
  • 😕
  • ❓
  • ❗
  • 71 queries in 0.092 seconds