知乎专栏 |
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/conf.d/www.mydomain.com.conf:25 nginx: configuration file /etc/nginx/nginx.conf test failed
在location,if中使用证则匹配proxy_pass末尾不能写/
if ($request_uri ~* "^/info/{cn|tw}/{news|info}/\d\.html") { proxy_pass http://info.example.com/; break; } location ~ ^/info/ { proxy_pass http://info.example.com/; break; }
proxy_pass http://info.example.com/; 改为 proxy_pass http://info.example.com; 可以解决
如果用户Cookie信息没有经过 proxy_pass 传递给最终服务器,SESSION信息将丢失,解决方案
proxy_set_header Cookie $http_cookie;
配置 worker_rlimit_nofile 参数即可
user nginx; worker_processes 8; worker_rlimit_nofile 65530;
配置 ulimit 也能达到同样效果,但我更喜欢 worker_rlimit_nofile 因为它仅仅作用于nginx,而不是全局配置。
server_name www.example.com www.example.net www.example.org;
下来SSI标签无论你使用那个域名访问,输出永远是server_name的第一域名www.example.com
<!--#echo var="SERVER_NAME"-->
需要通过SERVER_NAME判定展示不同结果时需要注意。
下面的例子是 Document root 是 /www/netkiller.com/m.netkiller.com, 我们需要 /www/netkiller.com/www.netkiller.com 中的资源。
server { listen 80; server_name m.netkiller.com; charset utf-8; access_log /var/log/nginx/m.netkiller.com.access.log; error_log /var/log/nginx/m.netkiller.com.error.log; location / { root /www/netkiller.com/m.netkiller.com; index.html } location /module { root /www/netkiller.com/www.netkiller.com; } }
server { listen 80; server_name m.netkiller.com; charset utf-8; access_log /var/log/nginx/m.netkiller.com.access.log; error_log /var/log/nginx/m.netkiller.com.error.log; location / { root /www/netkiller.com/m.netkiller.com; index.html } location ^~ /module/ { root /www/netkiller.com/www.netkiller.com; } }
上面的例子location /module 是指 /www/netkiller.com/www.netkiller.com + /module,如果 /www/netkiller.com/www.netkiller.com 目录下面没有 module 目录是出现404, error.log显示 "/www/netkiller.cn/www.netkiller.cn/module/index.html" failed (2: No such file or directory)
text/html 是 gzip_types 默认值,所以不要将text/html加入到gzip_types列表内
链接本地端口失败,已经关闭防火墙,同时使用 curl http://127.0.0.1:8080 一切正常
日志片段
2018/09/07 12:31:27 [crit] 10202#10202: *4 connect() to [::1]:8080 failed (13: Permission denied) while connecting to upstream, client: 47.90.97.183, server: www.api.netkiller.cn, request: "GET /api/ HTTP/2.0", upstream: "http://[::1]:8080/api/", host: "api.netkiller.cn" 2018/09/07 12:31:27 [warn] 10202#10202: *4 upstream server temporarily disabled while connecting to upstream, client: 47.90.97.183, server: www.api.netkiller.cn, request: "GET /api/ HTTP/2.0", upstream: "http://[::1]:8080/api/", host: "api.netkiller.cn" 2018/09/07 12:31:27 [crit] 10202#10202: *4 connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream, client: 47.90.97.183, server: www.api.netkiller.cn, request: "GET /api/ HTTP/2.0", upstream: "http://127.0.0.1:8080/api/", host: "api.netkiller.cn" 2018/09/07 12:31:27 [warn] 10202#10202: *4 upstream server temporarily disabled while connecting to upstream, client: 47.90.97.183, server: www.api.netkiller.cn, request: "GET /api/ HTTP/2.0", upstream: "http://127.0.0.1:8080/api/", host: "api.netkiller.cn"
问题出现在 AWS 亚马逊云主机。经过筛查发现是 SELINUX 问题
[root@netkiller ~]# cat /var/log/audit/audit.log | grep nginx | grep denied | more type=AVC msg=audit(1536320093.274:345): avc: denied { sys_resource } for pid=9544 comm="nginx" capability=24 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capabi lity type=AVC msg=audit(1536320093.274:346): avc: denied { sys_resource } for pid=9545 comm="nginx" capability=24 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capabi lity type=AVC msg=audit(1536320093.275:347): avc: denied { sys_resource } for pid=9546 comm="nginx" capability=24 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capabi lity type=AVC msg=audit(1536321850.706:459): avc: denied { sys_resource } for pid=9798 comm="nginx" capability=24 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capabi lity type=AVC msg=audit(1536321850.707:460): avc: denied { sys_resource } for pid=9799 comm="nginx" capability=24 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capabi lity type=AVC msg=audit(1536321920.108:461): avc: denied { name_connect } for pid=9796 comm="nginx" dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=t cp_socket type=AVC msg=audit(1536321920.109:462): avc: denied { name_connect } for pid=9796 comm="nginx" dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=t cp_socket
问题分析,此问题出在 SELINUX
2021/07/13 02:18:52 [crit] 6671#0: *3 connect() to 192.168.60.7:8000 failed (13: Permission denied) while connecting to upstream, client: 192.168.90.137, server: www.netkiller.cn, request: "GET / HTTP/2.0", upstream: "http://192.168.60.7:8000/", host: "www.netkiller.cn"
查看 SELINUX 设置
[root@localhost ~]# getsebool -a | grep httpd httpd_anon_write --> off httpd_builtin_scripting --> on httpd_can_check_spam --> off httpd_can_connect_ftp --> off httpd_can_connect_ldap --> off httpd_can_connect_mythtv --> off httpd_can_connect_zabbix --> off httpd_can_network_connect --> on httpd_can_network_connect_cobbler --> off httpd_can_network_connect_db --> off httpd_can_network_memcache --> off httpd_can_network_relay --> off httpd_can_sendmail --> off httpd_dbus_avahi --> off httpd_dbus_sssd --> off httpd_dontaudit_search_dirs --> off httpd_enable_cgi --> on httpd_enable_ftp_server --> off httpd_enable_homedirs --> off httpd_execmem --> off httpd_graceful_shutdown --> off httpd_manage_ipa --> off httpd_mod_auth_ntlm_winbind --> off httpd_mod_auth_pam --> off httpd_read_user_content --> off httpd_run_ipa --> off httpd_run_preupgrade --> off httpd_run_stickshift --> off httpd_serve_cobbler_files --> off httpd_setrlimit --> off httpd_ssi_exec --> off httpd_sys_script_anon_write --> off httpd_tmp_exec --> off httpd_tty_comm --> off httpd_unified --> off httpd_use_cifs --> off httpd_use_fusefs --> off httpd_use_gpg --> off httpd_use_nfs --> off httpd_use_opencryptoki --> off httpd_use_openstack --> off httpd_use_sasl --> off httpd_verify_dns --> off
设置此选项可以解决
[root@localhost ~]# setsebool -P httpd_can_network_connect true
解决方案
proxy_buffer_size 64k; proxy_buffers 32 64k; proxy_busy_buffers_size 128k;
完整例子
server { listen 80; listen 443 ssl http2; server_name www.netkiller.cn; ssl_certificate "/etc/pki/nginx/server.crt"; ssl_certificate_key "/etc/pki/nginx/private/server.key"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers PROFILE=SYSTEM; ssl_prefer_server_ciphers on; access_log /var/log/nginx/www.netkiller.cn.access.log; error_log /var/log/nginx/www.netkiller.cn.error.log; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { #proxy_set_header Host $host; #proxy_set_header X-Real-IP $remote_addr; #proxy_set_header REMOTE-HOST $remote_addr; #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffer_size 64k; proxy_buffers 32 64k; proxy_busy_buffers_size 128k; proxy_pass http://192.168.30.50; } error_page 497 https://$host$uri?$args; if ($scheme = http) { return 301 https://$server_name$request_uri; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
情景模拟
server { listen 80; listen 443 ssl http2; server_name www.netkiller.cn; access_log /var/log/nginx/www.netkiller.cn.access.log; error_log /var/log/nginx/www.netkiller.cn.error.log; error_page 497 https://$host$uri?$args; if ($scheme = http) { return 301 https://$server_name$request_uri; } location / { root /opt/netkiller.cn/www.netkiller.cn; index index.html; } location /api/ { proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://gateway.netkiller.cn:8080/; proxy_connect_timeout 120; proxy_send_timeout 120; proxy_read_timeout 120; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
问题分析,这个问题是因为 root 目录指向放在了 location / 下面造成的。解决方案:
server { listen 80; listen 443 ssl http2; server_name www.netkiller.cn; access_log /var/log/nginx/www.netkiller.cn.access.log; error_log /var/log/nginx/www.netkiller.cn.error.log; error_page 497 https://$host$uri?$args; if ($scheme = http) { return 301 https://$server_name$request_uri; } root /opt/netkiller.cn/www.netkiller.cn; location / { index index.html; } location /api/ { proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://gateway.netkiller.cn:8080/; proxy_connect_timeout 120; proxy_send_timeout 120; proxy_read_timeout 120; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }