preface

Kerberos is a network user authentication protocol, Kerberos is a three-headed guard dog in Greek mythology, so the title is because the integration of Kerberos took two weeks of my off work time to set up, I read many articles on the Internet directly turn off the server firewall Settings. However, I only opened the port for security reasons. According to the Settings of official documents and several articles, I only opened the TCP port 88. Therefore, when I continued to do the following, the default Settings were correct. Because mongo client can be remotely logged in, SO I identified the problem appeared in the Java code, breakpoint debugging for several times but failed to find the problem, put a lot of abnormal information to Google Baidu for many times and follow the Settings can not be solved, reinstalled different versions of the database, how many times I want to give up, But thinking of the security of the database is very important, they bravely continue to troubleshoot problems one by one. Eliminate the problem almost, I began to suspect that the port is open to the problem, want to try to develop UDP 88 port, did not think of ah! It worked.

Front knowledge

  • SSL/TLS

    SSL/TLS is a communication protocol. The general goal of SSL/TLS is to protect communication (integrity and confidentiality) between client and server. The client should always check the identity of the SSL/TLS server, which also provides a mechanism for the server to check the identity of the client. What it can do also depends on how it is configured. SSL/TLS is most commonly used with X.509 certificates: this is how the browser checks the identity of the HTTPS server. The server can also be configured to request clients to identify themselves with certificates (client certificate authentication)

  • SASL

    SASL is essentially an indirect layer that allows plugable authentication systems and data security in existing application protocols (such as LDAP, SMTP, Subversion, and so on), provided those protocols need to understand the extensions. If you want to use Kerberos with SASL, you will need another level of indirection: GSS-API (most often used with Kerberos, but other mechanisms can be allowed)

  • kerberos

    • What is the kerberos

      • Kerberos is a computer network authentication protocol designed to provide strong authentication for client/server applications through the use of key encryption. It runs on Tickets, allowing nodes to communicate over an unsecured network to prove their identity to each other in a secure way. The Kerberos protocol protects messages from eavesdropping and replay attacks
    • How Kerberos works Kerberos does not require clients to enter a username/password for each service they access, but allows single sign-on using ticket. These tickets are issued by a trusted third party (Key Distribution Center) and are usually encrypted using a password or symmetric Key.

      • Key Distribution Center In order to manage access to resources through Kerberos, all components, services, and users must be in the Kerberos Realm. The Kerberos Distribution Center (KDC) is the core of the Kerberos realm with the following key server components

        • Database ServerStores the keys of registered users and services, the actual stored keys are salted and hashed, and the database itself is password protected
        • User Authentication ServerProvides access toTicket Allocation Servicetheticket
        • Ticket Granting Server (Ticket-Granting Server)Providing access to the service eventually to be reachedticket
      • User Authentication Process

        • 1️ –> User using Kinit Login user introduces himself to AS (User Authentication Server) by running the kinit

          command

          • Cyan key in the picture: youkinit <username>orkinit -kt name.keytabThe obtained user’s principle key
        • 2️ -> Sending a ticket-granting Ticket (TGT) request to AS

          • AS_REQ1 include:

            • User name: Indicates the user name
            • Requested service:TGS (Ticket-Granting Service)
            • Network address: indicates the IP address of the user
            • Expiration time: the lifetime of a TGT
            • Timestamp: The time when the request was generated
        • 3️ –> AS returns the customer key and TGT user decrypts AS_RES1 with the cyan key in the figure after receiving the request to obtain the information inside

          • AS_RES1 is encrypted by the user’s key (the cyan lock in the picture) and contains:

            • The service that generated this message: TGS
            • Timestamp: The time when the request was generated
            • Valid time: the lifetime of a TGT
            • TGS session key
          • AS_RES2/TGT is encrypted by KDC (yellow lock en route) and contains:

            • User name: Indicates the user name
            • The service that generated this message: TGS
            • Timestamp: The time when the request was generated
            • Network address: IP address
            • Valid time: the lifetime of a TGT
            • TGS session key
          • The yellow key: TGS key

          • Magenta key: TGS session key

        • 4️ –> Use TGT request TGS to obtain the key to access Mongodb. After receiving the request, TGS checks whether the timestamp is within 5 minutes and whether the Mongodb service is registered in KDC

          • TGS_REQ1 include:

            • Valid time: the lifetime of a TGT
            • Requested service: MongoDB service
            • TGT (only KDC can decrypt)
          • TGS_REQ2 is encrypted by the TGS key (magenta lock) and contains:

            • User name: Indicates the user name
            • Timestamp: The time when the request was generated
        • 5️ –> TGS generate session keys of ticket and MongoDB to access the service (dark blue lock in figure)

          • TGS_RES1 is encrypted by the TGS session key (magenta lock) and contains:

            • Requested service: MongoDB service
            • Timestamp: The time when the request was generated
            • Valid time: the lifetime of a TGT
            • Service Session key (dark blue key)
          • TGS_RES2/STKT is encrypted by MongoDB’s session key (the green lock), which contains:

            • User name: Indicates the user name
            • Requested service: MongoDB service
            • Timestamp: The time when the request was generated
            • Network address: IP address
            • Valid time: duration of STKT
            • MongoDB session keys
          • The green lock: the key of the MongoDB service in KDC

        • 6️ –> The user sends a login request to the MongoDB service. When the MongoDB server receives the request, check whether the timestamp is within 5 minutes, check whether the user has been registered in the MongoDB database of the MongoDB server, and finally assign roles and permissions to the user

          • AP_REQ1 is the MongoDB session key (the blue lock), which contains:

            • User name: Indicates the user name
            • Timestamp: The time when the request was generated
          • AP_REQ2 is the same as TGS_RES2/STKT

        • 7️ –> MongoDB server return information

          • AP_RES1 is encrypted by the MongoDB session key (dark blue lock) and contains:

            • User name: Indicates the user name
            • Service: MongoDB service
        • 8️ –> Users can communicate directly with MongoDB Users receive the response of MongoDB service and decrypt with MongoDB session key. After decryption and successful verification, users can communicate directly with MongoDB

