Nginx SELinux Configuration

Importance of SELinux

SELinux is Linux security system based on role access. It comes enabled by default in recent RedHat and CentOS versions. Quite many sources online will tell you to disable <abbr class="nocode" title="" data-original-title="Security-Enhanced Linux" style="box-sizing: border-box; border-bottom: 1px dotted rgb(119, 119, 119); cursor: help; text-decoration: none;">SELinux</abbr> for other things to work. But this isn’t correct. You shouldn’t lessen your server security. You must configure SELinux properly instead!

Let’s review basic configuration changes you need for SELinux to play nicely with servers running nginx.

Enable SELinux

First of all, let’s make sure that SELinux is running in enforcing mode globally.

setenforce 1

Default SELinux policy labels nginx and its associated files and ports with domain (type) httpd_t.
So what we are going to do next is allow nginx to run in permissive mode.
In this mode nginx (and php-fpm) will run without restrictions, but, Linux will log all SELinux related errors. Run:

semanage permissive -a httpd_t

Ok, great. Now our system is enforcing SELinux policy while still allowing all activity for nginx and php-fpm. We can now use log entries to adjust SELinux configuration.

Install complementary tools

yum install selinux-policy-doc # will install documentation for policy

Check SELinux violations

grep nginx /var/log/audit/audit.log | audit2allow -m nginx

If you don’t have any policy violations by nginx, the command will output:

You must specify the -p option with the path to the policy file.

Otherwise it will build up a SELinux policy for us.

We we will not use the generated policy directly. Instead, it will help us to identify the nginx configuration errors or adjust the SELinux configuration via boolean flags (most common case).

Example 1. Bad location for nginx fastcgi cache

Example output:

module nginx 1.0;

require {
    type httpd_t;
    type httpd_config_t;
    class dir { add_name remove_name write };
}

#============= httpd_t ==============
allow httpd_t httpd_config_t:dir { add_name remove_name write };

How to really interpret this? It appears that nginx tries to change contents of httpd_config_t. Let’s see what it is:

semanage fcontext -l | grep httpd_config_t

You will see that the output includes location /etc/nginx(/.*)?. So in most probability nginx is trying to change contents within its own configuration (/etc/nginx).

This is commonly caused by storing fastcgi cache within that directory. In our case, the misconfiguration is with the following nginx configuration line for micro-fastcgi cache:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=microcache:10m max_size=256m inactive=30m;

Let’s find a more appropriate place for storing it, which might be already allowed by default SELinux policy. To see all locations associated with nginx, run:

semanage fcontext -l | grep nginx

In the output we see /var/lib/nginx(/.*)? location present with context system_u:object_r:httpd_var_lib_t:s0. That sounds like a better location for our microcache. But it is not present! Let’s create the location and make sure to re-label it (apply SELinux contexts):

mkdir -p /var/lib/nginx/microcache
chown -R nginx /var/lib/nginx
restorecon -Rv /var/lib/nginx

Now adjust nginx configuration to point to the new location which satisfies current SELinux policy better:

fastcgi_cache_path /var/lib/nginx/microcache levels=1:2 keys_zone=microcache:10m max_size=256m inactive=30m;

Let’s verify that our microcache directory SELinux label matches to the one in policy:

matchpathcon -V /var/lib/nginx/microcache

Should output “/var/lib/nginx/microcache verified.“.

Example 2. worker_rlimit_nofile and SELinux

If you’re using this nginx configuration directive, e.g. worker_rlimit_nofile some-number; then the following would likely be included into generated SELinux policy:

module nginx 1.0;

require {
    type httpd_t;
    class process setrlimit;
}

#============= httpd_t ==============

#!!!! This avc can be allowed using the boolean 'httpd_setrlimit'
allow httpd_t self:process setrlimit;

Look at the 2 last lines. They tell you that nginx is trying to issue setrlimit system call. It suggests to use a boolean flag to easily enable this activity. This is all we need to allow that activity in enforcing mode:

setsebool -P httpd_setrlimit on

SELinux and PHP-FPM

Check for PHP-FPM errors like so:

grep -R php-fpm /var/log/audit/audit.log

You might see errors of the following type:

