On a system with SELinux enabled (Enforced mode), you might encounter security issues when using PHP Sessions with the default PHP-COMMON and PHP-FPM configurations. By default, sessions will be stored in /var/lib/php/sessions.
If SELinux denies writing in the sessions directory, error messages should be displayed in the /var/log/security file.
If you think it is a good idea to store sessions in this directory, you might have to create an SELinux policy to allow the user running your PHP code (httpd or apache for most setups).
The audit2allow utility will ease your task but you might have to install it.
$ sudo yum install policycoreutils-python
For those you wonder how to find package containing a command or utility on YUM based distribution, here you go...
$ sudo yum provides "*/audit2allow"
Now that the tool is installed, you can run the following command as root:
Install Nginx is quite easy here https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-centos-7
About Nginx
Nginx is a high performance web server software. It is a much more flexible and lightweight program than Apache HTTP Server.
This tutorial will teach you how to install and start Nginx on your CentOS 7 server.
Prerequisites
The steps in this tutorial require the user to have root privileges. You can see how to set that up by following steps 3 and 4 in the Initial Server Setup with CentOS 7 tutorial.
Step One—Add Nginx Repository
To add the CentOS 7 Nginx yum repository, open terminal and use the following command:
Now that the Nginx repository is installed on your server, install Nginx using the followingyum command:
sudo yum install nginx
After you answer yes to the prompt, Nginx will finish installing on your virtual private server (VPS).
Step Three—Start Nginx
Nginx does not start on its own. To get Nginx running, type:
sudo systemctl start nginx.service
You can do a spot check right away to verify that everything went as planned by visiting your server's public IP address in your web browser (see the note under the next heading to find out what your public IP address is if you do not have this information already):
http://server_domain_name_or_IP/
You will see the default CentOS 7 Nginx web page, which is there for informational and testing purposes. It should look something like this:
If you see this page, then your web server is now correctly installed.
Before continuing, you will probably want to enable Nginx to start when your system boots. To do so, enter the following command:
sudo servicectl enable nginx.service
Congratulations! Nginx is now installed and running!
How To Find Your Server's Public IP Address
You can run the following command to reveal your server’s public IP address:
ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
Server Root and Configuration
If you want to start serving your own pages or application through Nginx, you will want to know the locations of the Nginx configuration files and default server root directory.
Default Server Root
The default server root directory is /usr/share/nginx/html. Files that are placed in there will be served on your web server. This location is specified in the default server block configuration file that ships with Nginx, which is located at /etc/nginx/conf.d/default.conf.
Server Block Configuration
Any additional server blocks (known as Virtual Hosts in Apache) by creating new configuration files in /etc/nginx/conf.d. Files that end with .conf in that directory will be loaded when Nginx is started.
Nginx Global Configuration
The main Nginx configuration file is located at /etc/nginx/nginx.conf. This is where you can change settings like the user that runs the Nginx daemon processes, and the number of worker processes that get spawned when Nginx is running, among other things.
====
The hard part is the SELinux here http://axilleas.me/en/blog/2013/selinux-policy-for-nginx-and-gitlab-unix-socket-in-fedora-19/
The installation of GitLab in Fedora 19 went fine. I followed the official installation guide with some deviations where necessary, mostly taken from the CentOS guide in gitlab-recipes. I setup nginx using the ssl config, and poked some holes in iptables. For systemd services I used these files.
So, everything is set, configuration tests pass, services are started, nginx is started and I finally point firefox to my FQDN (which by the way is fedora.axilleas.me, no secret) just to see a big fat 502 Bad Gateway.
The server was acting as a gateway or proxy and received an invalid response from the upstream server.
Spot on! The server (nginx) is acting as a proxy and received an invalid response from the upstream server (unicorn). But what was that invalid response?
I could reach ip_addr:8080 at which unicorn was listening, but not through my fqdn which nginx was serving. So there clearly was something wrong with nginx.
So we got a permission denied while nginx is trying to connect to the unix socket of GitLab. After some hours searching and reading answers in stackoverflow, it sroke to me to check whether SELinux is to blame. I set it to permissive mode with setenforce 0 and voila, nginx was suddenly recieving requests.
SELinux you crafty little blocker
I remembered the awesome introductory guide of SELinux at CentOS wiki, which I had used when rewriting the CentOS installation guide for GitLab and immediately started reading.
By default, SELinux log messages are written to /var/log/audit/audit.log via the Linux Auditing System auditd. If the auditd daemon is not running, then messages are written to /var/log/messages. SELinux log messages are labeled with the AVC keyword so that they might be easily filtered from other messages, as with grep.
So, by greping nginx in /var/log/audit/audit.log I found those relative AVC messages, which indicate indeed a denial of nginx connection to gitlab.socket.
Using a tool called audit2allow we are able to clear the AVC messages. If you haven't got it installed, it is shipped with the policycoreutils-devel package.
grepnginx/var/log/audit/audit.log|audit2allow
and the result is:
#============= httpd_t ==============#!!!! This avc is allowed in the current policyallowhttpd_thttp_cache_port_t:tcp_socketname_connect;#!!!! This avc is allowed in the current policyallowhttpd_thttpd_log_t:filesetattr;#!!!! This avc is allowed in the current policyallowhttpd_thttpd_sys_content_t:sock_filewrite;#!!!! This avc is allowed in the current policyallowhttpd_tinitrc_t:unix_stream_socketconnectto;#!!!! This avc is allowed in the current policyallowhttpd_tuser_home_dir_t:dirsearch;#!!!! This avc is allowed in the current policyallowhttpd_tuser_home_t:dir{searchgetattr};#!!!! This avc is allowed in the current policyallowhttpd_tuser_home_t:sock_filewrite;#!!!! This avc is allowed in the current policyallowhttpd_tvar_run_t:file{readwrite};
These are the policies that should be used with SELinux. Notice that user_home is essential since GitLab's APP_ROOT is in /home/git/. Similarly, you notice a policy related to the denied socket connection: unix_stream_socket connectto.
Create a custom SELinux policy module
After all the investigation we are closer to the solution. All we have to do is useaudit2allow to generate a set of policy rules that would allow the required actions. We can generate a local nginx Type Enforcement policy file (nginx.te):
grepnginx/var/log/audit/audit.log|audit2allow-mnginx>nginx.tecatnginx.temodulenginx1.0;require{typevar_run_t;typeuser_home_dir_t;typehttpd_log_t;typehttpd_t;typeuser_home_t;typehttpd_sys_content_t;typeinitrc_t;typehttp_cache_port_t;classsock_filewrite;classunix_stream_socketconnectto;classdir{searchgetattr};classfile{readwritesetattr};classtcp_socketname_connect;}#============= httpd_t ==============#!!!! This avc is allowed in the current policyallowhttpd_thttp_cache_port_t:tcp_socketname_connect;allowhttpd_thttpd_log_t:filesetattr;allowhttpd_thttpd_sys_content_t:sock_filewrite;allowhttpd_tinitrc_t:unix_stream_socketconnectto;#!!!! This avc is allowed in the current policyallowhttpd_tuser_home_dir_t:dirsearch;#!!!! This avc is allowed in the current policyallowhttpd_tuser_home_t:dir{searchgetattr};allowhttpd_tuser_home_t:sock_filewrite;allowhttpd_tvar_run_t:file{readwrite};
We are not done yet, as this is a file for review only. We can then go ahead and use audit2allow to make a custom policy module to allow these actions:
We can check the policy module loaded correctly by listing loaded modules with semodule -l.
After that, remember to enable SELinux again with setenforce 1.
Add nginx to git group
Unrelated to this article, but it is also needed for nginx to access the unix socket. First we add nginx to git group, and then we make sure the group that owns /home/git/ has read and execute permissions: