- Nginx, php-fpm and SELinux enforcing on CentOS 7
- Upgrading to php 7
- Add user for your application
- Application layout
- DAC permissions
- Nginx configuration
- php-fpm configuration
- SELinux context
- app.php of awesomium
- avc: denied in audit.log and notes
- Leave a comment
- About the author
- Centos 7 tmp php fpm
- Нет доступа к файлам в /tmp из Php-FPM?
- Защищаем изменения от перезаписи
- Saved searches
- Use saved searches to filter your results more quickly
- Can’t open subdirectory of /tmp or /var/tmp #94
- Can’t open subdirectory of /tmp or /var/tmp #94
- Comments
Nginx, php-fpm and SELinux enforcing on CentOS 7
I’ll cover some basic setup needed to get your own php application, installed underneath /opt , running on CentOS 7. Nginx is on the frontline passing requests to php 7.1’s fpm (php-fpm). Application will have it’s own dedicated php-fpm worker pool and user and the app’s directories will have proper SELinux labels.
Upgrading to php 7
CentOS 7 ships with venerable php 5.4 so in order to get your sockets on php 7 add Remi’s RPM repository or IUS. They both, Remi and IUS, depend on EPEL. Remi will be used in this this example.
yum install epel-release nginx yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
Install php-cli and php-fpm, opcache is optional but the ~30% speed boost speaks for itself. Again php-cli is optional but as lot of application ship with console commands then whatteheck.
yum install php71-php-fpm php71-php-cli php71-php-opcache
Optional stuff like mcrypt, bcmath and mysql related.
yum install php71-php-mcrypt php71-php-bcmath yum install php71-php-pdo php71-php-mysqlnd
Add user for your application
Having a user for the application (not nginx nor apache as php-fpm worker user) makes it alot easier to secure stuff. Pros include:
- nginx only needs read access to document root which served via httpd anyway.
- nginx doesn’t necessarily need read access to any php files given you have a single (or just a few) entry points for your application and they are located outside of document root .
- your app won’t have any access to nginx’s files.
- consistent ownership of application files, sessions, tmp and uploads etc.
- sudoers for dishing out permissions to run application cli commands is easier.
- after initial ‘extra work’ it simplifies spawning new apps and keeps them properly separated at DAC level.
I’ll add two users. dbut shall be the application ‘owner’ and his buddy in the dbut group will dbutter , the application user.
useradd -r dbut useradd -r -g dbut dbutter
Application layout
Example application directory structure shoved under /opt/dbut
DAC permissions
Strip permissions from others to sensitive directories (originally created with umask 0022).
cd /opt/dbut chmod o-rx -R log session application
And grant write access for the application user by making rw directories group writable
chmod g+rwx log session document_root/user_content
Nginx configuration
Following will just smack 1 week expiration for the regex matched directories. As for other request Nginx will try to serve a file under root , if no file matches the request, php-fpm will handle it with a hard-coded SCRIPT_FILENAME . Only minimal amount of $_SERVER variables are available for the application itself. If you need more e.g. REMOTE_ADDR see /etc/nginx/fastcgi_params .
server < listen 80; listen [::]:80; server_name dbut.local; root /opt/dbut/document_root; location ~ ^/(css|js|image|user_content)/ < expires 1w; >try_files $uri @php; location @php < fastcgi_pass unix:/var/run/php-fpm-dbut.socket; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param REQUEST_URI $request_uri; fastcgi_param SCRIPT_FILENAME /opt/dbut/application/app.php; >>
php-fpm configuration
A skeleton config for socket. Only nginx user can access the socket. catch_workers_output and error_log directives try to ensure errors pop up somewhere before app’s own error handler lands on the stage.
[dbut] user = dbutter group = dbut listen = /var/run/php-fpm-dbut.socket listen.owner = nginx listen.group = nginx listen.mode = 0600 pm = dynamic pm.max_children = 10 pm.start_servers = 2 pm.min_spare_servers = 2 pm.max_spare_servers = 5 pm.max_requests = 100 catch_workers_output = yes security.limit_extensions = .php php_admin_value[error_log] = /opt/dbut/log/php-fpm-error.log php_admin_flag[log_errors] = on [global] process_control_timeout = 5s
SELinux context
First I’d recommend installing this handy package for managing SELinux filesystem path contexts and port lists:
yum install policycoreutils-python
Php-fpm process runs as httpd_t (same label as Apache and Nginx) so I’ll use the following labels for filesystem:
- httpd_sys_content_t for read-only
- httpd_log_t for append only
- httpd_sys_rw_content_t for read-write
As SELinux matches rules in order they created the most generic has to be created first. Making the whole application directory read-only:
semanage fcontext -a -t httpd_sys_content_t "/opt/dbut(/.*)?"
Log directory gets httpd_log_t . Functions like fopen() must use mode ‘a’ or file_put_contents() must be flagged with FILE_APPEND .
semanage fcontext -a -t httpd_log_t "/opt/dbut/log(/.*)?"
Session and user_content directories will be read-write.
semanage fcontext -a -t httpd_sys_rw_content_t "/opt/dbut/session(/.*)?" semanage fcontext -a -t httpd_sys_rw_content_t "/opt/dbut/document_root/user_content(/.*)?"
In case of oooops. To remove a rule
semanage fcontext -d "/opt/dbut/document_root/user_content(/.*)?"
Finally restore context restorecon the whole directory recursively
and ls -Z should say something like this:
[root@burp]# ls -Z /opt/dbut drwxr-x---. dbut dbut unconfined_u:object_r:httpd_sys_content_t:s0 application drwxr-xr-x. dbut dbut unconfined_u:object_r:httpd_sys_content_t:s0 document_root drwxrwx---. dbut dbut unconfined_u:object_r:httpd_log_t:s0 log drwxrwx---. dbut dbut unconfined_u:object_r:httpd_sys_rw_content_t:s0 session [root@burp]# ls -Z /opt/dbut/document_root drwxr-xr-x. dbut dbut unconfined_u:object_r:httpd_sys_content_t:s0 css drwxr-xr-x. dbut dbut unconfined_u:object_r:httpd_sys_content_t:s0 image drwxr-xr-x. dbut dbut unconfined_u:object_r:httpd_sys_content_t:s0 js drwxrwxr-x. dbut dbut unconfined_u:object_r:httpd_sys_rw_content_t:s0 user_content
app.php of awesomium
avc: denied in audit.log and notes
If you want to see selinux denying all the things you can either flip selinux to permissive and restore stock context for the application directories
setenforce 0 chcon -r -t user_t /opt/dbut` setenforce 1
or drop all the rules created previously listed below and restorecon -r /opt/dbut
[root@burp]# semanage fcontext -l | grep /opt/dbut /opt/dbut(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 /opt/dbut/log(/.*)? all files system_u:object_r:httpd_log_t:s0 /opt/dbut/session(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /opt/dbut/document_root/user_content(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0
Leave a comment
About the author
My name is Jesse Sandberg. I’m a dad, husband, DB Columnist, cyclist and a pirate from Finland. I usually write about CentOS / Linux stuff.
This blog powered by Oblog and in case you want to contact me here’s a blop of methods:
Centos 7 tmp php fpm
DirectAdmin — это удобная панель управления хостингом. Легкость в настройке, легкость в использовании!
ДиректАдмин — самая быстрая и нересурсоемкая панель из всех существующих коммерческих панелей управления для хостинга. Бесплатные и регулярные обновления версии панели DirectAdmin на протяжении всего времени ее использования заметно выделяют ее среди других.
Нет доступа к файлам в /tmp из Php-FPM?
Вероятно вы заметили, что на сервере под управлением CentOS 7 некоторые PHP скрипты, которые работали ранее, могут не работать: причиной тому отсутствие доступа до файлов сессии, временных файлов, размещенных в /tmp. Так же может не работать php_uploadscan.sh скрипт Directadmin, с помощью которого загружаемые через веб-форму файлы проверяются ClamAV на предмет наличия злонамеренного кода, что в свою очередь ломает полностью загрузку файлов.
Причиной всему этому является особенность CentOS 7:
Что эта опция делает — это монтирует /tmp и /var/tmp в режиме приватной файловой системы, видимой и доступной только тому процессу, для которого она смонтирована. Так что, когда php-fpm пишет в /tmp, это не та же временная директория /tmp, которую вы видите из консоли даже как root, — это виртуальная директория, доступная только php-fpm. И как только вы остановите процесс или он сам завершит свою работу, то созданная для него виртуальная /tmp со всем содержимым будет удалена.
Информация из документации по systemd.exec:
PrivateTmp= Takes a boolean argument. If true, sets up a new file system namespace for the executed processes and mounts private /tmp and /var/tmp directories inside it, that are not shared by processes outside of the namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via /tmp or /var/tmp impossible. All temporary data created by service will be removed after service is stopped. Defaults to false.
Для того, чтобы это исправить нужно отредактировать файл (или другой по номеру версии PHP):
/etc/systemd/system/php-fpm55.service
затем перезапустить процесс.
Защищаем изменения от перезаписи
Каждый раз при обновлении PHP или ClamAv внесенные ранее изменения будут терятся. Для сохранения их скопируйте измененные файлы из /etc/systemd/system/ в /usr/local/directadmin/custombuild/custom/systemd/.
Вам нужна помощь или консультация по данному руководству?! Задайте свой вопрос на форуме. Вам нужен профессионал?! Воспользуйтесь услугами системного администратора для работ по вашему серверу. Мы поможем вам с переездом, настройкой, оптимизацией сервисов, равно как и с другими вопросами по части Linux/Unix.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can’t open subdirectory of /tmp or /var/tmp #94
Can’t open subdirectory of /tmp or /var/tmp #94
Comments
I faced this problem while using xhprof and php-fpm on centos 7.
If you use php-fpm daemon configured to use private tmp directory (set to true by default in centos 7) and set xhprof.output_dir as subdirectory of /tmp , you probably notice than reports files can’t be saved to that dir.
In that case you get the following message: «PHP Warning: fopen(/tmp/xhprof/58ed54f13807d.xhprof_testing.xhprof): failed to open stream: No such file or directory in /usr/share/pear/xhprof_lib/utils/xhprof_runs.php on line 136«.
This happens because of php-fpm service cleans up /tmp directory each time the service started/restarted. So you have to create all subdirectories into /tmp each time you restart php-fpm.
$ cat /etc/php.d/xhprof.ini [xhprof] extension=xhprof.so xhprof.output_dir="/tmp/xhprof"
$ cat /usr/lib/systemd/system/php-fpm.service | grep PrivateTmp PrivateTmp=true
$ sudo ls /tmp/systemd-private-b5096469cfb44152913c896b78570a6d-php-fpm.service-lP5PdF/tmp/xhprof 58f35870bd648.xhprof_testing.xhprof
$ sudo systemctl restart php-fpm
$ sudo ls /tmp/systemd-private-b5096469cfb44152913c896b78570a6d-php-fpm.service-EqBde7/tmp/xhprof ls: cannot access /tmp/systemd-private-b5096469cfb44152913c896b78570a6d-php-fpm.service-EqBde7/tmp/xhprof: No such file or directory
The text was updated successfully, but these errors were encountered: