亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

LDAP/SASL/GSSAPI/Kerberos編程API(3)--LDAP/SASL

發布時間:2020-05-14 21:34:06 來源:網絡 閱讀:450 作者:lu_linlin 欄目:編程語言

一.安裝開發庫
客戶機:vmcln(192.168.1.20)
root@vmcln:/# apt-get install libkrb5-dev libldap2-dev libsasl2-dev

二.SASL/GSSAPI(不含krb5庫)
1.源代碼
//源文件名:testsasl.c

#include <sasl/sasl.h>
#include <ldap.h>
#include <stdio.h>
#include <stdlib.h>

//回調函數
static int  _ldap_sasl_interact( )
{ return LDAP_SUCCESS; //#1    
}

int main()
{ 
  LDAP *ld;
  int rc;
  unsigned long version = LDAP_VERSION3;

  if (( rc = ldap_initialize(&ld,"ldap://192.168.1.11/")) != LDAP_SUCCESS) //LDAP服務器地址
  {
    return(1);
  }

  rc = ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,(void*)&version);

  //綁定
  if ((rc=ldap_sasl_interactive_bind_s(ld,NULL,  
                                          "GSSAPI",//認證機制
                                          NULL,NULL,LDAP_SASL_AUTOMATIC,
                                          _ldap_sasl_interact,//#2
                                          NULL)
          ) != LDAP_SUCCESS)
  { printf ("Error: %s\n",ldap_err2string (rc));
    char *msg=NULL;
    ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg);
    printf ("Additional info: %s\n", msg);
    ldap_memfree(msg);
    return(1);
  }

  //--v-- 讀取目錄信息
  LDAPMessage *res;
  if ((rc=ldap_search_ext_s(ld,"",LDAP_SCOPE_ONELEVEL,NULL,NULL,0,NULL,NULL,NULL,0,&res)!=LDAP_SUCCESS))
  { printf("ldap_search  failed with 0x%x.\n",rc);         
    return(1);
  }
  printf("Success!\n");
  LDAPMessage *entry = ldap_first_entry( ld, res );
  int entry_count = ldap_count_entries(ld, res);
  for (int i = 0 ; i < entry_count; i++)
  { printf("dn: %s\n",ldap_get_dn(ld, entry));
    BerElement * ber;
    char * attribute = ldap_first_attribute(ld,entry, &ber);
    while(attribute)
    { printf ("attribute = %s\n",attribute);
      attribute = ldap_next_attribute(ld,entry, ber);
    }
    ber_free(ber,0);
    entry = ldap_next_entry(ld, entry);   
  }
  //--^--
  return 0;   
}

2.解析
1)回調函數
代碼#1處直接返回LDAP_SUCCESS即可,ldap_sasl_interactive_bind_s就成功.這個是最簡單能成功的回調函數代碼,應該也是很不規范.至于如何編寫完善的回調函數代碼,其實我也不懂

可返回的值還有:
LDAP_PARAM_ERROR、LDAP_OTHER、LDAP_PARAM_ERROR,這幾個返回錯誤,ldap_sasl_interactive_bind_s便失敗.

2)
代碼#2處不能直接填LDAP_SUCCESS或NULL,否則會出錯提示'Error: Local error',必需填為回調函數

3)跟蹤測試
ldap_sasl_interactive_bind_s的GSSAPI會讀取/etc/krb5.conf和票據/tmp/krb5cc_1000

3.編譯
linlin@vmcln:~$ gcc -o testsasl testsasl.c -lldap -llber -lsasl2

4.運行
linlin@vmcln:~$ ls /tmp
(空)
linlin@vmcln:~$ ./testsasl
SASL/GSSAPI authentication started 開始SASL/GSSAPI認證
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_1000))
linlin@vmcln:~$
失敗,提示沒有有效票據,找不到/tmp/krb5cc_1000

