Running docker commands with an user without root privileges (possibly with www-data user of Apache) - apache

I am developing a simple Flask application (configured with a Apache webserver) which provides a web interface for docker management. My apache server runs as ‘www-data’ user and it uses the same for all of its API operations.
But i get the ‘Permission denied’ error for the following,
docker images
docker run, etc…
as it doesnt allow ‘www-data’ user to run the above commands.
Can you please provide me a suggestion on using the ‘www-data’ user for docker operations.
I dont want to add ‘www-data’ user to sudoers list.
Is adding the user to docker group alone will be a proper solution ???
Or please suggest me a best practice solution for this.
Thanks
GuruPrasad

It would be easier, clearer, and no less dangerous to tell Apache to run your process as root.
Remember that, if you can run any Docker command at all, you can trivially get unrestricted root-level access to anything on the system. For example, if your tool decides it really does want www-data to be in the host's sudoers list, it can
docker run --rm -v /:/host busybox \
sh -c 'echo www-data ALL = (ALL) NOPASSWD: ALL >> /host/etc/sudoers'
Depending on what your management tool does, it potentially is offering equal unprotected root-level access to the host to anyone who can reach the Web page. Even if it isn't, you need to be extremely careful with how you invoke Docker (another SO answer I was looking at had the potential to root the system if a user could create a directory with an arbitrary name and run the script from there, for instance).

Related

AUTH (crontab command not allowed) - Bitnami LAMP Stack centos

I'm trying to setup a crontab to execute at set intervals. The crontab job is setup as part of my PHP-Slim application running on Apache. For some reason, it just doesn't add the job to the crontab, so when I run the command:
crontab -u daemon -l
It says 'no crontab for daemon' (daemon is the default Apache account). I did manage to get the cronjob manually added using another account (and it executes with no further issues) so it's most likely a permissions issue. What is the best way to troubleshoot this, without resorting to things like chmod 777 (it will be a production server so I need to careful with setting permissions and documenting them)?
Managed to find the answer just after posting.
I looked in the log file for cron:
cat /var/log/cron
Lots of (daemon) AUTH (crontab command not allowed) error messages. Some further googling lead me to look at /etc/cron/allow which doesn't exist, but /etc/cron.deny does, and the daemon account was listed there. Problem solved.
By default we do not allow the user daemon to run crontab jobs. If you want that user to run crontab jobs, you would need to modify /etc/cron.deny and remove the daemon user from there.
Hope it helps.

Dockerfile privileged flag for Docker container (Needed because of Apache error ulimit ) AWS

I would like to start a container with privileges. Manually I can do that directly by typing:
sudo docker run -privileged name/image
But how can I generated a container from a Dockerfile with privileges, is there any command to do that in the dockerfile?
In my case I am doing a deployment in amazon, in case it can not be done from a Dockerfile can it be done from the Dockerrun.aws.json?
PS. To give some context to the question, I need privileges in the docker container to be able to change the ulimit because of apache.
Edit:
I don't change it locally in the container because in Docker the ulimit of the container is the one of the host. That is why the change doesn't affect the container if I change it locally.
Running the container with elevated privileges probably raises all sorts of security and reliability issues.
I would suggest that rather than starting the whole Docker session with elevated privileges, which will potentially mean that everything run on it will have elevated privileges, instead you create a docker container with an changed number set for ulimit.
I am not an expert but the instructions for creating your own container look clear enough then sudo vi /etc/security/limits.conf within your new container, changing soft nofile and soft nproc, save and then export the new container seems the way to go. You can then run the new container with normal privilege levels.
The other option that seems to be used in many places is to run multiple container instances so as to avoid congestion issues.

Connecting to a running docker container - differences between using ssh and running a command with "-t -i" parameters

Could you please point me what is the difference between installing openssh-server and starting a ssh session with a given docker container and running docker run -t -i ubuntu /bin/bash and then performing some operations. How does docker attach compare to those two methods?
Difference 1. If you want to use ssh, you need to have ssh installed on the Docker image and running on your container. You might not want to because of extra load or from a security perspective. One way to go is to keep your images as small as possible - avoids bugs like heartbleed ;). Whether you want ssh is a point of discussion, but mostly personal taste. I would say only use it for debugging, and not to actually change your image. If you would need the latter, you'd better make a new and better image. Personally, I have yet to install my first ssh server on a Docker image.
Difference 2. Using ssh you can start your container as specified by the CMD and maybe ENTRYPOINT in your Dockerfile. Ssh then allows you to inspect that container and run commands for whatever use case you might need. On the other hand, if you start your container with the bash command, you effectively overwrite your Dockerfile CMD. If you then want to test that CMD, you can still run it manually (probably as a background process). When debugging my images, I do that all the time. This is from a development point of view.
Difference 3. An extension of the 2nd, but from a different point of view. In production, ssh will always allow you to check out your running container. Docker has other options useful in this respect, like docker cp, docker logs and indeed docker attach.
According to the docs "The attach command will allow you to view or interact with any running container, detached (-d) or interactive (-i). You can attach to the same container at the same time - screen sharing style, or quickly view the progress of your daemonized process." However, I am having trouble in actually using this in a useful manner. Maybe someone who uses it could elaborate in that?
Those are the only essential differences. There is no difference for image layers, committing or anything like that.

Allowing a PHP script to ssh, using sudo

