Kerberos+LDAP+NFSv4 實現單點登陸(續2)--一鍵安裝linux
( 附: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_01api
本篇是前兩篇的總結,編寫成一鍵安裝腳本onekeysso.sh,並需名爲dns.ldif文件.dns.ldif是從bind9-dyndb-ldap包的模式文件修改而來,可參考上篇安全
下面是onekeysso.sh的內容,將onekeysso.sh和dns.ldif放在同一目錄下,以root用戶運行onekeysso.shbash
重要提示:本腳本用在全新的安裝,不是原步平滑升級配置.腳本會完全卸載刪除一些包及原有文件(如krb5主密鑰、krb5/ldap數據庫等等),並從新初始化爲空的數據庫文件.若是你的系統已經是正在用於生產環境,請當心,請備份你的數據文件,本腳本會清空你一切的數據庫.仍是請準備乾淨(未用在生產環境)的系統一鍵安裝服務器
環境:debian 10網絡
運行:
root@debian:~# ls
dns.ldif onekeysso.sh
root@debian:~# ./onekeysso.shfrontend
內容:dom
#! /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/mykdc@XX.YY寫ldap數據庫 sed -i '/olcAccess: {2}to \* by \* read/a olcAccess: {3}to * 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同步.tcp
2.krb5Key屬性安全問題
腳本沒設置krb5Key屬性的讀寫權限,所以是匿名可讀,heimdal文檔也沒說明krb5Key屬性的安全問題.
爲提升安全性,用戶可自行參考userPassword屬性的設置方法來禁止匿名讀取krb5Key屬性.
3.動態更新DNS模式
通常手冊推薦標準模式standard,但使用了bind9-dyndb-ldap,在模式standard下客戶機第一次分配地址能添加到DNS,但客戶機地址改變時沒法更新DNS,提示沒DHCIDRecord屬性,而bind-dyndb-ldap模式沒有DHCIDRecord屬性.
因此動態更新DNS模式改成interim,客戶機地址改變時已可正常更新DNS
修正:
#1.2)設置LDAP ACL
的{3}to * by self write by
改成{3}to * by