Security: Kerberos and Ranger

A Hadoop cluster without Kerberos believes any user name a client claims. This lesson shows that on our lab, then builds a real Kerberos KDC and a secured NameNode, logs in with tickets, reads what the KDC recorded and adds an HDFS ACL. Apache Ranger, encryption and audit complete the picture of how companies protect payroll, patient and payment data.

Module 12 · Multiple clusters and operations⏱ 30 minIntermediateReal KDC + secured NameNodeArchitecture diagram + 2 animationsRuns in your browser (Python)8 practice problems
1 The story

One environment variable, and the folder was gone

The canteen cluster now holds payroll files for the staff. Riya, testing permissions, is correctly refused: Permission denied: user=riya. Then Kabir types one extra word before the same command, HADOOP_USER_NAME=hadoop, and the folder is listed, and then deleted. Nobody hacked anything. On a cluster without Kerberos, Hadoop simply believes whatever user name the client says it is.

Without Kerberos (simple auth) client“I am hadoop” NameNode“OK, hadoop” Deleted /secure_demo the name is a claim, never checked With Kerberos KDC clientshows a ticket NameNodechecks it no ticket → “Client cannot authenticate” Both results are from our lab: a normal cluster, then a NameNode secured with a real MIT Kerberos KDC. myphatshala.in
Riya

Sir, so the permissions are fake?

Arjun Sir

The permissions are real; the identity is not. HDFS checks riya against the folder correctly. It just has no way to know you really are Riya. That is authentication, and in Hadoop it is done by Kerberos.

Kabir

And once we know who someone is, who decides what they may read in every table and folder, across HDFS and Hive?

Arjun Sir

That is authorization: HDFS permissions and ACLs at the simplest level, and Apache Ranger for central policies with audit. Today we build a real Kerberos KDC and a secured NameNode, try to cheat it, read the KDC's log, and add an ACL. Ranger we study on paper, because our laptop lab did not run it.

2 Definition

Hadoop security: Kerberos and Ranger

Formal definition (write this in exams)

Hadoop security rests on four pillars: authentication (proving identity), authorization (deciding what an identity may do), audit (recording who did what) and data protection (encryption on the wire and at rest). By default Hadoop uses simple authentication, in which the client's claimed user name is trusted. In secure mode (hadoop.security.authentication=kerberos) every user and service proves its identity to a Kerberos Key Distribution Center (KDC): a principal obtains a ticket-granting ticket (TGT) from the Authentication Service with a password or a keytab, then obtains service tickets from the Ticket-Granting Service for each Hadoop service, such as nn/host@REALM; jobs then use Hadoop delegation tokens. Apache Ranger provides centralized, fine-grained authorization: administrators define resource-based or tag-based policies in Ranger Admin, plugins inside services such as the NameNode, HiveServer2, HBase and YARN enforce them locally, and every access decision is written to an audit store.

In simple words

Kerberos is the ID card: no card, no entry, and you cannot borrow someone else's name. Ranger is the rule book and the CCTV: one place says who may open which door, every building follows it, and every opening is recorded.

Words you'll meet in this lesson

PrincipalA Kerberos identity: riya@LAB.MYPHATSHALA or nn/nn-secure@LAB.MYPHATSHALA.
KDCKey Distribution Center: the Authentication Service plus the Ticket-Granting Service.
TGTTicket-granting ticket: proof you logged in, used to ask for service tickets.
Service ticketA ticket for one service, e.g. the NameNode nn/nn-secure.
KeytabA file holding a principal's keys, so services log in without a password.
auth_to_localRules that map a principal to a short Hadoop user name.
Delegation tokenA Hadoop token a job carries, so tasks need no Kerberos ticket.
Ranger policy“Who may do what on which resource”, enforced by a plugin and audited.

From our lab (Hadoop 3.5.0, MIT Kerberos from Ubuntu 24.04)

Unsecuredriya: Permission denied … inode="/secure_demo":hadoop:supergroup:drwx------; with HADOOP_USER_NAME=hadoop: listed, then Deleted /secure_demo
Secured, no ticketAccessControlException · Client cannot authenticate via:[TOKEN, KERBEROS]; HADOOP_USER_NAME=nn gives the same
Secured, riya's ticketklist: TGT krbtgt/LAB.MYPHATSHALA for 10 hours; her file is owned by riya; /payroll denied, also when she claims to be nn
KDC log1 AS_REQ riya@… for krbtgt/…, then 4 TGS_REQ riya@… for nn/nn-secure@…; wrong password: kinit: Password incorrect
HDFS ACLuser:kabir:r-x on /finance: kabir sees 1 file, riya is denied; ls -d shows drwxr-x---+
Not runApache Ranger, secure DataNodes, KMS encryption zones: explained here, not installed in our lab

Architecture at a glance

A secured cluster as most companies run it. Green borders are what our lab really ran; dashed grey boxes are explained but were not installed.

People / jobsriya, kabir, ETL AD / LDAPusers, groups KDCAS → TGT · TGS → ticketsran in our lab NameNodekeytab nn/nn-secureHDFS perms + ACLs (ran)Ranger plugin (not run) HiveServer2Ranger plugin: masking, rows Ranger Admin + policy DBpolicies · usersync from ADtags from Atlas Audit storeSolr / HDFS: who, what, allowed? KMSkeys for encryption zones ① kinit ② ticket ③ policies ④ audit Solid green border = ran in our lab · dashed = explained only · ① login ② ticket to the service ③ policies pulled by plugins ④ every decision audited myphatshala.in

Security at three levels

Pick your level. New to this? Start at Beginner and climb.

Beginner The office building

  • Authentication is the ID card at the gate. Without Kerberos, the guard asks “what's your name?” and believes the answer: that is what HADOOP_USER_NAME exploited.
  • Authorization is which rooms your card opens: HDFS permissions, ACLs and Ranger policies.
  • Audit is the visitor register and CCTV. Encryption is locking the files themselves, so a stolen disk is useless.

