How do I create a the first mongodb user with authorization enabled? - mongodb

I am trying to create a admin user. I've tried several different ways.
I realize that authorization is enabled, and if I turned it off, then back on it would allow me to create the first user. However I am trying to create the first user while authorization is enabled.
I have wiped the data directory and I am dealing with a fresh database.
I've been able to use rs.initiate() and db.createUser() from the console, but what I'm discovering is that it's impossible for me to run a script that both 1)initiates the replica set and 2) creates the admin user using --eval at the same time.
My config looks like this:
storage:
dbPath: /var/mongodb/db/1
net:
bindIp: localhost,192.168.103.100
port: 27001
security:
authorization: enabled
keyFile: /var/mongodb/pki/m103-keyfile
systemLog:
destination: file
path: /var/mongodb/db/mongod1.log
logAppend: true
processManagement:
fork: true
replication:
replSetName: m103-repl
Then I connect with this:
mongo --host localhost:27001
The within the mongo console I tried this:
use admin
db.createUser({
user: "m103-admin",
pwd: "m103-pass",
roles: [
{role: "root", db: "admin"}
]
})
and I get this error:
2020-03-16T19:57:36.796+0000 E QUERY [thread1] Error: couldn't add user: not master :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
DB.prototype.createUser#src/mongo/shell/db.js:1437:15
#(shell):1:1
Update, I've tried starting the mongod then running rs.initiate, however I am still getting and issue when I try and create a user.
# ------------------------------------------------------------------------------------------
echo "\nchanging the directory to home dir\n"
cd ~/
# ------------------------------------------------------------------------------------------
echo "\nkilling all running mongo processes\n"
sleep 3
kill $(ps aux | grep '[m]ongod' | awk '{print $2}')
sleep 3
# ------------------------------------------------------------------------------------------
echo "\nremoving all data directories\n"
rm -rf /var/mongodb/db/1
# ------------------------------------------------------------------------------------------
echo "\nremoving all log files\n"
rm -rf /var/mongodb/db/mongod1.log
# ------------------------------------------------------------------------------------------
echo "\nremoving all log files\n"
rm -rf /var/mongodb/pki/m103-keyfile
# ------------------------------------------------------------------------------------------
echo "\ncreating the keyfile\n"
sudo mkdir -p /var/mongodb/pki
sudo chown vagrant:vagrant -R /var/mongodb
openssl rand -base64 741 > /var/mongodb/pki/m103-keyfile
chmod 600 /var/mongodb/pki/m103-keyfile
# ------------------------------------------------------------------------------------------
echo "\ncreating data directories\n"
mkdir -p /var/mongodb/db/1
# ------------------------------------------------------------------------------------------
echo "\ntouching the logs\n"
touch /var/mongodb/db/mongod1.log
# ------------------------------------------------------------------------------------------
echo "\nstarting up mongo repl 1\n"
mongod --config /shared/replica-sets/mongod-repl-1.conf
sleep 3
# ------------------------------------------------------------------------------------------
echo "\nreplicaSet initiate\n"
mongo --port 27001 --eval='rs.initiate()'
# ------------------------------------------------------------------------------------------
echo "\ncreating the user\n"
mongo mongodb://localhost:27001/admin?replicaSet=m103-repl --eval='db.createUser({user:"m103-admin",pwd:"m103-pass",roles:[{role:"userAdminAnyDatabase",db:"admin"}]});'
Here's what the script returns:
MongoDB shell version v3.6.17
connecting to: mongodb://localhost:27001/admin?gssapiServiceName=mongodb&replicaSet=m103-repl
2020-03-16T20:41:39.786+0000 I NETWORK [thread1] Starting new replica set monitor for m103-repl/localhost:27001
2020-03-16T20:41:39.787+0000 I NETWORK [thread1] Successfully connected to localhost:27001 (1 connections now open to localhost:27001 with a 5 second timeout)
2020-03-16T20:41:39.788+0000 I NETWORK [thread1] Successfully connected to 192.168.103.100:27001 (1 connections now open to 192.168.103.100:27001 with a 5 second timeout)
2020-03-16T20:41:39.788+0000 W NETWORK [thread1] Unable to reach primary for set m103-repl
2020-03-16T20:41:39.788+0000 W NETWORK [thread1] Unable to reach primary for set m103-repl
2020-03-16T20:41:40.333+0000 W NETWORK [thread1] Unable to reach primary for set m103-repl
2020-03-16T20:41:40.933+0000 I NETWORK [thread1] changing hosts to m103-repl/192.168.103.100:27001 from m103-repl/localhost:27001
Implicit session: session { "id" : UUID("bb96245e-3187-4b01-923f-a1a7d7533159") }
MongoDB server version: 3.6.17
2020-03-16T20:41:40.938+0000 E QUERY [thread1] Error: couldn't add user: there are no users authenticated :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
DB.prototype.createUser#src/mongo/shell/db.js:1437:15
#(shell eval):1:1

