blob: 39002407cca9566752dc066adba1fa5c6b204a97 [file] [log] [blame]
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Authentication using Kerberos · Apache Pulsar</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="generator" content="Docusaurus"/><meta name="description" content="[Kerberos](https://web.mit.edu/kerberos/) is a network authentication protocol. By using secret-key cryptography, [Kerberos](https://web.mit.edu/kerberos/) is designed to provide strong authentication for client applications and server applications. "/><meta name="docsearch:version" content="2.10.0"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Authentication using Kerberos · Apache Pulsar"/><meta property="og:type" content="website"/><meta property="og:url" content="https://pulsar.apache.org/"/><meta property="og:description" content="[Kerberos](https://web.mit.edu/kerberos/) is a network authentication protocol. By using secret-key cryptography, [Kerberos](https://web.mit.edu/kerberos/) is designed to provide strong authentication for client applications and server applications. "/><meta name="twitter:card" content="summary"/><meta name="twitter:image" content="https://pulsar.apache.org/img/pulsar.svg"/><link rel="shortcut icon" href="/img/pulsar.ico"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://pulsar.apache.org/blog/atom.xml" title="Apache Pulsar Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://pulsar.apache.org/blog/feed.xml" title="Apache Pulsar Blog RSS Feed"/><link rel="stylesheet" href="/css/code-blocks-buttons.css"/><script type="text/javascript" src="https://buttons.github.io/buttons.js"></script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script><script type="text/javascript" src="/js/custom.js"></script><script src="/js/scrollSpy.js"></script><link rel="stylesheet" href="/css/main.css"/><script src="/js/codetabs.js"></script></head><body class="sideNavVisible separateOnPageNav"><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/en"><img class="logo" src="/img/pulsar.svg" alt="Apache Pulsar"/></a><a href="/en/versions"><h3>2.10.0</h3></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li class="siteNavGroupActive"><a href="/docs/en/getting-started-standalone" target="_self">Docs</a></li><li class=""><a href="/en/download" target="_self">Download</a></li><li class="siteNavGroupActive"><a href="/docs/en/client-libraries" target="_self">Clients</a></li><li class=""><a href="#restapis" target="_self">REST APIs</a></li><li class=""><a href="#cli" target="_self">Cli</a></li><li class=""><a href="/blog/" target="_self">Blog</a></li><li class=""><a href="#community" target="_self">Community</a></li><li class=""><a href="#apache" target="_self">Apache</a></li><li class=""><a href="https://pulsar-next.staged.apache.org/" target="_self">New Website (Beta)</a></li><span><li><a id="languages-menu" href="#"><img class="languages-icon" src="/img/language.svg" alt="Languages icon"/>English</a><div id="languages-dropdown" class="hide"><ul id="languages-dropdown-items"><li><a href="/docs/ja/security-kerberos">日本語</a></li><li><a href="/docs/fr/security-kerberos">Français</a></li><li><a href="/docs/ko/security-kerberos">한국어</a></li><li><a href="/docs/zh-CN/security-kerberos">中文</a></li><li><a href="/docs/zh-TW/security-kerberos">繁體中文</a></li><li><a href="https://crowdin.com/project/apache-pulsar" target="_blank" rel="noreferrer noopener">Help Translate</a></li></ul></div></li><script>
const languagesMenuItem = document.getElementById("languages-menu");
const languagesDropDown = document.getElementById("languages-dropdown");
languagesMenuItem.addEventListener("click", function(event) {
event.preventDefault();
if (languagesDropDown.className == "hide") {
languagesDropDown.className = "visible";
} else {
languagesDropDown.className = "hide";
}
});
</script></span></ul></nav></div></header></div></div><div class="navPusher"><div class="docMainWrapper wrapper"><div class="docsNavContainer" id="docsNav"><nav class="toc"><div class="toggleNav"><section class="navWrapper wrapper"><div class="navBreadcrumb wrapper"><div class="navToggle" id="navToggler"><div class="hamburger-menu"><div class="line1"></div><div class="line2"></div><div class="line3"></div></div></div><h2><i></i><span>Security</span></h2><div class="tocToggler" id="tocToggler"><i class="icon-toc"></i></div></div><div class="navGroups"><div class="navGroup"><h3 class="navGroupCategoryTitle">Get Started</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/getting-started-standalone">Run Pulsar locally</a></li><li class="navListItem"><a class="navItem" href="/docs/en/getting-started-docker">Run Pulsar in Docker</a></li><li class="navListItem"><a class="navItem" href="/docs/en/getting-started-helm">Run Pulsar in Kubernetes</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Concepts and Architecture</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/concepts-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-messaging">Messaging</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-architecture-overview">Architecture</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-clients">Clients</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-replication">Geo Replication</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-multi-tenancy">Multi Tenancy</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-authentication">Authentication and Authorization</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-topic-compaction">Topic Compaction</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-proxy-sni-routing">Proxy support with SNI routing</a></li><li class="navListItem"><a class="navItem" href="/docs/en/concepts-multiple-advertised-listeners">Multiple advertised listeners</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Pulsar Schema</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/schema-get-started">Get started</a></li><li class="navListItem"><a class="navItem" href="/docs/en/schema-understand">Understand schema</a></li><li class="navListItem"><a class="navItem" href="/docs/en/schema-evolution-compatibility">Schema evolution and compatibility</a></li><li class="navListItem"><a class="navItem" href="/docs/en/schema-manage">Manage schema</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Pulsar Functions</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/functions-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-runtime">Setup: Configure Functions runtime</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-worker">Setup: Pulsar Functions Worker</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-develop">How-to: Develop</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-package">How-to: Package</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-debug">How-to: Debug</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-deploy">How-to: Deploy</a></li><li class="navListItem"><a class="navItem" href="/docs/en/functions-cli">Reference: CLI</a></li><li class="navListItem"><a class="navItem" href="/docs/en/window-functions-context">Window Functions: Context</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Pulsar IO</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/io-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-quickstart">Get started</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-use">Use</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-debug">Debug</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-connectors">Built-in connector</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-cdc">CDC connector</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-develop">Develop</a></li><li class="navListItem"><a class="navItem" href="/docs/en/io-cli">CLI</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Pulsar SQL</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/sql-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/sql-getting-started">Query data</a></li><li class="navListItem"><a class="navItem" href="/docs/en/sql-deployment-configurations">Configuration and deployment</a></li><li class="navListItem"><a class="navItem" href="/docs/en/sql-rest-api">REST APIs</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Tiered Storage</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/tiered-storage-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/tiered-storage-aws">AWS S3 offloader</a></li><li class="navListItem"><a class="navItem" href="/docs/en/tiered-storage-gcs">GCS offloader</a></li><li class="navListItem"><a class="navItem" href="/docs/en/tiered-storage-filesystem">Filesystem offloader</a></li><li class="navListItem"><a class="navItem" href="/docs/en/tiered-storage-azure">Azure BlobStore offloader</a></li><li class="navListItem"><a class="navItem" href="/docs/en/tiered-storage-aliyun">Aliyun OSS offloader</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Transactions</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/txn-why">Why transactions?</a></li><li class="navListItem"><a class="navItem" href="/docs/en/txn-what">What are transactions?</a></li><li class="navListItem"><a class="navItem" href="/docs/en/txn-how">How transactions work?</a></li><li class="navListItem"><a class="navItem" href="/docs/en/txn-use">How to use transactions?</a></li><li class="navListItem"><a class="navItem" href="/docs/en/txn-monitor">How to monitor transactions?</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Kubernetes (Helm)</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/helm-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/helm-prepare">Prepare</a></li><li class="navListItem"><a class="navItem" href="/docs/en/helm-install">Install</a></li><li class="navListItem"><a class="navItem" href="/docs/en/helm-deploy">Deployment</a></li><li class="navListItem"><a class="navItem" href="/docs/en/helm-upgrade">Upgrade</a></li><li class="navListItem"><a class="navItem" href="/docs/en/helm-tools">Required Tools</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Deployment</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/deploy-aws">Amazon Web Services</a></li><li class="navListItem"><a class="navItem" href="/docs/en/deploy-kubernetes">Kubernetes</a></li><li class="navListItem"><a class="navItem" href="/docs/en/deploy-bare-metal">Bare metal</a></li><li class="navListItem"><a class="navItem" href="/docs/en/deploy-bare-metal-multi-cluster">Bare metal multi-cluster</a></li><li class="navListItem"><a class="navItem" href="/docs/en/deploy-dcos">DC/OS</a></li><li class="navListItem"><a class="navItem" href="/docs/en/deploy-docker">Docker</a></li><li class="navListItem"><a class="navItem" href="/docs/en/deploy-monitoring">Monitor</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Administration</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/administration-zk-bk">ZooKeeper and BookKeeper</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-geo">Geo-replication</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-pulsar-manager">Pulsar Manager</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-stats">Pulsar statistics</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-load-balance">Load balance</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-proxy">Pulsar proxy</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-upgrade">Upgrade</a></li><li class="navListItem"><a class="navItem" href="/docs/en/administration-isolation">Pulsar isolation</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Security</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/security-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-policy-and-supported-versions">Security Policy and Supported Versions</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-tls-transport">Transport Encryption using TLS</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-tls-authentication">Authentication using TLS</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-tls-keystore">Using TLS with KeyStore configure</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-jwt">Authentication using JWT</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-athenz">Authentication using Athenz</a></li><li class="navListItem navListItemActive"><a class="navItem" href="/docs/en/security-kerberos">Authentication using Kerberos</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-oauth2">Authentication using OAuth 2.0 access tokens</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-authorization">Authorization and ACLs</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-encryption">End-to-End Encryption</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-extending">Extend Authentication and Authorization</a></li><li class="navListItem"><a class="navItem" href="/docs/en/security-bouncy-castle">Bouncy Castle Providers</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Performance</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/performance-pulsar-perf">Pulsar Perf</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Client Libraries</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-java">Java</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-go">Go</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-python">Python</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-cpp">C++</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-node">Node.js</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-websocket">WebSocket</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-dotnet">C#</a></li><li class="navListItem"><a class="navItem" href="/docs/en/client-libraries-rest">REST</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Admin API</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-overview">Overview</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-clusters">Clusters</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-tenants">Tenants</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-brokers">Brokers</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-namespaces">Namespaces</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-permissions">Permissions</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-topics">Topics</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-functions">Functions</a></li><li class="navListItem"><a class="navItem" href="/docs/en/admin-api-packages">Packages</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Adaptors</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/adaptors-kafka">Kafka client wrapper</a></li><li class="navListItem"><a class="navItem" href="/docs/en/adaptors-spark">Apache Spark</a></li><li class="navListItem"><a class="navItem" href="/docs/en/adaptors-storm">Apache Storm</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Cookbooks</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-compaction">Topic compaction</a></li><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-deduplication">Message deduplication</a></li><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-non-persistent">Non-persistent messaging</a></li><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-retention-expiry">Message retention and expiry</a></li><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-encryption">Encryption</a></li><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-message-queue">Message queue</a></li><li class="navListItem"><a class="navItem" href="/docs/en/cookbooks-bookkeepermetadata">BookKeeper Ledger Metadata</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Development</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/develop-tools">Simulation tools</a></li><li class="navListItem"><a class="navItem" href="/docs/en/developing-binary-protocol">Binary protocol</a></li><li class="navListItem"><a class="navItem" href="/docs/en/develop-schema">Custom schema storage</a></li><li class="navListItem"><a class="navItem" href="/docs/en/develop-load-manager">Modular load manager</a></li><li class="navListItem"><a class="navItem" href="/docs/en/develop-plugin">Plugin</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Reference</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/en/reference-terminology">Terminology</a></li><li class="navListItem"><a class="navItem" href="/docs/en/reference-cli-tools">Pulsar CLI tools</a></li><li class="navListItem"><a class="navItem" href="/docs/en/reference-configuration">Pulsar configuration</a></li><li class="navListItem"><a class="navItem" href="/docs/en/reference-metrics">Pulsar Metrics</a></li></ul></div></div></section></div><script>
var coll = document.getElementsByClassName('collapsible');
var checkActiveCategory = true;
for (var i = 0; i < coll.length; i++) {
var links = coll[i].nextElementSibling.getElementsByTagName('*');
if (checkActiveCategory){
for (var j = 0; j < links.length; j++) {
if (links[j].classList.contains('navListItemActive')){
coll[i].nextElementSibling.classList.toggle('hide');
coll[i].childNodes[1].classList.toggle('rotate');
checkActiveCategory = false;
break;
}
}
}
coll[i].addEventListener('click', function() {
var arrow = this.childNodes[1];
arrow.classList.toggle('rotate');
var content = this.nextElementSibling;
content.classList.toggle('hide');
});
}
document.addEventListener('DOMContentLoaded', function() {
createToggler('#navToggler', '#docsNav', 'docsSliderActive');
createToggler('#tocToggler', 'body', 'tocActive');
var headings = document.querySelector('.toc-headings');
headings && headings.addEventListener('click', function(event) {
var el = event.target;
while(el !== headings){
if (el.tagName === 'A') {
document.body.classList.remove('tocActive');
break;
} else{
el = el.parentNode;
}
}
}, false);
function createToggler(togglerSelector, targetSelector, className) {
var toggler = document.querySelector(togglerSelector);
var target = document.querySelector(targetSelector);
if (!toggler) {
return;
}
toggler.onclick = function(event) {
event.preventDefault();
target.classList.toggle(className);
};
}
});
</script></nav></div><div class="container mainContainer docsContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/apache/pulsar/edit/master/site2/docs/security-kerberos.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 id="__docusaurus" class="postHeaderTitle">Authentication using Kerberos</h1></header><article><div><span><p><a href="https://web.mit.edu/kerberos/">Kerberos</a> is a network authentication protocol. By using secret-key cryptography, <a href="https://web.mit.edu/kerberos/">Kerberos</a> is designed to provide strong authentication for client applications and server applications.</p>
<p>In Pulsar, you can use Kerberos with <a href="https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer">SASL</a> as a choice for authentication. And Pulsar uses the <a href="https://en.wikipedia.org/wiki/Java_Authentication_and_Authorization_Service">Java Authentication and Authorization Service (JAAS)</a> for SASL configuration. You need to provide JAAS configurations for Kerberos authentication.</p>
<p>This document introduces how to configure <code>Kerberos</code> with <code>SASL</code> between Pulsar clients and brokers and how to configure Kerberos for Pulsar proxy in detail.</p>
<h2><a class="anchor" aria-hidden="true" id="configuration-for-kerberos-between-client-and-broker"></a><a href="#configuration-for-kerberos-between-client-and-broker" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configuration for Kerberos between Client and Broker</h2>
<h3><a class="anchor" aria-hidden="true" id="prerequisites"></a><a href="#prerequisites" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Prerequisites</h3>
<p>To begin, you need to set up (or already have) a <a href="https://en.wikipedia.org/wiki/Key_distribution_center">Key Distribution Center(KDC)</a>. Also you need to configure and run the <a href="https://en.wikipedia.org/wiki/Key_distribution_center">Key Distribution Center(KDC)</a>in advance.</p>
<p>If your organization already uses a Kerberos server (for example, by using <code>Active Directory</code>), you do not have to install a new server for Pulsar. If your organization does not use a Kerberos server, you need to install one. Your Linux vendor might have packages for <code>Kerberos</code>. On how to install and configure Kerberos, refer to <a href="https://help.ubuntu.com/community/Kerberos">Ubuntu</a>,
<a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Smart_Cards/installing-kerberos.html">Redhat</a>.</p>
<p>Note that if you use Oracle Java, you need to download JCE policy files for your Java version and copy them to the <code>$JAVA_HOME/jre/lib/security</code> directory.</p>
<h4><a class="anchor" aria-hidden="true" id="kerberos-principals"></a><a href="#kerberos-principals" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kerberos principals</h4>
<p>If you use the existing Kerberos system, ask your Kerberos administrator for a principal for each Brokers in your cluster and for every operating system user that accesses Pulsar with Kerberos authentication(via clients and tools).</p>
<p>If you have installed your own Kerberos system, you can create these principals with the following commands:</p>
<pre><code class="hljs css language-shell"><span class="hljs-meta">#</span><span class="bash"><span class="hljs-comment">## add Principals for broker</span></span>
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey broker/{hostname}@{REALM}'
sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{broker-keytabname}.keytab broker/{hostname}@{REALM}"
<span class="hljs-meta">#</span><span class="bash"><span class="hljs-comment">## add Principals for client</span></span>
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey client/{hostname}@{REALM}'
sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{client-keytabname}.keytab client/{hostname}@{REALM}"
</code></pre>
<p>Note that <em>Kerberos</em> requires that all your hosts can be resolved with their FQDNs.</p>
<p>The first part of Broker principal (for example, <code>broker</code> in <code>broker/{hostname}@{REALM}</code>) is the <code>serverType</code> of each host. The suggested values of <code>serverType</code> are <code>broker</code> (host machine runs service Pulsar Broker) and <code>proxy</code> (host machine runs service Pulsar Proxy).</p>
<h4><a class="anchor" aria-hidden="true" id="configure-how-to-connect-to-kdc"></a><a href="#configure-how-to-connect-to-kdc" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure how to connect to KDC</h4>
<p>You need to enter the command below to specify the path to the <code>krb5.conf</code> file for the client side and the broker side. The content of <code>krb5.conf</code> file indicates the default Realm and KDC information. See <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/tutorials/KerberosReq.html">JDK’s Kerberos Requirements</a> for more details.</p>
<pre><code class="hljs css language-shell">-Djava.security.krb5.conf=/etc/pulsar/krb5.conf
</code></pre>
<p>Here is an example of the krb5.conf file:</p>
<p>In the configuration file, <code>EXAMPLE.COM</code> is the default realm; <code>kdc = localhost:62037</code> is the kdc server url for realm <code>EXAMPLE.COM</code>:</p>
<pre><code class="hljs">[libdefaults]
<span class="hljs-attr">default_realm</span> = EXAMPLE.COM
[realms]
EXAMPLE.<span class="hljs-attr">COM</span> = {
<span class="hljs-attr">kdc</span> = localhost:<span class="hljs-number">62037</span>
}
</code></pre>
<p>Usually machines configured with kerberos already have a system wide configuration and this configuration is optional.</p>
<h4><a class="anchor" aria-hidden="true" id="jaas-configuration-file"></a><a href="#jaas-configuration-file" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JAAS configuration file</h4>
<p>You need JAAS configuration file for the client side and the broker side. JAAS configuration file provides the section of information that is used to connect KDC. Here is an example named <code>pulsar_jaas.conf</code>:</p>
<pre><code class="hljs"> PulsarBroker {
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarbroker.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"broker/localhost@EXAMPLE.COM"</span>;
};
PulsarClient {
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarclient.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"client/localhost@EXAMPLE.COM"</span>;
};
</code></pre>
<p>You need to set the <code>JAAS</code> configuration file path as JVM parameter for client and broker. For example:</p>
<pre><code class="hljs css language-shell"> -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf
</code></pre>
<p>In the <code>pulsar_jaas.conf</code> file above</p>
<ol>
<li><code>PulsarBroker</code> is a section name in the JAAS file that each broker uses. This section tells the broker to use which principal inside Kerberos and the location of the keytab where the principal is stored. <code>PulsarBroker</code> allows the broker to use the keytab specified in this section.</li>
<li><code>PulsarClient</code> is a section name in the JASS file that each broker uses. This section tells the client to use which principal inside Kerberos and the location of the keytab where the principal is stored. <code>PulsarClient</code> allows the client to use the keytab specified in this section.
The following example also reuses this <code>PulsarClient</code> section in both the Pulsar internal admin configuration and in CLI command of <code>bin/pulsar-client</code>, <code>bin/pulsar-perf</code> and <code>bin/pulsar-admin</code>. You can also add different sections for different use cases.</li>
</ol>
<p>You can have 2 separate JAAS configuration files:</p>
<ul>
<li>the file for a broker that has sections of both <code>PulsarBroker</code> and <code>PulsarClient</code>;</li>
<li>the file for a client that only has a <code>PulsarClient</code> section.</li>
</ul>
<h3><a class="anchor" aria-hidden="true" id="kerberos-configuration-for-brokers"></a><a href="#kerberos-configuration-for-brokers" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kerberos configuration for Brokers</h3>
<h4><a class="anchor" aria-hidden="true" id="configure-the-brokerconf-file"></a><a href="#configure-the-brokerconf-file" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure the <code>broker.conf</code> file</h4>
<p>In the <code>broker.conf</code> file, set Kerberos related configurations.</p>
<ul>
<li>Set <code>authenticationEnabled</code> to <code>true</code>;</li>
<li>Set <code>authenticationProviders</code> to choose <code>AuthenticationProviderSasl</code>;</li>
<li>Set <code>saslJaasClientAllowedIds</code> regex for principal that is allowed to connect to broker;</li>
<li>Set <code>saslJaasBrokerSectionName</code> that corresponds to the section in JAAS configuration file for broker;</li>
</ul>
<p>To make Pulsar internal admin client work properly, you need to set the configuration in the <code>broker.conf</code> file as below:</p>
<ul>
<li>Set <code>brokerClientAuthenticationPlugin</code> to client plugin <code>AuthenticationSasl</code>;</li>
<li>Set <code>brokerClientAuthenticationParameters</code> to value in JSON string <code>{&quot;saslJaasClientSectionName&quot;:&quot;PulsarClient&quot;, &quot;serverType&quot;:&quot;broker&quot;}</code>, in which <code>PulsarClient</code> is the section name in the <code>pulsar_jaas.conf</code> file, and <code>&quot;serverType&quot;:&quot;broker&quot;</code> indicates that the internal admin client connects to a Pulsar Broker;</li>
</ul>
<p>Here is an example:</p>
<pre><code class="hljs"><span class="hljs-attr">authenticationEnabled</span>=<span class="hljs-literal">true</span>
<span class="hljs-attr">authenticationProviders</span>=org.apache.pulsar.broker.authentication.AuthenticationProviderSasl
<span class="hljs-attr">saslJaasClientAllowedIds</span>=.*client.*
<span class="hljs-attr">saslJaasBrokerSectionName</span>=PulsarBroker
<span class="hljs-comment">## Authentication settings of the broker itself. Used when the broker connects to other brokers</span>
<span class="hljs-attr">brokerClientAuthenticationPlugin</span>=org.apache.pulsar.client.impl.auth.AuthenticationSasl
<span class="hljs-attr">brokerClientAuthenticationParameters</span>={<span class="hljs-string">"saslJaasClientSectionName"</span>:<span class="hljs-string">"PulsarClient"</span>, <span class="hljs-string">"serverType"</span>:<span class="hljs-string">"broker"</span>}
</code></pre>
<h4><a class="anchor" aria-hidden="true" id="set-broker-jvm-parameter"></a><a href="#set-broker-jvm-parameter" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Set Broker JVM parameter</h4>
<p>Set JVM parameters for JAAS configuration file and krb5 configuration file with additional options.</p>
<pre><code class="hljs css language-shell"> -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf
</code></pre>
<p>You can add this at the end of <code>PULSAR_EXTRA_OPTS</code> in the file <a href="https://github.com/apache/pulsar/blob/master/conf/pulsar_env.sh"><code>pulsar_env.sh</code></a></p>
<p>You must ensure that the operating system user who starts broker can reach the keytabs configured in the <code>pulsar_jaas.conf</code> file and kdc server in the <code>krb5.conf</code> file.</p>
<h3><a class="anchor" aria-hidden="true" id="kerberos-configuration-for-clients"></a><a href="#kerberos-configuration-for-clients" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kerberos configuration for clients</h3>
<h4><a class="anchor" aria-hidden="true" id="java-client-and-java-admin-client"></a><a href="#java-client-and-java-admin-client" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Java Client and Java Admin Client</h4>
<p>In client application, include <code>pulsar-client-auth-sasl</code> in your project dependency.</p>
<pre><code class="hljs"><span class="xml"> <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.pulsar<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>pulsar-client-auth-sasl<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>$</span><span class="hljs-template-variable">{pulsar.version}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</span></code></pre>
<p>Configure the authentication type to use <code>AuthenticationSasl</code>, and also provide the authentication parameters to it.</p>
<p>You need 2 parameters:</p>
<ul>
<li><code>saslJaasClientSectionName</code>. This parameter corresponds to the section in JAAS configuration file for client;</li>
<li><code>serverType</code>. This parameter stands for whether this client connects to broker or proxy. And client uses this parameter to know which server side principal should be used.</li>
</ul>
<p>When you authenticate between client and broker with the setting in above JAAS configuration file, we need to set <code>saslJaasClientSectionName</code> to <code>PulsarClient</code> and set <code>serverType</code> to <code>broker</code>.</p>
<p>The following is an example of creating a Java client:</p>
<pre><code class="hljs css language-java">System.setProperty(<span class="hljs-string">"java.security.auth.login.config"</span>, <span class="hljs-string">"/etc/pulsar/pulsar_jaas.conf"</span>);
System.setProperty(<span class="hljs-string">"java.security.krb5.conf"</span>, <span class="hljs-string">"/etc/pulsar/krb5.conf"</span>);
Map&lt;String, String&gt; authParams = Maps.newHashMap();
authParams.put(<span class="hljs-string">"saslJaasClientSectionName"</span>, <span class="hljs-string">"PulsarClient"</span>);
authParams.put(<span class="hljs-string">"serverType"</span>, <span class="hljs-string">"broker"</span>);
Authentication saslAuth = AuthenticationFactory
.create(org.apache.pulsar.client.impl.auth.AuthenticationSasl<span class="hljs-class">.<span class="hljs-keyword">class</span>.<span class="hljs-title">getName</span>(), <span class="hljs-title">authParams</span>)</span>;
PulsarClient client = PulsarClient.builder()
.serviceUrl(<span class="hljs-string">"pulsar://my-broker.com:6650"</span>)
.authentication(saslAuth)
.build();
</code></pre>
<blockquote>
<p>The first two lines in the example above are hard coded, alternatively, you can set additional JVM parameters for JAAS and krb5 configuration file when you run the application like below:</p>
</blockquote>
<pre><code class="hljs">java -cp -Djava<span class="hljs-selector-class">.security</span><span class="hljs-selector-class">.auth</span><span class="hljs-selector-class">.login</span>.config=/etc/pulsar/pulsar_jaas<span class="hljs-selector-class">.conf</span> -Djava<span class="hljs-selector-class">.security</span><span class="hljs-selector-class">.krb5</span>.conf=/etc/pulsar/krb5<span class="hljs-selector-class">.conf</span> <span class="hljs-variable">$APP</span>-jar-with-dependencies<span class="hljs-selector-class">.jar</span> <span class="hljs-variable">$CLASSNAME</span>
</code></pre>
<p>You must ensure that the operating system user who starts pulsar client can reach the keytabs configured in the <code>pulsar_jaas.conf</code> file and kdc server in the <code>krb5.conf</code> file.</p>
<h4><a class="anchor" aria-hidden="true" id="configure-cli-tools"></a><a href="#configure-cli-tools" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure CLI tools</h4>
<p>If you use a command-line tool (such as <code>bin/pulsar-client</code>, <code>bin/pulsar-perf</code> and <code>bin/pulsar-admin</code>), you need to perform the following steps:</p>
<p>Step 1. Enter the command below to configure your <code>client.conf</code>.</p>
<pre><code class="hljs css language-shell">authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationSasl
authParams={"saslJaasClientSectionName":"PulsarClient", "serverType":"broker"}
</code></pre>
<p>Step 2. Enter the command below to set JVM parameters for JAAS configuration file and krb5 configuration file with additional options.</p>
<pre><code class="hljs css language-shell"> -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf
</code></pre>
<p>You can add this at the end of <code>PULSAR_EXTRA_OPTS</code> in the file <a href="https://github.com/apache/pulsar/blob/master/conf/pulsar_tools_env.sh"><code>pulsar_tools_env.sh</code></a>,
or add this line <code>OPTS=&quot;$OPTS -Djava.security.auth.login.config=/etc/pulsar/pulsar_jaas.conf -Djava.security.krb5.conf=/etc/pulsar/krb5.conf &quot;</code> directly to the CLI tool script.</p>
<p>The meaning of configurations is the same as the meaning of configurations in Java client section.</p>
<h2><a class="anchor" aria-hidden="true" id="kerberos-configuration-for-working-with-pulsar-proxy"></a><a href="#kerberos-configuration-for-working-with-pulsar-proxy" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kerberos configuration for working with Pulsar Proxy</h2>
<p>With the above configuration, client and broker can do authentication using Kerberos.</p>
<p>A client that connects to Pulsar Proxy is a little different. Pulsar Proxy (as a SASL Server in Kerberos) authenticates Client (as a SASL client in Kerberos) first; and then Pulsar broker authenticates Pulsar Proxy.</p>
<p>Now in comparison with the above configuration between client and broker, we show you how to configure Pulsar Proxy as follows.</p>
<h3><a class="anchor" aria-hidden="true" id="create-principal-for-pulsar-proxy-in-kerberos"></a><a href="#create-principal-for-pulsar-proxy-in-kerberos" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Create principal for Pulsar Proxy in Kerberos</h3>
<p>You need to add new principals for Pulsar Proxy comparing with the above configuration. If you already have principals for client and broker, you only need to add the proxy principal here.</p>
<pre><code class="hljs css language-shell"><span class="hljs-meta">#</span><span class="bash"><span class="hljs-comment">## add Principals for Pulsar Proxy</span></span>
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey proxy/{hostname}@{REALM}'
sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{proxy-keytabname}.keytab proxy/{hostname}@{REALM}"
<span class="hljs-meta">#</span><span class="bash"><span class="hljs-comment">## add Principals for broker</span></span>
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey broker/{hostname}@{REALM}'
sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{broker-keytabname}.keytab broker/{hostname}@{REALM}"
<span class="hljs-meta">#</span><span class="bash"><span class="hljs-comment">## add Principals for client</span></span>
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey client/{hostname}@{REALM}'
sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{client-keytabname}.keytab client/{hostname}@{REALM}"
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="add-a-section-in-jaas-configuration-file-for-pulsar-proxy"></a><a href="#add-a-section-in-jaas-configuration-file-for-pulsar-proxy" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Add a section in JAAS configuration file for Pulsar Proxy</h3>
<p>In comparison with the above configuration, add a new section for Pulsar Proxy in JAAS configuration file.</p>
<p>Here is an example named <code>pulsar_jaas.conf</code>:</p>
<pre><code class="hljs"> PulsarBroker {
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarbroker.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"broker/localhost@EXAMPLE.COM"</span>;
};
PulsarProxy {
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarproxy.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"proxy/localhost@EXAMPLE.COM"</span>;
};
PulsarClient {
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarclient.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"client/localhost@EXAMPLE.COM"</span>;
};
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="proxy-client-configuration"></a><a href="#proxy-client-configuration" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Proxy client configuration</h3>
<p>Pulsar client configuration is similar with client and broker configuration, except that you need to set <code>serverType</code> to <code>proxy</code> instead of <code>broker</code>, for the reason that you need to do the Kerberos authentication between client and proxy.</p>
<pre><code class="hljs css language-java">System.setProperty(<span class="hljs-string">"java.security.auth.login.config"</span>, <span class="hljs-string">"/etc/pulsar/pulsar_jaas.conf"</span>);
System.setProperty(<span class="hljs-string">"java.security.krb5.conf"</span>, <span class="hljs-string">"/etc/pulsar/krb5.conf"</span>);
Map&lt;String, String&gt; authParams = Maps.newHashMap();
authParams.put(<span class="hljs-string">"saslJaasClientSectionName"</span>, <span class="hljs-string">"PulsarClient"</span>);
authParams.put(<span class="hljs-string">"serverType"</span>, <span class="hljs-string">"proxy"</span>); <span class="hljs-comment">// ** here is the different **</span>
Authentication saslAuth = AuthenticationFactory
.create(org.apache.pulsar.client.impl.auth.AuthenticationSasl<span class="hljs-class">.<span class="hljs-keyword">class</span>.<span class="hljs-title">getName</span>(), <span class="hljs-title">authParams</span>)</span>;
PulsarClient client = PulsarClient.builder()
.serviceUrl(<span class="hljs-string">"pulsar://my-broker.com:6650"</span>)
.authentication(saslAuth)
.build();
</code></pre>
<blockquote>
<p>The first two lines in the example above are hard coded, alternatively, you can set additional JVM parameters for JAAS and krb5 configuration file when you run the application like below:</p>
</blockquote>
<pre><code class="hljs">java -cp -Djava<span class="hljs-selector-class">.security</span><span class="hljs-selector-class">.auth</span><span class="hljs-selector-class">.login</span>.config=/etc/pulsar/pulsar_jaas<span class="hljs-selector-class">.conf</span> -Djava<span class="hljs-selector-class">.security</span><span class="hljs-selector-class">.krb5</span>.conf=/etc/pulsar/krb5<span class="hljs-selector-class">.conf</span> <span class="hljs-variable">$APP</span>-jar-with-dependencies<span class="hljs-selector-class">.jar</span> <span class="hljs-variable">$CLASSNAME</span>
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="kerberos-configuration-for-pulsar-proxy-service"></a><a href="#kerberos-configuration-for-pulsar-proxy-service" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kerberos configuration for Pulsar proxy service</h3>
<p>In the <code>proxy.conf</code> file, set Kerberos related configuration. Here is an example:</p>
<pre><code class="hljs css language-shell"><span class="hljs-meta">#</span><span class="bash"><span class="hljs-comment"># related to authenticate client.</span></span>
authenticationEnabled=true
authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderSasl
saslJaasClientAllowedIds=.*client.*
saslJaasBrokerSectionName=PulsarProxy
<span class="hljs-meta">
#</span><span class="bash"><span class="hljs-comment"># related to be authenticated by broker</span></span>
brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationSasl
brokerClientAuthenticationParameters={"saslJaasClientSectionName":"PulsarProxy", "serverType":"broker"}
forwardAuthorizationCredentials=true
</code></pre>
<p>The first part relates to authenticating between client and Pulsar Proxy. In this phase, client works as SASL client, while Pulsar Proxy works as SASL server.</p>
<p>The second part relates to authenticating between Pulsar Proxy and Pulsar Broker. In this phase, Pulsar Proxy works as SASL client, while Pulsar Broker works as SASL server.</p>
<h3><a class="anchor" aria-hidden="true" id="broker-side-configuration"></a><a href="#broker-side-configuration" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Broker side configuration.</h3>
<p>The broker side configuration file is the same with the above <code>broker.conf</code>, you do not need special configuration for Pulsar Proxy.</p>
<pre><code class="hljs"><span class="hljs-attr">authenticationEnabled</span>=<span class="hljs-literal">true</span>
<span class="hljs-attr">authenticationProviders</span>=org.apache.pulsar.broker.authentication.AuthenticationProviderSasl
<span class="hljs-attr">saslJaasClientAllowedIds</span>=.*client.*
<span class="hljs-attr">saslJaasBrokerSectionName</span>=PulsarBroker
</code></pre>
<h2><a class="anchor" aria-hidden="true" id="regarding-authorization-and-role-token"></a><a href="#regarding-authorization-and-role-token" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Regarding authorization and role token</h2>
<p>For Kerberos authentication, we usually use the authenticated principal as the role token for Pulsar authorization. For more information of authorization in Pulsar, see <a href="/docs/en/security-authorization">security authorization</a>.</p>
<p>If you enable 'authorizationEnabled', you need to set <code>superUserRoles</code> in <code>broker.conf</code> that corresponds to the name registered in kdc.</p>
<p>For example:</p>
<pre><code class="hljs css language-bash">superUserRoles=client/{clientIp}@EXAMPLE.COM
</code></pre>
<h2><a class="anchor" aria-hidden="true" id="regarding-authentication-between-zookeeper-and-broker"></a><a href="#regarding-authentication-between-zookeeper-and-broker" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Regarding authentication between ZooKeeper and Broker</h2>
<p>Pulsar Broker acts as a Kerberos client when you authenticate with Zookeeper. According to <a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/Client-Server+mutual+authentication">ZooKeeper document</a>, you need these settings in <code>conf/zookeeper.conf</code>:</p>
<pre><code class="hljs">authProvider.<span class="hljs-number">1</span>=org<span class="hljs-selector-class">.apache</span><span class="hljs-selector-class">.zookeeper</span><span class="hljs-selector-class">.server</span><span class="hljs-selector-class">.auth</span><span class="hljs-selector-class">.SASLAuthenticationProvider</span>
requireClientAuthScheme=sasl
</code></pre>
<p>Enter the following commands to add a section of <code>Client</code> configurations in the file <code>pulsar_jaas.conf</code>, which Pulsar Broker uses:</p>
<pre><code class="hljs"><span class="hljs-built_in"> Client </span>{
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarbroker.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"broker/localhost@EXAMPLE.COM"</span>;
};
</code></pre>
<p>In this setting, the principal of Pulsar Broker and keyTab file indicates the role of Broker when you authenticate with ZooKeeper.</p>
<h2><a class="anchor" aria-hidden="true" id="regarding-authentication-between-bookkeeper-and-broker"></a><a href="#regarding-authentication-between-bookkeeper-and-broker" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Regarding authentication between BookKeeper and Broker</h2>
<p>Pulsar Broker acts as a Kerberos client when you authenticate with Bookie. According to <a href="http://bookkeeper.apache.org/docs/latest/security/sasl/">BookKeeper document</a>, you need to add <code>bookkeeperClientAuthenticationPlugin</code> parameter in <code>broker.conf</code>:</p>
<pre><code class="hljs">bookkeeperClientAuthenticationPlugin=org<span class="hljs-selector-class">.apache</span><span class="hljs-selector-class">.bookkeeper</span><span class="hljs-selector-class">.sasl</span><span class="hljs-selector-class">.SASLClientProviderFactory</span>
</code></pre>
<p>In this setting, <code>SASLClientProviderFactory</code> creates a BookKeeper SASL client in a Broker, and the Broker uses the created SASL client to authenticate with a Bookie node.</p>
<p>Enter the following commands to add a section of <code>BookKeeper</code> configurations in the <code>pulsar_jaas.conf</code> that Pulsar Broker uses:</p>
<pre><code class="hljs"> BookKeeper {
com.sun.security.auth.module.Krb5LoginModule required
<span class="hljs-attribute">useKeyTab</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">storeKey</span>=<span class="hljs-literal">true</span>
<span class="hljs-attribute">useTicketCache</span>=<span class="hljs-literal">false</span>
<span class="hljs-attribute">keyTab</span>=<span class="hljs-string">"/etc/security/keytabs/pulsarbroker.keytab"</span>
<span class="hljs-attribute">principal</span>=<span class="hljs-string">"broker/localhost@EXAMPLE.COM"</span>;
};
</code></pre>
<p>In this setting, the principal of Pulsar Broker and keyTab file indicates the role of Broker when you authenticate with Bookie.</p>
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/docs/en/security-athenz"><span class="arrow-prev"></span><span>Authentication using Athenz</span></a><a class="docs-next button" href="/docs/en/security-oauth2"><span>Authentication using OAuth 2.0 access tokens</span><span class="arrow-next"></span></a></div></div></div><nav class="onPageNav"><ul class="toc-headings"><li><a href="#configuration-for-kerberos-between-client-and-broker">Configuration for Kerberos between Client and Broker</a><ul class="toc-headings"><li><a href="#prerequisites">Prerequisites</a></li><li><a href="#kerberos-configuration-for-brokers">Kerberos configuration for Brokers</a></li><li><a href="#kerberos-configuration-for-clients">Kerberos configuration for clients</a></li></ul></li><li><a href="#kerberos-configuration-for-working-with-pulsar-proxy">Kerberos configuration for working with Pulsar Proxy</a><ul class="toc-headings"><li><a href="#create-principal-for-pulsar-proxy-in-kerberos">Create principal for Pulsar Proxy in Kerberos</a></li><li><a href="#add-a-section-in-jaas-configuration-file-for-pulsar-proxy">Add a section in JAAS configuration file for Pulsar Proxy</a></li><li><a href="#proxy-client-configuration">Proxy client configuration</a></li><li><a href="#kerberos-configuration-for-pulsar-proxy-service">Kerberos configuration for Pulsar proxy service</a></li><li><a href="#broker-side-configuration">Broker side configuration.</a></li></ul></li><li><a href="#regarding-authorization-and-role-token">Regarding authorization and role token</a></li><li><a href="#regarding-authentication-between-zookeeper-and-broker">Regarding authentication between ZooKeeper and Broker</a></li><li><a href="#regarding-authentication-between-bookkeeper-and-broker">Regarding authentication between BookKeeper and Broker</a></li></ul></nav></div><footer class="nav-footer" id="footer"><section class="copyright">Copyright © 2022 The Apache Software Foundation. All Rights Reserved. Apache, Apache Pulsar and the Apache feather logo are trademarks of The Apache Software Foundation.</section><span><script>
const community = document.querySelector("a[href='#community']").parentNode;
const communityMenu =
'<li>' +
'<a id="community-menu" href="#">Community <span style="font-size: 0.75em">&nbsp;▼</span></a>' +
'<div id="community-dropdown" class="hide">' +
'<ul id="community-dropdown-items">' +
'<li><a href="/en/contact">Contact</a></li>' +
'<li><a href="/en/contributing">Contributing</a></li>' +
'<li><a href="/en/coding-guide">Coding guide</a></li>' +
'<li><a href="/en/events">Events</a></li>' +
'<li><a href="https://twitter.com/Apache_Pulsar" target="_blank">Twitter &#x2750</a></li>' +
'<li><a href="https://github.com/apache/pulsar/wiki" target="_blank">Wiki &#x2750</a></li>' +
'<li><a href="https://github.com/apache/pulsar/issues" target="_blank">Issue tracking &#x2750</a></li>' +
'<li><a href="https://pulsar-summit.org/" target="_blank">Pulsar Summit &#x2750</a></li>' +
'<li>&nbsp;</li>' +
'<li><a href="/en/resources">Resources</a></li>' +
'<li><a href="/en/team">Team</a></li>' +
'<li><a href="/en/powered-by">Powered By</a></li>' +
'</ul>' +
'</div>' +
'</li>';
community.innerHTML = communityMenu;
const communityMenuItem = document.getElementById("community-menu");
const communityDropDown = document.getElementById("community-dropdown");
communityMenuItem.addEventListener("click", function(event) {
event.preventDefault();
if (communityDropDown.className == 'hide') {
communityDropDown.className = 'visible';
} else {
communityDropDown.className = 'hide';
}
});
</script></span></footer></div><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script></body></html>