dev.to
Open in
urlscan Pro
151.101.66.217
Public Scan
URL:
https://dev.to/ndaidong/how-to-make-your-mongodb-container-more-secure-1646
Submission: On January 22 via api from IN — Scanned from DE
Submission: On January 22 via api from IN — Scanned from DE
Form analysis
3 forms found in the DOMGET /search
<form method="get" action="/search" role="search" accept-charset="UTF-8"><input name="utf8" type="hidden" value="✓">
<div class="crayons-fields crayons-fields--horizontal">
<div class="crayons-field flex-1 relative"><input class="crayons-header--search-input crayons-textfield" type="text" id="" name="q" placeholder="Search..." autocomplete="off" aria-label="Search term"><button type="submit" aria-label="Search"
class="c-btn c-btn--icon-alone absolute inset-px left-auto mt-0 py-0"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" class="crayons-icon c-btn__icon" focusable="false">
<path
d="m18.031 16.617 4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617zm-2.006-.742A6.977 6.977 0 0 0 18 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 0 0 4.875-1.975l.15-.15z">
</path>
</svg></button></div>
</div>
</form>
POST /comments
<form class="comment-form print-hidden" id="new_comment" action="/comments" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" autocomplete="off">
<input type="hidden" name="authenticity_token" value="NOTHING" id="new_comment_authenticity_token">
<input value="454805" autocomplete="off" type="hidden" name="comment[commentable_id]" id="comment_commentable_id">
<input value="Article" autocomplete="off" type="hidden" name="comment[commentable_type]" id="comment_commentable_type">
<span class="crayons-avatar m:crayons-avatar--l mr-2 shrink-0">
<img src="https://media.dev.to/cdn-cgi/image/width=256,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" width="32" height="32" alt="pic"
class="crayons-avatar__image overflow-hidden" id="comment-primary-user-profile--avatar" loading="lazy">
</span>
<div class="comment-form__inner">
<div class="comment-form__field" data-tracking-name="comment_form_textfield">
<textarea placeholder="Add to the discussion" onfocus="handleFocus(event)" onkeyup="handleKeyUp(event)" onkeydown="handleKeyDown(event)" oninput="handleChange(event)" id="text-area" required="required"
class="crayons-textfield comment-textarea crayons-textfield--ghost" aria-label="Add a comment to the discussion" name="comment[body_markdown]"></textarea>
</div>
<div class="response-templates-container crayons-card crayons-card--secondary p-4 mb-4 comment-form__templates fs-base hidden">
<header class="mb-3">
<button type="button" class="crayons-btn personal-template-button active" data-target-type="personal" data-form-id="new_comment">Personal</button>
<button type="button" class="crayons-btn moderator-template-button hidden" data-target-type="moderator" data-form-id="new_comment">Trusted User</button>
</header>
<div class="personal-responses-container">
</div>
<div class="moderator-responses-container hidden">
</div>
<a target="_blank" rel="noopener nofollow" href="/settings/response-templates">
Create template
</a>
<p>Templates let you quickly answer FAQs or store snippets for re-use.</p>
</div>
<div class="comment-form__preview text-styles text-styles--secondary" id="preview-div"></div>
<div class="comment-form__buttons mb-4">
<button type="submit" class="crayons-btn mr-2 js-btn-enable" onclick="validateField(event)" data-tracking-name="comment_submit_button" disabled="">Submit</button>
<button type="button" class="preview-toggle crayons-btn crayons-btn--secondary comment-action-preview js-btn-enable mr-2" data-tracking-name="comment_preview_button" disabled="">Preview</button>
<a href="/404.html" class="dismiss-edit-comment crayons-btn crayons-btn--ghost js-btn-dismiss hidden">Dismiss</a>
</div>
</div>
<div class="code-of-conduct" id="toggle-code-of-conduct-checkbox"></div>
</form>
POST /comments/hide
<form id="hide-comments-modal__form" class="hide-comments-modal__form" data-type="json" action="/comments/hide" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="✓" autocomplete="off"><input type="hidden"
name="_method" value="patch" autocomplete="off"><input type="hidden" name="authenticity_token" value="xyj899Q6h1IIs8uBmHZYSHePBRNMaN1o3d8oPvEA_xG1rIjigDEq-VHI6EoZ4Bz_s_oEohUbvsvzc79jDpTWTw" autocomplete="off">
<div class="hide-comments-modal__content">
<p class="pb-2"> Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's <a id="hide-comments-modal__comment-permalink" href="#">permalink</a>. </p>
<label class="crayons-field crayons-field--checkbox my-2">
<input name="hide_children" type="hidden" value="0" autocomplete="off"><input class="hide_children crayons-checkbox" type="checkbox" value="1" name="hide_children" id="hide_children">
<p class="crayons-field__label">Hide child comments as well</p>
</label>
<p class="pb-4 pt-2">
<button type="submit" class="crayons-btn"> Confirm </button>
</p>
</div>
</form>
Text Content
Skip to content Navigation menu Search Log in Create account DEV COMMUNITY Close 22 Add reaction 18 Like 4 Unicorn 0 Exploding Head 0 Raised Hands 0 Fire 1 Jump to Comments 39 Save More... Copy link Copy link Copied to Clipboard Share to Twitter Share to LinkedIn Share to Reddit Share to Hacker News Share to Facebook Share to Mastodon Share Post via... Report Abuse Dong Nguyen Posted on Sep 13, 2020 18 4 HOW TO MAKE YOUR MONGODB CONTAINER MORE SECURE? #mongodb #docker #security START IT WITH DOCKER The most simple way to get MongoDB instance in your machine is using docker to run mongodb image on docker hub as below: docker run --name mongodb -p 27017:27017 mongo Enter fullscreen mode Exit fullscreen mode By specifying -p 27017:27017, you can access to it with the connection string such as mongodb://localhost:27017 or mongodb://0.0.0.0:27017, as same as installed MongoDB server. This database instance is only available locally. In the case you want to access to it from another computer, you have to overwrite the default config file with a custom MongoDB configuration file. ALLOW TO CONNECT FROM OUTSIDE The command looks like below: docker run --name mongodb -p 27017:27017 -v /path/to/custom/mongod.conf:/etc/mongod.conf mongo Enter fullscreen mode Exit fullscreen mode In which, the mongod.conf file has been customized to allow to connect from outside: # mongod.conf # other settings # network interfaces net: port: 27017 # bindIp: 127.0.0.1 # this is default setting bindIp: 0.0.0.0 # this is what changed # other settings Enter fullscreen mode Exit fullscreen mode But since now your database is public and no longer secure. In my experience, the first thing we should do in this situation is change the default port. CHANGE DEFAULT PORT Let's map it to another free port: docker run --name mongodb -p 27117:27017 -v /path/to/custom/mongod.conf:/etc/mongod.conf mongo Enter fullscreen mode Exit fullscreen mode So that the connection string will become mongodb://IP_ADDRESS:27117, not default port. As you know, there are many bots those automatically scan for public databases on the internet. They try to check the popular default ports, such as 3306 (mysql), 5432 (posgres), 6379 (redis), 27017 (mongo), etc. Changing to a strange port may help you in almost cases. However, that's not enough. ENABLE AUTHENTICATION By default MongoDB will start with authentication disabled. We should enable it with a little bit change to entrypoint. In order to make things easier management, we create a docker-compose.yaml file as below: version: "3" services: mongodb: image: mongo container_name: mongodb ports: - 27117:27017 volumes: - ./mongod.conf:/etc/mongod.conf entrypoint: ["mongod", "--auth", "--config", "/etc/mongod.conf"] Enter fullscreen mode Exit fullscreen mode In the above .yaml file, we added our custom entrypoint to run mongodb with --auth flag. Now when we run it with docker-compose, we should get MongoDB within a container named mongodb similar to the docker run command earlier. And the following is the most important parts of this article... CREATE USERS WITH SPECIFIC PERMISSIONS Until now, our MongoDB instance does not have any user yet. We will get into its container and create a few ones. Firstly, let's get the interactive mongo shell by running: docker exec -it mongodb mongo Enter fullscreen mode Exit fullscreen mode With opening mongo shell, we can now run the commands to switch to admin database and create a user named boss with admin permission on any database: use admin db.createUser({ user: 'boss', pwd: 'YourVeryComplexPassword', roles:['userAdminAnyDatabase'] }) Enter fullscreen mode Exit fullscreen mode Done, press Ctrl + C to exit the shell and leave that session. Note that, at this time, we had already a MongoDB instance run with authentication mode enabled, and an admin user. The connection string for boss user now looks like: mongodb://boss:YourVeryComplexPassword@IP_ADDR:27117 But that's power user, don't use it for regular applications. Instead, we should create more users for different purposes. To create more user or database, we have to come back to mongo shell as boss user: docker exec -it mongodb mongo -u boss Enter fullscreen mode Exit fullscreen mode Enter password when asked and you should see something like: Assume that we have a plan to use a database blogs to store our great blog posts. We should add a user named writer which can write to this database, and a user named reader which can read only. Do that as below: # go to database `admin` use admin # add writer db.createUser({ user: 'writer', pwd: 'YourComplexPassword', roles:[ { role: 'readWrite', db: 'blogs' } ] }) # add reader db.createUser({ user: 'reader', pwd: 'YourSimplePassword', roles:[ { role: 'read', db: 'blogs' } ] }) Enter fullscreen mode Exit fullscreen mode Done, press Ctrl + C to exit the shell and leave that session again. Now we have 2 new users, one for read/write and other for read only action. Their connection strings are: mongodb://writer:YourComplexPassword@IP_ADDR:27117 mongodb://reader:YourSimplePassword@IP_ADDR:27117 With the apps or API endpoints those only load and show blog posts, we just need to use the connection string for reader. Otherwise, when we need to add more blog posts, we will connect to database as writer. That's it. Enjoy playing with docker and MongoDB :) TOP COMMENTS (1) Subscribe Personal Trusted User Create template Templates let you quickly answer FAQs or store snippets for re-use. Submit Preview Dismiss Collapse Expand Mohamed Mohamed Mohamed Follow Learning & growing that's what I am all about! * Location Netherlands * Work Software Engineer * Joined Nov 3, 2020 • Nov 3 '20 Dropdown menu * Copy link * * Hide * * Report abuse * Thank you for your blog! I appreciate the effort :) Like comment: Like comment: 1 like Like Comment button Reply Code of Conduct • Report abuse Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well Confirm For further actions, you may consider blocking this person and/or reporting abuse READ NEXT CRAFTING A DOCKER IMAGE FOR YOUR FLASK WEB APP tinega - Jan 12 TERRAPIN SSH ATTACK: AN OVERVIEW Sandipan Roy - Jan 12 BUILD DOCKER IMAGES FASTER USING BUILD CACHE Kyle Galbraith - Jan 7 MINDSDB DOCKER EXTENSION: BUILD ML POWERED APPS AT A MUCH FASTER PACE Ajeet Singh Raina - Jan 1 Dong Nguyen Follow A software engineer who is also interested in finance, crypto and stock market. * Location Vietnam * Joined Mar 8, 2018 TRENDING ON DEV COMMUNITY HOT Coding Bootcamps: Elevate Your Career or Stall Your Ambitions? #discuss #career #beginners What was your win this week? #discuss #weeklyretro 3 Tools increasing your productivity 📈🤯 #programming #productivity #career #webdev DEV Community Dropdown menu * What's a billboard? * Manage preferences -------------------------------------------------------------------------------- * Report billboard DID YOU KNOW? You can use this area right here to promote your company's: 🧠 Products and tools 🎪 Events 🍎 Job listings 🎉 And more We run simple, no-tracking, privacy-focused ads that convert because they are contextual and community-focused. Learn More Once suspended, ndaidong will not be able to comment or publish posts until their suspension is removed. Note: Submit & Suspend Once unsuspended, ndaidong will be able to comment and publish posts again. Note: Submit & Unsuspend Once unpublished, all posts by ndaidong will become hidden and only accessible to themselves. If ndaidong is not suspended, they can still re-publish their posts from their dashboard. Note: Unpublish all posts Once unpublished, this post will become invisible to the public and only accessible to Dong Nguyen. They can still re-publish the post if they are not suspended. Unpublish Post Thanks for keeping DEV Community safe. Here is what you can do to flag ndaidong: Make all posts by ndaidong less visible ndaidong consistently posts content that violates DEV Community's code of conduct because it is harassing, offensive or spammy. Report other inappropriate conduct Confirm Flag Unflagging ndaidong will restore default visibility to their posts. Confirm Unflag DEV Community — A constructive and inclusive social network for software developers. With you every step of your journey. * Home * Podcasts * Videos * Tags * FAQ * Forem Shop * Advertise on DEV * About * Contact * Guides * Software comparisons * Code of Conduct * Privacy Policy * Terms of use Built on Forem — the open source software that powers DEV and other inclusive communities. Made with love and Ruby on Rails. DEV Community © 2016 - 2024. We're a place where coders share, stay up-to-date and grow their careers. Log in Create account Some content on our site requires cookies for personalization. Read our full privacy policy to learn more. Dismiss Accept Cookies