In a Replica Set you first have to initialize the Replica Set with
rs.initiate()
Then connect to the PRIMARY host, there you can create the admin user.
Follow the Deploy Replica Set With Keyfile Authentication tutorial, it describes the deployment step-by-step.
For Sharded Cluster follow Deploy Sharded Cluster with Keyfile Authentication
Follow these tutorials carefully, have a particular look which commands are executed on each host or only once or just on Primary Hosts, etc.

Related

mongodb authentication disable and enable issue

Now I have a mongoDB in my computer,locates at c:\mongodb\bin. At first, it is auth disable. so when I press:
C:\Windows\system32>mongo
There is some warnings:
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten] ** WARNING:
Access contr ol is not enabled for the database.
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten] **
Read and wri te access to data and configuration is unrestricted.
So I tried to add access control to mongoDB. What I did are:
C:\mongodb\bin>use admin
db.createUser(
{
user: "myUserAdmin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
But after I did above, still I can log in MongoDb without username and pwd. Even after I restart the mongoDB service, or restart the computer. eg:
C:\Windows\system32>mongo
MongoDB shell version v3.4.9
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.9
Server has startup warnings:
2018-03-28T16:53:43.515+0800 I CONTROL [initandlisten]
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten] ** WARNING: Access contr
ol is not enabled for the database.
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten] ** Read and wri
te access to data and configuration is unrestricted.
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten]
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten] Hotfix KB2731284 or late
r update is not installed, will zero-out data files.
2018-03-28T16:53:43.516+0800 I CONTROL [initandlisten]
> show dbs
admin 0.000GB
local 0.000GB
> use admin
switched to db admin
>
The only way that I can make the mongodb change to authentication is delete the mongodb service and install this service again by using follwoing script:
C:\mongodb\bin>sc delete MongoDB
C:\mongodb\bin>mongod --dbpath C:\mongodb\data --logpath C:\mongodb\log\MongoDB.log --auth --install
But If I use this way to create the auth mongoDB, when I try to login without username and pwd, it will faied as below:
C:\Windows\system32>mongo
MongoDB shell version v3.4.9
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.9
> show dns
2018-03-28T17:59:06.344+0800 E QUERY [thread1] Error: don't know how to show
[dns] :
shellHelper.show#src/mongo/shell/utils.js:906:11
shellHelper#src/mongo/shell/utils.js:659:15
#(shellhelp2):1:1
> show dbs
2018-03-28T17:59:10.073+0800 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { listDatabases:
1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs#src/mongo/shell/mongo.js:62:1
shellHelper.show#src/mongo/shell/utils.js:769:19
shellHelper#src/mongo/shell/utils.js:659:15
#(shellhelp2):1:1
>
So I can NOT create a user and pwd for this mongoDB. How could I login?
Anybody can tell me how to do the setting step by step to make my mongoDB to authentication? or delete a old mongoDB and create a new one with authutication and also with username and pwd?
I will get an exception below if I tried to set a without auth mongoDB and auth one.
C:\Windows\system32>mongod --auth --port 27017 --dbpath C:\mongodb\data
2018-03-28T16:49:43.874+0800 I CONTROL [initandlisten] MongoDB starting : pid=7
988 port=27017 dbpath=C:\mongodb\data 64-bit host=wolf-PC
.....
2018-03-28T16:49:43.877+0800 I STORAGE [initandlisten] exception in initAndList
en: 98 Unable to create/open lock file: C:\mongodb\data\mongod.lock Another program is using this file.... Is a mongod instance already running?, terminating
I checked the questions:
MongoDB: Server has startup warnings ''Access control is not enabled for the database''
which I failed to follow with step4 on above excpetion.
MongoDB: Server has startup warnings
I got the same exception.
So anyone can give me a detail soultion?
The reason why authentication is not working in your first example is because you have not yet enabled it. Auth is enabled by configuration only and not by the presence of db users. As you already demonstrated, the way to enable auth is to either start the db with the --auth flag or ensure that authorization is enabled within the security section of your mongod.conf file (like below).
security:
authorization: enabled
Once authorization is enabled, you must authenticate first before performing any operations by using the below options when you start the shell.
mongo <db> -u <username> -p <password>
For example, since you already created your myUserAdmin user on the admin database, then you can authenticate like this:
mongo admin -u myUserAdmin -p abc123
Or, if you have already started the shell with just mongo, then you can authenticate like this:
1) First switch to the admin db.
use admin
2) Then authenticate your user:
db.auth('myUserAdmin ', 'abc123')
Also, keep in mind that the userAdminAnyDatabase is a very powerful admin role, but it only allows read/write access to the admin database (not databases that you create to store data for your app). It also enables admin operations (e.g. createUser, createRole, etc) across ALL databases which could be dangerous if compromised.
So, if you are trying to create a user to read/write from a non-system database, then you should create a different, specific user for that. For Example...
1) authenticate your admin user (like what was shown above).
2) create a new user to read/write from your app database:
db.createUser(
{
user: <app db user>,
pwd: <password>,
roles: [ { role: "readWrite", db: <app db> } ]
}
);
Here is more detail about each of the mongodb roles and how they behave.