instructions

  • Deployment locations: MongoDB is deployed on server A, KDC is deployed on server B, and SpringBoot is deployed on server C

  • Domain name: MYEXAMPLE.COM

  • Host: < server A IP > mongodb01.example.com, < server B IP > kdc.example.com, < server C IP > client01.example.com

  • Users created in MongoDB: [email protected]

  • Database created in MongoDB: mytest

  • KDC created within the body of the: mongodb/[email protected] [email protected]

  • Default file location

    • mongodb
      • Mongod. Conf: / etc/mongod. Conf
      • Database table: /var/lib/mongodb/
      • Log file: /var/log/mongodb/
    • kerberos
      • Krb5.conf: / etc/krb5. Conf
      • KDC. Conf: /etc/krb5kdc/kdc.conf
      • Kadm5. acl: /etc/krb5kdc/kadm5.acl

Set up the MongoDB Enterprise (deployed on server A)

Relatively simple, only write simple steps, such as problems see the following reference documentation

  • Pay attention to

    • Support for the following systems (Ubuntu only)

      • 20.04 LTS (” Focal “)
      • 18.04 LTS (” Bionic “)
      • 16.04 LTS (” Xenial “)
    • 32-bit systems cannot be used

    • No support for Windows Subsystem for Linux (WSL)

  • steps

    • Select the version you want to download from the official website

    • Import the public key used by the package management system

      Wget - qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt -- the key to addCopy the code

      If OK is returned, it indicates normal

    • Go to the official web page below, select the Ubuntu system you are using, and copy the code provided and run it

    • Reload the local package database

      sudo apt-get update
      Copy the code
    • Install the MongoDB Enterprise package (the latest version is installed by default). For specific versions and components, go to the MongoDB Enterprise website

      sudo apt-get install -y mongodb-enterprise
      Copy the code
    • Don’t start ecryptfs until you’ve set up ecryptfs, because ecryptfs can only encrypt files when they’re empty

    • Change of file ownership

      Sudo chown -r mongodb:mongodb /var/lib/mongodb sudo chown -r mongodb:mongodb /var/log/mongodb /var/lib/mongodb # log files will be placed in /var/log/mongodb # config files will be placed in /etc/mongodCopy the code
  • reference

    • Docs.mongodb.com/manual/tuto…
    • Juejin. Cn/post / 702560…