Intermediate How a Kerberos login works in Hadoop

  • kinit riya sends an AS_REQ; the KDC returns a TGT encrypted with a key derived from riya's password. Only the right password can open it, so the password never crosses the network. A wrong one gives Password incorrect.
  • The first hdfs dfs command uses the TGT to send a TGS_REQ for nn/nn-secure. Our KDC log shows 4 of them for riya's commands; Java keeps those service tickets in memory, which is why klist showed only the TGT.
  • The NameNode decrypts the ticket with its own key from the keytab, learns “this is riya@LAB.MYPHATSHALA”, maps it to the short name riya (auth_to_local) and then checks permissions as before.
  • A MapReduce or Spark job obtains delegation tokens at submission and ships them to its containers, so thousands of tasks don't each hit the KDC.

Advanced Running it in production

  • Every daemon gets its own principal and keytab (nn/host, dn/host, rm/host, nm/host, HTTP/host for SPNEGO web UIs); keytabs are root-only files.
  • Secure DataNodes need privileged ports or SASL data-transfer protection with HTTPS; that is why our secure lab ran only a NameNode and created empty files.
  • Kerberos needs DNS (forward and reverse) and clocks within 5 minutes of each other; most “GSS initiate failed” incidents are clock skew, DNS or an expired keytab (wrong KVNO).
  • Companies usually use Active Directory as the KDC, run Ranger for policies and audit, encrypt RPC (hadoop.rpc.protection=privacy) and data transfer, and use HDFS encryption zones with a KMS for sensitive data. Apache Knox can give a single HTTPS entry point.