Graylog2 mongo profiler plugin won't connect to mongo instance, error: "Exception opening socket" (everything dockerized)

I am trying to play with graylog's mongo profiler plugin using docker to run everything. But I can't get any profiling logs into graylog.
When I start the mongo input from the graylog UI it eventually times out with an error:
Timed out after 30000 ms while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:37017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}].
This is my setup based on following the graylog dockerhub installation and the mongo profiler plugin guide and modifying bits:
(1) I bring up graylog, mongo and elastic using a docker-compose file:
version: '2'
services:
some-mongo:
image: "mongo:3"
some-elasticsearch:
image: "elasticsearch:2"
command: "elasticsearch -Des.cluster.name='graylog'"
graylog:
image: graylog2/server:2.2.1-1
environment:
GRAYLOG_PASSWORD_SECRET: somepasswordpepper
GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
GRAYLOG_WEB_ENDPOINT_URI: http://127.0.0.1:9000/api
links:
- some-mongo:mongo
- some-elasticsearch:elasticsearch
ports:
- "9000:9000"
- "514:514/udp"
- "12202:12202"
- "37017:37017"
That has worked fine so far and I've been able to send in syslog udp messages and gelf http messages.
(2) I created a separate mongo docker container with ports mapped because I worry that if I use 27017, that graylog might look in its own internal mongodb container:
docker run -d -p 37017:27017 mongo:2.4
I start a mongo session and enable profiling for a "graylog" database:
$ mongo --port 37017
> use graylog
> db.setProfilingLevel(2)
{ "was" : 0, "slowms" : 100, "ok" : 1 }
> db.foo.insert({_id:1})
// Check that profiling data is being written to system.profile:
> db.system.profile.find().limit(1).sort( { ts : -1 } ).pretty()
{
"op" : "query",
"ns" : "graylog.foo",
"query" : {
},
"ntoreturn" : 0,
"ntoskip" : 0,
....
"allUsers" : [ ],
"user" : ""
}
So it seems like the mongod instance is running and profiling is working.
(3) I download the plugin jar and docker cp it into the plugins dir inside the graylog docker container. Something like:
docker cp graylog-plugin-mongodb-profiler-2.0.1.jar e89a2decda37:/usr/share/graylog/plugin
Then restart graylog.
I can see that the file is there:
$ docker exec -it e89a2decda37 /bin/sh
# ls /usr/share/graylog/plugin
graylog-plugin-anonymous-usage-statistics-2.2.1.jar graylog-plugin-map-widget-2.2.1.jar
graylog-plugin-beats-2.2.1.jar graylog-plugin-mongodb-profiler-2.0.1.jar
graylog-plugin-collector-2.2.1.jar graylog-plugin-pipeline-processor-2.2.1.jar
graylog-plugin-enterprise-integration-2.2.1.jar
So that part seemed to work fine and I can see an entry "Mongo profiler input" in the list of input types in the graylog UI.
(4) I create a "Mongo profiler input" input with:
hostname: localhost
port: 37017
database: graylog
(5) After I click save, the input tries to start then eventually fails like above. Restarting graylog or trying to restart the input results in the same failures.
I have tried step (2) with different versions of mongo in case there was some driver incompatibility but they all fail with same error. I've tried docker images:
mongo:3
mongo:2.6
mongo:2.4
Thanks in advance!
Like Thilo suggested above, the hostname for the graylog input shouldn't be "localhost" as that will point graylog to the docker container hosting it.
So I found the ip of the host machine using:
docker exec -it [CONTAINER ID] /bin/sh
/sbin/ip route|awk '/default/ { print $3 }'
and rewired the input and Bob's your Uncle!

Rubber + Google cloud as generic provider