Set up EcryptFS (deployed on server A)

  • Install ecryptfs

    sudo apt-get ecryptfs-utils
    Copy the code
  • mount

    sudo mount -t /var/lib/mongodb /var/lib/mongodb
    Copy the code
  • Check whether the mount is successful

    • Enter the following command

      mount
      Copy the code
    • The encryption succeeds if the following information is displayed

  • Unmount (if necessary)

    • Enter the following command

      Sudo umount -t Ecryptfs file nameCopy the code
  • reference

    • Blog.csdn.net/agjirowjtg/…
    • Juejin. Cn/post / 702560…

Initial configuration of MongoDB (deployed on server A)

  • Open the mongo

    sudo systemctl start mongod
    Copy the code
  • Check mongod service status

    sudo systemctl status mongod
    Copy the code
  • Adding an Administrator Account

    Before role access control is enabled, user rights are not restricted

    Mysql > select * from test database Use admin # to add an administrator account Db. CreateUser ({user:' admin', PWD :'admin',roles:[{role:'userAdmin ',db:'admin'}]}); There are many other roles besides userAdminAnyDatabase, See https://docs.mongodb.com/manual/reference/built-in-roles/ # ensure themselves within the admin database, Mysql > create account db.auth(' username ',' password '); mysql > create account db.auth(' username ',' password '); Select * from userAdminAnyDatabase; select * from userAdminAnyDatabase; use mytest; Db.createuser ({user: 'username ', PWD:' username ', roles: [{role: 'readWrite ', db: "mytest" } ] });Copy the code
  • Enable role-based access control

    If a user is not created before role access control is enabled, that is, a user is created after role access control is enabled, a localhost exception will occur (when logging in to the mongodb host, a user can be created, and a new user must be created after logging in to the mongodb host).

    Add the following content to the MongoDB configuration file: authorization: enabledCopy the code
  • Modifying Connection Settings

    Mysql > select * from 'net' where 127.0.0.1 is 0.0.0.0; mysql > select * from 'net' where 127.0.0.1 is 0.0.0.0; mysql > select * from 'net' where 127.0.0.1 is 0.0.0.0; Port: 66666 bindIp: 0.0.0.0Copy the code
  • Conf configuration file to take effect

    Sudo systemctl restart MongodCopy the code
  • Connect to the client (test)

    # go to mongo 127.0.0.1:66666Copy the code
  • reference

    • Docs.mongodb.com/manual/refe…
    • Docs.mongodb.com/manual/refe…
    • Juejin. Cn/post / 702560…

Mongodb SSL configuration (deployed on server A)

  • Encrypted transmission using SSL from the certificate

    • steps

      • Generating a Root Certificate

        • #-days: indicates the validity period of the certificate. The default value is 365 days. # Generate the root certificate openssl req -out ca.pem -new -x509 -days 3650Copy the code
        • openssl req -out ca.pem -new -x509 -days 3650
          Copy the code
          # Country Name: Name of Country # State or Province Name: Name of Province # Locality Name: Name of city # Organization Name: Organization Name # Origanization Util Name: department Name of the organization # Common Name: host Name # Email Address: Email AddressCopy the code
        • Pay attention to

          • The Common Name of the server and client must be the same, but cannot be the same as that of the root certificate
          • Set the password must be saved, convenient to use later
      • Generate a server certificate

        • Openssl genrsa -out server.key 2048Copy the code
        • Openssl req -key server.key -new -out server.reqCopy the code
          # Country Name: Name of Country # State or Province Name: Name of Province # Locality Name: Name of city # Organization Name: Organization Name # Origanization Util Name: department Name of the organization # Common Name: host Name # Email Address: Email AddressCopy the code

          Note that the Common Name of the server and client must be the same, but not the same as the root certificate

        • Pem -cakey privkey. Pem -cacreateserial -out server. CRT -days 3650Copy the code
        • CRT > server.pem cat server.key server. CRT > server.pemCopy the code
        • Pem server.pem openssl verify-cafile ca.pem server.pemCopy the code
      • Generate a client certificate

        • Openssl genrsa -out client.key 2048Copy the code
        • Openssl req -key client.key -new-out client.reqCopy the code
        • Pem -cakey privkey. Pem -caserial ca.srl -out client. CRT -days 3650Copy the code
        • CRT > client.pem cat client.key client. CRT > client.pemCopy the code
        • Pem client file openssl verify-cafile ca.pem client.pemCopy the code
    • Mongodb The local connection is mongodb SSL

      Mongo --tlsAllowInvalidHostnames -- TLS --tlsCertificateKeyFile server.pem file path --tlsCAFile ca.pem file path --host 127.0.0.1:27017Copy the code
    • Navicat mongodb after SSL connection

      “Connection succeeded” is displayed

