Preface
Since the previous services were all in the intranet, the Zookeeper cluster configurations were all intranet IP, and the external network did not open relevant ports. Recently, due to business upgrades, we have purchased Alibaba Cloud's services and need to open Zookeeper services to the public.
question
Zookeeper+dubbo, how to set up security authentication? I don't want other services to connect to Zookeeper because this Zookeeper server is on the external network.
Query the official documentation:
Zookeeper is a sub-project of Apacahe Hadoop. It is a tree-type directory service that supports change push. It is suitable as a registration center for Dubbo services. It has high industrial intensity and can be used in production environments. It is recommended to use it.
Process description:
•When the service provider starts: Write your own URL address to the /dubbo/com.foo.BarService/providers directory
• When the service consumer starts: Subscribe to the provider URL address in the /dubbo/com.foo.BarService/providers directory. And write your own URL address to the /dubbo/com.foo.BarService/consumers directory
•When the monitoring center starts: Subscribe to all provider and consumer URL addresses in the /dubbo/com.foo.BarService directory
Supports the following functions:
• When the provider has an abnormal shutdown such as power outage, the registration center can automatically delete the provider information.
• When the registration center is restarted, the registration data can be automatically restored and subscription requests can be subscribed.
• When the session expires, the registration data can be automatically restored and subscription requests can be subscribed.
•When setting <dubbo:registry check="false" />, the registration and subscription request failed is recorded, and the background is timed to retry
•The zookeeper login information can be set through < dubbo:registry username="admin" password="1234" />
•The root node of zookeeper can be set through <dubbo:registry group="dubbo" />. If you do not set it, you will use the rootless tree.
•Supports the * wildcard character < dubbo:reference group="" version="" /> to subscribe to all groups and all versions of the service
Article 5 of the official website document clearly states that zookeeper login information can be set through the username and password fields.
The following are the registry parameters description:
However, if you set the ACL through digest on Zookeeper and then configure the corresponding user and password on dubbo registry, the service will not be registered on Zookeeper and will report KeeperErrorCode = NoAuth error.
However, when I checked the ZookeeperRegistry related source code, I found no relevant authentication. I rarely asked similar questions on the entire network, and this question did not seem to be paid attention to.
ACL in Zookeeper
Overview
In traditional file systems, ACLs are divided into two dimensions, one is a group and the other is permissions. Subdirectories/files inherit the ACLs of the parent directory by default. In Zookeeper, node's ACL has no inheritance relationship and is independently controlled. Zookeeper's ACL can be understood from three dimensions: one is scheme; the second is user; and the third is permission, which is usually expressed as
scheme:id:permissions
The following are introduced from these three aspects:
scheme: scheme corresponds to which scheme is used to manage permissions. zookeeper implements a pluggable ACL scheme, which can extend the ACL mechanism by extending the scheme. zookeeper-3.4.4 supports the following schemes by default:
world: There is only one id below it, called anyone, world:anyone represents anyone, and the node in zookeeper that has permission to everyone belongs to world:anyone
auth: It does not require id, as long as the user through authentication has permissions (zookeeper supports authentication through kerberos, and also supports authentication in the form of username/password)
digest: Its corresponding id is username:BASE64(SHA1(password)), it needs to pass the authentication in the form of username:password
ip: Its corresponding id is the client's IP address. When setting it, you can set an IP segment, such as ip: 192.168.1.0/16, which means that the IP segments match the first 16 bits
super: In this scheme, the corresponding id has super permissions and can do anything (cdrwa)
permission: zookeeper currently supports the following permissions:
CREATE(c): Create permission, you can create child node under the current node
DELETE(d): Delete permissions, you can delete the current node
READ(r): Read permission, you can get the data of the current node, you can list all child nodes in the current node
WRITE(w): Write permission, you can write data to the current node
ADMIN(a): Admin permissions, you can set the permission of the current node
Client Management
We can connect to the client through the following command:
./zkCli.sh
help
[zk: localhost:2181(CONNECTED) 2] helpZooKeeper -server host:port cmd args connect host:port get path [watch] ls path [watch] set path data [version] rmr path delquota [-n|-b] path quit printwatches on|off create [-s] [-e] path data acl stat path [watch] close ls2 path [watch] history listquota path setAcl path acl getAcl path sync path redo cmdno addauth scheme auth delete path [version] setquota -n|-b val path
Simple operation
[zk: localhost:2181(CONNECTED) 12] ls /[dubbo, test, zookeeper][zk: localhost:2181(CONNECTED) 13] create /itstyle data ip:192.168.1.190:cdrwCreated /itstyle[zk: localhost:2181(CONNECTED) 14] getAcl /itstyle'ip,'192.168.1.190: cdrw
zkclient operation code
import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.I0Itec.zkclient.ZkClient;import org.apache.zookeeper.ZooDefs;import org.apache.zookeeper.data.ACL;import org.apache.zookeeper.data.Id;import org.apache.zookeeper.data.Stat;import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;public class Acl { private static final String zkAddress = "192.168.1.190:2181"; private static final String testNode = "/dubbo"; private static final String readAuth = "read-user:123456"; private static final String writeAuth = "write-user:123456"; private static final String deleteAuth = "delete-user:123456"; private static final String allAuth = "super-user:123456"; private static final String adminAuth = "admin-user:123456"; private static final String digest = "digest"; private static void initNode() throws NoSuchAlgorithmException { ZkClient zkClient = new ZkClient(zkAddress); System.out.println(DigestAuthenticationProvider.generateDigest(allAuth)); zkClient.addAuthInfo(digest, allAuth.getBytes()); if (zkClient.exists(testNode)) { zkClient.delete(testNode); System.out.println("Node delete successful!"); } List<ACL> acls = new ArrayList<ACL>(); acls.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(allAuth)))); acls.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(allAuth)))); acls.add(new ACL(ZooDefs.Perms.READ, new Id(digest, DigestAuthenticationProvider.generateDigest(readAuth)))); acls.add(new ACL(ZooDefs.Perms.WRITE, new Id(digest, DigestAuthenticationProvider.generateDigest(writeAuth))))); acls.add(new ACL(ZooDefs.Perms.DELETE, new Id(digest, DigestAuthenticationProvider.generateDigest(deleteAuth)))); acls.add(new ACL(ZooDefs.Perms.ADMIN, new Id(digest, DigestAuthenticationProvider.generateDigest(adminAuth)))); zkClient.createPersistent(testNode, testNode, acls); System.out.println(zkClient.readData(testNode)); System.out.println("Node was created successfully!"); zkClient.close(); } private static void readTest() { ZkClient zkClient = new ZkClient(zkAddress); try { System.out.println(zkClient.readData(testNode));//No authentication information, an error will occur when reading} catch (Exception e) { System.err.println(e.getMessage()); } try { zkClient.addAuthInfo(digest, adminAuth.getBytes()); System.out.println(zkClient.readData(testNode));//The admin permission does not match the read permission, and reading will also occur when reading} catch (Exception e) { System.err.println(e.getMessage()); } try { zkClient.addAuthInfo(digest, readAuth.getBytes()); System.out.println(zkClient.readData(testNode));//Only the authentication information with read permission can be read normally} catch (Exception e) { System.err.println(e.getMessage()); } zkClient.close(); } private static void writeTest() { ZkClient zkClient = new ZkClient(zkAddress); try { zkClient.writeData(testNode, "new-data");//Write fails without authentication information} catch (Exception e) { System.err.println(e.getMessage()); } try { zkClient.addAuthInfo(digest, writeAuth.getBytes()); zkClient.writeData(testNode, "new-data");//Write normally after adding authentication information} catch (Exception e) { System.err.println(e.getMessage()); } try { zkClient.addAuthInfo(digest, readAuth.getBytes()); System.out.println(zkClient.readData(testNode));//Read new value verification} catch (Exception e) { System.err.println(e.getMessage()); } zkClient.close(); } private static void deleteTest() { ZkClient zkClient = new ZkClient(zkAddress); zkClient.addAuthInfo(digest, deleteAuth.getBytes()); try { System.out.println(zkClient.readData(testNode)); zkClient.delete(testNode); System.out.println("Node delete successful!"); } catch (Exception e) { System.err.println(e.getMessage()); } zkClient.close(); } private static void changeACLTest() { ZkClient zkClient = new ZkClient(zkAddress); //Note: zkClient.setAcl method can be found to view the source code. ReadData and setAcl methods are called. //So to modify the ACL attributes of the node, you must have both read and admin permissions: read and admin zkClient.addAuthInfo(digest, adminAuth.getBytes()); zkClient.addAuthInfo(digest, readAuth.getBytes()); try { List<ACL> acls = new ArrayList<ACL>(); acls.add(new ACL(ZooDefs.Perms.ALL, new Id(digest, DigestAuthenticationProvider.generateDigest(adminAuth))); zkClient.setAcl(testNode, acls); Map.Entry<List<ACL>, Stat> aclResult = zkClient.getAcl(testNode); System.out.println(aclResult.getKey()); } catch (Exception e) { System.err.println(e.getMessage()); } zkClient.close(); } public static void main(String[] args) throws Exception { initNode(); System.out.println("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Summarize
Most of the services are deployed on the intranet and are rarely open to the external network. However, Dubbo's zookeeper user permission authentication does not seem to work. If you have to open it to the outside world, you can only use iptables or firewall to perform IP Access Control. If it is an Alibaba Cloud server, the security group is also a good choice.
The above example of security authentication of distributed service Dubbo+Zookeeper is the entire content shared by the editor. I hope it can give you a reference and I hope you can support Wulin.com more.