When running a saltstack, for security reasons I don't want them to run as root. Although I would not mind creating a new 'salt' user with NOPASS sudo access to run the salt minion / master on.
My question is that even though the documentation says here: https://docs.saltstack.com/en/latest/ref/configuration/nonroot.html that we can configure salt to run as a non root user, does it append sudo to normal commands instead or looses that functionality entirely.
Additional Research: Both the master and the minion config files have an uption for setting the users to anything other than root but the minion config file has an option to setup a sudo-user which defaults to saltdev but I changed to root. Not sure if this implies that the minion should sudo and use the root account or not. If so, why is this not present on the master config file.
The direct answer to the title question is NO. As stated in the docs:
[...] running the minion as an unprivileged user will keep it from making changes to things like users, installed packages, etc. unless access controls (sudo, etc.) are setup on the minion to permit the non-root user to make the needed changes.
In order to setup sudo on the minion you should use the sudo_user config. After setting a user to this variable Salt will invoke the salt.module.sudo every time a command is issued to this minion.
This sudo option is only available on the minion because the execution of commands on hosts is intended to be made only by the minion. Even if you are managing your master with Salt, the minion inside the master is what runs the commands.
Related
We have a scenario in which single server is running, which is getting data from the network span.
Every developer should work on their machine locally but the data to work on is only available in the server. how can I get the data to be replicated into each developers machine so that once they have completed development on their local machine, developers can push it to a GIT in the server.
PS: The network span data is constantly written to the server (data is in size of 100s of GB's).
What we have tried so far:
So we created a GIT server in the server we were getting the data on. But once a developer log in using his username then he creates a new branch in a directory. This works fine until another developer logs into the server with his username and switches to another branch in the same directory which will cause all the developers branch to the new one. which is not what we were expecting.
Probabily this question should go to https://serverfault.com/, but, anyway...
The git advantage is to have local and remotre repositories, so, in the server, you should have "only" the remote repositories, and they should be cloned in localmachines.
to work with that paradigm, or with the one you are asking for, you need a umask of 007 (depending on your distribution edit /etc/login.defs and change there)
You should have diferent groups for the diferent kind of shared projects, and a user to "own all the repositories", for example, git-adm ).
With all the prerequisites, you create with that user the base folder for all the repositories:
sudo -i
mkdir /srv/git
chown git-adm:gitgrp /srv/git
chmod g+s /srv/git
exit
The last line in the "sticky bite", wich allows to mantain the group (and avoid the problems you previously stated), so, in order to cerate a repository should be something like:
sudo su - git-adm
mkdir /srv/git/<group>/<repoName>.git
cd /srv/git/<group>/<repoName>.git
git init --bare
exit
And thats all: if the folder /srv/git/<group>/ we owned for a diferent group, then it'll keep the group.
I read this article about why you shouldn't run containerized applications as root user,
and I'd like someone to confirm my understanding:
Article brief
The article is basically saying that just as you won't run binaries on your machine
as root, but rather as a least-privileged-required user, you won't run containerized applications as root either.
The recommendation of the author is to create a user with a known uid in the Dockerfile
and run the process as that user.
The start of the dockerfile should look like
this:
FROM <base image>
RUN groupadd -g 999 appuser && \
useradd -r -u 999 -g appuser appuser
<br>USER appuser
... <rest of Dockerfile> ..
Validating my understanding, and some questions:
1. Why bother?
Ok, I understand that it's not good to run a container process as root,
just like it's not good to run any process as root.
That's why we should create a user in the Dockerfile and run the application process as that user.
But, if it's possible to run:
~$ docker run -u 0 some_docker_image
then why bother adding a user to my Dockerfile and switch to that user?
The question boils down to the question: What are we "afraid" of? What is the threat?
If the answer is that we're afraid of some untrusted user connected to the system (who is not a sudoer),
then this user can't even run docker containers, unless he is a member of the "docker" group,
in which case - again - he could run the container with -u 0?
So I guess that we're not concerned about the user. We're concerned about the binary itself.
In that case, two possible options exist:
a. The binary is of our creation. In that case: why are we concerned?
b. The binary is of someone else's creation. In that case i can understand why we would like to
switch user.
Am I missing something?
2. Why "Known uid"?
Why is that important to specify the uid of the newly created user, and not just name it something?
3. Why in the start of the Dockerfile?
Is it important to create+switch to the new user in the beginning of the Dockerfile?
Seemingly, this is an approach that's hard to implement, since usually during the docker build process
you need to run a lot of tasks that require root privileges, such as apt-get install etc.
4. What about adding a user and adding it to sudoers?
I have a case in which I need to create a docker image, which when the container runs,
it'll run a ssh server. In order to run the ssh server, you need root privileges.
Is there a point creating a user, adding it to sudoers, and then run the ssh server as root?
Running as root in Docker is dangerous for most of the same reasons as running as root directly on the host. The container has limited Linux privileges so there are some things it can't do (reconfigure the network, reboot the host), but it can do things like overwrite the application code inside the container.
Nobody's code is absolutely perfect, so one of the big reasons to run as non-root is to minimize the damage possible when a mistake does happen.
It doesn't matter what the user ID is, just that it's not 0. There's an argument to make it different from any uid the host might be using, but since your image could run on any host, it's just a guess.
You should create the user at the start of the Dockerfile, since that setup will change infrequently and Docker layer caching can skip it. But, you should use the USER directive and switch to the user at the end of the Dockerfile, after COPYing code in and RUNning the build. Do not RUN chown ... to make the non-root user own the code: you want most files to be owned by root, so that the non-root user can't overwrite them.
(In a compiled language, with a multi-stage build, you can consider the Dockerfile equivalent of the ./configure; make; sudo make install sequence, switching to a non-privileged user to do the build. I haven't seen this pattern in many Dockerfiles but I'd recognize it if I saw it.)
Do not add a user to /etc/sudoers. There are a couple of good reasons for this. The most basic one is that a container only runs a single process, and as already discussed we probably don't want it to be root. You can either configure it with no password (in which case you might as well be root) or hard-code a password in plain text in your Dockerfile (also a bad idea). You also usually don't want to run sudo inside a script (its behaviors of putting up random password prompts and hiding environment variables can cause trouble), and so correspondingly don't want to RUN sudo ... in a Dockerfile.
If you need to break into a container to debug it, you can always docker exec -u root ... to get a root shell there.
At my workplace we have some computer labs. In these laboratories each computer has the operating system windows and linux. Both systems are in our AD domain.
I did a lab of tests and I have a functional puppet server. I put some nodes/agents as root and Everything working perfectly when I run puppet agent -t.
The problem:
When I log in with a domain user (e.g: xiru) on linux machines and run the puppet agent -t command, a new certificate is generated, but an error occurs warning that it does not match the server's certificate.
For the domain users, the puppet creates the new certificate on the path: /home/<user>/.puppetlabs/etc/puppet/ssl
Linux machines names in the test:
mint-client.mycompany.intra
ubuntu-client.mycompany.intra
I try set certname variable on the puppet conf, but the error remains.
[main]
certname = mint-client.mycompany.intra
[agent]
server = puppet.mycompany.intra
How can I get around this and make it always with the same certificate that I configure via root user?
I think you must setup your environtment to accept non-root users.
When you run it, do you use sudo or the users are present on sudoers?
If its not, on puppet docs theres some tips to run it as non-root users...
Installation and configuration
To properly configure non-root agent access, you need to:
Install a monolithic PE master
Install and configure PE agents, disable the puppet service on all nodes, and create non-root users
Verify the non-root configuration
Install and configure a monolithic master
As a root user, install and configure a monolithic PE master. Use the web-based installer or the text-mode installer.
Use the PE console to make sure no new agents can get added to the MCollective group.
a. In the console, click Nodes > Classification, and in the PE Infrastructure group, select the PE MCollective group.
b. On the Rules tab, under Fact, locate aio_agent_version and click Remove.
c. Commit changes.
Install and configure PE agents and create non-root users
1. On each agent node, install a PE agent while logged in as a root user. Refer to the instructions for installing agents.
2. As a root user, log in to an agent node, and add the non-root user with puppet resource user <UNIQUE NON-ROOT USERNAME> ensure=present managehome=true.
Note: Each and every non-root user must have a unique name.
3. As a root user, still on the agent node, set the non-root user’s password. For example, on most *nix systems run passwd
4. By default, the puppet service runs automatically as a root user, so it needs to be disabled. As a root user on the agent node, stop the service by running puppet resource service puppet ensure=stopped enable=false.
5. Disable the MCollective service on the agent node. As a root user, run puppet resource service mcollective ensure=stopped enable=false.
6. Disable the PXP agent.
a. In the console, click Nodes > Classification* and in the PE Infrastructure group, select the PE Agent group.
b. On the Classes tab, select the puppet_enterprise::profile::agent class, and set the parameter pxp_enabled to false.
7. Change to the non-root user.
Tip: If you wish to use su - <NON-ROOT USERNAME> to switch between accounts, make sure to use the - (-l in some unix variants) argument so that full login privileges are correctly granted. Otherwise you may see “permission denied” errors when trying to apply a catalog.
8. As the non-root user, generate and submit the cert for the agent node. From the agent node, execute the following command:
puppet agent -t --certname "<UNIQUE NON-ROOT USERNAME.HOSTNAME>" --server "<PUPPET MASTER HOSTNAME>"
This Puppet run submits a cert request to the master and creates a ~/.puppet directory structure in the non-root user’s home directory.
9. As an admin user, log into the console, navigate to the pending node requests, and accept the requests from non-root user agents.
Note: It is possible to also sign the root user certificate in order to allow that user to also manage the node. However, you should do so only with great caution as this introduces the possibility of unwanted behavior and potential security issues. For example, if your site.pp has no default node configuration, running agent as non-admin could lead to unwanted node definitions getting generated using alt hostnames, which is a potential security issue. In general, if you deploy this scenario, you should ensure that the root and non-root users never try to manage the same resources,ensure that they have clear-cut node definitions, and ensure that classes scope correctly. As the non-root user, run puppet config set certname <UNIQUE NON-ROOT USERNAME.HOSTNAME> --section agent.
10. As the non-root user, run puppet config set server <PUPPET MASTER HOSTNAME> --section agent. Steps 7 and 8 create and set the configuration for the non-root agent’s puppet.conf, created in /.puppetlabs/etc/puppet/ in the non-root user’s home directory.
[main]
certname = <UNIQUE NON-ROOT USERNAME.HOSTNAME>
server = <PUPPET MASTER HOSTNAME>
11. You can now connect the non-root agent node to the master and get PE to configure it. Log into the agent node as the non-root user and run puppet agent -t.
Source: https://puppet.com/docs/pe/2017.1/deploy_nonroot-agent.html
Check the permissions. To make it work, you can provide relevant permissions to the folder where certificates are stored, so that domain user has permissions on the certificates.
I use a mercurial repository for global configuration. The system config files are linked to /opt/config which is a hg repo owned by root.
I d like all users to be able to update settings from repo i.e. to call hg pull -u in /opt/config
I tried to create the following script
# -rwsr-x--x 1 root users 343 Mar 15 14:10 /bin/update_config
#! /bin/bash
cd /opt/config
hg pull -u
(Pay attention, the s-bit is set) . In this case, hg does not read the settings from /root/.hgrc which contain the HTTP login parameter (user cannot does not know the parameters)
even if I do export HOME=/root the hgrc file is not read.
How should I change my script to make it possible?
EDIT
It seems to be a general permission problem. I use sles11. The line touch /root/bla does not work in this script, why?
Mercurial being a distributed versioning system, it seems to me that you are not using it correctly. If users are required to modify the repository, every user should handle its own repository and then configure it to push into your desired location (/opt/config). Hence, the mercurial workflow will handle the merge problems. If they are only consumers of the repository, you should either 1) create a cron entry to update it automatically or 2) use a continuous integration system like Jenkins or TeamCity that will automatically update the repository when something is pushed to it.
If you still want to realize what you asked, you should look into the sudo command for this purpose. Make the /opt/config ownership to a new passwordless user, configure sudo to allow the switch to this user without password and make the configuration only in ~theuser/.hgrc . This will make it easier to maintain (only a single .hgrc to handle).
Background
My question seems simple, but it gets more complex really fast.
Basically, I got really tired of maintaining my servers manually (screams in background) and I decided it was time to find a way to make being a server admin much more liveable. That's when I found Ansible. Great huh? Sure beats making bash scripts (louder scream) for everything I wanted to automate.
What's the problem?
I'm having a lot of trouble figuring out what user my Ansible playbook will run certain things as. I also need the ability to specify what user certain tasks will run as. Here are some specific use cases:
Cloning a repo as another user:
My purpose with this is it run my node.js webapp from another user, who we'll call bill (that can only use sudo to run a script that I made that starts the node server, as opposed to root or my user that can use sudo for all commands). To do this, I need the ability to have Ansible's git module clone my git repo as bill. How would I do that?
Knowing how Ansible will gain root:
As far as I understand, you can set what user Ansible will connect to the server you're maintaining by defining 'user' and the beginning of the playbook file. Here's what I don't understand: if I tell it to connect via my username, joe, and ask it to update a package via the apt module, how will it gain root? Sudo usually prompts me for my password, and I'd prefer keeping it that way (for security).
Final request
I've scoured the Ansible docs, done some (what I thought was thorough) Googling, and generally just tried to figure it out on my own, but this information continues to elude me.
I am very new to Ansible, and while it's mostly straight-forwards, I would benefit greatly if I could understand exactly how Ansible runs, on which users it runs, and how/where I can specify what user to use at different times.
Thank you tons in advance
You may find it useful to read the Hosts and Users section on Ansible's documentation site:
http://docs.ansible.com/playbooks_intro.html#hosts-and-users
In summary, ansible will run all commands in a playbook as the user specified in the remote_user variable (assuming you're using ansible >= 1.4, user before that). You can specify this variable on a per-task basis as well, in case a task needs to run as a certain user.
Use sudo: true in any playbook/task to use sudo to run it. Use the sudo_user variable to specify a user to sudo to if you don't want to use root.
In practice, I've found it easiest to run my playbook as a deploy user that has sudo privileges. I set up my SSH keys so I can SSH into any host as deploy without using a password. This means that I can run my playbook without using a password and even use sudo if I need to.
I use this same user to do things like cloning git repos and starting/stopping services. If a service needs to run as a lower-privileged user, I let the init script take care of that. A quick Google search for a node.js init.d script revealed this one for CentOS:
https://gist.github.com/nariyu/1211413
Doing things this way helps to keep it simple, which I like.
Hope that helps.
My 2 cents:
Ansible uses your local user (eg Mike) to ssh to the remote machine. (That required Mike to be able to ssh to the machine)
From there it can change to a remote user if needed
It can also sudo if needed and if Mike is allowed. If no user is specified then root will be selected via your ~/.ansible.cfg on your local machine.
If you supply a remote_user with the sudo param then like no.3 it will not use root but that user.
You can specify different situations and different users or sudo via the playbooks.
Playbook's define which roles will be run into each machine that belongs to the inventory selected.
I suggest you read Ansible best practices for some explanation on how to setup your infrastructure.
Oh and btw since you are not referring to a specific module that ansible uses and your question is not related to python, then I don't find any use your question having the python tag.
Just a note that Ansible>=1.9 uses privilege escalation commands so you can execute tasks and create resources as that secondary user if need be:
- name: Install software
shell: "curl -s get.dangerous_software.install | sudo bash"
become_user: root
https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/become.html
I notice current answers are a bit old and suffering from link rot.
Ansible will SSH as your current user, by default:
https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html#connecting-to-remote-nodes
Ansible communicates with remote machines over the SSH protocol. By default, Ansible uses native OpenSSH and connects to remote machines using your current user name, just as SSH does.
This can be overridden using:
passing the -u parameter at the command line
setting user information in your inventory file
setting user information in your configuration file
setting environment variables
But then you must ensure a route exists to SSH as that user. An approach to maintaining user-level ownership I see more often is become (root) and then to chown -R jdoe:jdoe /the/file/path.
In my 2.12 release of ansible I found the only way I could change the user was by specifying become: yes as an option at the play level. That way I am SSHing as the unprivileged, default, user. This user must have passwordless sudo enabled on the remote and is about the safest I could make my VPS. From this I could then switch to another user, with become_user, from an arbitrary command task.
Like this:
- name: Getting Started
gather_facts: false
hosts: all
become: yes # All tasks that follow will become root.
tasks:
- name: get the username running the deploy
command: echo $USER
become_user: trubuntu # From root we can switch to trubuntu.
If the user permitted SSH access to your remote is, say, victor, and not your current user, then remote_user: victor has a place at the play level, adjacent to become: yes.