Springboot integrates SSL with Mongodb

  • Generating SSL files

    CRT and client.pem from server A. trustStore openssl pkCS12 -export -in server. CRT -inkey server.key -out P12 -name server.12 # keyStore openssl pkCS12 -export -in client.pem out keyStoreCopy the code
  • The source code

    • # application. Yml spring: data: mongodb: host: Password: # password of the mongodb account you want to log in to database: # database you want to access authentication-database: # which database you want to authenticate your identityCopy the code
    • @Configuration public class MongoSSLConfig { @Bean public MongoClient createNetworkMongoClient(MongoProperties properties) throws UnrecoverableKeyException, CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException KeyManagementException {/ / the properties object for springboot created, MongoClient = getCredential(properties); // MongoClient = getCredential(properties) String host = properties.getHost() == null ? "localhost" : properties.getHost(); int port = properties.getPort() == null ? 27017 : properties.getPort(); List<ServerAddress> addresses = Collections.singletonList(new ServerAddress(host, port)); P12 String trustStorePath = "trustStore file path "; // SSL // trustStore is server. // keyStore is keyStore String keyStorePath = "keyStore file path "; String keyStorePassword = "keyStore password "; String trustStorePassword = "Password of the trustStore "; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init( getKeyManagers(keyStorePath, keyStorePassword), getTrustManagers(trustStorePath, trustStorePassword), null ); MongoClientSettings settings = MongoClientSettings.builder() .credential(credential) .applyToSslSettings(builder -> Builder.enabled (true) // Enable SSL.context (sslContext) // Configure keyStore and trustStore. invalidHostNameAllowed(true)) // for specific users Disable TLS certificate of host name validation. ApplyToClusterSettings (builder - > builder. Hosts (addresses) mode (ClusterConnectionMode. SINGLE) / / stand-alone mode  .requiredClusterType(ClusterType.STANDALONE)) .build(); return MongoClients.create(settings); } // getKeyManagers private KeyManager[] getKeyManagers(String keystoreFile, String ksPassword) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException { KeyStore keystore = getKeyStore(keystoreFile, ksPassword); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, ksPassword.toCharArray()); return keyManagerFactory.getKeyManagers(); } private TrustManager[] getTrustManagers(String truststoreFile, String tsPassword) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException { KeyStore truststore = getKeyStore(truststoreFile, tsPassword); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(truststore); return trustManagerFactory.getTrustManagers(); } // getKeyStore private keystore getKeyStore(String keystoreFile, String ksPassword) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { KeyStore keystore = KeyStore.getInstance("PKCS12"); InputStream in = new FileInputStream(keystoreFile); keystore.load(in, ksPassword.toCharArray()); return keystore; } private MongoCredential getCredential(MongoProperties properties) { String username = properties.getUsername(); String database = properties.getDatabase() == null ? properties.getMongoClientDatabase() : properties.getDatabase(); // To decrypt the encrypted password, replace the value of properties.setPassword(new String(properties.getPassword()).tochararray ()); char[] password = properties.getPassword(); return MongoCredential.createCredential(username, database, password); }}Copy the code
    • The MongoSSLConfig configuration class could also be written as 👇

      @Configuration public class MongoSSLConfig { @Bean public MongoClient createNetworkMongoClient(MongoProperties properties) throws UnrecoverableKeyException, CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException KeyManagementException {/ / the properties object for springboot created, MongoClient = getCredential(properties); // MongoClient = getCredential(properties) String host = properties.getHost() == null ? "localhost" : properties.getHost(); int port = properties.getPort() == null ? 27017 : properties.getPort(); List<ServerAddress> addresses = Collections.singletonList(new ServerAddress(host, port)); // SSL String trustStorePath = "trustStore file path "; String keyStorePath = "keyStore file path "; String keyStorePassword = "keyStore password "; String trustStorePassword = "Password of the trustStore "; // the path to a trust store containing the certificate of the signing authority System.setProperty("javax.net.ssl.trustStore", trustStorePath); // the password to access this trust store System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); // The path to a key store containing the client's SSL certificates system. setProperty("javax.net.ssl.keyStore", keyStorePath); // the password to access this key store System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword); MongoClientSettings settings = MongoClientSettings.builder() .credential(credential) .applyToSslSettings(builder -> Builder.enabled (true) // Enable SSL.context (sslContext) // Configure keyStore and trustStore. invalidHostNameAllowed(true)) // for specific users Disable TLS certificate of host name validation. ApplyToClusterSettings (builder - > builder. Hosts (addresses) mode (ClusterConnectionMode. SINGLE) / / stand-alone mode  .requiredClusterType(ClusterType.STANDALONE)) .build(); return MongoClients.create(settings); } private MongoCredential getCredential(MongoProperties properties) { String username = properties.getUsername(); String database = properties.getDatabase() == null ? properties.getMongoClientDatabase() : properties.getDatabase(); // To decrypt the encrypted password, replace the value of properties.setPassword(new String(properties.getPassword()).tochararray ()); char[] password = properties.getPassword(); return MongoCredential.createCredential(username, database, password); }}Copy the code
    • reference

      • Mongo. Making. IO/mongo Java -…
  • reference

    • Yellowcong.blog.csdn.net/article/det…
    • Juejin. Cn/post / 702560…

Preliminary work on kerberos setup

  • Make sure server B uses MongoDB Enterprise

    mongod --version
    Copy the code

  • Set the host file for all servers

    Mongodb01.example.com server-b - IP kdc.example.com server-c - IP: mongodb01.example.com server-c - IP: mongodb01.example.com server-c - IP client01.example.comCopy the code
  • Chrony is installed on all servers (servers A, B, and C)

    • steps

      • Enable UDP port 323 123

      • Install chrony

        apt-get install chrony
        Copy the code
      • Setting up the server (that is, KDC server B)

        Systemctl status chronyCopy the code
        • Editing a Configuration File

          Conf # Add content server ntp.aliyun.com iBurst allow Client IP address/subnet mask to connect to this serverCopy the code
        • Make the configuration take effect

          Systemctl restart chronyCopy the code
        • Viewing synchronization Status

          Chronyc sources -v # If the following information is displayed, the connection is successfulCopy the code

      • Setting up clients (servers A and C)

        Systemctl status chronyCopy the code
        • Editing a Configuration File

          Conf: vi /etc/chrony.conf: vi /etc/chrony.conf: vi /etc/chrony.confCopy the code
        • Make the configuration take effect

          Systemctl restart chronyCopy the code
        • Viewing synchronization Status

          Chronyc sources - vCopy the code
    • reference

      • Ubuntu.com/server/docs…
      • Blog.csdn.net/qq_43437874…
      • Compared with other time synchronization component chrony.tuxfamily.org/comparison….
      • Juejin. Cn/post / 702560…

Installing the Kerberos KDC (deployed on server B)

  • steps

    • Enable TCP port 88 and UDP port 88

    • Set the host

      • Set a fully qualified domain name

        hostnamectl set-hostname kdc.example.com
        Copy the code
    • apt update

    • Install the Kerberos server

      sudo apt install krb5-kdc krb5-admin-server
      Copy the code
      • You will be asked to provide Kerberos Realm during installation

      • The Kerberos server host name is then required

      • You are then asked to provide the host name of the administration server

      • Click OK to complete the installation

      • If the host name is incorrect, you can change the host name in either of the following ways

        • If you need to adjust the Key Distribution Center (KDC) Settings, simply edit the file and restart the KRB5-KDC daemon

          sudo systemctl restart krb5-admin-server.service
          Copy the code
        • If you need to reconfigure Kerberos from scratch, perhaps by changing the domain name, enter the following

          sudo dpkg-reconfigure krb5-kdc
          Copy the code
      • Initialize a Kerberos Realm

        krb5_newrealm
        Copy the code
        • You will then be asked to enter the primary password used to decrypt the Kerberos database, which must be remembered

          # This script should be run on the master KDC/admin server... #... # Enter KDC database master key: # Re-enter KDC database master key to verify: # ... # Don't forget to set up DNS information...Copy the code
      • Modify acLs to assign permissions to users

        Run the following command to modify the kadm5.acl file: vi /etc/krb5kdc/kadm5.aclCopy the code

        👆 This entry grants */admin the ability to perform any action on all principals in the realm

        Now restart krb5-admin-Server for the new ACL to take effect

        sudo systemctl restart krb5-admin-server.service
        Copy the code
      • Modify krb5.conf (used by Kerberos 5 library)

        includedir /etc/krb5.conf.d/ [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server  = FILE:/var/log/kadmind.log [libdefaults] dns_lookup_realm = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true rdns = false default_realm = EXAMPLE.COM [realms] EXAMPLE.COM = { kdc = kdc.example.com admin_server = kdc.example.com } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COMCopy the code
      • Modify kdC. conf (KDC configuration file)

        [kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] EXAMPLE.COM = { #master_key_type = aes256-cts dict_file = /usr/share/dict/words supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal  camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal }Copy the code
      • Add the subject

        • Go to the Kerberos console

          kadmin.local
          Copy the code
        • Input? You can view all commands

          add_principal, addprinc, ank
                                   Add principal
          delete_principal, delprinc
                                   Delete principal
          modify_principal, modprinc
                                   Modify principal
          ...
          Copy the code
        • Rules for body naming

          <username>/<instance>@<KERBEROS REALM> # or <username>@<KERBEROS REALM> # <applicationName>/<instance>@<KERBEROS REALM> Host name = '/etc/hosts'; mongodb/[email protected] # service consumers named < username > @ < KERBEROS REALM > # # username here is the host name, such as: [email protected]Copy the code
        • Enter the name of the principal

          # add mongo service main body addprinc - randkey mongodb/mongodb01.example.com # actual deposit is in the kerberos database mongodb/[email protected] # add client01 users subject addprinc - randkey client01.example.com # actual in kerberos The database stores [email protected]Copy the code
        • View all principles

          Getprincs mongodb/[email protected] [email protected] # can see the actual generated behind auto-complete realm...Copy the code
    • Uninstall kerberos server (uninstall and reinstall if installation fails)

      • Start by searching for relevant software

        dpkg --get-selections | grep krb5
        Copy the code
      • To delete

        Sudo apt-get remove -- Purge software nameCopy the code
  • reference

    • Ubuntu.com/server/docs…
    • Medium.com/hackernoon/…
    • Blog.csdn.net/agjirowjtg/…
    • Web.mit.edu/kerberos/kr…
    • Juejin. Cn/post / 702560…

Mongodb integration kerberos (deployed on server A)

  • steps

    • Enable TCP port 88 and UDP port 88

    • Set the host

      • Set a fully qualified domain name

        hostnamectl set-hostname mongodb01.example.com
        Copy the code
      • Edit the /etc/hosts file on your computer and set up hostname resolution so that the two systems can communicate by hostname

        Sudo vi /etc/hosts server -a -ip mongodb01.example.com server -b -ip kdc.example.com server -c -ip client01.example.comCopy the code
    • Install the Kerberos client

      sudo apt install krb5-user
      Copy the code
      • You will be asked to provide Kerberos Realm during installation

      • The Kerberos server host name is then required

      • You are then asked to provide the host name of the administration server

      • Click OK to complete the installation

    • Copy the /etc/krb5.conf file on the KDC server to MongoDB server B

      Cat /etc/krb5.conf can be copied to each Kerberos client server at onceCopy the code
    • Add Kerberos Settings to mongod.conf

      systemLog:
        destination: file
        logAppend: true
        path: /var/log/mongodb/mongod.log
      storage:
        dbPath: /var/lib/mongo
        journal:
          enabled: true
      processManagement:
        fork: true  # fork and run in background
        timeZoneInfo: /usr/share/zoneinfo
      net:
        port: 27017
        bindIp: 0.0.0.0 # <-- TODO: Exposes MongoDB to Public IP. Please use internal IPs instead
      security:
        authorization: enabled
      setParameter:
        authenticationMechanisms: GSSAPI
      Copy the code
    • Create a folder to store the Kerberos Keytab file

      sudo mkdir -p /var/lib/mongo/private
      Copy the code
    • Generate the corresponding keytab at KDC

      # generate mongodb/mongodb01.example.com keytab ktadd - k mongo. Keytab mongodb/mongodb01.example.comCopy the code
    • Add the absolute path to the keytab file to the environment variable

      export KRB5_KTNAME="/var/lib/mongo/private/mongodb.keytab"
      Copy the code
  • Set the file permissions of the private folder to be readable only by system users mongodb

    sudo chown -R mongodb:mongodb /var/lib/mongo/private
    sudo systemctl start mongod
    Copy the code
  • Add priciple from the Kerberos database to the mongodb database

    db.createUser({user: 'mongodb/[email protected]', roles: [{ role: 'readWrite', db: 'mytest'}]});
    Copy the code
  • Mongokerberos test connection

    • Server mode (server is the server where mongodb resides, such as server A)

      • Type the command

        mongokerberos --server
        Copy the code
      • If Kerberos is configured correctly on the server and the service principal is successfully created, the output might look something like the following

        Resolving kerberos environment... [OK] Kerberos environment resolved without errors. Verifying DNS resolution works with Kerberos service at <hostname>...  [OK] DNS test successful. Getting MIT Kerberos KRB5 environment variables... * KRB5CCNAME: not set. * KRB5_CLIENT_KTNAME: not set. * KRB5_CONFIG: not set. * KRB5_KTNAME: not set. * KRB5_TRACE: not set. [OK] Verifying existence of KRB5 keytab FILE:/etc/krb5.keytab... [OK] KRB5 keytab exists and is populated. Checking principal(s) in KRB5 keytab... Found the following principals for MongoDB service mongodb: * mongodb/[email protected] Found the following kvnos in keytab entries for service mongodb: * 3 [OK] KRB5 keytab is valid. Fetching KRB5 Config... KRB5 config profile resolved as: <Your Kerberos profile file will be output here> [OK] KRB5 config profile resolved without errors. Attempting to initiate security context with service credentials... [OK] Security context initiated successfully.Copy the code
    • Client mode (the client is the server that will connect to MondoDB, such as server C)

      • Type the command

        mongokerberos --client --username mongodb/mongodb01.example.com
        Copy the code
      • If the credentials provided are valid and the Kerberos option in the configuration file is valid, the output might look something like the following

        Resolving kerberos environment... [OK] Kerberos environment resolved without errors. Verifying DNS resolution works with Kerberos service at <hostname>...  [OK] DNS test successful. Getting MIT Kerberos KRB5 environment variables... * KRB5CCNAME: not set. * KRB5_CLIENT_KTNAME: not set. * KRB5_CONFIG: not set. * KRB5_KTNAME: not set. * KRB5_TRACE: not set. [OK] Verifying existence of KRB5 client keytab FILE:/path/to/client.keytab... [OK] KRB5 client keytab exists and is populated. Checking principal(s) in KRB5 keytab... [OK] KRB5 keytab is valid. Fetching KRB5 Config... KRB5 config profile resolved as: <Your Kerberos profile file will be output here> [OK] KRB5 config profile resolved without errors. Attempting client half of GSSAPI conversation... [OK] Client half of GSSAPI conversation completed successfully.Copy the code
  • Log (Always, always, always learn to log)

    • tail /var/log/mongodb/mongod.log -n 100
      Copy the code
  • Logging In to the Database

    The kinit - kt mongo. # into the client mongo \ keytab mongodb/mongodb01.example.com - tlsAllowInvalidHostnames \ \ - TLS --host mongodb01.example.com --port 23332 # mongodb01.example.com Use $external # db. Auth ({mechanism: "GSSAPI", user: "[email protected]"}) #Copy the code
  • reference

    • Docs.mongodb.com/manual/tuto…
    • Web.mit.edu/kerberos/kr…
    • Web.mit.edu/kerberos/kr…
    • Docs.mongodb.com/manual/refe…
    • Juejin. Cn/post / 702560…

Springboot integrates Kerberos (deployed on server C)

  • steps

    • Install the Kerberos client (same as on server A)

    • Copy the /etc/krb5.conf file of the KDC and replace the krb5.conf file of the local server

    • Generate the corresponding keytab at KDC

      Keytab ktadd -k client.keytab for client01.example.com client01.example.comCopy the code
    • Testing mongodb connections

      Kinit -kt client.keytab client01.example.com # Enter client mongo \ --tlsAllowInvalidHostnames \ -- TLS \ -- mongodb01.example.com --host mongodb01.example.com --port 23332 # Use $external # login user db.auth({mechanism: "GSSAPI", user: "[email protected]"}) #Copy the code
    • Create the gss-jas.conf file

      com.sun.security.jgss.initiate { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true KeyTab =" Client. keyTab absolute path "useTicketCache=false Principal ="[email protected]" doNotPrompt=true debug=true; };Copy the code
    • Springboot connects to mongodb using Kerberos and SSL

      @Configuration public class MongoSSLConfig { @Bean public MongoClient createNetworkMongoClient(MongoProperties Properties) throws IOException {// SSL String trustStorePath = "path of server.p12 "; String keyStorePath = "keystore path "; String keyStorePassword = "keyStore password "; String trustStorePassword = "trustStore Password "; // the path to a trust store containing the certificate of the signing authority System.setProperty("javax.net.ssl.trustStore", trustStorePath); // the password to access this trust store System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); // The path to a key store containing the client's SSL certificates system. setProperty("javax.net.ssl.keyStore", keyStorePath); // the password to access this key store System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword); // Kerberos String gssJaasPath = "path to gss-jaas.conf "; // Set the JVM variable system.setProperty ("java.security.krb5.realm", "MYEXAMPLE.COM"); System.setProperty("java.security.krb5.kdc", "kdc.example.com"); Conf file to obtain domain information. // String krb5Path = "path to krb5.conf "; // System.setProperty("java.security.krb5.conf", krb5Path); System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); System.setProperty("java.security.auth.login.config", gssJaasPath); MongoCredential credential = getCredential(properties); String host = properties.getHost() == null ? "localhost" : properties.getHost(); int port = properties.getPort() == null ? 23332 : properties.getPort(); List<ServerAddress> addresses = Collections.singletonList(new ServerAddress(host, port)); MongoClientSettings settings = MongoClientSettings.builder() .applyToSslSettings(builder -> builder.enabled(true) .invalidHostNameAllowed(true)) .applyToClusterSettings(builder -> builder.hosts(addresses) .mode(ClusterConnectionMode.SINGLE) .requiredClusterType(ClusterType.STANDALONE)) .credential(credential) .build(); Can / / / / using uri MongoClientSettings Settings = MongoClientSettings. Builder () / /. ApplyConnectionString (new ConnectionString( // "mongodb://" + // "client01.example.com%40MYEXAMPLE.COM@" + // "mongodb01.example.com:66666/?" + //  "authSource=$external&" + // "tls=true&" + // "tlsAllowInvalidHostnames=true&" + // "authMechanism=GSSAPI&" + // "authMechanismProperties=CANONICALIZE_HOST_NAME:true")) // .build(); return MongoClients.create(settings); } private MongoCredential getCredential(MongoProperties properties) { String username = properties.getUsername(); return MongoCredential .createGSSAPICredential(username) .withMechanismProperty(MongoCredential.CANONICALIZE_HOST_NAME_KEY, true); }}Copy the code
    • application.yml

      spring:
        data:
          mongodb:
            host: mongodb01.example.com
            port: 23332
            username: '[email protected]'
            database: mytest
      Copy the code
  • reference

    • Techjogging.com/create-keyt…

    • Mongo. Making. IO/mongo Java -…

    • Juejin. Cn/post / 702560…

If you have any questions, go to the comments section at 😸