From 7b38586716b9e6c49cb5451d0a550661c1e5e74e Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 4 Feb 2024 16:52:52 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=B3=20docs:=20How=20to=20Authenticate?= =?UTF-8?q?=20MongoDB=20(#1724)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: remove `--noauth` flag from `mongod` command * docs: add mongodb auth instructions * Update manage_your_database.md * chore: add example * Update manage_your_database.md --- docs/features/manage_your_database.md | 18 +- docs/install/configuration/docker_override.md | 307 ++++++++++++++++++ 2 files changed, 324 insertions(+), 1 deletion(-) diff --git a/docs/features/manage_your_database.md b/docs/features/manage_your_database.md index 3de01e21cbc..99e04c285c8 100644 --- a/docs/features/manage_your_database.md +++ b/docs/features/manage_your_database.md @@ -40,7 +40,23 @@ services: restart: always ``` -3. **Security Notice:** Before using this configuration, replace `admin` and `password` with a unique username and password for accessing Mongo Express. These credentials should be strong and not easily guessable to prevent unauthorized access. +3. **Security Notice:** +- a. Before using this configuration, replace `admin` and `password` with a unique username and password for accessing Mongo Express. These credentials should be strong and not easily guessable to prevent unauthorized access. +- b. You can also add native authentication to your database. See the [`docker-compose.override` guide](../install/configuration/docker_override.md#mongodb-authentication) for instructions on how to do so + - After following the guide to authenticate MongoDB, you will need these variables under the environment section for mongo-express: + +```yaml + environment: + ME_CONFIG_MONGODB_SERVER: mongodb + ME_CONFIG_BASICAUTH_USERNAME: admin + ME_CONFIG_BASICAUTH_PASSWORD: password + # database authentication variables, using example credentials from guide + ME_CONFIG_MONGODB_URL: 'mongodb://adminUser:securePassword@mongodb:27017' + ME_CONFIG_MONGODB_ADMINUSERNAME: adminUser + ME_CONFIG_MONGODB_ADMINPASSWORD: securePassword +``` + +- c. If using authentication for your database, make sure the admin user has the "clusterAdmin" and "readAnyDatabase" permissions as detailed in the [`docker-compose.override` guide](../install/configuration/docker_override.md#step-1-creating-an-admin-user) 4. Save the `docker-compose.override.yml` file and run the following command from the directory where your `docker-compose.yml` file is located to start Mongo-Express along with your other Docker services: diff --git a/docs/install/configuration/docker_override.md b/docs/install/configuration/docker_override.md index f4f5bc756f1..bc5dc7bf394 100644 --- a/docs/install/configuration/docker_override.md +++ b/docs/install/configuration/docker_override.md @@ -86,3 +86,310 @@ After starting your services with the modified configuration, you can verify tha - **Security**: When customizing ports and publicly exposing services, always be conscious of the security implications. Avoid using defaults for production or sensitive environments. By following these steps and considerations, you can easily and safely modify your Docker Compose configuration without altering the original `docker-compose.yml` file, making it simpler to manage and maintain different environments or local customizations. + + +# MongoDB Authentication + +Use of the `docker-compose.override.yml` file allows us to enable explicit authentication for MongoDB. + +**Notes:** +- The default configuration is secure by blocking external port access, but we can take it a step further with access credentials. +- As noted by the developers of MongoDB themselves, authentication in MongoDB is fairly complex. We will be taking a simple approach that will be good enough for most cases, especially for existing configurations of LibreChat. To learn more about how mongodb authentication works with docker, see here: https://hub.docker.com/_/mongo/ +- This guide focuses exclusively on terminal-based setup procedures. +- While the steps outlined may also be applicable to Docker Desktop environments, or with non-Docker, local MongoDB, or other container setups, details specific to those scenarios are not provided. + +**There are 3 basic steps:** +- Create an admin user within your mongodb container +- Enable authentication and create a "readWrite" user for "LibreChat" +- Configure the MONGO_URI with newly created user + +## Step 1: Creating an Admin User + +First, we must stop the default containers from running, and only run the mongodb container. + +```bash +docker-compose down +docker-compose up -d mongodb +``` + +> Note: The `-d` flag detaches the current terminal instance as the container runs in the background. If you would like to see the mongodb log outputs, omit it and continue in a separate terminal. + +Once running, we will enter the container's terminal and execute `mongosh`: + +```bash +docker exec -it chat-mongodb mongosh +``` +You should see the following output: + +```bash +~/LibreChat$ docker exec -it chat-mongodb mongosh +Current Mongosh Log ID: 65bfed36f7d7e3c2b01bcc3d +Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.1.1 +Using MongoDB: 7.0.4 +Using Mongosh: 2.1.1 + +For mongosh info see: https://docs.mongodb.com/mongodb-shell/ + +test> +``` + +Optional: While we're here, we can disable telemetry for mongodb if desired, which is anonymous usage data collected and sent to MongoDB periodically: + +Execute the command below. + +> Notes: +> - All subsequent commands should be run in the current terminal session, regardless of the environment (Docker, Linux, `mongosh`, etc.) +> - I will represent the actual terminal view with # example input/output or simply showing the output in some cases + +Command: + +```bash +disableTelemetry() +``` +Example input/output: +```bash +# example input/output +test> disableTelemetry() +Telemetry is now disabled. +``` + +Now, we must access the admin database, which mongodb creates by default to create our admin user: + +```bash +use admin +``` +> switched to db admin + +Replace the credentials as desired and keep in your secure records for the rest of the guide. + +Run command to create the admin user: +```bash +db.createUser({ user: "adminUser", pwd: "securePassword", roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"] }) +``` + +You should see an "ok" output: +> { ok: 1 } + +You can also confirm the admin was created by running `show users`: +```bash +# example input/output +admin> show users +[ + { + _id: 'admin.adminUser', + userId: UUID('86e90441-b5b7-4043-9662-305540dfa6cf'), + user: 'adminUser', + db: 'admin', + roles: [ + { role: 'userAdminAnyDatabase', db: 'admin' }, + { role: 'readWriteAnyDatabase', db: 'admin' } + ], + mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ] + } +] +``` + +:warning: **Important:** if you are using `mongo-express` to [manage your database (guide here)](../../features/manage_your_database.md), you need the additional permissions for the `mongo-express` service to run correctly: + +```bash +db.grantRolesToUser("adminUser", ["clusterAdmin", "readAnyDatabase"]); +``` + +Exit the Mongosh/Container Terminal by running `exit`: +```bash +# example input/output +admin> exit +``` + +And shut down the running container: +```bash +docker-compose down +``` + +## Step 2: Enabling Authentication and Creating a User with `readWrite` Access + +We must now create/edit the `docker-compose.override.yml` file to enable authentication for our mongodb container. You can use this configuration to start or reference: + +```yaml +version: '3.4' + +services: + api: + volumes: + - ./librechat.yaml:/app/librechat.yaml # Optional for using the librechat config file. + mongodb: + command: mongod --auth # <--- Add this to enable authentication +``` + +After configuring the override file as above, run the mongodb container again: + +```bash +docker-compose up -d mongodb +``` + +And access mongosh as the admin user: + +```bash +docker exec -it chat-mongodb mongosh -u adminUser -p securePassword --authenticationDatabase admin +``` + +Confirm you are authenticated: +```bash +db.runCommand({ connectionStatus: 1 }) +``` + +```bash +# example input/output +test> db.runCommand({ connectionStatus: 1 }) +{ + authInfo: { + authenticatedUsers: [ { user: 'adminUser', db: 'admin' } ], + authenticatedUserRoles: [ + { role: 'readWriteAnyDatabase', db: 'admin' }, + { role: 'userAdminAnyDatabase', db: 'admin' } + ] + }, + ok: 1 +} +test> +``` + +Switch to the "LibreChat" database + +> Note: This the default database unless you changed it via the MONGO_URI; default URI: `MONGO_URI=mongodb://mongodb:27017/LibreChat` + +```bash +use LibreChat +``` + +Now we'll create the actual credentials to be used by our Mongo connection string, which will be limited to read/write access of the "LibreChat" database. As before, replace the example with your desired credentials: +```bash +db.createUser({ user: 'user', pwd: 'userpasswd', roles: [ { role: "readWrite", db: "LibreChat" } ] }); +``` + +You should see an "ok" output again: +> { ok: 1 } + +You can verify the user creation with the `show users` command. + +Exit the Mongosh/Container Terminal again with `exit`, and bring the container down: + +```bash +exit +``` + +```bash +docker-compose down +``` + +I had an issue where the newly created user would not persist after creating it. To solve this, I simply repeated the steps to ensure it was created. Here they are for your convenience: + +```bash +# ensure container is shut down +docker-compose down +# start mongo container +docker-compose up -d mongodb +# enter mongosh as admin +docker exec -it chat-mongodb mongosh -u adminUser -p securePassword --authenticationDatabase admin + +# check LibreChat db users first; if persisted, exit after this +use LibreChat +show users + +# Exit if you see user output. If not, run the create user command again +db.createUser({ user: 'user', pwd: 'userpasswd', roles: [ { role: "readWrite", db: "LibreChat" } ] }); +``` + +If it's still not persisting, you can try running the commands with all containers running, but note that the `LibreChat` container will be in an error/retrying state. + +## Step 3: Update the `MONGO_URI` to Use the New Credentials + +Finally, we add the new connection string with our newly created credentials to our `docker-compose.override.yml` file under the `api` service: + +```yaml + environment: + - MONGO_URI=mongodb://user:userpasswd@mongodb:27017/LibreChat +``` + +So our override file looks like this now: + +```yaml +version: '3.4' + +services: + api: + volumes: + - ./librechat.yaml:/app/librechat.yaml + environment: + - MONGO_URI=mongodb://user:userpasswd@mongodb:27017/LibreChat + mongodb: + command: mongod --auth +``` + +You should now run `docker-compose up` successfully authenticated with read/write access to the LibreChat database + +Example successful connection: +```bash +LibreChat | 2024-02-04 20:59:43 info: Server listening on all interfaces at port 3080. Use http://localhost:3080 to access it +chat-mongodb | {"t":{"$date":"2024-02-04T20:59:53.880+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"192.168.160.4:58114","uuid":{"uuid":{"$uuid":"027bdc7b-a3f4-429a-80ee-36cd172058ec"}},"connectionId":17,"connectionCount":10}} +``` + +If you're having Authentication errors, run the last part of Step 2 again. I'm not sure why it's finicky but it will work after a few tries. + +## TL;DR + +These are all the necessary commands if you'd like to run through these quickly or for reference: + +```bash +# Step 1: +docker-compose down +docker-compose up -d mongodb +docker exec -it chat-mongodb mongosh +use admin +db.createUser({ user: "adminUser", pwd: "securePassword", roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"] }) +exit +docker-compose down +# Step 2: +# Edit override file with --auth flag +docker-compose up -d mongodb +docker exec -it chat-mongodb mongosh -u adminUser -p securePassword --authenticationDatabase admin +use LibreChat +db.createUser({ user: 'user', pwd: 'userpasswd', roles: [ { role: "readWrite", db: "LibreChat" } ] }); +exit +docker-compose down +# Step 3: +# Edit override file with new connection string +docker-compose up +``` + +# Example + +Example `docker-compose.override.yml` file using the [`librechat.yaml` config file](./custom_config.md), MongoDB with [authentication](#mongodb-authentication), and `mongo-express` for [managing your MongoDB database](../../features/manage_your_database.md): + +```yaml +version: '3.4' + +services: + api: + volumes: + - ./librechat.yaml:/app/librechat.yaml + environment: + - MONGO_URI=mongodb://user:userpasswd@mongodb:27017/LibreChat + mongodb: + command: mongod --auth + mongo-express: + image: mongo-express + container_name: mongo-express + environment: + ME_CONFIG_MONGODB_SERVER: mongodb + ME_CONFIG_BASICAUTH_USERNAME: admin + ME_CONFIG_BASICAUTH_PASSWORD: password + ME_CONFIG_MONGODB_URL: 'mongodb://adminUser:securePassword@mongodb:27017' + ME_CONFIG_MONGODB_ADMINUSERNAME: adminUser + ME_CONFIG_MONGODB_ADMINPASSWORD: securePassword + ports: + - '8081:8081' + depends_on: + - mongodb + restart: always +``` \ No newline at end of file