With this uncomplicated recipe, you will learn how to manage ports on your raspberry pi (or any Debian), and how to enable remote access to your database server. The installation of mongodb on the pi is also covered.
So you know how to install a raspberry pi 3B+ , and you have seen how easy it is to set up a database for data logging and analysis with mongoDB .
Actually, the two work very well together. You can set up your database on the pi, which consumes so little power that you can afford to leave it always on to log your data. And simultaneously, you can analyse this data remotely from your laptop.
In this post, you will learn how to:
However, we are not going to deal with the security of the mongodb server.
First of all, querying a database can be an expensive operation, so I suggest you to choose the relatively powerful raspberry pi 3B+.
If not already done, follow the standard method to install Raspbian on the pi , or perform a headless install. I've explained the headless install on a raspberry pi zero W, but the method works just as well on the 3B+.
Now we move on to the installation of mongoDB.
One thing to keep in mind is that Raspian is a 32 bit system. Therefore, we can only install the 32 bit version of mongoDB. And in this version, the amount of data that can be stored in the database is limited to about 2 GB . Still, it could be more than enough for a pi-based project, which by essence is probably not too ambitious.
Also, MongoDB does not provide a package for the raspberry pi. That's not a problem, as mongodb is included in the raspbian distribution. To install it, just do:
sudo apt install mongodb
sudo systemctl enable mongodb
Then, you can test it using the mongo shell. Type:
mongo
And in the mongo shell do the following:
> use test
switched to db test
> db.col.insert({a:1})
> db.col.insert({a:2})
> db.col.find()
{ "_id" : ObjectId("5ce6ad86dace0cba25fa3458"), "a" : 1 }
{ "_id" : ObjectId("5ce6ad8bdace0cba25fa3459"), "a" : 2 }
We see that we can retrieve the two documents we have inserted in the database.
Now let's see how to access the database remotely.
Log in another computer featuring a terminal. It could be a mac or a Linux PC. Let's assume that the IP address of your pi is 192.168.1.10.
First, install mongodb on this computer to obtain the mongo shell. Then try to connect to the mongoDB server running on the pi:
> mongo 192.168.1.10
MongoDB shell version v4.0.9
connecting to: mongodb://rasptest2.lan:27017/test?gssapiServiceName=mongodb
2019-05-23T16:27:44.934+0200 E QUERY [js] Error: couldn't connect to server 192.168.1.10:27017, connection attempt failed: SocketException: Error connecting to rasptest2.lan:27017 (192.168.86.70:27017) :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:343:13
@(connect):2:6
exception: connect failed
We see that the connection is refused... Let's investigate.
Go back to the pi, and install lsof, which is a handy tool to list the open ports on a machine:
sudo apt install lsof
Then, do:
> sudo lsof -i -P -n | grep LISTEN
mongod 312 mongodb 9u IPv4 11595 0t0 TCP 127.0.0.1:27017 (LISTEN)
mongod 312 mongodb 11u IPv4 11597 0t0 TCP 127.0.0.1:28017 (LISTEN)
sshd 533 root 3u IPv4 14346 0t0 TCP *:22 (LISTEN)
sshd 533 root 4u IPv6 14348 0t0 TCP *:22 (LISTEN)
Let's have a careful look at this output.
On my pi, we see that 3 ports are open to IPv4 addresses: 27017, 28017, and 22.
But first of all, what's a port? you can see it as a plug through which network communications can enter and exit the computer. For two computers A and B to communicate, a connection must be established between port X of computer A and port Y of computer B.
On each computer, it is possible to decide to close a port completely, or to open it only to a selection of IP addresses, by setting up a local firewall on the computer.
Let's go back to the printout of lsof for our pi, and consider this line:
sshd 533 root 3u IPv4 14346 0t0 TCP *:22 (LISTEN)
This means that the sshd daemon (the ssh server) is listening to port 22. In other words, all connections made to this port from a remote computer will be handled by the sshd server. Also, *:22 means that this port is open to all IP addresses. So we can connect to this computer with ssh from anywhere. Of course, if the traffic to port 22 is blocked between the remote computer and the pi, e.g. by a firewall, the connection will still fail.
Now let's have a look at the two lines concerning mongod, the mongoDB daemon:
mongod 312 mongodb 9u IPv4 11595 0t0 TCP 127.0.0.1:27017 (LISTEN)
mongod 312 mongodb 11u IPv4 11597 0t0 TCP 127.0.0.1:28017 (LISTEN)
These two lines correspond to two different ports, 27017 and 28017. The first one is used for standard connections to databases on the mongoDB server. The second one is used to administrate the server with a web interface, more on that later. We see that both ports are only open to 127.0.0.1, which is the localhost address.
And this is the reason why we cannot connect!
Now let's see how to open these ports
In most linux distributions, the local firewall is managed by iptables. This tool is extremely flexible but a bit difficult to configure... Actually, I never bother using it directly.
Instead, I use ufw, which is a high-level interface to iptables. It's easy, hence the name: the uncomplicated firewall.
First, let's install it:
sudo apt install ufw
Then, we're going to configure a few rules:
sudo ufw allow ssh
sudo ufw allow 27017
sudo ufw allow 28017
The first line allow ssh connections from the outside. It's very important to add this rule before enabling ufw if you need remote ssh access to the computer.
The next two lines open the two mongodb ports to the outside world.
⚠️ A word of caution. We are now opening our mongodb ports to remote connections, and we have not secured our mongodb server... This means that in principle, anybody will be able to connect to the server.
This is bad practice, but you might find it acceptable if your local network is protected by a firewall. For instance, the firewall on my internet router blocks the 27017 and 28017 ports. So the only machines that are able to access my mongodb server are the ones that are already connected to my local network. I'm ok with this situation at home, but I would never do that in a professional environment.
That's your choice and your responsibility.
If you are sure about what you're doing, you can now enable ufw, and check its status:
sudo ufw enable
sudo ufw status
We have one more thing to do to enable remote connection to the mongodb server. Edit the mongodb configuration file:
sudo nano /etc/mongodb.conf
And comment this line:
# bind_ip = 127.0.0.1
Now, restart the mongodb service:
sudo systemctl restart mongodb
Now open a browser on a remote computer, and go to the following url, which specified the IP address of the pi, and the port of the mongodb web interface:
http://192.168.1.10:28017/
You should land on a page like this:
And finally, we can test the remote access to our database. On the remote computer, start the mongo command line client:
mongo 192.168.1.10
And access your database:
> use test
switched to db test
> db.col.find()
{ "_id" : ObjectId("5ce6ad86dace0cba25fa3458"), "a" : 1 }
{ "_id" : ObjectId("5ce6ad8bdace0cba25fa3459"), "a" : 2 }
It works! You can now fill and read the database remotely.
In this post, you have learnt how to:
Please keep in mind that I have not addressed the security of the mongodb server. I will do so in a future post, when I secure my server.
Until then, you should make sure that the mongodb ports are blocked by your router firewall.
Please let me know what you think in the comments! I’ll try and answer all questions.
And if you liked this article, you can subscribe to my mailing list to be notified of new posts (no more than one mail per week I promise.)
You can join my mailing list for new posts and exclusive content: