Kerberos 5 and NAT

Douglas E. Engert deengert at anl.gov
Wed Jun 19 16:34:30 EDT 2002


Steven McElwee wrote:
> 
> Hi,
>         We are running a firewall that is using one set of ip addresses
> for our system internally and another set is presented externally, i.e.,
> NAT. How can we teach a given system to incoporate its external ip address
> (note- not that assigned to its ethernet interface) in its kerberos TGT
> ticket file? What are our options and what are the strengths and
> weaknesses.

One way is to not use addresses at all. See the kinit -A

Another way is to add in the addresess as needed. See the attached 
two patches to 1.2.3 for src/lib/krb5/os/localaddr.c and 
src/lib/gssapi/krb5/init_sec_context.c 

Its upto the user to determin the external addres of the NAT box,
and set the KRB5NATADDR



*** ,localaddr.c        Wed Jan  9 16:27:58 2002
--- localaddr.c Fri Jan 11 15:42:51 2002
***************
*** 321,326 ****
--- 321,341 ----
        est_if_count = ifconfsize / est_ifreq_size;
      }
  #endif
+ /*
+  * Solaris and HPUX have SIOCGIFNUM to return size of array
+  * of ifconfs needed for the SIOCGIFCONF
+  * the default of 8 is not enought on some web servers
+  */
+ #ifdef SIOCGIFNUM
+     {
+         int ifnum;
+         code = ioctl (s, SIOCGIFNUM, &ifnum);
+         if (!code) {
+             est_if_count = ifnum;
+         }
+     }
+ #endif
+ 
      if (current_buf_size == 0) {
        current_buf_size = est_ifreq_size * est_if_count;
      }
***************
*** 585,590 ****
--- 600,628 ----
  
      for (count = 0; hostrec->h_addr_list[count]; count++);
  
+ /*
+  * DEE add in any extra addresses as defined by the KRB5NATADDR
+  * This is usefull for NAT machines.
+  * And allows the user to determine ar run time the addr.
+  * Assume IP only, and n.n.n.n
+  */
+    {
+      char * exenv;
+      int i;
+ 
+      exenv = getenv("KRB5NATADDR");
+      while (exenv && *exenv) {
+        for (i=0;i<4;i++) {
+          while (*exenv >= '0' && *exenv <='9') {
+             exenv++;
+          }
+          if (*exenv)
+             exenv++;
+        }
+        count++;
+      }
+    }
+ /* DEE */
  
      paddr = (krb5_address **)malloc(sizeof(krb5_address *) * (count+1));
      if (!paddr) {
***************
*** 594,599 ****
--- 632,639 ----
  
      memset(paddr, 0, sizeof(krb5_address *) * (count+1));
  
+       for (count = 0; hostrec->h_addr_list[count]; count++);
+ 
      for (i = 0; i < count; i++)
      {
          paddr[i] = (krb5_address *)malloc(sizeof(krb5_address));
***************
*** 614,619 ****
--- 654,706 ----
                 hostrec->h_addr_list[i],
                 paddr[i]->length);
      }
+ /*
+  * DEE add in any extra addresses as defined by the KRB5NATADDR
+  * This is usefull for NAT machines.
+  * And allows the user to determine ar run time the addr.
+  * Assume IP only, and n.n.n.n
+  */
+    {
+       krb5_address *address;
+       char * exenv;
+       unsigned char * ucp;
+       int i;
+       int n;
+       exenv = getenv("KRB5NATADDR");
+       while (exenv && *exenv) {
+         address = (krb5_address *) malloc (sizeof(krb5_address));
+         if (address) {
+           address->magic = KV5M_ADDRESS;
+           address->addrtype = ADDRTYPE_INET;
+           address->length = sizeof(struct in_addr);
+           address->contents = (unsigned char *)malloc(address->length);
+           if (!address->contents) {
+               krb5_xfree(address);
+               address = 0;
+           } else {
+             ucp = address->contents;
+             for (i=0;i<4;i++) {
+               n = 0;
+               while (*exenv >= '0' && *exenv <='9') {
+                 n = n*10 + *exenv -'0';
+                 exenv++;
+               }
+               if (*exenv)
+                 exenv++;
+               *ucp = n;
+                         /*fprintf(stderr,"addr=%d",n);*/
+               ucp++;
+             }
+                       /*fprintf(stderr,"\n");*/
+           }
+         }
+         if (address)
+           paddr[count++] = address;
+         address = 0;
+       }
+         /*fprintf(stderr,"count=%d\n",count);*/
+     }
+ /* DEE */
  
   cleanup:
      if (err) {


*** ,init_sec_context.c Wed Jan  9 16:27:43 2002
--- init_sec_context.c  Fri Jan 11 15:14:28 2002
***************
*** 182,189 ****
--- 370,418 ----
   
      /* compute the hash of the channel bindings */
  
+ #ifdef _WIN32
+       /*
+        * Many times we are behind a firewall which is doing NAT
+        * such as at home on a PC. 
+        * If the KRB5NATADDR is set, and our initiator addr starts
+        * with 198, and the acceptor address does not, i.e. its 
+        * outside the firewall, we will then replace the initator 
+        * address with the KRB5NATADDR.
+        */
+       if (chan_bindings !=  GSS_C_NO_CHANNEL_BINDINGS 
+               && chan_bindings->initiator_addrtype == GSS_C_AF_INET 
+               && chan_bindings->acceptor_addrtype == GSS_C_AF_INET 
+               && chan_bindings->initiator_address.length == 4 
+               && chan_bindings->acceptor_address.length == 4
+               && *((unsigned char *)chan_bindings->initiator_address.value) == 192
+               && *(((unsigned char *)chan_bindings->initiator_address.value)+1) == 168
+               && *((unsigned char *)chan_bindings->acceptor_address.value) != 192
+               && *(((unsigned char *)chan_bindings->acceptor_address.value)+1) != 168) {
+               char * ncp; 
+               int i,n;
+               if (ncp = getenv("KRB5NATADDR")) {
+                       for (i=0; i<4; i++) {
+                               n = 0;
+                               while (*ncp >= '0' && *ncp <='9') {
+                                       n = n*10 + *ncp -'0';
+                                       ncp++;
+                               }
+                               if (*ncp) ncp++;
+                               nataddr[i] = n;
+                       }
+                       saved_addr = chan_bindings->initiator_address.value;
+                       chan_bindings->initiator_address.value = nataddr;
+               }
+       }
+ #endif
+ 
      if ((code = kg_checksum_channel_bindings(context, chan_bindings, &md5, 0)))
          return(code);
+ #ifdef _WIN32
+               if (saved_addr) {
+                       chan_bindings->initiator_address.value = saved_addr;
+               }
+ #endif
  
      krb5_auth_con_set_req_cksumtype(context, ctx->auth_context,
                                    CKSUMTYPE_KG_CB);



>         Please send a response to steven at duke.edu and tmanino at duke.edu
> as my news reader is very, very poorly configured.
> 
> thanks in advance,
> Steven McElwee, Duke University
> 
> ________________________________________________
> Kerberos mailing list           Kerberos at mit.edu
> http://mailman.mit.edu/mailman/listinfo/kerberos

-- 

 Douglas E. Engert  <DEEngert at anl.gov>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439 
 (630) 252-5444



More information about the Kerberos mailing list