The concept of file permissions and ownership is crucial in preventing private or sensitive data from being exposed to dodgy actors. In this guide, we will explain Linux file permissions and ownership to help us improve the security of our Network Node server.
Our Ursa CLI process is run by a
user, that has some sort of permissions, some users run it as
root which should be considered, as
root privileges are not a necessary good.
Let's discuss the topic and open up a few ideas to help us improve the security of our server!
To follow the guide, you will need the following:
- Familiarity with the command-line interface
- A supported Linux Server Operating system
- Ubuntu (22.04 LTS), or earlier
- Debian (version 11), or earlier
- ArchLinux, which has rolling updates.
- Ursa Network Node installed and running correctly
A walkthrough video is provided as a quick reference for the users, we try to keep it simple and would suggest the text guide version to get more detailed information.
The video content is stored in our Fleek Network playlist on the Fleek XYZ Youtube channel.
How do you find the video content? Help us improve by sending feedback in our Discord channel here.
Why should I care?
You should be interested in securing the server, to prevent unwanted access to sensitive data, for instance, your identity (private keys) to which the rewards are sent!
This can happen in many ways, but if you follow good practices you can reduce some of the risks managing the server where the Ursa Network Node is run.
A Linux server is a multi-user system that uses permissions and ownership has security. By allowing multiple users into a system, trust has to be thought out! There should be a way to control file permissions, naming who's allowed to access what, and in which locations.
Ideally, you should be the only actor who can read or modify the private keys. The processes or programs installed should not be able to read your private files without permission. For example, if you run a random script from the internet, as
root, and if the script is maliciously targeting Fleek Network node operators, your identity and private data can be compromised. There'll be no one to help you or blame than yourself!
As the Wu-Tang once rapped about "Protect ya neck".
How do I know if my system is vulnerable?
If you are running the Docker Stack, or the Ursa CLI, as the
root user, your file permissions are likely in need of good care.
On the other hand, if you have questions, or are curious, about where your identity (private keys) is kept and don't know how to improve the security of the files, then this is a good start! You'll also find our guide about Managing the key store a good read.
There's also a section in this about How to check if the Ursa directories are secured
Securing the Ursa home directory
We'll look into securing access to the
$HOME/.ursa directory, where sensitive data, such as the identity is stored. Providing control to specific users or groups helps prevent unwanted access to private files. Don't trust, verify!
"Trust leads to the dark side." - Obi Wan Kenobi
💡 For our example, we are sticking with Ubuntu, do the equivalent for your OS. We'll assume that you are login as
root, to emphasize our goal. Additionally, we're going to use the Docker Stack, but it should be similar even if you have Ursa installed natively, but you'll have to do the required tweaks accordingly.
What's the relation with running the node?
Before we get started, let's look at how the
Docker daemon works! Your container runs one single process. The process runs as a
UID:GID (User:Group), just like any other process on your system. We should set the permissions on the directory we bind mount accordingly!
This means that the same principle is applied if running the Node natively! In other words, there is nothing special about this process running in the container - treat it as if it wasn't!
Docker daemon runs as the
root user, the
root user has full control of the system and has the power to do some nasty things if not careful. You can run Docker daemon without root (Rootless mode) and docker provides documentation about it.
For our use-case, we want to run the Docker Stack as a non-administrative user (lower permissions in the system), as our service is meant to be run with non-root privileges, and ideally, only elevate their privileges to modify the underlying system when authorized. In any case, be aware that even if you can start the docker daemon without root, you'd still have the ability to start our Docker Stack with root, which is something we want you to avoid doing, as it's not necessary.
Stopping the Network Node
Before going any further, let's stop the Docker Stack (a must, if you have started the Fleek Network Ursa Docker Stack with
root user). If you're following while running in a native setup, you need to stop the
ursa cli process, as mentioned earlier we'll stick with the Docker stack as an example, so apply the required tweaks where needed.
Change the directory to the Ursa repository (by default, located in
docker compose -f ./docker/full-node/docker-compose.yml down
Afterward, we'll run the Docker Stack as a new user with non-root privileges.
Group existence checkups
Start by checking if the
docker group exists in the system by running the following command (if the
docker group exists, you should get the response "🥳 Docker group exists!").
💡 If you are following this guide while running a native build, you don't need a
docker group, but you might consider creating a group meant to manage and run the Ursa process, you can name it whatever is more meaningful to you. We'll stick with the Docker Stack setup as an example, and apply the required tweaks where necessary.
cat /etc/group | grep 'docker' > /dev/null && echo "🥳 Docker group exists!"
If not, create the
sudo groupadd docker
Create a new user for running the node
Add a new user with the following command:
sudo adduser <YOUR-USERNAME>
For our example, we'll name it
skywalker but you can choose any other name:
sudo adduser skywalker
Let's add the user
skywalker to the docker group:
sudo usermod -aG docker skywalker
⚠️ If you are following this guide on a native setup, you won't need a
docker group, but another group of your liking might apply. Make the required tweaks as necessary, as we'll stick with Docker Stack as an example.
💡 You may have to restart the Docker daemon (which requires
sudo if you are not
Restart the docker daemon
stop and then
systemctl stop docker
systemctl start docker
From now on, the user
skywalker will have the ability to
down the Docker Stack without
# Change directory to where Ursa repository is stored
# by default `$HOME/fleek-network/ursa`
# e.g., if you've installed as user `root` it'll be located
# in `/home/root/fleek-network/ursa` by default
# after switching user you'd have to `mv` or `reinstall`
# to have it in the /home/username/fleek-network/ursa path
# The `down` command
docker compose -f ./docker/full-node/docker-compose.yml down
# The `up` command
docker compose -f ./docker/full-node/docker-compose.yml up
Things to have in mind
Here are a few things to have in mind - there are more -, but these are the ones that came to mind at the time of writing (feel free to contribute or provide feedback):
- Our recommendation is to keep the user
sudoerslist, as a proper Jedi, we separate ourselves from the dark forces
- Advanced users might customize their system as they wish, here we try to provide knowledge for the inclusivity of all kinds of knowledge users
- You should NOT run the Fleek Network Stack with
sudoallows users to execute system commands with
- A user in the
sudoerlist can do whatever he wants in the system
- Do not trust users e.g., anyone might run a script or command that exposes or compromises your private keys located in
- Users who logged in as
rootduring the installation, most likely have it installed under
/home/root/fleek-network/ursa, meaning that when switching users have to move the
Move the Ursa source to the new user's home
Since we are logged in as, installed as, and running as
root, our Ursa repository is stored in the
$HOME/fleek-network by default, which
/home/root. The user
skywalker won't have permission to read, write or execute in or from the directory. We'll then either, reinstall the Ursa using our assisted installer after we switch the user to
skywalker, or move
mv the directories beforehand.
We're going to opt to move the directories, as an example but if you have a preference for running the assisted installer, that's fine! Do remember to remove or delete the
/home/root/.ursa (⚠️ be careful, the
.ursa directory has your private keys, so do a backup otherwise you'll lose it and we won't be able to help).
💡 Notice that we are using the default
$HOME/fleek-network/ursa path, you may have installed it in a different location, so tweak it accordingly to your customizations
mv /home/root/fleek-network /home/skywalker/
This is how the directory
/home/skywalker/fleek-network looks like at the time of writing:
We do the same for
mv /home/root/.ursa /home/skywalker/
This is what the directory
/home/skywalker/.ursa looks like at the time of writing:
│ ├── index_provider_db
│ └── ursa_db
Changing Ursa files ownership
We haven't yet switched from
skywalker, so before we switch from
skywalker, we're going to change the owner of the
$HOME/.ursa directory, where sensitive data is located (in particular the private identity keys).
chown -R skywalker:skywalker /home/skywalker/.ursa
Including, changing permissions for the directory
$HOME/.ursa and files recursively (the parent and nested child directories and files), granting read, write and execute permissions for the user
skywalker and group
chmod -R u+rwx /home/skywalker/.ursa
Following up, we say g
group and o
other should NOT have read, write and execute permissions for
chmod -R go-rwx /home/skywalker/.ursa
Alternatively, you can do
chmod -R 700 /home/skywalker/.ursa, but as we are aiming for clarity in the instructions, we opted for the clearest option to suit more users.
Switching to the non-administrative user
Finally, we switch to the user
Change the directory to the
skywalker Ursa's source repository path:
Start Ursa as the non-administrative user
Start the Docker Stack as
skywalker by executing the following command that you should be familiar with at this point:
docker compose -f ./docker/full-node/docker-compose.yml up
💡 Use the flag
--detach at the end to start the Docker Stack in detached mode if you'd like to run the containers in the background (meaning that the process does NOT communicate via the screen and the keyboard, e.g., avoid displaying the log output which can be enabled at any time with
docker compose -f ./docker/full-node/docker-compose.yml up --detach
Make sure everything's ok by doing a quick health check. If you'd like to learn more about health checks, check our guide here.
You can do this check in any location, but ideally from outside the server network to ensure you're making a remote call
curl -w "\n" https://YOUR-DOMAIN-NAME/ping
Should reply with the response
That's it skywalker! If you've followed this guide successfully, you've secured the
.ursa directory, the configuration files and your private keys.
How to check if the Ursa directories are secured?
It's a good practice to verify the health of your setup from time to time. Doing a permissions checkup on the file system gives you peace of mind and helps ensure that sensitive data is protected.
⚠️ You're required to have followed the steps before to secure the
.ursa configuration directory and also run the Node as non-root. If you haven't yet, follow the steps provided here.
We're using the example username
skywalker, change to the one you've used on your setup accordingly.
Use the ls command to list information about the files. For example, we can check the parent directory with
ls and the
ls -l /home/skywalker/.ursa
You can keep inspecting the nested directories but it's quite a lot of labor.
-rwx------ 1 skywalker skywalker 687 Feb 15 18:24 config.toml
drwx------ 4 skywalker skywalker 4096 Feb 15 18:24 data
drwx------ 2 skywalker skywalker 4096 Feb 15 18:24 keystore
You can check all the directories and files recursively if you wish. For example:
find $HOME/.ursa -printf '%M %u %g %p\n' | less
You can exclude certain directories, for example, let's filter out the
find $HOME/.ursa -printf '%M %u %g %p\n' | grep -v "$HOME/.ursa/data" | less
Here's what the output looks like at the time of writing:
drwx------ skywalker skywalker /home/skywalker/.ursa
-rwx------ skywalker skywalker /home/skywalker/.ursa/config.toml
drwx------ skywalker skywalker /home/skywalker/.ursa/keystore
-rwx------ skywalker skywalker /home/skywalker/.ursa/keystore/default.pem
In the outputs, we can see the
UID:GID (user:group) identifiers and also in the left bit the permissions that are set.
🤔 Try to read it this way, the first character is the file type while the remaining is the access permissions.
d represents a directory, when not
file, we then have
rwx for read, write and execute for section
Notice that after,
------ there's nothing set for
other. In short (file type)(user permissions)(group permissions)(other permissions).
Also, remember that the group may have permissions, and when a user is added to the group it'll inherit those permissions.
We started by declaring that is crucial to learn about Linux file permissions and ownership, to improve the security of our server, also protect sensitive data from being captured by malicious actors.
Used the Docker Stack for guidance, where we instruct how to start it without
sudo, learned how to create a new user and groups, and change ownership and permissions in the file system, including the
.ursa configuration files where the identity or private keys are stored.
Finally, completed our guide by demonstrating how to check if the Ursa directories are secured by providing some command examples and a description to help understand the attributes that describe the file types and permissions.
The guide serves as a getting started in the subject and in any way tries to fulfill the role of granting the ultimate security of the server. For advanced topics in securing a Linux server, it's best to invest time and better resources which is not possible in the scope of this short guide: the knowledge of Linux security is applicable in the context of running a Fleek Network node.
If you'd like to contribute and share your knowledge you are free to do so by providing us a PR in our repository here.
Discover more about the project by watching/contributing on Github, following us on Twitter, and joining our community Discord for all the best updates!