What does this haproxy statement mean: Unfortunately many administrators confuse "start as root" and "run as root" - haproxy

there is one statement in haproxy "Security consideration" section:
Unfortunately many administrators confuse "start as root" and "run as root", resulting in the uid change to be done prior to starting haproxy, and reducing the effective security restrictions.
https://cbonte.github.io/haproxy-dconv/2.3/management.html#8
I don't get the point, by right, when we start the haproxy, for simplicity, let me use linux default nobody account:
we need to config it in /etc/haproxy/haproxy.cfg glboal section:
uid 99
gid 99
and then start haproxy
done
ps -lef|grep "haproxy"
5 S nobody 25613 1 0 80 0 - 6446 ep_pol 17:16 ? 00:00:00 /usr/local/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid
we can see that nobody is the process owner
I mean by right, the uid and gid config should be done prior to starting haproxy,
why that statement suggest it's wrong to do so?
I'm trying to understand what it implies, I got this:
may be it suggest we should use root user for the config:
uid 0
gid 0
and then start haproxy,
and then change uid and gid to another user,
and then restart it
Again, I don't understand the point.

On most UNIX system are ports below 1024 defined as privileged ports check this answer https://stackoverflow.com/a/10182831/6778826
When you want to bind to port 80/443 or any other port below 1024 HAPorxy must start as root. After the bind was done switch HAProxy to the defined unprivileged user which is defined in the config file.
From your steps is the last one not necessary.
may be it suggest we should use root user for the config:
uid 0
gid 0
and then start haproxy,
and then change uid and gid to another user,
# and then restart it <= this is not necessary
listen on privileged ports and accept requests

Related

What difference does specifying the user root make in a systemd service?

Which user is a systemd service run as by default in a centos if no user is explicitly specified?
My assumption was that the service would then run as root. However, there seem to be differences in terms of permissions if you explicitly specify User=root.
[Unit]
Requires=docker.service
After=docker.service
[Service]
User=root
...
ExecStartPre=/usr/local/bin/docker-compose down -v --remove-orphans
ExecStartPre=/usr/local/bin/docker-compose rm -fv
ExecStart=/usr/local/bin/docker-compose up --remove-orphans
[Install]
WantedBy=multi-user.target
In this specific case, a docker compose up is executed in the systemd service. The docker images are obtained via the ECR. The credentials for this are provided using amazon-ecr-credential-helper.
When trying to get the image from the ECR, the error message you get is "no basic auth credentials".
But since everything works as desired if you specify the user=root in the systemd service, I assume that the configuration of the amazon-ecr-credential-helper works with docker and that the problem is to be found in the systemd context.
Does any of you have any idea what the explicit specification user=root does?
From man systemd.exec:
User=, Group=
Set the UNIX user or group that the processes are executed as, respectively. Takes a single user or group name, or a numeric ID
as argument. For system services (services run by the system
service manager, i.e. managed by PID 1) and for user services of
the root user (services managed by root's instance of systemd
--user), the default is "root", but User= may be used to specify
a different user...
The default is already root. Specifying User=root does not change anything except perhaps to be explicit so a reader understands that this is really being run by root. It makes no difference to systemd

Drop tcpdump permissions