SASL的GSSAPI不提供交互輸入口令,而是直接讀取票據.我們可用kinit來先生成票據,下面krblinlin是Kerberos用戶主體
linlin@vmcln:~$ kinit --no-forwardable krblinlin
krblinlin@CTP.NET's Password: 輸入口令
linlin@vmcln:~$
因為我的KDC服務端是heimdal,需帶參數no-forwardable.如果服務端是mit則不用帶參數no-forwardable

linlin@vmcln:~$ ls /tmp
krb5cc_1000
linlin@vmcln:~$
已見到票據,由kinit生成

再次執行,已成功讀出ldap目錄信息
linlin@vmcln:~$ ./testsasl
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET 這里可以看到krblinlin用戶,即testsasl程序里不傳入用戶、口令,而是通過票據
SASL SSF: 56
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...

三.SASL/GSSAPI + krb5
基于上面代碼增加krb5用戶輸入口令登錄認證,目的是程序自己生成票據
1.源代碼
//源文件名:testldapkrb.c

#include <sasl/sasl.h>
#include <ldap.h>
#include <stdio.h>
#include <stdlib.h>
#include <krb5.h>

static int  _ldap_sasl_interact( )
{ return LDAP_SUCCESS;
}

int main()
{ 
  krb5_context context = NULL;
  krb5_error_code krberr;
  krb5_principal kprincpw = NULL;
  krb5_creds * my_creds_ptr = NULL;
  krb5_creds my_creds;
  const char * errmsg;
  krberr = krb5_init_context(&context);

  if (krberr) {
            errmsg = krb5_get_error_message(NULL, krberr);
            printf("Err: Kerberos context initialization failed -> %s\n", errmsg);
            goto cleanup;
        }

  krberr = krb5_parse_name(context, "krblinlin@CTP.NET", &kprincpw); //用戶

  if (krberr) {
            errmsg = krb5_get_error_message(context, krberr);
            printf("Err: Failed to parse princpal %s -> %s\n", errmsg);
            goto cleanup;
        }

  const char *password="linlin"; //口令
  printf("begin get init creds password\n");
  krberr = krb5_get_init_creds_password(context, &my_creds,kprincpw, (char *)password,NULL,NULL,0,NULL,NULL);

  if (krberr) {
            errmsg = krb5_get_error_message(context, krberr);
            printf("Err: Failed to get init creds password -> %s\n", errmsg);
            goto cleanup;
        }        
  my_creds_ptr = &my_creds;
  printf("get init creds password OK\n");

//--v
  krb5_ccache ccache = NULL;

  krberr = krb5_cc_resolve(context, "MEMORY:dhcp_ld_krb5_cc", &ccache); //#11
  //krberr = krb5_cc_resolve(context, "FILE:/tmp/krb5cc_1000", &ccache);
  if (krberr) {
            errmsg = krb5_get_error_message(context, krberr);
            printf("Err: Couldnt resolve ccache -> %s\n", errmsg);
            goto cleanup;
        }     

  krberr = krb5_cc_initialize(context, ccache, kprincpw);
  if (krberr) {
            errmsg = krb5_get_error_message(context, krberr);
            printf("Err: Failed to init ccache -> %s\n", errmsg);
            goto cleanup;
        }  

  krberr = krb5_cc_store_cred(context, ccache, &my_creds);

  if (krberr) {
            errmsg = krb5_get_error_message(context, krberr);
            printf("Err: Failed to store credentials -> %s\n", errmsg);
            goto cleanup;
        }            

  printf("Successfully store creds\n");

//--^

//--v-- 同第二章節代碼
  LDAP *ld;
  int rc;
  unsigned long version = LDAP_VERSION3;

  if (( rc = ldap_initialize(&ld,"ldap://192.168.1.11/")) != LDAP_SUCCESS)   //#12
  //if (( rc = ldap_initialize(&ld,"ldap://127.0.0.1/")) != LDAP_SUCCESS)
  {
    return(1);
  }

  rc = ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,(void*)&version);

  if ((rc=ldap_sasl_interactive_bind_s(ld,NULL,"GSSAPI",NULL,NULL,LDAP_SASL_AUTOMATIC, _ldap_sasl_interact,NULL) ) != LDAP_SUCCESS)
  { printf ("Error: %s\n",ldap_err2string (rc));
    char *msg=NULL;
    ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg);
    printf ("Additional info: %s\n", msg);
    ldap_memfree(msg);
    return(1);
  }

  LDAPMessage *res;
  if ((rc=ldap_search_ext_s(ld,"",LDAP_SCOPE_ONELEVEL,NULL,NULL,0,NULL,NULL,NULL,0,&res)!=LDAP_SUCCESS))
  { printf("ldap_search  failed with 0x%x.\n",rc);         
    return(1);
  }
  printf("Success!\n");
  LDAPMessage *entry = ldap_first_entry( ld, res );
  int entry_count = ldap_count_entries(ld, res);
  for (int i = 0 ; i < entry_count; i++)
  { printf("dn: %s\n",ldap_get_dn(ld, entry));
    BerElement * ber;
    char * attribute = ldap_first_attribute(ld,entry, &ber);
    while(attribute)
    { printf ("attribute = %s\n",attribute);
      attribute = ldap_next_attribute(ld,entry, ber);
    }
    ber_free(ber,0);
    entry = ldap_next_entry(ld, entry);   
  }  