Exam tip: For “Explain Kerberos authentication in Hadoop”, give the three exchanges (AS: TGT; TGS: service ticket; client to service: ticket), name the keytab and the principal format service/host@REALM, and say why simple authentication is unsafe (the client's user name is trusted).

3 Types and ways to use it

The layers of Hadoop security

LayerQuestionHadoop toolIn our lab?
AuthenticationWho are you, really?Kerberos (MIT or Active Directory), delegation tokensYes: KDC + secured NameNode
Authorization (basic)May this user touch this file?HDFS permissions, POSIX-style ACLs, YARN queue ACLsYes: ACL on /finance
Authorization (central)One policy for HDFS, Hive, HBase, Kafka…Apache Ranger (resource and tag policies, masking, row filters)No (concepts)
AuditWho did what, when, allowed or denied?Ranger audit, HDFS audit log (hdfs-audit.log)KDC log only
Encryption in transitCan someone sniff the network?RPC privacy, data transfer protection, TLS for web UIsNo
Encryption at restIs a stolen disk readable?HDFS transparent encryption zones + Hadoop KMSNo
PerimeterOne safe door from outsideApache Knox gateway, edge nodesNo

HDFS ACL or Ranger policy?

HDFS permissions + ACLs

Stored on each file or folder in the NameNode. Good for a few exceptions (“kabir may also read /finance”). Spread across thousands of paths, hard to review, HDFS only.

built in

Ranger resource policy

“Group finance-analysts: read on /finance/*, select on db finance”. Defined once in Ranger Admin, cached by plugins, audited centrally, works across HDFS, Hive, HBase, Kafka.

central

Ranger tag policy

Columns tagged PII in Apache Atlas are masked for everyone except approved groups, wherever the data is copied.

by classification

Ranger masking / row filter

Hive shows XXXX-XXXX-1234 instead of a card number, or only the rows of the analyst's own state.

Hive, Impala

Animated example: an intern and the salary table

A bank with Kerberos, Ranger and audit in place. The story is illustrative; the messages in the first two steps are the ones our lab printed.

Kerberos, Ranger and audit together 6 steps
Animated example intern KDC HiveServer2 Ranger audit 10:02 · HADOOP_USER_NAME=hr_admin beeline …Client cannot authenticate via:[TOKEN, KERBEROS] Claiming a name does nothing: no ticket, no entry. 10:03 · kinit intern1 → TGT for 10 hher own identity, proven by her own password 10:04 · SELECT * FROM hr.salariesHiveServer2 knows: this is intern1 (group: interns) Ranger plugin: no policy allows interns on hr.*Permission denied: user [intern1] does not have [select] audit: 10:04 intern1 select hr.salaries DENIEDpolicy id -, client 10.4.7.21, HiveServer2 Next day: masked view for internssalary shown as NULL, names visible: work continues myphatshala.in

Pick the lightest tool that works: owner/group permissions for most paths, an ACL for a rare exception, and Ranger once you have many users, several services, or auditors asking “who could read this column last March?”.

4 Step by step

From “anyone can be hadoop” to tickets and ACLs

Part 1 runs on the Module 8 lab. Part 2 uses three new containers (kerberos/docker-compose.yaml in “Run it on your PC”): an Ubuntu KDC, a Kerberos-secured NameNode and a client.

  1. Unsecured: claim to be the owner

    HADOOP_USER_NAME=riya   hdfs dfs -cat /secure_demo/salaries.csv
    HADOOP_USER_NAME=hadoop hdfs dfs -rm -r -skipTrash /secure_demo
    Permission denied: user=riya, access=EXECUTE, inode="/secure_demo":hadoop:supergroup:drwx------ Deleted /secure_demo
    With hadoop.security.authentication=simple the client simply sends a user name, taken from the OS or from HADOOP_USER_NAME. HDFS checks permissions against that name faithfully, which protects against mistakes, never against intent.
  2. Build a KDC and secure the NameNode

    kdb5_util create -s -r LAB.MYPHATSHALA
    kadmin.local -q "addprinc -randkey nn/nn-secure@LAB.MYPHATSHALA"
    kadmin.local -q "addprinc -pw riya123 riya@LAB.MYPHATSHALA"
    kadmin.local -q "ktadd -k /keytabs/nn.keytab nn/nn-secure@LAB.MYPHATSHALA HTTP/nn-secure@LAB.MYPHATSHALA"
    CORE-SITE.XML_hadoop.security.authentication=kerberos
    HDFS-SITE.XML_dfs.namenode.kerberos.principal=nn/nn-secure@LAB.MYPHATSHALA
    HDFS-SITE.XML_dfs.namenode.keytab.file=/keytabs/nn.keytab
    INFO UserGroupInformation - Login successful for user nn/nn-secure@LAB.MYPHATSHALA using keytab file nn.keytab INFO Server - IPC Server listener on 8020: starting
    Our first start failed for real: the image formats the NameNode when the container starts, before the KDC had written the keytab, giving KerberosAuthException: failure to login … Unable to obtain password from user. The fix was to wait until kinit -kt works, then format and start.
  3. No ticket, no entry

    hdfs dfs -ls /
    HADOOP_USER_NAME=nn hdfs dfs -ls /
    AccessControlException Client cannot authenticate via:[TOKEN, KERBEROS] Client cannot authenticate via:[TOKEN, KERBEROS]
    The client offered neither a Kerberos ticket nor a delegation token, so the NameNode refused the connection before any file was checked. The environment variable is ignored in secure mode.
  4. Log in as riya and look at the ticket

    kinit riya@LAB.MYPHATSHALA
    klist
    hdfs dfs -touchz /user/riya/notes.txt
    hdfs dfs -ls /user/riya
    Default principal: riya@LAB.MYPHATSHALA Valid starting Expires Service principal 10/22/2026 10:08:23 10/22/2026 20:08:23 krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA -rw-r--r-- riya /user/riya/notes.txt
    The TGT lasts 10 hours (ticket_lifetime = 10h in krb5.conf). Hadoop's Java client then asks the KDC for a service ticket for nn/nn-secure and keeps it in memory. We used touchz because the secure lab has no DataNode: secure DataNodes need privileged ports or SASL with HTTPS.
  5. Try the payroll folder, and try to pretend

    hdfs dfs -cat /payroll/salaries.csv
    HADOOP_USER_NAME=nn hdfs dfs -cat /payroll/salaries.csv
    kdestroy; kinit riya@LAB.MYPHATSHALA      # with a wrong password
    Permission denied: user=riya, access=EXECUTE, inode="/payroll":nn:supergroup:drwx------ Permission denied: user=riya, access=EXECUTE, inode="/payroll":nn:supergroup:drwx------ kinit: Password incorrect while getting initial credentials
    Now the user name comes from the ticket, so both attempts are riya. Note the owner of /payroll is nn: the short name of nn/nn-secure@LAB.MYPHATSHALA after the default auth_to_local rule.
  6. Read the KDC's log

    docker logs lab12k-kdc-1 | grep -E "AS_REQ|TGS_REQ"
    1 AS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA 4 TGS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for nn/nn-secure@LAB.MYPHATSHALA 1 AS_REQ 172.23.0.3: ISSUE: nn/nn-secure@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA 4 TGS_REQ 172.23.0.3: ISSUE: nn/nn-secure@LAB.MYPHATSHALA for nn/nn-secure@LAB.MYPHATSHALA
    Exactly the two exchanges from the definition: one AS request for a TGT, then TGS requests for the NameNode's service ticket (one per hdfs command, since each is a new JVM). The KDC never sees a password; it only encrypts with the key derived from it.
  7. Authorization beyond owner and group: an ACL

    hdfs dfs -chmod 750 /finance
    hdfs dfs -setfacl -m user:kabir:r-x /finance
    hdfs dfs -getfacl /finance
    user::rwx user:kabir:r-x group::r-x mask::r-x other::--- -- kabir (named in the ACL): 1 file visible -- riya (not in the ACL): Permission denied: user=riya drwxr-x---+ hadoop /finance
    The + after the permission bits means “has an ACL”. Ranger generalises this idea: policies by user or group, kept in one place, across services, with audit. (This step ran on the unsecured lab, so the names are only as trustworthy as step 1.)

Keytabs are as powerful as passwords that never expire. Keep them readable only by the service user, never in Git, and rotate them; a copied keytab lets anyone become that service.

5 See it happen

A Kerberos login, as the KDC saw it

Six steps from our secure lab: the client's terminal on the left, the KDC and NameNode on the right.

Tickets, not names 6 steps
What you see hadoop@client : ~ $ hdfs dfs -ls /AccessControlExceptionClient cannot authenticate via:[TOKEN, KERBEROS] $ HADOOP_USER_NAME=nn hdfs dfs -ls /Client cannot authenticate via:[TOKEN, KERBEROS] $ kinit riya@LAB.MYPHATSHALAPassword for riya@LAB…: ******$ klistkrbtgt/LAB.MYPHATSHALA 10 h $ hdfs dfs -touchz /user/riya/notes.txt$ hdfs dfs -ls /user/riya-rw-r--r-- riya notes.txt $ HADOOP_USER_NAME=nn hdfs dfs -cat /payroll/salaries.csvPermission denied: user=riya $ kinit riya (wrong password)kinit: Password incorrect whilegetting initial credentials myphatshala.in
Behind the screen client KDC NameNode SASL: no Kerberos ticket, no tokenconnection refused before any file check the variable is not part of the handshakesecure mode ignores HADOOP_USER_NAME AS_REQ: riya → krbtgtTGT encrypted with riya's password key 4 × TGS_REQ: riya → nn/nn-secureNameNode decrypts with its keytab: “riya” /payroll nn drwx------riya: EXECUTE deniedidentity from the ticket,permission check as always the KDC does reply, but the replyonly opens with the right password keyno password ever crossed the network myphatshala.in
6 Real-world use

Security at work

card numberXXXX-1234

1. Banking: masking card numbers

Analysts query transaction tables in Hive; a Ranger masking policy shows only the last four digits of card numbers to everyone outside the fraud team, and every query is audited.

Analyst query→Ranger mask policy→Masked result + audit
PII tag

2. Hospitals: tag-based policies on patient data

Columns such as patient name and diagnosis are tagged PII in Atlas; one Ranger tag policy protects them in every table and copy, so researchers get de-identified data.

Atlas tags→Ranger tag policy→De-identified views
ADKDC

3. Telecom: one login for thousands of employees

The corporate Active Directory acts as the KDC; employees' Windows logins give them Kerberos tickets, and leaving the company disables cluster access the same day.

Employee login→AD Kerberos→Cluster access
zone🔑 KMS

4. Government schemes: encryption zones for beneficiary data

Folders holding beneficiary records are HDFS encryption zones; files are encrypted with keys held by the KMS, so a disk taken out for repair reveals nothing.

Beneficiary files→Encryption zone + KMS→Encrypted blocks

5. E-commerce: audit trails for compliance reviews

Ranger audit records who read customer address tables; a monthly report flags unusual access, for example a service account suddenly reading data it never read before.

Audit store→Monthly review→Alerts

Simplified; organisations differ in tools and policies. India's Digital Personal Data Protection Act, 2023 adds legal duties for personal data; ask your legal team what applies, this lesson is not legal advice.

7 Run the code

Simulate a Kerberos login

A toy Kerberos with real ideas and fake cryptography: each principal has a secret key, tickets are “sealed” with the key of whoever must read them, and every ticket has an expiry time. Watch how riya gets into the NameNode and why an impostor cannot.

import hashlib
def key(secret):                                  # a "key" derived from a password or keytab
    return hashlib.sha256(secret.encode()).hexdigest()[:8]
def seal(k, data):  return {"sealed_with": k, "data": data}
def open_(k, box):
    if box["sealed_with"] != k:
        raise PermissionError("cannot decrypt: wrong key")
    return box["data"]

KDC = {"riya@LAB": key("riya123"), "krbtgt@LAB": key("kdc-secret"), "nn/nn-secure@LAB": key("from-keytab")}

def as_req(user, now):                           # 1. AS: password -> TGT
    tgt = seal(KDC["krbtgt@LAB"], {"user": user, "expires": now + 10})
    return seal(KDC[user], {"tgt": tgt})          # only the user's key opens the reply

def tgs_req(tgt, service, now):                   # 2. TGS: TGT -> service ticket
    t = open_(KDC["krbtgt@LAB"], tgt)
    if now > t["expires"]:
        raise PermissionError("TGT expired")
    return seal(KDC[service], {"user": t["user"], "expires": t["expires"]})

def namenode(ticket, claimed_name=None):          # 3. service: reads the user from the ticket
    t = open_(KDC["nn/nn-secure@LAB"], ticket)
    return f"NameNode sees user={t['user'].split('@')[0]} (claimed {claimed_name})"

reply = as_req("riya@LAB", now=0)
tgt = open_(key("riya123"), reply)["tgt"]         # riya types the right password
ticket = tgs_req(tgt, "nn/nn-secure@LAB", now=1)
print(namenode(ticket, claimed_name="nn"))
try:
    open_(key("wrongpass"), reply)
except PermissionError as e:
    print("wrong password:", e)
NameNode sees user=riya (claimed nn) wrong password: cannot decrypt: wrong key
  • return seal(KDC[user], {"tgt": tgt}) # only the user's key opens the replyThe KDC answers anyone, but the answer is sealed with the user's key. That is why a wrong password gave "Password incorrect" without the password crossing the network.
  • return seal(KDC[service], {"user": t["user"], "expires": t["expires"]})A service ticket is sealed with the service's key, which the NameNode has in its keytab.
  • t = open_(KDC["nn/nn-secure@LAB"], ticket)The NameNode takes the user from the ticket. The claimed name is ignored, as HADOOP_USER_NAME was in our lab.

Run it on your PC: a KDC, a secured NameNode and an ACL

Part 1 and Part 3 use the Module 8 lab. Part 2 needs the three containers in the kerberos folder: an Ubuntu KDC (it installs MIT Kerberos with apt the first time, so it needs internet), a NameNode with Kerberos switched on, and a client. Put the five files below in a folder called kerberos, with an empty keytabs subfolder, then run docker compose -p lab12k up -d, wait about two minutes and run bash kerberos_lab.sh. Our secure NameNode has no DataNodes, so the demo only creates empty files.

The three containers

# Lab 12.5: a Kerberos KDC, a Kerberos-secured NameNode, and a client machine.
services:
  kdc:
    image: ubuntu:24.04
    hostname: kdc
    command: ["bash", "/lab/kdc.sh"]
    volumes: [./:/lab:ro, ./keytabs:/keytabs]
  nn-secure:
    image: apache/hadoop:3.5.0
    hostname: nn-secure
    command: ["bash", "-c", "until kinit -kt /keytabs/nn.keytab nn/nn-secure@LAB.MYPHATSHALA 2>/dev/null; do sleep 3; done; kdestroy; [ -d /tmp/hadoop-hadoop/dfs/name/current ] || hdfs namenode -format -force -nonInteractive; hdfs namenode"]
    env_file: [./config]
    # no ENSURE_NAMENODE_DIR: the image would format before the keytab exists; we format after the KDC is up
    environment: { KRB5_CONFIG: /lab/krb5.conf }
    volumes: [./:/lab:ro, ./keytabs:/keytabs:ro, ./krb5.conf:/etc/krb5.conf:ro]
    depends_on: [kdc]
  client:
    image: apache/hadoop:3.5.0
    hostname: client
    command: ["sleep", "infinity"]
    env_file: [./config]
    volumes: [./krb5.conf:/etc/krb5.conf:ro, ./keytabs:/keytabs:ro]

# ---- krb5.conf (same folder) ----
# [libdefaults]
#   default_realm = LAB.MYPHATSHALA
#   dns_lookup_realm = false
#   dns_lookup_kdc = false
#   udp_preference_limit = 1
#   ticket_lifetime = 10h
#   forwardable = true
# [realms]
#   LAB.MYPHATSHALA = {
#     kdc = kdc
#     admin_server = kdc
#   }
# ---- config (same folder) ----
# CORE-SITE.XML_fs.defaultFS=hdfs://nn-secure:8020
# CORE-SITE.XML_hadoop.security.authentication=kerberos
# CORE-SITE.XML_hadoop.security.authorization=true
# HDFS-SITE.XML_dfs.namenode.rpc-address=nn-secure:8020
# HDFS-SITE.XML_dfs.namenode.kerberos.principal=nn/nn-secure@LAB.MYPHATSHALA
# HDFS-SITE.XML_dfs.namenode.keytab.file=/keytabs/nn.keytab
# HDFS-SITE.XML_dfs.web.authentication.kerberos.principal=HTTP/nn-secure@LAB.MYPHATSHALA
# HDFS-SITE.XML_dfs.web.authentication.kerberos.keytab=/keytabs/nn.keytab
# HDFS-SITE.XML_dfs.block.access.token.enable=true
# HDFS-SITE.XML_dfs.replication=1
$ docker compose -p lab12k up -d Container lab12k-nn-secure-1 Started $ docker logs lab12k-nn-secure-1 | grep -E "Login successful|listener on 8020" INFO UserGroupInformation:1143 - Login successful for user nn/nn-secure@LAB.MYPHATSHALA using keytab file nn.keytab. Keytab auto renewal enabled : false INFO Server:1618 - IPC Server listener on 8020: starting

Real lines (timestamps removed). The NameNode command waits until kinit with the keytab works, then formats and starts. Our first version let the image format at container start, before the keytab existed, and failed with "KerberosAuthException: failure to login … Unable to obtain password from user".

The KDC: realm, principals, keytab

# kdc.sh: a tiny MIT Kerberos KDC for the lab: realm LAB.MYPHATSHALA
set -e
apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq krb5-kdc krb5-admin-server > /dev/null
cp /lab/krb5.conf /etc/krb5.conf
mkdir -p /etc/krb5kdc /var/lib/krb5kdc
printf '[logging]\n kdc = STDERR\n[realms]\n LAB.MYPHATSHALA = {\n  database_name = /var/lib/krb5kdc/principal\n  acl_file = /etc/krb5kdc/kadm5.acl\n  key_stash_file = /etc/krb5kdc/stash\n }\n' > /etc/krb5kdc/kdc.conf
echo '*/admin@LAB.MYPHATSHALA *' > /etc/krb5kdc/kadm5.acl
kdb5_util create -s -r LAB.MYPHATSHALA -P masterkey123 > /dev/null
kadmin.local -q "addprinc -randkey nn/nn-secure@LAB.MYPHATSHALA" > /dev/null      # the NameNode service
kadmin.local -q "addprinc -randkey HTTP/nn-secure@LAB.MYPHATSHALA" > /dev/null    # its web UI (SPNEGO)
kadmin.local -q "addprinc -pw riya123 riya@LAB.MYPHATSHALA" > /dev/null           # two people
kadmin.local -q "addprinc -pw kabir123 kabir@LAB.MYPHATSHALA" > /dev/null
rm -f /keytabs/nn.keytab
kadmin.local -q "ktadd -k /keytabs/nn.keytab nn/nn-secure@LAB.MYPHATSHALA HTTP/nn-secure@LAB.MYPHATSHALA" > /dev/null
chmod 644 /keytabs/nn.keytab
kadmin.local -q "listprincs"
echo "KDC ready"
exec krb5kdc -n
HTTP/nn-secure@LAB.MYPHATSHALA K/M@LAB.MYPHATSHALA kabir@LAB.MYPHATSHALA kadmin/admin@LAB.MYPHATSHALA kadmin/changepw@LAB.MYPHATSHALA krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA nn/nn-secure@LAB.MYPHATSHALA riya@LAB.MYPHATSHALA KDC ready krb5kdc: starting...

Real output of docker logs lab12k-kdc-1. krbtgt is the KDC's own principal (it seals every TGT); K/M is the master key.

Unsecured vs Kerberos vs ACL

# kerberos_lab.sh: the same commands on an unsecured cluster and on a Kerberos-secured NameNode.
# Run on your PC: part 1 uses the Module 8 lab, part 2 the lab12k containers.
echo "######## 1. UNSECURED (Module 8 lab): Hadoop believes whatever user name you claim"
docker exec lab8-namenode-1 bash -c '
hdfs dfs -mkdir -p /secure_demo && hdfs dfs -chmod 700 /secure_demo && hdfs dfs -put -f /etc/hostname /secure_demo/salaries.csv
echo "-- as riya (not the owner):"
HADOOP_USER_NAME=riya hdfs dfs -cat /secure_demo/salaries.csv 2>&1 | grep -o "Permission denied.*" | cut -c1-120
echo "-- as riya, claiming to be the owner \"hadoop\":"
HADOOP_USER_NAME=hadoop hdfs dfs -ls /secure_demo 2>&1 | grep salaries | awk "{print \$1, \$3, \$8}"
echo "-- as anyone, claiming to be the owner, deleting it:"
HADOOP_USER_NAME=hadoop hdfs dfs -rm -r -skipTrash /secure_demo 2>&1 | grep -v INFO'
echo
echo "######## 2. KERBEROS (lab12k): identity comes from a ticket, not from a variable"
docker exec lab12k-client-1 bash -c 'quiet() { grep -vE "^\s|^Usage|^$|^Generic|^command|^-[a-z]+ <|WARN"; }

echo "-- no ticket:"
hdfs dfs -ls / 2>&1 | grep -oE "Client cannot authenticate via:\[[A-Z, ]+\]|AccessControlException|GSS initiate failed" | sort -u | head -2
echo "-- claiming a name does nothing now:"
HADOOP_USER_NAME=nn hdfs dfs -ls / 2>&1 | grep -oE "Client cannot authenticate via:\[[A-Z, ]+\]" | head -1
echo "-- the service admin logs in with its keytab and makes a home folder for riya:"
kinit -kt /keytabs/nn.keytab nn/nn-secure@LAB.MYPHATSHALA
hdfs dfs -mkdir -p /user/riya /payroll 2>&1 | quiet
hdfs dfs -chown riya /user/riya; hdfs dfs -chmod 700 /payroll
hdfs dfs -touchz /payroll/salaries.csv      # our secure lab has no DataNode, so we create empty files (metadata only)
kdestroy
echo "-- riya logs in with her password:"
echo riya123 | kinit riya@LAB.MYPHATSHALA > /dev/null
klist | sed -n "1,6p"
hdfs dfs -touchz /user/riya/notes.txt
hdfs dfs -ls /user/riya | grep notes | awk "{print \$1, \$3, \$8}"
echo "-- riya tries the payroll folder, and tries to pretend:"
hdfs dfs -cat /payroll/salaries.csv 2>&1 | grep -o "Permission denied.*" | cut -c1-110
HADOOP_USER_NAME=nn hdfs dfs -cat /payroll/salaries.csv 2>&1 | grep -o "Permission denied.*" | cut -c1-110
echo "-- the cache holds only the TGT; Java asks the KDC for the NameNode service ticket in memory"
klist | grep -E "krbtgt|nn/"
echo "-- wrong password:"
kdestroy; echo wrongpass | kinit riya@LAB.MYPHATSHALA 2>&1 | tail -1'
echo "-- the KDC log saw all of it:"
docker logs lab12k-kdc-1 2>&1 | grep -E "AS_REQ|TGS_REQ" | sed -E 's/^.*krb5kdc\[[0-9]+\]\(info\): //; s/ \([0-9]+ etypes \{[^}]*\}\)//; s/authtime [0-9]+, etypes \{[^}]*\}, //' | uniq -c | tail -8
echo
echo "######## 3. AUTHORIZATION beyond owner/group: an HDFS ACL (Module 8 lab; the idea Ranger extends)"
docker exec lab8-namenode-1 bash -c '
hdfs dfs -mkdir -p /finance && hdfs dfs -chmod 750 /finance && hdfs dfs -touchz /finance/q3.csv
hdfs dfs -setfacl -m user:kabir:r-x /finance
hdfs dfs -getfacl /finance
echo "-- kabir (named in the ACL): $(HADOOP_USER_NAME=kabir hdfs dfs -ls /finance 2>&1 | grep -c q3.csv) file visible"
echo "-- riya (not in the ACL): $(HADOOP_USER_NAME=riya hdfs dfs -ls /finance 2>&1 | grep -o "Permission denied: user=riya" )"
hdfs dfs -ls -d /finance | awk "{print \$1, \$3, \$8}"
hdfs dfs -rm -r -skipTrash /finance > /dev/null'

# Run on your PC:  bash kerberos_lab.sh
######## 1. UNSECURED (Module 8 lab): Hadoop believes whatever user name you claim -- as riya (not the owner): Permission denied: user=riya, access=EXECUTE, inode="/secure_demo":hadoop:supergroup:drwx------ -- as riya, claiming to be the owner "hadoop": -rw-r--r-- hadoop /secure_demo/salaries.csv -- as anyone, claiming to be the owner, deleting it: Deleted /secure_demo ######## 2. KERBEROS (lab12k): identity comes from a ticket, not from a variable -- no ticket: AccessControlException Client cannot authenticate via:[TOKEN, KERBEROS] -- claiming a name does nothing now: Client cannot authenticate via:[TOKEN, KERBEROS] -- the service admin logs in with its keytab and makes a home folder for riya: -- riya logs in with her password: Ticket cache: FILE:/tmp/krb5cc_1001 Default principal: riya@LAB.MYPHATSHALA Valid starting Expires Service principal 10/22/2026 10:08:23 10/22/2026 20:08:23 krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA -rw-r--r-- riya /user/riya/notes.txt -- riya tries the payroll folder, and tries to pretend: Permission denied: user=riya, access=EXECUTE, inode="/payroll":nn:supergroup:drwx------ Permission denied: user=riya, access=EXECUTE, inode="/payroll":nn:supergroup:drwx------ -- the cache holds only the TGT; Java asks the KDC for the NameNode service ticket in memory 10/22/2026 10:08:23 10/22/2026 20:08:23 krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA -- wrong password: kinit: Password incorrect while getting initial credentials -- the KDC log saw all of it: 1 AS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA 4 TGS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for nn/nn-secure@LAB.MYPHATSHALA 1 AS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA 1 AS_REQ 172.23.0.3: ISSUE: nn/nn-secure@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA 4 TGS_REQ 172.23.0.3: ISSUE: nn/nn-secure@LAB.MYPHATSHALA for nn/nn-secure@LAB.MYPHATSHALA 1 AS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA 4 TGS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for nn/nn-secure@LAB.MYPHATSHALA 1 AS_REQ 172.23.0.3: ISSUE: riya@LAB.MYPHATSHALA for krbtgt/LAB.MYPHATSHALA@LAB.MYPHATSHALA ######## 3. AUTHORIZATION beyond owner/group: an HDFS ACL (Module 8 lab; the idea Ranger extends) # file: /finance # owner: hadoop # group: supergroup user::rwx user:kabir:r-x group::r-x mask::r-x other::--- -- kabir (named in the ACL): 1 file visible -- riya (not in the ACL): Permission denied: user=riya drwxr-x---+ hadoop /finance

Real output. The KDC log section shows the last 8 groups of requests, so it includes earlier runs of the script. Ranger is not part of this lab.

8 Line by line

Which key opens which ticket

Follow riya's login with three keys: hers, the KDC's and the NameNode's. Each step can only be opened by one of them.

Worked examples: real problems, solved and traced in memory

Four security design problems from different organisations: naming, mapping, policies and long jobs.

Example 1BeginnerNaming · telecom

Name the principals for a new cluster

Problem statement

A telecom company adds a cluster with a NameNode on nn1.blr.telco.in, 2 workers (w1, w2, each a DataNode and a NodeManager) and a ResourceManager on rm1. Realm: TELCO.IN. List the service principals they need (ignore HTTP).

Input
nn1, rm1, w1, w2 · realm TELCO.IN
Expected output
6 principals
nn/nn1.blr.telco.in@TELCO.IN
rm/rm1.blr.telco.in@TELCO.IN
dn/w1.blr.telco.in@TELCO.IN
nm/w1.blr.telco.in@TELCO.IN
dn/w2.blr.telco.in@TELCO.IN
nm/w2.blr.telco.in@TELCO.IN

Approach

  1. One principal per service per host: service/host@REALM.
  2. Workers run two services each.
  3. Count them.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 2IntermediateMapping · university

Map principals to short names

Problem statement

A university's users log in as roll123@STUDENTS.UNI.AC.IN and staff as name@STAFF.UNI.AC.IN; the cluster realm is STAFF. HDFS home folders are /user/<short name>. Which short names do these principals get with “strip the realm for both realms, deny others”?

Input
3 principals · 2 trusted realms
Expected output
roll123@STUDENTS.UNI.AC.IN     -> roll123
meera@STAFF.UNI.AC.IN          -> meera
eve@EVIL.ORG                   -> nobody

Approach

  1. Split name and realm.
  2. Accept the two trusted realms, strip the realm.
  3. Everything else maps to nobody.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 3IntermediatePolicy design · hospital

ACLs or Ranger policies?

Problem statement

A hospital has 40 departments, each with a folder under /records, and 6 roles that need read access across several departments. Count the ACL entries needed if each role is added to each folder it needs (average 25 folders per role), versus Ranger policies written per role.

Input
6 roles · 25 folders each
Expected output
ACL entries to manage   : 150
Ranger policies to manage: 6 (each with a list of paths, audited centrally)

Approach

  1. ACL: one entry per role per folder.
  2. Ranger: one policy per role listing its folders.
  3. Compare what must be reviewed.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 4AdvancedLong jobs · bank

A 30-hour job and 10-hour tickets

Problem statement

A bank's year-end reconciliation runs 30 hours. Tickets last 10 hours and are renewable for 7 days. HDFS delegation tokens last 24 hours unless renewed (renew interval) and at most 7 days. Which credentials expire during the job, and what keeps it alive?

Input
job 30 h · TGT 10 h · token 24 h renew, max 7 d
Expected output
TGT expires during job: True - harmless after submission
delegation token renewed 1 time(s) by the RM; max life OK: True

Approach

  1. The client TGT is only needed at submission.
  2. Tasks use delegation tokens; the ResourceManager renews them.
  3. Check the hard 7-day maximum.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

9 Quiz and revision

Check yourself

Quick revision

Lesson 12.5 in one screen

  • Four pillars: authentication (Kerberos), authorization (permissions, ACLs, Ranger), audit, encryption (wire and at rest).
  • Simple auth trusts the client's user name: in our lab HADOOP_USER_NAME=hadoop deleted a 700 folder.
  • Kerberos: AS_REQ → TGT (kinit), TGS_REQ → service ticket (nn/host@REALM), service decrypts with its keytab.
  • Lab: no ticket → “Client cannot authenticate via:[TOKEN, KERBEROS]”; riya's ticket → files owned by riya; pretending does nothing.
  • auth_to_local maps principals to short names; jobs use delegation tokens, renewed by the RM.
  • ACL: hdfs dfs -setfacl -m user:kabir:r-x; Ranger: central resource/tag policies, masking, row filters, audit.
  • Production: AD as KDC, keytabs locked down, clocks synced (5 min skew), RPC privacy, encryption zones + KMS, Knox.

Interview and viva questions

Why is Kerberos needed in Hadoop?

Without it Hadoop uses simple authentication: the client's user name (from the OS or HADOOP_USER_NAME) is trusted, so anyone with network access can act as any user, including the HDFS superuser. Kerberos makes every user and service prove its identity with tickets from a KDC, so permissions, ACLs and Ranger policies apply to the real person.

How does Kerberos authentication work in Hadoop?

The user runs kinit and the KDC's Authentication Service returns a ticket-granting ticket sealed with a key derived from the password. The client then asks the Ticket-Granting Service for a service ticket for a Hadoop service such as nn/host@REALM, and presents it to that service, which decrypts it with the key in its keytab. Jobs then use Hadoop delegation tokens so tasks do not contact the KDC.

What is Apache Ranger?

A central authorization and audit framework for the Hadoop ecosystem. Administrators define policies in Ranger Admin (by user, group, resource or Atlas tag); plugins inside HDFS, Hive, HBase, YARN, Kafka and others download the policies, enforce them locally and send audit events to Solr or HDFS. Ranger also supports column masking and row filtering for Hive.

What is the difference between HDFS ACLs and Ranger?

ACLs are stored on each file or directory in the NameNode and only cover HDFS. Ranger policies are defined centrally, can cover many paths and services with one policy, support groups from LDAP/AD, tags, masking and row filters, and keep a searchable audit of every decision.

What is a keytab and why is it sensitive?

A keytab stores a principal's long-term keys so a service (or a scheduled job) can log in to Kerberos without typing a password. Anyone who can read it can act as that principal until the keys are changed, so keytabs must be readable only by the service user, kept out of source control and rotated.

Practice problems

Security exercises built on the real messages and settings from our lab.

P1Easy

Read a principal

Split nn/nn-secure@LAB.MYPHATSHALA into service, host and realm.

Input
one principal
Expected output
nn nn-secure LAB.MYPHATSHALA
Show solution and explanation
p = "nn/nn-secure@LAB.MYPHATSHALA"
name, realm = p.split("@"); service, host = name.split("/")
print(service, host, realm)
nn nn-secure LAB.MYPHATSHALA

How it works: nn (the NameNode service), host nn-secure, realm LAB.MYPHATSHALA.

P2Easy

Ticket expiry

riya's TGT was valid from 10:08:23 for 10 hours. When does it expire?

Input
10:08:23 + 10 h
Expected output
20:08:23
Show solution and explanation
from datetime import datetime, timedelta
print((datetime(2026, 10, 22, 10, 8, 23) + timedelta(hours=10)).time())
20:08:23

How it works: 20:08:23, exactly what klist showed.

P3Easy

Read the permission bits

/payroll is drwx------ owned by nn. Which of owner, group and others may enter it?

Input
drwx------
Expected output
owner can enter
group cannot enter
others cannot enter
Show solution and explanation
bits = "rwx------"
for who, part in zip(["owner", "group", "others"], [bits[0:3], bits[3:6], bits[6:9]]):
    print(who, "can enter" if part[2] == "x" else "cannot enter")
owner can enter group cannot enter others cannot enter

How it works: Only the owner nn; riya needed EXECUTE on the folder, hence access=EXECUTE in the error.

P4Medium

Effective ACL rights with a mask

The mask limits named users and groups. With user:kabir:rwx but mask::r-x, what can kabir do?

Input
rwx AND r-x
Expected output
kabir effective: r-x
Show solution and explanation
def eff(entry, mask):
    return "".join(e if (e != "-" and m != "-") else "-" for e, m in zip(entry, mask))
print("kabir effective:", eff("rwx", "r-x"))
kabir effective: r-x

How it works: r-x: the mask removes write, which is why getfacl shows the mask line.

P5Medium

Count KDC traffic

Each hdfs command is a new JVM that asks for a service ticket. 500 analysts each run 40 commands a day. How many TGS requests? How many AS requests if each logs in twice?

Input
500 × 40 · 500 × 2
Expected output
TGS: 20000 AS: 1000
Show solution and explanation
print("TGS:", 500 * 40, "AS:", 500 * 2)
TGS: 20000 AS: 1000

How it works: 20,000 TGS and 1,000 AS requests a day: why big companies run several KDCs (or AD domain controllers).

P6Medium

Clock skew

Kerberos rejects tickets if clocks differ by more than 5 minutes. Which servers fail?

Input
offsets in seconds
Expected output
['w2', 'edge1']
Show solution and explanation
offsets = {"nn1": 12, "w1": -40, "w2": 410, "edge1": -305}
print([h for h, s in offsets.items() if abs(s) > 300])
['w2', 'edge1']

How it works: w2 and edge1: “Clock skew too great”. Run NTP or chrony everywhere.

P7Business problem

Cost of not securing

One accidental or malicious delete of a 40 TB folder takes 3 engineers 5 days to restore from DR (₹8,000 per engineer-day) plus a day of lost analytics for 200 users (₹2,000 each). Compare with a 2-week Kerberos + Ranger project for 2 engineers.

Input
illustrative costs
Expected output
one incident Rs 520,000 vs project Rs 160,000
Show solution and explanation
incident = 3 * 5 * 8000 + 200 * 2000
project = 2 * 10 * 8000
print(f"one incident Rs {incident:,} vs project Rs {project:,}")
one incident Rs 520,000 vs project Rs 160,000

How it works: ₹5.2 lakh for one incident vs ₹1.6 lakh (illustrative), before counting audit findings or leaked data.

P8Advanced

Simulate impersonation attempts

For each request, decide what a simple-auth and a Kerberos cluster believe the user is.

Input
3 requests
Expected output
claimed=hadoop ticket=None  simple->hadoop  kerberos->REJECTED
claimed=nn     ticket=riya  simple->nn      kerberos->riya
claimed=None   ticket=kabir simple->os-user kerberos->kabir
Show solution and explanation
reqs = [{"claimed": "hadoop", "ticket": None}, {"claimed": "nn", "ticket": "riya"}, {"claimed": None, "ticket": "kabir"}]
for r in reqs:
    simple = r["claimed"] or "os-user"
    kerberos = r["ticket"] or "REJECTED"
    print(f"claimed={r['claimed']!s:6} ticket={r['ticket']!s:5} simple->{simple:7} kerberos->{kerberos}")
claimed=hadoop ticket=None simple->hadoop kerberos->REJECTED claimed=nn ticket=riya simple->nn kerberos->riya claimed=None ticket=kabir simple->os-user kerberos->kabir

How it works: Simple auth believes the claim; Kerberos only the ticket, and rejects requests without one.

Real-world scenario questions (asked in company interviews)

Security questions come up in Hadoop admin, data engineering and platform interviews, usually with a story.

Concepts · KerberosFresher

“Explain Kerberos in Hadoop in two minutes”

A standard opening question.

The interviewer is checking: the three exchanges and why Hadoop needs it.

Show a strong answer
  • Without Kerberos, Hadoop trusts the user name the client sends; anyone can be the superuser.
  • kinit → TGT from the AS; TGT → service ticket for nn/host@REALM from the TGS; the NameNode decrypts it with its keytab.
  • Jobs get delegation tokens at submission so tasks don't hit the KDC; the RM renews them.
Troubleshooting · GSSExperienced

All jobs on one worker fail with “GSS initiate failed”

Other workers are fine; nothing was deployed.

The interviewer is checking: a methodical Kerberos checklist.

Show a strong answer
  • Check the clock (more than 5 minutes of skew), forward and reverse DNS of the host, and that the keytab's KVNO matches the KDC (klist -kt).
  • Try kinit -kt with the service keytab on that host; enable sun.security.krb5.debug=true for the details.
  • Check krb5.conf (realm, KDC address, allowed encryption types) against the working workers.
Design · RangerExperienced

Analysts need customer data, but not phone numbers

An e-commerce company must restrict PII without blocking reports.

The interviewer is checking: masking, tags and audit, not more copies.

Show a strong answer
  • Tag PII columns in Atlas; one Ranger tag policy masks them (hash or last 4 digits) for analysts, clear for an approved group.
  • Row-level filters if analysts should see only their region.
  • Keep HDFS paths of the raw tables closed to analysts so they cannot bypass Hive; review Ranger audit monthly.
Basics · permissionsFresher

“Our folder is 700, so it's secure, right?”

A teammate on an unsecured cluster.

The interviewer is checking: that you know permissions need authentication.

Show a strong answer
  • Not on simple auth: anyone can set HADOOP_USER_NAME to the owner's name, as our lab showed with a delete.
  • Permissions protect against mistakes; against people you need Kerberos (and a firewall around the cluster).
  • Then add Ranger for central policies and audit, and encryption for data at rest.