I've setup and created (manually) instance at google cloud, added my ssh key (from id_rsa.pub) into it, so I can ssh username#x.x.x.x without any password, user set as sudoer.
I've setup 'generic' provider in rubber.yml:
generic: key_file: "#{Dir[(File.expand_path('~') rescue '/root') +
'/.ssh/id_rsa.pub'].first}"
I've set in deploy.rb:
set :initial_ssh_user, 'username'
Now when i am trying to cap rubber:create_staging RAILS_ENV=staging,
After few questions of role/ip its asking me for root password:
** Instance api-staging created: api-staging
Waiting for instances to start
** Instance running, fetching hostname/ip data
.Trying to enable root login
Password for username # x.x.x.x: .
* 2014-11-16 14:07:45 executing `rubber:_ensure_key_file_present'
* 2014-11-16 14:07:45 executing `rubber:_allow_root_ssh'
* executing "sudo -p 'sudo password: ' bash -l -c 'mkdir -p /root/.ssh && cp /home/username/.ssh/authorized_keys /root/.ssh/'"
servers: ["x.x.x.x"]
** Can't connect as user cat.of.duty to x.x.x.x, assuming root allowed
* 2014-11-16 14:07:46 executing `rubber:_direct_connection_x.x.x.x'
* executing "echo"
servers: ["x.x.x.x"]
.. ** Failed to connect to x.x.x.x, retrying
Over and over again

Ansible postgresql_db task fails after a very long pause

The following ansible task (in a vagrant VM) fails :
- name: ensure database is created
postgresql_db: name={{dbname}}
sudo_user: postgres
the task pauses for a few minutes before failing
the vagrant VM is a centos6.5.1,
the tasks output is :
TASK: [postgresql | ensure database is created] *******************************
fatal: [192.168.78.6] => failed to parse:
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo via ansible, key=glxzviadepqkwddapvjheeuillbdakly] password:
FATAL: all hosts have already failed -- aborting
I have verified that postgres is prooperly installed
by doing vagrant ssh and connecting vial psql.
I also validated that I can do a "sudo su postgres" within the VM ...
======== update
It looks like the problem is the sudo_user: postgres, because removing the
above postgres tasks and replacing with this one causes the same problem :
- name: say hello from postgress
command: echo "hello"
sudo_user: postgres
the output is exactly the same as above, so it's really a problem of
ansible doing a sudo_user on centos6.5
one interesting observation, although I can do "sudo su postgres" from
inside the vm
when I call "psql" (as the postgres user) I get the message :
could not change directory to "/home/vagrant": Permission denied
but the psql shell still starts successfully
======== conclusion
Problem was fixed by changing to a stock centos box,
lesson learned : when using ansible/vagrant, only use stock OS images...
I am using the wait for host:
- local_action: wait_for port=22 host="{{PosgresHost}}" search_regex=OpenSSH delay=1 timeout=60
ignore_errors: yes
PS:
I think you should use gather_facts: False and do setup after ssh is up.
Example main.yml:
---
- name: Setup
hosts: all
#connection: local
user: root
gather_facts: False
roles:
- main
Example roles/main/tasks/main.yml
- debug: msg="System {{ inventory_hostname }} "
- local_action: wait_for port=22 host="{{ inventory_hostname}}" search_regex=OpenSSH delay=1 timeout=60
ignore_errors: yes
- action: setup
ansible-playbook -i 127.0.0.1, main.yml
PLAY [Setup] ******************************************************************
TASK: [main | debug msg="System {{ inventory_hostname }} "] *******************
ok: [127.0.0.1] => {
"msg": "System 127.0.0.1 "
}
TASK: [main | wait_for port=22 host="{{ inventory_hostname}}" search_regex=OpenSSH delay=1 timeout=60] ***
ok: [127.0.0.1 -> 127.0.0.1]
PLAY RECAP ********************************************************************
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0

Add new member to replicas set in mongodb with python and subprocess.call

i try to add new member to replicas set in mongodb. there is possibility to
do it with os.system. But how would it be with subprocess.call()?
So far i have:
import subprocess
task='''"rs.add('alehandro-VirtualBox:27067')"'''
port=27072
subprocess.call(["/usr/bin/mongo", " --port {0}".format(port), " --eval {0}".format(task)])
OUTPUT:
MongoDB shell version: 2.4.5
connecting to: --port 27072
Sun Jul 28 16:34:18.884 JavaScript execution failed: Error: [ --port 27072] is not a valid database name at src/mongo/shell/mongo.js:L40
exception: connect failed
Can anybody help me with it?
The mongo process is being invoked with a parameter called --port 27072 and a value of --eval .. because of the way you are passing your parameters to subprocess.call.
If you change the subprocess.call invocation to the following, then it should work :
subprocess.call(["/usr/bin/mongo", "--port", str(port), "--eval", task])