//--^--

cleanup:
    if (ccache) krb5_cc_close(context, ccache);  //#13
    if (kprincpw) krb5_free_principal(context, kprincpw);
    if (my_creds_ptr) krb5_free_cred_contents(context, &my_creds);
    if (context) krb5_free_context(context);

  return 0;   
}

2.解析
1)代碼#11處,票據可以是
MEMORY : 進程內存里的票據,隨進程的結束而銷毀
FILE : 文件系統上的票據,不會自動銷毀,即使系統重啟,所以要防范票據在生存期內被復制走盜用登錄.當然票據通常是放在/tmp下,一般系統的啟動/關閉都會清理/tmp目錄.

2)本文將測試MEMORY、FILE兩種類型票據
在#11處分別編譯
'MEMORY '的名稱隨便定,我不清楚是否有規范的名稱
'FILE'指定/tmp/krb5cc_1000作為票據文件.當前登錄用戶linlin的uid為1000,在當前用戶運行有關的SASL/GSSAPI,默認票據路徑文件/tmp/krb5cc_1000.所以上面程序為配合默認路徑文件,寫死了 "FILE:/tmp/krb5cc_1000" 與之保持一致,運行命令就不用再指定環境變量(除非程序生成票據與默認路徑文件不一致)

3)代碼#13處不會銷毀票據(包括內存票據、文件票據)

3.編譯
1)編譯成內存票據執行文件testldapkrb_m
#11處,按"MEMORY:dhcp_ld_krb5_cc"編譯
linlin@vmcln:~$ gcc -o testldapkrb_m testldapkrb.c -lldap -llber -lsasl2 -lkrb5

2)編譯成文件票據執行文件testldapkrb_f
#11處,改為"FILE:/tmp/krb5cc_1000"編譯
linlin@vmcln:~$ gcc -o testldapkrb_f testldapkrb.c -lldap -llber -lsasl2 -lkrb5

4.服務端環境
krb5+ldap+dns在同一臺機器上vmkdc(192.168.1.11)
機器名:vmkdc
ldap應用服務主體:ldap/vmkdc@CTP.NET

5.在客戶機上運行
1)客戶端環境
平臺 : debian 11
sasl的modules: mit或heimdal

2)安裝mit庫
root@vmcln:/# apt-get install libsasl2-modules-gssapi-mit

或者下載debian 9 libsasl2-modules-gssapi-heimdal軟件包安裝到debian 11

3)客戶機配置
在客戶機vmcln(192.168.1.20)上是按#12處連接LDAP服務器192.168.1.11

為了匹配ldap應用服務ldap/vmkdc主體,/etc/hosts要增加一行如下:
192.168.1.11 vmkdc

linlin@vmcln:~$ cat /etc/resolv.conf
domain ctp.net
search ctp.net
nameserver 192.168.1.11
linlin@vmcln:~$
顯示指定了DNS服務器192.168.1.11

linlin@vmcln:~$ cat /etc/krb5.conf
[libdefaults]
default_realm = CTP.NET
linlin@vmcln:~$
/etc/krb5.conf僅配置default_realm 這個就可,KDC地址可通過DNS的SRV(服務)資源記錄獲得

4)執行票據是內存類型的命令
在命令之前要設環境變量,完整命令如下:
linlin@vmcln:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 56
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...
已成功

5)執行票據是文件類型的命令
linlin@vmcln:~$ ls /tmp
(空)
linlin@vmcln:~$

無需設環境變量,命令生成票據和SASL/GSSAPI默認都是/tmp/krb5cc_1000
linlin@vmcln:~$ ./testldapkrb_f
begin get init creds password
get init creds password OK
Successfully store creds 生成了票據
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 56
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...
已成功
linlin@vmcln:~$ ls /tmp
krb5cc_1000

可見在/tmp生成了票據krb5cc_1000文件

再用ldap工具測試
linlin@vmcln:~$ ldapwhoami -Y GSSAPI -h 192.168.1.11
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 56
SASL data security layer installed.
dn:uid=krblinlin,cn=gssapi,cn=auth
linlin@vmcln:~$
可見ldapwhoami用到上面程序生成的票據krb5cc_1000已成功

加-d調試
linlin@vmcln:~$ ldapwhoami -Y GSSAPI -h 192.168.1.11 -d -1
ldap_create
ldap_url_parse_ext(ldap://192.168.1.11)
ldap_sasl_interactive_bind: user selected: GSSAPI
ldap_int_sasl_bind: GSSAPI
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP 192.168.1.11:389
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 192.168.1.11:389
ldap_pvt_connect: fd: 3 tm: -1 async: 0
attempting to connect:
connect success
ldap_int_sasl_open: host=vmkdc 注意此處主機名,應該是反向解析192.168.1.11出vmkdc
SASL/GSSAPI authentication started
ldap_sasl_bind
ldap_send_initial_request
ldap_send_server_request
ber_scanf fmt ({it) ber:
...

查看vmkdc的kdc log
TGS-REQ krblinlin@CTP.NET from IPv4:192.168.1.20 for ldap/vmkdc@CTP.NET [canonicalize]
注意日志出現的'ldap/vmkdc@CTP.NET',應該是客戶端通過/etc/hosts反向解析ldap服務器(192.168.1.11,本實驗是krb5和ldap在同一臺機器vmkdc上)拼接出ldap/vmkdc@CTP.NET,并與ldap的應用服務主體(ldap/vmkdc@CTP.NET)一致

四.跟蹤調試
上面是已先給出正常運行的結論,是我逐步調試后的結果.實際調試的過程是很凌亂,下面整理總結第三章節(SASL/GSSAPI + krb5)調試過程

1.debian 10版本以上(新版)libsasl2-modules-gssapi-heimdal的BUG
1)新版libsasl2-modules-gssapi-heimdal
測試內存票據
linlin@vmcln:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Miscellaneous failure (see text) (Did not find a plugin for ccache_ops)
內存票據失敗,根據所提示的'Did not find a plugin for ccache_ops'查看源碼、搜索網上資料,找不到ccache_ops問題所在

測試文件票據
linlin@vmcln:~$ ls /tmp
(空)
linlin@vmcln:~$ ./testldapkrb_f
...
Successfully store creds
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 56
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...
文件票據正常

說明新版libsasl2-modules-gssapi-heimdal對內存票據有問題,不是生成的內存票據有問題,而是讀取內存票據的功能有BUG

2)用新版libsasl2-modules-gssapi-mit或者debian 9(舊版)libsasl2-modules-gssapi-heimdal代替新版libsasl2-modules-gssapi-heimdal,讀取內存票據已正常
root@vmcln:/home/linlin#
linlin@vmcln:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 256
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...

2.環境變量
1)不設環境變量
1.1)/etc/krb5.conf缺省的default_ccache_name
linlin@vmcln:~$ ./testldapkrb_m
...
Successfully store creds 到此步是通過krb5密碼認證成功的,并已生成了票據在內存
SASL/GSSAPI authentication started 開始LDAP/SASL/GSSAPI認證,在此失敗,提示找不到票據
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Miscellaneous failure (see text) (get-principal lstat(/tmp/krb5cc_1000))
根據錯誤提示,無環境變量,SASL/GSSAPI 默認是/tmp/krb5cc_1000

1.2)/etc/krb5.conf添加一行 default_ccache_name = KEYRING:persistent:%{uid}
{uid}表示登錄用戶的uid號,如當前用戶linlin的uid為1000

linlin@vmcln:~$ ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No Kerberos credentials available (default cache: KEYRING:persistent:1000))
從錯誤提示已說明是按krb5.conf的配置KEYRING:persistent:1000作SASL/GSSAPI缺省值,也說明無配置default_ccache_name,krb5.conf的缺省是FILE:/tmp/krb5cc_1000

2)運行之前設環境變量
linlin@vmcln:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 256
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...
已成功

也可在程序源碼里開頭設置環境變量,這樣執行命令就不需輸入環境變量
int ret = setenv("KRB5CCNAME", "MEMORY:dhcp_ld_krb5_cc", 1);

我沒去研究/etc/krb5.conf里能否配置default_ccache_name為進程內存票據以便不需設環境變量,即使能也不妥,因為其它的krb5程序會用到/etc/krb5.conf,
況且通常的krb5程序可以不需自己生成票據,只要有別的程序(如kinit)提供生成票據即可.如果default_ccache_name為進程內存票據,那豈不是其它的krb5程序必須自己生成票據到內存

3)小結:
SASL/GSSAPI應該是優先讀取環境變量KRB5CCNAME,然后才是/etc/krb5.conf

3.客戶端無配置/etc/krb5.conf
linlin@vmcln:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds 到此步是通過krb5密碼認證成功的,并已生成了票據
SASL/GSSAPI authentication started 開始LDAP/SASL/GSSAPI認證,在此失敗,提示找不到 realm
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Configuration file does not specify default realm)
linlin@vmcln:~$

LDAP/SASL/GSSAPI API能否在程序里指定realm,我沒去探究,在此就按提示配置/etc/krb5.conf解決

4.關于ldap/vmkdc@CTP.NET還是ldap/vmkdc.ctp.net@CTP.NET的匹配問題
本文實驗環境krb5+ldap+dns在同一臺機器vmkdc上

1)在客戶機vmcln(192.168.1.20)上測試

1.1)查看配置

linlin@vmcln:~$cat /etc/resolv.conf
domain ctp.net
search ctp.net
nameserver 192.168.1.11
linlin@vmcln:~$ hostname -d
ctp.net

或者

linlin@vmcln:~$cat /etc/resolv.conf
nameserver 192.168.1.11
linlin@vmcln:~$ hostname -d
hostname: Temporary failure in name resolution
linlin@vmcln:~$cat /etc/hosts
127.0.0.1      localhost
linlin@vmcln:~$

即/etc/hosts不再添加一行 192.168.1.11 vmkdc 解析主機,而是完全由dns解析,DNS服務器正向解析vmkdc、vmkdc.ctp.net為192.168.1.11,反向解析192.168.1.11為vmkdc.ctp.net

1.2)測試
linlin@vmcln:~$ ./testldapkrb_f
...
Successfully store creds
SASL/GSSAPI authentication started
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Server not found in Kerberos database)
失敗

linlin@vmcln:~$ ldapwhoami -Y GSSAPI -h 192.168.1.11
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Server not found in Kerberos database)
linlin@vmcln:~$
失敗

查看kdc log
2019-12-16T08:17:08 Got TGS FAST request
2019-12-16T08:17:08 TGS-REQ krblinlin@CTP.NET from IPv4:192.168.1.20 for ldap/vmkdc.ctp.net@CTP.NET [canonicalize]
2019-12-16T08:17:08 Searching referral for vmkdc.ctp.net
2019-12-16T08:17:08 Server not found in database: ldap/vmkdc.ctp.net@CTP.NET: no such entry found in hdb 找不到主體
2019-12-16T08:17:08 Failed building TGS-REP to IPv4:192.168.1.20
注意日志出現的是'ldap/vmkdc.ctp.net@CTP.NET',應該是在客戶機通過DNS服務器反向解析192.168.1.11出vmkdc.ctp.net,并拼接出ldap/vmkdc.ctp.net@CTP.NET,但在KDC并沒有該主體

1.3)往vmkdc添加ldap/vmkdc.ctp.net主體再測試
到服務器
root@vmkdc:~# kadmin -l
新增
kadmin> add -r ldap/vmkdc.ctp.net

導出到krb5.keytab
kadmin> ext -k /etc/ldap/krb5.keytab ldap/vmkdc.ctp.net

應該是追加而不是覆蓋,查看可見包含了ldap/vmkdc@CTP.NET和ldap/vmkdc.ctp.net@CTP.NET

root@vmkdc:~# ktutil -k /etc/ldap/krb5.keytab list
/etc/ldap/krb5.keytab:

Vno  Type                                    Principal                                 Aliases
  1  aes256-cts-hmac-sha1-96  ldap/vmkdc@CTP.NET          
  1  des3-cbc-sha1                    ldap/vmkdc@CTP.NET          
  1  arcfour-hmac-md5               ldap/vmkdc@CTP.NET          
  1  aes256-cts-hmac-sha1-96  ldap/vmkdc.ctp.net@CTP.NET  
  1  des3-cbc-sha1                    ldap/vmkdc.ctp.net@CTP.NET  
  1  arcfour-hmac-md5              ldap/vmkdc.ctp.net@CTP.NET  
root@vmkdc:~# 

回到客戶機
linlin@vmcln:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
Error: Invalid credentials
Additional info: SASL(-13): authentication failure: GSSAPI Failure: gss_accept_sec_context
linlin@vmcln:~$
krb5.keytab里雖有ldap/vmkdc.ctp.net@CTP.NET,但仍失敗

查看kdc log
2019-12-17T01:52:16 TGS-REQ krblinlin@CTP.NET from IPv4:192.168.1.20 for ldap/vmkdc.ctp.net@CTP.NET [canonicalize]
2019-12-17T01:52:16 TGS-REQ authtime: 2019-12-17T01:52:16 starttime: 2019-12-17T01:52:16 endtime: 2019-12-18T01:52:16 renew till: unset
2019-12-17T01:52:16 sending 639 bytes to IPv4:192.168.1.20
雖然在KDC已找到了ldap/vmkdc.ctp.net@CTP.NET,但可能是ldap應用服務是使用ldap/vmkdc@CTP.NET主體,兩者不一致導致失敗

2)在服務器vmkdc(192.168.1.11)本機上測試
/etc/hosts的內容
127.0.0.1 localhost

2.1)代碼#12處為連接到地址192.168.1.11
linlin@vmkdc:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m
...
Successfully store creds
SASL/GSSAPI authentication started
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Server not found in Kerberos database)
linlin@vmkdc:~$
失敗

查看kdc log
2019-12-17T00:46:30 TGS-REQ krblinlin@CTP.NET from IPv4:127.0.0.1 for ldap/localhost@CTP.NET
2019-12-17T00:46:30 Server not found in database: ldap/localhost@CTP.NET: no such entry found in hdb
注意日志出現的'ldap/localhost@CTP.NET',在KDC不存在

2.2)代碼#12處改為 ldap_initialize(&ld,"ldap://127.0.0.1/"),即連接本地服務器
重新編譯為testldapkrb_m_local

當/etc/resolv.conf為空
或設nameserver 127.0.0.1
或設nameserver 192.168.2.3 不同KDC服務器網段隨便不存在的地址

linlin@vmkdc:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m_local
...
Successfully store creds
SASL/GSSAPI authentication started
SASL username: krblinlin@CTP.NET
SASL SSF: 56
SASL data security layer installed.
Success!
dn: ou=dns,dc=ctp,dc=net
attribute = objectClass
attribute = ou
...
已成功