Even after changing the group and ownership of tcpdump to user mode, I still get the following error:
tcpdump -i eth0
tcpdump: eth0: You don't have permission to capture on that device
(socket: Operation not permitted)
ls -la /usr/sbin/tcpdump
-rwxr-x--- 1 user1 user1 830920 Apr 24 21:28 /usr/sbin/tcpdump
I know it is not good to drop the permission of tcpdump from root to user but for ease of use in my case, I would like to be able to use it from user level.
I took the hint from:
"tcpdump -w 1.pcap" works, but "tcpdump -C 100 -w 1.pcap" - permission denied
and installed AppArmor as I am using Ubuntu 12.04 LTS.
And did:
sudo aa-complain /usr/sbin/tcpdump
Still I get the same error msg. If I use "-Z" with the tcpdump command, I can drop the privileges and run tcpdump but not otherwise.
Is there a way out?
Thanks
libpcap (which tcpdump is based on) require admin privilege to set your interface into promiscuous mode. There is nothing you can do about it, the kernel won't let you/tcpdump/libpcap do that, period.
What you can do is use tcpdump without promiscuous mode, but that will severely limit its functionality: you will only see traffic directed explicitly to/from your machine, as opposed to everything that's seen on the wire, which is usually what you want to to (and is why using promisc mode is the default). In order to do that, use this tcpdump option:
--no-promiscuous-mode
Don't put the interface into promiscuous mode. Note that the
interface might be in promiscuous mode for some other reason;
hence, `-p' cannot be used as an abbreviation for `ether host
{local-hw-addr} or ether broadcast'.
For more info on promiscuous mode:
http://en.wikipedia.org/wiki/Promiscuous_mode
I quote:
Many operating systems require superuser privileges to enable
promiscuous mode.
In Linux, at the low level, this is done by setting the IFF_PROMISC flag on the netdevice via a SIOCSIFFLAGS ("set flag") ioctl. And as you can see here:
http://man7.org/linux/man-pages/man7/netdevice.7.html
... "Setting the active flag word is a privileged operation", and "using it requires an effective user ID of 0 or the CAP_NET_ADMIN capability. If this is not the case, EPERM will be returned."
So another direction may be to give your "userjoe" account the CAP_NET_ADMIN rights, but I would advice against this. Security wise it's not better, if not worst, than to be part of the sudo'ers and explictly sudo when you need to.

wsgi nginx error: permission denied while connecting to upstream

There seem to be many questions on StackOverflow about this but unfortunately nothing has worked for me.
I'm getting a 502 bad gateway on nginx, and the following on the logs: connect() to ...myproject.sock failed (13: Permission denied) while connecting to upstream
I'm running wsgi and nginx on ubuntu, and I've been following this guide from Digital Ocean. I apparently configured wsgi correctly since uwsgi -s myproject.sock --http 0.0.0.0:8000 --module app --callable app worked, but I keep getting the nginx permission denied error and I have no idea why:
After coming across this question and this other one, I changed the .ini file and added the chown-socket, chmod-socket, uid and gid parameters (also tried just setting the first two, either or, and a couple of different permission settings --and even the most permissive didn't work).
This one seemed promising, but I don't believe selinux is installed on my Ubuntu (running sudo apt-get remove selinux gives "Package 'selinux' is not installed, so not removed" and find / -name "selinux" doesn't show anything). Just in case, though, I tried what this post recommended as well. Uninstalling apparmor (sudo apt-get install apparmor) didn't work either.
Every time I make a change, I run sudo service nginx restart, but I only see the 502 Gateway Error (and the permission denied error when I read the logs).
This is is my nginx configuration file:
server {
listen 80;
server_name 104.131.110.156;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/myproject/web_server/myproject.sock;
}
}
.conf file:
description "uWSGI server instance configured to serve myproject"
start on runlevel [2345]
stop on runlevel [!2345]
setuid user
setgid www-data
env PATH=/root/.virtualenvs/my-env/bin
chdir /home/user/myproject/web_server
exec uwsgi --ini /home/user/myproject/web_server/myproject.ini
.ini file:
[uwsgi]
module = wsgi
master = true
processes = 5
socket = /home/user/myproject/web_server/myproject.sock
chown-socket=www-data:www-data
chmod-socket = 664
uid = www-data
gid = www-data
vacuum = true
die-on-term = true
(If it helps, these are the specs of my Digital Ocean machine: Linux 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux)
Please let me know if there's anything I can do, and thank you very much.
After following all the advice in this thread I was still getting permission errors. The finally missing piece was to correct the nginx user in the /etc/nginx/nginx.conf file:
# old: user nginx;
user www-data;
I also followed that tutorial and ran into the same issue. After quite a bit of trial and error, the following steps allowed me to run uWSGI and nginx successfully:
My nginx.config file:
server {
listen 80;
server_name localhost;
location / { try_files #yourapplication; }
location #yourapplication; {
include uwsgi_params;
uwsgi_pass unix:/PATH_TO_PROJECT/PROJECT.sock;
}
}
My .ini file wasn't working very well, so I decided to take advantage of uWSGI's extensive arguments that are available. Here's what I used:
uwsgi -s /PATH_TO_PROJECT/PROJECT.sock -w wsgi:app -H /PATH_TO_PROJECT/venv --http-processes=4 --chmod-socket=666 --master &
Where:
-s /PATH_TO_PROJECT/PROJECT.sock = the location of my .sock file
-w wsgi:app = the location of my wsgi.py file and app being the name of my Flask object
-H /PATH_TO_PROJECT/venv = the location of my virtual environment
--http-processes=4 = the number of http processes for uWSGI to create
--chmod-socket=666 = the permissions to set on the socket
--master = allow uWSGI to run with its master process manager
& = run uWSGI in the background
To summarize what others have said to solve permission denied error in nginx (which you can look into /var/log/nginx/error.log is usually due to the following:
you are writing .sock file at a place nginx does not have permission
SELinux is causing the problem
To solve 1: First, don't write .sock file at /tmp as suggested here server fault answer because different services see different /tmp in fedora. You can write at some place such as ~/myproject/mysocket.sock. The nginx user must have access to our application directory in order to access the socket file there. By default, CentOS locks down each user's home directory very restrictively, so we will add the nginx user to our user's group so that we can then open up the minimum permissions necessary to grant access.
You can add the nginx user to your user group with the following command. Substitute your own username for the user in the command:
sudo usermod -a -G $USER nginx
Now, we can give our user group execute permissions on our home directory. This will allow the Nginx process to enter and access content within:
chmod 710 /path/to/project/dir
If the permission denied error is still there:
then the hack sudo setenforce 0 will do the trick.
The path: unix:/PATH_TO_PROJECT/PROJECT.sock should be placed in /tmp this fixed my problem.
(13: Permission denied)
This indicates that Nginx was unable to connect to the uWSGI socket because of permissions problems. Usually, this happens when the socket is being created in a restricted environment or if the permissions were wrong. While the uWSGI process is able to create the socket file, Nginx is unable to access it.
This can happen if there are limited permissions at any point between the root directory (/) the socket file. We can see the permissions and ownership values of the socket file and each of its parent directories by passing the absolute path to our socket file to the namei command:
namei -nom /PATH_TO_YOUR_SOCKET_FILE/YOUR_SOCKET.sock
The output should be similar to this (Your case might have different folder name)
f: /run/uwsgi/firstsite.sock
drwxr-xr-x root root /
drwxr-xr-x root root run
drwxr-xr-x sammy www-data uwsgi
srw-rw---- sammy www-data firstsite.sock
The output displays the permissions of each of the directory components. By looking at the permissions (first column), owner (second column) and group owner (third column), we can figure out what type of access is allowed to the socket file.
In the above example, each of the directories leading up to the socket file have world read and execute permissions (the permissions column for the directories end with r-x instead of ---). The www-data group has group ownership over the socket itself. With these settings, Nginx process should be able to access the socket successfully.
If any of the directories leading up to the socket are not owned by the www-data group or do not have world read and execute permission, Nginx will not be able to access the socket. Usually, this means that the configuration files have a mistake.
So you fix this issue but giving all the upper folder the permission using this command:
chmod 755 directory_name
I know it is late, but to help others overcome the issue faster, I have posted this answer. Hope it helps, good luck.
This may happen if user www-data may not have the permission to create new
socket in the given path, so use root user.
Relpace user www-data to user root in nginx.conf;
ex: #nginx.conf
#user www-data;
user root;
worker_processes auto;
pid /var/run/nginx.pid;
.............
If you have tested all the permissions and it is still not working then maybe SELinux is enabled, this will cause the same behaviour.
Run getenforce and if the result is Enforcing then that will not help.
Quick fix is to disable it, setenforce 0 but a restart is required.
2 things helped me
I had correct configuration in nginx I also was seeing /tmp/wsgi.sock with my two eyes in the folder but there was still permission denied or directory not exists:
In file /lib/systemd/system/nginx.service set PrivateTmp=false and restart nginx (do not forget systemctl daemon reload to refresh config)
Run command setenforce 0
Bonus material:
/usr/local/bin/uwsgi --chdir /home/biohazard/myproject -s /tmp/wsgi.sock -w api:app --chmod-socket=777 --master --thunder-lock --http-processes=2 where in api:app api stands for /home/biohazard/myproject/api.py
And
location = /api { rewrite ^ /api/; }
location /api { try_files $uri #api; }
location #api {
include uwsgi_params;
uwsgi_pass unix:/tmp/wsgi.sock;
}
Where nginx is serving my http://example.org/api endpoint only
Check user field on the first line in nginx.conf file. By default it is www-data. Change the name to user root in nginx.conf file if you logged in as root.
I Am Also Getting Same Issue While Deploying Flask Using Nginx And Gunicorn.
I Solved This Issue By putting .Sock file in /temp folder.
There are many things that can cause this particular error, in my case it was the ownership of my PROJECT.socket file that caused it.
Instead of:
srwxr-xr-x 1 yourusername yourusername 0 Nov 4 22:32 PROJECT.sock
it should be: srwxr-xr-x 1 www-data www-data 0 Nov 4 22:32 PROJECT.sock
Just run sudo chown www-data:www-data PROJECT.sock and that's it.

Mongodb monitoring using mikoomi plugin of zabbix is not rendering any data

I'm using mikoomi plugin to monitor mongodb, in that there is shell script which is calling php script and returning 0 to zabbix and parallely writing a data file and log file in /tmp/ directory.
Now my question : How is zabbix reading that data/log file and how are keys fetching information from that file? I need to debug this because zabbix is not rendering any data.
How do I set this up correctly?
Format of data file is as follows:
<Mongo Hostname> mem_virtual 39484
<Mongo Hostname> connections_current 34
<Mongo Hostname> mem_resident 1018
Mikoomi script is using zabbix_sender utility to notify zabbix server about the data collected.
exec("zabbix_sender -vv -z 127.0.0.1 -i $data_file_name 2>&1", $log_file_data) ;
Zabbix server will read the key values from data file and update the db.
Which OS are you using? Check for selinux policy related errors. If selinux policies are enabled in your server, disable and check whether data file is getting updated.
For checking selinux policy enable/disable, run below command
getenforce
If the output is Enforcing then selinux policies are enabled. Disable using following command.
setenforce 0
And again run getenforce to check whether the output is Permissive.
make sure you configured a cron job to run the script for every MongoDB host.
something along the lines of:
* * * * * /usr/lib/zabbix/externalscripts/mikoomi-mongodb-plugin.sh -h [ip address] -p 27017 -z [hostname]
the hostname has to be as it's configured in Zabbix for the target MongoDB server

Restarting apache as www-data using perl

I'm working on a webpage, which after certain events, needs to restart the apache server that it's running on to update some files. I tried adding www-data to the sudoers file:
www-data ALL=(ALL) NOPASSWD: /etc/init.d/apache2 start, /etc/init.d/apache2 stop, /etc/init.d/apache2 restart, /sbin/services apache2 restart
but when I try restarting apache, I get the following:
sudo -u www-data /etc/init.d/apache2 restart
Restarting web server apache2 (13)Permission denied: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
When looking online, I found that people seemed to be against allowing www-data to restart apache and I couldn't find anything suggesting how I would do it if I wanted to ignore the warnings for this particular case. If it isn't possible, what would be the easiest alternative way to have a webpage restart apache? I am going under the assumption that the site is private and secure and will not be used by malicious individuals, and I think it's a fair one given the circumstances I am under. Thanks for your time
The init-scripts can/should only be run as root (at least on my standard-Debian this is the case).
The apache-process (and the ones of the other services) will call setuid (or one of its friends) to change the actual user of the process.
root should restart the webserver:
sudo /etc/init.d/apache2 restart
This will make apache run under the www-data user.
you don't need to add www-data to the sudoers file unless you want to allow the www-data user to restart the server - but typically you should not log in under the www-data account, it's a system account.