I need to allow a PHP script on my local web server, to SSH to another machine to perform a specified task on some files. My httpd runs as _www with low permissions, so setting up direct passwordless SSH is difficult, not to say ill-advised.
The way I do it now is to have a minimal PHP script that sudo-exec's (as me) a shell script which is outside of the document root. The shell script in turn calls (as me) the PHP code that does the actual SSH work, and prints its output. Here's the code.
read_remote_files.php (The script I call from my browser):
exec('sudo -u me -n /home/me/run_php.sh /path/to/my_prog.php', $results);
print $results;
/home/me/run_php.sh (Runs as me, calls whatever it's given):
php $1 2>&1
sudoers:
_www ALL = (me) NOPASSWD: /home/me/run_php.sh
This all works, as my_prog.php is called as me and can SSH as me. It seems it's not too insecure since run_php.sh can't be called directly from a browser (outside document root). The issue I'm having is that my_prog.php isn't called as an HTTP program so doesn't have access to the HTTP environment variables (DOCUMENT_ROOT etc).
Two questions:
Am I making this too complicated?
Is there an easy way for my final script to get the HTTP variables?
Thanks!
Andy
Many systems do stuff like this using a (privileged) cron job that frequently checks for the existence of a file, a database record or some other resource, and then performs actions if there are any.
The huge advantage of this is that there is no direct interaction between the PHP script and the privileged script at all. The PHP script leaves the instructions in a resource, the privileged script fetches it. As long as the instructions can't lead to the system getting compromised or damaged, it's definitely more secure than sudoing.
The disadvantage is that you can't push changes whenever you like; you have to wait until the cron job runs again. But maybe it's an option anyway?
"I need to allow a PHP script on my local web server, to SSH to another machine to perform a specified task on some files."
I think that you are phrasing this in terms of a solution that you have difficulty in getting to work rather than a requirement. Surely what you should be saying is "I want to invoke a task on machine B from a PHP script running under Apache on Machine A." And then research solutions to this -- to which there are many from a simple 'roll-your-own' RPC tunnelled over HTTP(S) to using an XMLRPC or SOA framework.
Two caveats:
Do a phpinfo(); on both machines to check what extensions are available and
Also check your php.ini setting to make sure that your service provider hasn't disabled any functions that you expect to use (or do a Q&D script to echo 'disable_functions = ' . ini_get('disable_functions') . "\n"; ...)
If you browse here and the wider internet you'll find many examples. Here is one that I use for a similar purpose.

Ldap server for developer

I am developing a project and that requires ldap validation. But, I don't have a developer/qa ldap server.
Does a small ldap server exist for windows for testing/development?.
I just want to test to validate a active account and detect if it is blocked or not, so i don't want to install a whole domain to do that.
---never mind---
I tried an compiled openldap but I was unable to understand it. Simply, I don't get how to connect to it, how to create a account and how to validate, the client ldap returned me some obfuscate error message, i tried several ways to do it and finally i give up.
Finally, i installed a domain, it was absurdly easy to install (2008 r2), restart the server and that's it.
Anyways, thanks for the advice of opendlap and aldps
If you're on Windows and use Active Directory, have a look at Active Directory Lightweight Directory Services (AD LDS) - a LDAP server you can install and use on your dev machine.
The open source LDAP server from OpenLDAP should give you what you need:
http://www.openldap.org/
Apache provide a directory server called "ApacheDS"(Apache Directory Server), and it provides a GUI management client called "Apache Directory Studio" which is based on Eclipse.
If you want to have a test only, this studio provides a built-in server for your test, easy to link.
You can also install the studio directly in Eclipse using this update site: http://directory.apache.org/studio/update/2.x/
Active Directory works fine as an LDAP server and its included in the Windows Server 2008 trial. See the answer to my question Testing LDAP Connections to Active Directory Server. I have it running in a KVM virtual machine on Linux and query it from an OpenLDAP based client.
Necromancing.
I've had the same problem.
OpenDS is very easy to get up and running, and doesn't require administrator rights.
You just need to download the ZIP file and run the installer.
The installer can populate the directory with test entries, too - if you want to see some example data.
That's exactly what you're looking for when wanting a simple dev test server.
Note:
OpenDS development has seized, and was forked into OpenDJ, a commercial project by forgerock.
While OpenDS still works on Java7, only OpenDJ will work with Java8.
However, OpenDJ is still FREE and OpenSource.
You can find the sourcecode here on Bitbucket
and you can grab it with git:
git clone https://stash.forgerock.org/scm/opendj/opendj.git
Forget OpenLDAP and AD-LDS; these are way too complicated for simple testing.
In addition, their user interface is horrible, and you need something that you can get up and running FAST, without admin rights, and have it populated with test data in a few minutes, not in a few weeks.
And ApacheDS will require administrator privileges, unfortunately (because it only works as windows service, and you can't start/stop these without being administrator).
So OpenDJ is the definite way to go.
Apache Directory Studio is a good client to browse, edit and import/export data via LDAP (LDIF).
However, despite Apache Directory Studio being written in Java, it adds a dependency to gtk, and only has binaries for x86/x64, which means it won't work on a Chromebook with ARM processor, or on a RaspberrryPI.
But with the test entries added automagically in OpenDJ/OpenDS (if you choose the option), you don't even need that.
When in doubt, use a web based interface that "talks LDAP".
Try OpenDS it is very simple and requires only Java.
You could roll your own LDAP server for testing pretty easily using godap: https://github.com/bradleypeabody/godap
It's written in Go. It's very small and simple.
You would basically need to copy the server example out of godap_test.go and wire it up however you need.
Try simple-ldap-server
I know its pretty late to answer this question. But for the reference of someone who runs into the same question.
I wrote a simple ldap server(using ldapjs on nodejs) for authentication testing purposes. Please feel free to use it. It's easy to configure. Can support both LDAP/LDAPS protocols, just require a json file including the user ids you want to add(or it comes with a pre-included users json file, which you can use if you want).
The project is on github. (I'll add a docker image too)
Feel free to visit and use
Docker image
Simple Ldap Server Git
OpenLDAP. Ships with most Unixes and Linuxes. For Windows it is available from several sources:
Cygwin
http://www.userbooster.de
as the Silver (free) edition of the CDS product http://www.symas.com/cds.shtml. This is crippled compared to the Userbooster version, which is complete.
You can use a Docker container with Samba as Domain controller, here I show how to setup one in just a few minutes
Basically you need to
Create an image with this (read the post if you want to know why)
$ git clone https://github.com/padiazg/alpine-samba-ad-container.git
$ cd alpine-samba-ad-container
# replace your-user with your username
$ docker build -t your-user/alpine-samba-ad-container .
Create some folders and files to persist the container data
mkdir /tmp/krb-conf
&& mkdir /tmp/krb-data
&& mkdir /tmp/smb-conf
&& modir /tmp/smb-data
&& touch /tmp/krb-conf/krb5.conf
Run the container
docker run -d \
-e SAMBA_ADMIN_PASSWORD=a-secure-password \
-e SAMBA_DOMAIN=local \
-e SAMBA_REALM=local.your-domain.io \
-e LDAP_ALLOW_INSECURE=true \
--mount type=bind,source=/tmp/krb-conf/krb5.conf,target=/etc/krb5.conf \
--mount type=bind,source=/tmp/krb-data,target=/var/lib/krb5kdc \
--mount type=bind,source=/tmp/smb-conf,target=/etc/samba \
--mount type=bind,source=/tmp/smb-data,target=/var/lib/samba \
-p 389:389 \
--name smb4ad \
your-user/alpine-samba-ad-container
And now you are good to go