type=SYSCALL msg=audit(1502113625.315:36455): arch=c000003e syscall=21 success=yes exit=0 a0=7f125afedcc8 a1=2 a2=0 
a3=7ffe5a8c3a00 items=0 ppid=9855 pid=13146 auid=4294967295 uid=1001 gid=1001 euid=1001 suid=1001 fsuid=1001 egid=1001 
sgid=1001 fsgid=1001 tty=(none) ses=4294967295 comm="php-fpm" exe="/usr/sbin/php-fpm" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1502113640.696:36458): avc:  denied  { write } for  pid=13190 comm="php-fpm" name="autoptimize" dev="sda" ino=262322 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=dir

If PHP-FPM is being used with nginx and cannot write to web directories when httpd_t is in enforcing mode, then you should relabel the directories that need to be written with proper type (httpd_sys_rw_content_t).

For WordPress, the default SELinux policy includes (among others) this location:

 /var/www/html(/.*)?/wp-content(/.*)?               all files          system_u:object_r:httpd_sys_rw_content_t:s0

So if we store our sites with different structure (outside html directory, for example), then we would need to add our locations permanently like so:

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/vhosts/(.*)/httpdocs/wp-content(/.*)?"
restorecon -Rv /var/www/vhosts/*/httpdocs/wp-content

These commands are much better alternative (and more correct) to setting httpd_unified boolean flag.

You might see similar errors logged related to locations. Most of the time the better solution would involve adding more locations to SELinux types (same as we did above). For the list of all file types relevant for web server, read man httpd_selinux.

ngx_pagespeed and SELinux

ngx_pagespeed module needs to execute things in memory (scheduler?). Which is why nginx would fail to startup should SELinux be in enforcing mode. This is the typical error you can find in nginx error log:

nginx[10624]: nginx: [emerg] dlopen() “/etc/nginx/modules/ngx_pagespeed.so” failed (/etc/nginx/modules/ngx_pagespeed.so: cannot enable executable stack as shared object requires: Permission denied) in /etc/nginx/nginx.conf:13

You can fix that with a one line command:

setsebool -P httpd_execmem on

Run Secure!

Now our nginx installation is ready to run in enforcing mode:

semanage permissive -d httpd_t

Thank you for reading and keep safe!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末符糊,一起剝皮案震驚了整個(gè)濱河市轰绵,隨后出現(xiàn)的幾起案子俗壹,更是在濱河造成了極大的恐慌西潘,老刑警劉巖程奠,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蒸绩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铃肯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門患亿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人押逼,你說我怎么就攤上這事步藕。” “怎么了挑格?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵咙冗,是天一觀的道長。 經(jīng)常有香客問我漂彤,道長雾消,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任挫望,我火速辦了婚禮立润,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘媳板。我一直安慰自己桑腮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布蛉幸。 她就那樣靜靜地躺著破讨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奕纫。 梳的紋絲不亂的頭發(fā)上提陶,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音若锁,去河邊找鬼搁骑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛又固,可吹牛的內(nèi)容都是我干的仲器。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼仰冠,長吁一口氣:“原來是場噩夢啊……” “哼乏冀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洋只,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤辆沦,失蹤者是張志新(化名)和其女友劉穎昼捍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肢扯,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妒茬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔚晨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乍钻。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖铭腕,靈堂內(nèi)的尸體忽然破棺而出银择,到底是詐尸還是另有隱情,我是刑警寧澤累舷,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布浩考,位于F島的核電站,受9級特大地震影響被盈,放射性物質(zhì)發(fā)生泄漏析孽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一害捕、第九天 我趴在偏房一處隱蔽的房頂上張望绿淋。 院中可真熱鬧,春花似錦尝盼、人聲如沸吞滞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽裁赠。三九已至,卻和暖如春赴精,著一層夾襖步出監(jiān)牢的瞬間佩捞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工蕾哟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留一忱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓谭确,卻偏偏與公主長得像帘营,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子逐哈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,294評論 0 10
  • 抬頭望不到天空 眼前是一片黑暗 我也不期望 能見到星星 她離我遠(yuǎn)去 不知不覺已多年 多年后的今天 留我一人想念 想...
    AAAria閱讀 176評論 0 0
  • 福報(bào)從哪里來昂秃?不是說你能力強(qiáng)就一定有福禀梳,因?yàn)楦?bào)也有它的前因后果杜窄。佛教告訴我們,福報(bào)來自福田算途,主要是悲田塞耕、恩田、敬...
    明善_閱讀 963評論 1 1
  • 最近莫名覺得壓力大心情差郊艘,宅暴飲暴食哭剪短發(fā)熬夜刷劇荷科,一口氣看完了人民的名義,權(quán)利的游戲纱注,最后是荼靡,作為...
    假裝在吃飯閱讀 415評論 0 0