查看kdc log
2019-12-17T00:35:17 TGS-REQ krblinlin@CTP.NET from IPv4:127.0.0.1 for ldap/vmkdc@CTP.NET [canonicalize]
2019-12-17T00:35:17 TGS-REQ authtime: 2019-12-17T00:35:17 starttime: 2019-12-17T00:35:17 endtime: 2019-12-18T00:35:17 renew till: unset
2019-12-17T00:35:17 sending 623 bytes to IPv4:127.0.0.1
注意日志已是'ldap/vmkdc@CTP.NET'

將resolv.conf改為vmkdc同網段但不存在的地址
nameserver 192.168.1.55
再次運行./testldapkrb_m_local也成功,但很慢很慢

為何連接本地127.0.0.1時SASL/GSSAPI卻能拼接出正確的ldap/vmkdc ?
查看主機名
linlin@vmkdc:~$ hostname
vmkdc
linlin@vmkdc:~$
是不是連接本地127.0.0.1時SASL/GSSAPI根據hostname結果?

臨時改主機名
linlin@vmkdc:~$ su
root@vmkdc:/home/linlin# hostname vmabc.efg
root@vmkdc:/home/linlin# exit

查看主機名結果為vmabc.efg
linlin@vmkdc:~$ hostname
vmabc.efg
linlin@vmkdc:~$ KRB5CCNAME="MEMORY:dhcp_ld_krb5_cc" ./testldapkrb_m_local
...
Successfully store creds
SASL/GSSAPI authentication started
Error: Local error
Additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Server not found in Kerberos database)
linlin@vmkdc:~$
失敗

查看kdc log
2019-12-17T01:34:59 TGS-REQ krblinlin@CTP.NET from IPv4:127.0.0.1 for ldap/vmabc.efg@CTP.NET [canonicalize]
注意日志出現的'ldap/vmabc.efg@CTP.NET',確實根據hostname結果(而非主機名稱解析dns或/etc/hosts)

五.SASL/GSSAPI客戶程序總結:
1.對于讀取票據位置,環境變量KRB5CCNAME優先,然后才按/etc/krb5.conf
2.
連接本地127.0.0.1時,SASL/GSSAPI根據hostname結果
連接遠程地址192.168.1.11時,SASL/GSSAPI根據dns或/etc/hosts反向解析出名稱拼接出ldap/xxx.yyy,或者解析不到就拼接出ldap/localhost

3.客戶機拼接出的app/xxx.yyy和應用服務器的app/xxx.yyy要匹配一致

4.在規劃域、主機名時,盡可能服務器、客戶機、應用服務主體、DNS解析都設為全限定名,這樣可省卻不可預知的陷阱.
即本文最好設定服務器全限定名vmkdc.ctp.net,應用服務主體ldap/vmkdc.ctp.net@CTP.NET,這樣客戶機/etc/hosts就不需添加192.168.1.11 vmkdc一行

六.后記
本人水平有限,文中難免有錯漏,更多的/etc/krb5.conf的參數配置,請參考有關MIT的文檔.
我在MIT文檔查閱到
[libdefaults]
rdns = false

will disable reverse DNS lookup on clients. The default setting is “true”.

不知設 rdns = false 禁用反向解析是不是可以解決客戶機和應用服務器主體不匹配問題?留待各位讀者探索

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

山阳县| 海晏县| 南漳县| 五常市| 萝北县| 奈曼旗| 拉萨市| 阜康市| 化州市| 交城县| 易门县| 东乡县| 安塞县| 齐齐哈尔市| 信宜市| 三都| 望都县| 图片| 平谷区| 舞钢市| 仁化县| 贵港市| 安岳县| 潞西市| 祥云县| 绿春县| 蓝山县| 洛宁县| 密山市| 达尔| 隆安县| 罗山县| 嘉兴市| 房产| 汶川县| 依兰县| 奉化市| 志丹县| 望城县| 综艺| 江西省|