Kerberos+LDAP+NFSv4 实现单点登录(续2)--一键安装

Kerberos+LDAP+NFSv4 实现单点登录(续2)--一键安装

( 附:LDAP简单认证登录 login4ldap-ver0.0.6.zip 源代码 下载地址 http://u.163.com/NeMVmlIT 提取码: ObEubL7Y )

上篇Kerberos+LDAP+NFSv4 实现单点登录(续1)链接地址http://lulinlin1.lofter.com/post/1cf3848f_11f58066?act=qbbloglofter_20150506_01

本篇是前两篇的总结,编写成一键安装脚本onekeysso.sh,并需名为dns.ldif文件.dns.ldif是从bind9-dyndb-ldap包的模式文件修改而来,可参考上篇

下面是onekeysso.sh的内容,将onekeysso.sh和dns.ldif放在同一目录下,以root用户运行onekeysso.sh

说明:脚本会卸载删除一些包及文件(如要重新一键安装),如果你的系统已是正在用于生产环境,请小心,还是请准备干净的系统一键安装

环境:debian 10

运行:
root@debian:~# ls
dns.ldif onekeysso.sh
root@debian:~# ./onekeysso.sh

内容:
#! /bin/bash

echo -n "before install new pack,Shall I remove some old files,database and uninstall [yes/no]?"
read
if [ "$REPLY" = "yes" ]; then
echo "install setup"
else
echo "exit install"
exit 0
fi

/etc/init.d/slapd stop
/etc/init.d/heimdal-kdc stop
apt-get -y remove --purge slapd
apt-get -y remove --purge heimdal-kdc
apt-get -y remove --purge krb5-config
apt-get -y remove --purge bind9-dyndb-ldap bind9 isc-dhcp-server-ldap isc-dhcp-server
rm /etc/ldap/krb5.keytab
rm /etc/bind/krb5.keytab
sed -i '/127.0.0.2/d' /etc/hosts

echo -n "input net(default: 192.168.1.0):"
read mynet
if [ -z $mynet ]; then
mynet="192.168.1.0"
fi

if [[ $mynet =~ [0-9]+.[0-9]+.[0-9]+.[0] ]] && !([[ $mynet =~ [^0-9.]+ ]]); then
echo ok
else
echo "必须是网络地址0"
exit 1
fi

IFS=. read -r myp1 myp2 myp3 myp4 <<< $mynet

mybroadcast=echo $mynet | sed 's/.0$/.255/'

myiprange="echo $mynet | sed 's/.0$/.20/' echo $mynet | sed 's/.0$/.240/'"

echo -n "input static ip(default: "$myp1.$myp2.$myp3".11):"
read mystaticip
if [ -z $mystaticip ]; then
mystaticip=$myp1.$myp2.$myp3.11
fi

if [[ $mystaticip =~ $myp1.$myp2.$myp3.[0-9]+ ]] && !([[ $mystaticip =~ [^0-9.]+ ]]); then
echo ok
else
echo "必须是上面所设的同网段"
exit 1
fi
IFS=. read -r mys1 mys2 mys3 mys4 <<< $mystaticip
if [ $mys4 = 0 ]; then
echo "不能是网络地址0"
exit 1
fi

if [ $mys4 = 255 ]; then
echo "不能是广播地址255"
exit 1
fi

echo -n "input router(default: "$myp1.$myp2.$myp3".1):"
read myrouter
if [ -z $myrouter ]; then
myrouter=$myp1.$myp2.$myp3.1
fi

if [[ $myrouter =~ [0-9]+.[0-9]+.[0-9]+.[0-9]+ ]] && !([[ $myrouter =~ [^0-9.]+ ]]); then
echo ok
else
echo error
exit 1
fi

echo -n "input hostname:"
read mykdc
if [[ $mykdc =~ [a-z]+ ]] && !([[ $mykdc =~ [^a-z]+ ]]); then
echo ok
else
echo "仅支持小写字母"
exit 1
fi

echo -n "input domain:"
read mydomain
if [[ $mydomain =~ [a-z.]+ ]] && !([[ $mydomain =~ [^a-z.]+ ]]); then
echo ok
else
echo "仅支持小写字母和点号"
exit 1
fi

echo '127.0.0.2 '$mykdc'.'$mydomain' '$mykdc >> /etc/hosts
echo $mykdc > /etc/hostname
hostname $mykdc

mydomain=hostname -d

myrealm=hostname -d | tr a-z A-Z
mysuffix="dc=echo $mydomain | sed 's/^\.//; s/\.$//; s/\./,dc=/g'"
mybasedn=$mysuffix

myfullname=$mykdc.$mydomain

echo $myfullname
echo $mybasedn
echo $mybroadcast
echo $myiprange

#预配置krb5-config
echo 'krb5-config krb5-config/default_realm string '$myrealm | debconf-set-selections
echo 'krb5-config krb5-config/admin_server string 127.0.0.1' | debconf-set-selections
echo 'krb5-config krb5-config/kerberos_servers string 127.0.0.1' | debconf-set-selections

apt-get -y install schema2ldif gzip
apt-get -y install slapd
apt-get -y install heimdal-kdc
apt-get -y install bind9 bind9-dyndb-ldap isc-dhcp-server isc-dhcp-server-ldap libsasl2-modules-gssapi-heimdal dnsutils

/etc/init.d/slapd stop
/etc/init.d/heimdal-kdc stop
/etc/init.d/bind9 stop
/etc/init.d/isc-dhcp-server stop

#1.修改配置
#1)ldap
#1.1)将krb5用户主体映射到ldap用户
sed -i '$a olcAuthzRegexp: {0}uid=dns/'"$mykdc"',cn=gssapi,cn=auth krb5PrincipalName=DNS/'"$mykdc"'@'"$myrealm"',ou=hdkrb5,'"$mysuffix"'' /etc/ldap/slapd.d/cn=config.ldif

#1.2)设置LDAP ACL,允许如DNS/[email protected]写ldap数据库
sed -i '/olcAccess: {2}to * by * read/a olcAccess: {3}to by self write by dn="cn=admin,'"$mysuffix"'" write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by read' /etc/ldap/slapd.d/cn=config/olcDatabase={1}mdb.ldif
sed -i '/olcAccess: {2}to * by * read/a olcAccess: {2}to dn.subtree="ou=dns,'"$mysuffix"'" by dn="krb5PrincipalName=DNS/'"$mykdc"'@'"$myrealm"',ou=hdkrb5,'"$mysuffix"'" write by read' /etc/ldap/slapd.d/cn=config/olcDatabase={1}mdb.ldif
sed -i '/olcAccess: {2}to * by \
read/d' /etc/ldap/slapd.d/cn=config/olcDatabase={1}mdb.ldif

#1.3)缺省搜索
sed -i '$a olcDefaultSearchBase: '"$mybasedn"'' /etc/ldap/slapd.d/cn=config/olcDatabase={-1}frontend.ldif

#1.4)必须启用同步,否则dig查询被拒绝
sed -i '/olcModuleLoad: {0}/a olcModuleLoad: {1}syncprov' /etc/ldap/slapd.d/cn=config/cn=module{0}.ldif

slapadd -b cn=config <<-EOF
dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpNoPresent: TRUE
EOF

chown openldap:openldap /etc/ldap/slapd.d/cn=config/olcDatabase={1}mdb
chown openldap:openldap /etc/ldap/slapd.d/cn=config/olcDatabase={1}mdb/olcOverlay={0}syncprov.ldif

#2)krb
#2.1)kdc.conf
sed -i '/[kdc]/a \n addresses = 0.0.0.0\n' /etc/heimdal-kdc/kdc.conf
sed -i '/dbname = \/var\/lib\/heimdal-kdc\/heimdal/a \n dbname = ldap:ou=hdkrb5,'"$mysuffix"'\n mkey_file = \/var\/lib\/heimdal-kdc\/m-key\n realm = '"$myrealm"'' /etc/heimdal-kdc/kdc.conf
sed -i '/dbname = \/var\/lib\/heimdal-kdc\/heimdal/d' /etc/heimdal-kdc/kdc.conf

#2.2)krb5.conf
sed -i '/[libdefaults]/a \n allow_weak_crypto = true\n dns_lookup_kdc = true\n dns_lookup_realm = true' /etc/krb5.conf
sed -i '/admin_server = 127.0.0.1/d' /etc/krb5.conf
sed -i '/forwardable = true/d' /etc/krb5.conf
sed -i '/proxiable = true/d' /etc/krb5.conf
sed -i '/# default_tgs_enctypes = des3-hmac-sha1/a default_tgs_enctypes = aes256-cts-hmac-sha1-96 des3-cbc-sha1 arcfour-hmac-md5' /etc/krb5.conf
sed -i '/# default_tkt_enctypes = des3-hmac-sha1/a default_tkt_enctypes = aes256-cts-hmac-sha1-96 des3-cbc-sha1 arcfour-hmac-md5' /etc/krb5.conf

#3)dhcp
mysecret=ddns-confgen | grep secret
sed -i '/INTERFACESv4=""/a INTERFACESv4="'"ls /sys/class/net | sed '/lo/d' | xargs"'"' /etc/default/isc-dhcp-server
sed -i '/INTERFACESv4=""/d' /etc/default/isc-dhcp-server
sed -i 's/^/#/' /etc/dhcp/dhcpd.conf
sed -i '1a ldap-server "127.0.0.1";\nldap-base-dn "'"$mybasedn"'";\nldap-method dynamic;' /etc/dhcp/dhcpd.conf
#将原放在ldap的密钥改放在dhcpd.conf
sed -i '1a key "ddns-key" { algorithm hmac-sha256; '"$mysecret"' }' /etc/dhcp/dhcpd.conf
chmod o-r /etc/dhcp/dhcpd.conf

#4)dns
sed -i '/include "\/etc\/bind\/named.conf.local";/a include "/etc/bind/named.conf.ldap";' /etc/bind/named.conf
sed -i '/include "\/etc\/bind\/named.conf.local";/d' /etc/bind/named.conf
sed -i '/include "\/etc\/bind\/named.conf.default-zones";/d' /etc/bind/named.conf
sed -i '/directory "\/var\/cache\/bind";/a \n allow-recursion { none; };' /etc/bind/named.conf.options
sed -i '/dnssec-validation auto;/d' /etc/bind/named.conf.options
sed -i '/auth-nxdomain no;/d' /etc/bind/named.conf.options
sed -i '/listen-on-v6 { any; };/d' /etc/bind/named.conf.options

#4.1)重装bind9时,bind用户及用户组ID可能有改变,而重装又没改到named.run
chown bind:bind /var/cache/bind/named.run

#4.2)新建named.conf.ldap
cat <<-EOF > /etc/bind/named.conf.ldap
logging {
channel default_debug {
file "named.run";
severity debug;
};
};

key "ddns-key" {
algorithm hmac-sha256;
$mysecret
};

controls {
inet 127.0.0.1 allow { 127.0.0.1; } keys { ddns-key; };
};

//不同体系路径如/usr/lib/i386-linux-gnu/bind/ldap.so
dyndb "my_db_name" "dpkg-query -S ldap.so | grep bind9-dyndb-ldap | sed 's/bind9-dyndb-ldap: //'" {
//bind9-dyndb-ldap有bug,必须加server_id此行
server_id "";
directory "/var/cache/bind";
uri "ldap://127.0.0.1";
base "ou=dns,$mysuffix";

//认证机制
auth_method "sasl";
sasl_mech "GSSAPI";
//--v-- 添加krb5主体
sasl_auth_name "DNS/$mykdc";
krb5_keytab "FILE:/etc/bind/krb5.keytab";
//--^--

//超时及重连接间隔的值需设大一点,解决因使用SASL认证无法写问题
timeout 50;
reconnect_interval 100;
};
EOF
chmod o-r /etc/bind/named.conf.ldap

#2.添加模式
#1)krb
schema2ldif /etc/ldap/schema/hdb.schema | slapadd -b cn=config

#2)dhcp
zcat /usr/share/doc/isc-dhcp-server-ldap/dhcp.schema.gz | schema2ldif -c dhcp | slapadd -b cn=config

#3)dns
slapadd -b cn=config -l dns.ldif

chown openldap:openldap /etc/ldap/slapd.d/cn=config/cn=schema/cn={}hdb.ldif
chown openldap:openldap /etc/ldap/slapd.d/cn=config/cn=schema/cn={
}dhcp.ldif
chown openldap:openldap /etc/ldap/slapd.d/cn=config/cn=schema/cn={*}dns.ldif

#3.添加条目
slapadd -b $mysuffix <<-EOF
#1)
dn: ou=hdkrb5,$mysuffix
krb5PrincipalName: default@$myrealm
ou: hdkrb5
objectClass: krb5Principal
objectClass: organizationalUnit

dn: ou=users,ou=hdkrb5,$mysuffix
objectClass: organizationalUnit
ou: users

dn: ou=hosts,ou=hdkrb5,$mysuffix
objectClass: organizationalUnit
ou: hosts

dn: ou=groups,$mysuffix
objectClass: organizationalUnit
ou: groups

dn: ou=sudoers,$mysuffix
objectClass: organizationalUnit
ou: sudoers

dn: ou=roles,$mysuffix
objectClass: organizationalUnit
ou: roles

#2)dhcp
dn: cn=$mykdc,$mysuffix
objectClass: dhcpServer
cn: $mykdc
dhcpServiceDN: cn=dhcp,$mysuffix

#Here is the config tree
dn: cn=dhcp,$mysuffix
cn: dhcp
objectClass: dhcpService
dhcpPrimaryDN: cn=$mykdc,$mysuffix
dhcpStatements: ddns-update-style interim
dhcpStatements: ignore client-updates
#动态更新DNS的密钥改放到dhcpd.conf,方便设置访问权限控制,免泄漏密钥
#dhcpStatements: key "ddns-key" { algorithm hmac-sha256; $mysecret }
dhcpStatements: zone $mydomain { primary 127.0.0.1; key ddns-key; }
dhcpStatements: default-lease-time 600
dhcpStatements: max-lease-time 7200

#Set up a subnet declaration with a pool statement. Also note that we have a dhcpOptions object with this entry
dn: cn=$mynet,cn=dhcp,$mysuffix
cn: $mynet
objectClass: dhcpSubnet
objectClass: dhcpOptions
dhcpOption: domain-name "$mydomain"
dhcpOption: domain-name-servers $mystaticip
dhcpOption: routers $myrouter
dhcpOption: subnet-mask 255.255.255.0
dhcpOption: broadcast-address $mybroadcast
dhcpNetMask: 24
dhcpRange: $myiprange

#3)dns
#定义正、反向区域存储到ldap数据库
dn: ou=dns,$mysuffix
objectClass: organizationalUnit
ou: dns

#Zone
dn: idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsZone
objectClass: idnsRecord
idnsName: $mydomain
#动态更新
idnsAllowDynUpdate: TRUE
#同步反向解析
idnsAllowSyncPTR: TRUE
#动态更新策略
idnsUpdatePolicy: grant ddns-key zonesub ANY;
idnsZoneActive: TRUE
idnsSOAmName: $mykdc
idnsSOArName: root.$mykdc
idnsSOAserial: 1
idnsSOArefresh: 10800
idnsSOAretry: 900
idnsSOAexpire: 604800
idnsSOAminimum: 86400
#域名服务器记录
NSRecord: $mydomain.
ARecord: $mystaticip

#别名
dn: idnsName=$mykdc,idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: $mykdc
CNAMERecord: $mydomain.

#DNS records for zone
#--v-- SRV资源记录
dn: idnsName=_kerberos._udp,idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: _kerberos._udp
SRVRecord: 0 100 88 $mykdc

dn: idnsName=_kerberos._tcp,idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: _kerberos._tcp
SRVRecord: 0 100 88 $mykdc

dn: idnsName=_kpasswd._udp,idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: _kpasswd._udp
SRVRecord: 0 100 464 $mykdc

dn: idnsName=_ldap._tcp,idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: _ldap._tcp
SRVRecord: 0 100 389 $mykdc

dn: idnsName=_ntp._udp,idnsName=$mydomain,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: _ntp._udp
SRVRecord: 0 100 123 $mykdc
#--^--

#--v-- 反向解析
dn: idnsName=$myp3.$myp2.$myp1.in-addr.arpa,ou=dns,$mysuffix
objectClass: idnsZone
objectClass: idnsRecord
idnsName: $myp3.$myp2.$myp1.in-addr.arpa
idnsAllowDynUpdate: TRUE
idnsUpdatePolicy: grant ddns-key zonesub ANY;
idnsZoneActive: TRUE
idnsSOAmName: $myfullname.
idnsSOArName: root.$myfullname.
idnsSOAserial: 1
idnsSOArefresh: 10800
idnsSOAretry: 900
idnsSOAexpire: 604800
idnsSOAminimum: 86400
NSRecord: $myfullname.

#必须配置kdc服务器地址的反向解析
dn: idnsName=$mys4,idnsName=$myp3.$myp2.$myp1.in-addr.arpa,ou=dns,$mysuffix
objectClass: idnsRecord
idnsName: $mys4
PTRRecord: $myfullname.
#--^--
EOF

#4.其它
/etc/init.d/slapd start
/etc/init.d/heimdal-kdc start

#1)初始化krb
kadmin -l init --realm-max-ticket-life=unlimited --realm-max-renewable-life=unlimited $myrealm

#2)添加krb5主体
#2.1)
kadmin -l add -r --use-defaults ldap/$mykdc

#使ldap/mykdc成为应用服务器
kadmin -l modify -a -disallow-svr ldap/$mykdc

#导出keytab
kadmin -l ext -k /etc/ldap/krb5.keytab ldap/$mykdc

#不知为何在/etc/default/slapd指定KRB5_KTNAME没作用,因此还是复制一份到/etc/下
cp -a /etc/ldap/krb5.keytab /etc/krb5.keytab

#krb5.keytab拥有者改为openldap,并只openldap用户可读
chown openldap:openldap /etc/ldap/krb5.keytab
chmod o-r /etc/ldap/krb5.keytab
chmod g-r /etc/ldap/krb5.keytab

#在/etc/default/slapd里增加一行
sed -i '$a export KRB5_KTNAME=/etc/ldap/krb5.keytab' /etc/default/slapd

#2.2)
kadmin -l add -r --use-defaults DNS/$mykdc
kadmin -l ext -k /etc/bind/krb5.keytab DNS/$mykdc

#krb5.keytab拥有者改为bind,并只bind用户可读
chown bind:bind /etc/bind/krb5.keytab
chmod o-r /etc/bind/krb5.keytab
chmod g-r /etc/bind/krb5.keytab

#3)略
#ssl
#密码同步

#4)
sed -i '/127.0.0.2/d' /etc/hosts
sed -i '/iface eth0 inet dhcp/a iface eth0 inet static\naddress '"$mystaticip"'\nnetmask 255.255.255.0' /etc/network/interfaces
sed -i '/iface eth0 inet dhcp/d' /etc/network/interfaces
#/etc/init.d/networking restart
/etc/init.d/bind9 start
/etc/init.d/isc-dhcp-server start

后记:
1.dig查询DNS被拒绝问题
bind9-dyndb-ldap文档有提到SyncRepl (RFC 4533) ,但没说明LDAP必须启用同步.
起初脚本没启用LDAP同步,DNS解析总被拒绝,调试bind9提示SyncRepl (RFC 4533)有问题,启用了LDAP同步就正常.
因此脚本添加加了启用LDAP同步.

2.krb5Key属性安全问题
脚本没设置krb5Key属性的读写权限,因此是匿名可读,heimdal文档也没说明krb5Key属性的安全问题.
为提高安全性,用户可自行参考userPassword属性的设置方法来禁止匿名读取krb5Key属性.

3.动态更新DNS模式
一般手册推荐标准模式standard,但使用了bind9-dyndb-ldap,在模式standard下客户机第一次分配地址能添加到DNS,但客户机地址改变时无法更新DNS,提示没DHCIDRecord属性,而bind-dyndb-ldap模式没有DHCIDRecord属性.
所以动态更新DNS模式改为interim,客户机地址改变时已可正常更新DNS

猜你喜欢

转载自blog.51cto.com/13752418/2117078
今日推荐