Primary script unknown error - can't figure out how to fix

Hi all,

I’m new to nginx and trying to setup a piwik virtual hosts on an
up-to-date CentOS 6.3 box with nginx 1.2.6, php-5.3.3 with php-fpm src
from the 5.3.20 release. I’m seeing some “Primary script unknown” errors
which I can’t figure out with the info in the book, wiki or google.
Below are my configs. Hopefully someone has a clue what I am doing
wrong.

ls -l /usr/share/nginx

drwxr-xr-x. 12 root root 4096 Jan 8 18:47 piwik

ls -l /usr/share/nginx/piwik

total 96
-rw-r-----. 1 nginx nginx 676 Aug 12 16:05 composer.json
drwxr-x—. 2 nginx nginx 4096 Nov 27 11:11 config
drwxr-x—. 25 nginx nginx 4096 Nov 27 11:11 core
-rw-r-----. 1 nginx nginx 822 Feb 14 2005 favicon.ico
-rw-rw-r–. 1 nginx nginx 273 Nov 27 11:11 How to install Piwik.html
-rw-r-----. 1 nginx nginx 1611 Mar 20 2012 index.php
drwxr-x—. 2 nginx nginx 4096 Nov 27 11:11 js
drwxr-x—. 2 nginx nginx 4096 Nov 27 11:11 lang
-rw-r-----. 1 nginx nginx 6070 Feb 13 2012 LEGALNOTICE
drwxr-x—. 21 nginx nginx 4096 Nov 27 11:11 libs
drwxr-x—. 6 nginx nginx 4096 Nov 27 11:11 misc
-rw-r-----. 1 nginx nginx 21548 Nov 1 10:02 piwik.js
-rw-r-----. 1 nginx nginx 2967 Oct 23 11:22 piwik.php
drwxr-x—. 46 nginx nginx 4096 Nov 27 11:11 plugins
-rw-r-----. 1 nginx nginx 2640 Mar 6 2012 README
drwxr-x—. 2 nginx nginx 4096 Nov 27 11:11 tests
drwxr-x—. 3 nginx nginx 4096 Nov 27 11:11 themes
drwxr-x—. 2 nginx nginx 4096 Nov 27 11:11 tmp

cat /etc/nginx/nginx.conf

user nginx nginx;

as recommended in the Nginx book, p98

worker_processes 2;
worker_rlimit_nofile 1024;
worker_priority -5;
worker_cpu_affinity 01 10;

error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
## as recommended in the Nginx book, p98
worker_connections 128;
## epoll is preferred on 2.6 Linux
use epoll;
## Accept as many connections as possible
multi_accept on;
}

http {
## Server names
server_names_hash_bucket_size 64;

 ## MIME types
 include       /etc/nginx/mime.types;
 default_type  application/octet-stream;

 ## FastCGI
 include /etc/nginx/fastcgi.conf;

 ## define the log format
 log_format  main  '$remote_addr - $remote_user [$time_local]

“$request” ’
'$status $body_bytes_sent “$http_referer” ’
‘“$http_user_agent” “$http_x_forwarded_for”’;

 ## Default log and error files
 access_log  /var/log/nginx/access.log  main;
 error_log  /var/log/nginx/error.log;

 ## Use sendfile() syscall to speed up I/O operations and speed up
 ## static file serving
 sendfile        on;

 ## Handling of IPs in proxied and load balancing situations
 set_real_ip_from 0.0.0.0/32; # all addresses get a real IP
 real_ip_header X-Forwarded-For; # ip forwarded from the load

balancer/proxy

 ## Define a zone for limiting the number of simultaneous
 ## connections nginx accepts. 1m means 32000 simultaneous
 ## sessions. We need to define for each server the limit_conn
 ## value refering to this or other zones
 limit_conn_zone $binary_remote_addr zone=arbeit:10m;

 ## Timeouts
 client_body_timeout 60;
 client_header_timeout 60;
 keepalive_timeout 10 10;
 send_timeout 60;

 ## reset lingering timed out connections. Deflect DDoS
 reset_timedout_connection on;

 ## Body size
 client_max_body_size 10m;

 ## TCP options
 tcp_nodelay on;
 ## Optimization of socket handling when using sendfile
 tcp_nopush on;

 ## Compression.
 gzip              on;
 gzip_buffers      16 8k;
 gzip_comp_level   1;
 gzip_http_version 1.1;
 gzip_min_length   10;
 gzip_types        text/plain text/css application/x-javascript

text/xml application/xml application/xml+rss text/javascript
image/x-icon application/vnd.ms-fontobject font/opentype
application/x-font-ttf;
gzip_vary on;
gzip_proxied any; # Compression for all requests
## No need for regexps. See
## Module ngx_http_gzip_module
gzip_disable “msie6”;

 ## Serve already compressed files directly, bypassing on-the-fly
 ## compression
 gzip_static on;

 ## Hide the Nginx version number.
 server_tokens off;

 ## Use a SSL/TLS cache for SSL session resume. This needs to be
 ## here (in this context, for session resumption to work. See this
 ## thread on the Nginx mailing list:
 ## http://nginx.org/pipermail/nginx/2010-November/023736.html
 ssl_session_cache shared:SSL:10m;
 ssl_session_timeout 10m;

 ## Enable clickjacking protection in modern browsers. Available in
 ## IE8 also. See
 ## 

https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header
add_header X-Frame-Options SAMEORIGIN;

 ## add Maxmind GeoIP databases
 ## http://dev.maxmind.com/geoip/geolite
 geoip_country  /etc/nginx/GeoIP.dat;
 ##geoip_country  /etc/nginx/GeoIPv6.dat;
 geoip_city     /etc/nginx/GeoLiteCity.dat;
 ##geoip_city     /etc/nginx/GeoLiteCityv6.dat;

 ## Include the upstream servers for PHP FastCGI handling config.
 include upstream_phpcgi.conf;

 ## FastCGI cache zone definition.
 include fastcgi_cache_zone.conf;

 ## Include the php-fpm status allowed hosts configuration block.
 ## Uncomment to enable if you're running php-fpm.
 include php_fpm_status_allowed_hosts.conf;

 ## Include all vhosts.
 include /etc/nginx/sites-enabled/*;

}

cat /etc/nginx/fastcgi.conf

fastcgi configuration.

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffers 256 4k;
fastcgi_intercept_errors on;

allow 4 hrs - pass timeout responsibility to upstream

fastcgi_read_timeout 14400;
fastcgi_index index.php;

cat /etc/nginx/upstream_phpcgi.conf

Upstream configuration for PHP FastCGI.

Add as many servers as needed. Cf.

Module ngx_http_upstream_module.
upstream phpcgi {
#Server unix:/var/run/php-fpm.sock;
server 127.0.0.1:9000;
}

cat /etc/nginx/fastcgi_cache_zone.conf

fastcgi_cache_path /var/lib/nginx/tmp/fastcgi levels=1:2
keys_zone=fcgicache:100k max_size=10M inactive=3h
loader_threshold=2592000000 loader_sleep=1 loader_files=100000;

cat /etc/nginx/sites-available/piwik.conf

Nginx configuration for Piwik.

based on GitHub - matomo-org/matomo-nginx: Nginx configuration for running Matomo

server {
listen <my_public_ip>:80; # IPv4
listen <my_public_ipv6>:80; # IPv6

 server_name  piwik.domain.com;

 # always redirect to the ssl version
 rewrite  ^ https://$server_name$request_uri? permanent;

}

server {
listen <my_public_ip>:80; # IPv4
listen <my_public_ipv6>:80; # IPv6

 ## SSL config
 ssl_protocols  SSLv3 TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers    HIGH:!aNULL:!MD5:!RC4;
 ssl_prefer_server_ciphers  on;

 # public server cert
 ssl_certificate  /etc/pki/tls/certs/piwik.domain.com.crt;
 # private server key without pass
 ssl_certificate_key  /etc/pki/tls/private/piwik.domain.com.key;
 # public CA cert to verify client certs
 ssl_client_certificate  /etc/pki/tls/certs/My_CA.crt;

 ## verify client certs
 ssl_verify_client on;
 #ssl_verify_depth 1;

 limit_conn arbeit 32;
 server_name piwik.domain.com;

 ## Access and error log files.
 access_log /var/log/nginx/piwik.domain.com_access.log;
 error_log /var/log/nginx/piwik.domain.com_error.log;

 root /usr/share/nginx/piwik.domain.com;
 index index.php;

 ## Disallow any usage of piwik assets if referer is non valid.
 location ~* ^.+\.(?:css|gif|jpe?g|js|png|swf)$ {
     ## Defining the valid referers.
     valid_referers none blocked *.domain.com domain.com;
     if ($invalid_referer)  {
         return 444;
     }
     expires max;
     ## No need to bleed constant updates. Send the all shebang in 

one
## fell swoop.
tcp_nodelay off;
## Set the OS file cache.
open_file_cache max=500 inactive=120s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
}

 ## Support for favicon. Return a 204 (No Content) if the favicon
 ## doesn't exist.
 location = /favicon.ico {
     try_files /favicon.ico =204;
 }

 ## Try all locations and relay to index.php as a fallback.
 location / {
     try_files $uri /index.php?$query_string;
 }

 ## Relay all index.php requests to fastcgi.
 location = /index.php {
     fastcgi_pass 127.0.0.1:9001;
     ## FastCGI cache.
     ## cache ui for 5m (set the same interval of your crontab)
     include sites-available/fcgi_piwik_cache.conf;
     fastcgi_index   index.php;
     fastcgi_param   SCRIPT_FILENAME

$document_root$fastcgi_script_name;
include fastcgi_params;
}

 ## Relay all piwik.php requests to fastcgi.
 location = /piwik.php {
     fastcgi_pass 127.0.0.1:9001;
     include sites-available/fcgi_piwik_long_cache.conf;
     fastcgi_index   index.php;
     fastcgi_param   SCRIPT_FILENAME

$document_root$fastcgi_script_name;
include fastcgi_params;
}

 ## Any other attempt to access PHP files redirects to the root.
 location ~* ^.+\.php$ {
     return 302 /;
 }

 ## Redirect to the root if attempting to access a txt file.
 location ~*

(?:DESIGN|(?:gpl|README|LICENSE)[^.]|LEGALNOTICE)(?:.txt)$ {
return 302 /;
}

 ## Disallow access to several helper files.
 location ~* \.(?:bat|html?|git|ini|sh|svn[^.]*|txt|tpl|xml)$ {
     return 404;
 }

 ## No crawling of this site for bots that obey robots.txt.
 location = /robots.txt {
     return 200 "User-agent: *\nDisallow: /\n";
 }

 ## Including the php-fpm status and ping pages config.
 ## Uncomment to enable if you're running php-fpm.
 include php_fpm_status_vhost.conf;

} # server

cat /etc/nginx/fastcgi_params

fastcgi parameters.

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

Maxmind GeoIP for Piwik

Guides - Analytics Platform - Matomo

fastcgi_param GEOIP_ADDR $remote_addr;
fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;
fastcgi_param GEOIP_REGION $geoip_region;
fastcgi_param GEOIP_REGION_NAME $geoip_region_name;
fastcgi_param GEOIP_CITY $geoip_city;
fastcgi_param GEOIP_AREA_CODE $geoip_area_code;
fastcgi_param GEOIP_LATITUDE $geoip_latitude;
fastcgi_param GEOIP_LONGITUDE $geoip_longitude;
fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code;

PHP only, required if PHP was built with --enable-force-cgi-redirect

fastcgi_param REDIRECT_STATUS 200;

cat /etc/php-fpm.conf

[global]
pid = run/php-fpm.pid
error_log = log/php-fpm.log
syslog.facility = daemon
log_level = notice
emergency_restart_threshold = 10
emergency_restart_interval = 1
process_control_timeout = 10s
daemonize = yes
rlimit_files = 131072
rlimit_core = unlimited
events.mechanism = epoll

[piwik]

user = nginx
group = nginx

listen = 127.0.0.1:9001

listen.owner = nginx
listen.group = nginx
listen.mode = 0666
listen.backlog = -1

listen.allowed_clients = 127.0.0.1

pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4

pm.status_path = /fpm-status
ping.path = /ping

access.log = /var/log/php-fpm-$pool.access.log
slowlog = /var/log/php-fpm-$pool.slow.log

request_slowlog_timeout = 5s
request_terminate_timeout = 120s

catch_workers_output = yes

security.limit_extensions = .php

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

The various errors I see are:

2013/01/08 19:31:00 [error] 638#0: *3 FastCGI sent in stderr: “Primary
script unknown” while reading response header from upstream, client:
<client_ipv6_address>, server: piwik.domain.com, request: “GET /
HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9001”, host:
piwik.domain.com

2013/01/08 19:32:00 [error] 638#0: *15 FastCGI sent in stderr: “Primary
script unknown”, client: <client_ipv6_address>, server:
piwik.domain.com, request: “GET / HTTP/1.1”, host: “piwik.domain.com

Any advice or pointers to docs where I can find a solution are most
appreciated.

Thanks/спасибо,
Patrick

At first glance I can’t see anything listening on port 443.

Cheers,

Steve

On Tue, Jan 08, 2013 at 08:08:33PM +0100, Patrick L. wrote:

Hi there,

I’m seeing some “Primary script unknown” errors

That message from the fastcgi server usually means that the
SCRIPT_FILENAME that it was given was not found as a file on its
filesystem.

Your filesystem has:

ls -l /usr/share/nginx

drwxr-xr-x. 12 root root 4096 Jan 8 18:47 piwik

ls -l /usr/share/nginx/piwik

> -rw-r-----. 1 nginx nginx 1611 Mar 20 2012 index.php

But your nginx config file has:

root /usr/share/nginx/piwik.domain.com;
location = /index.php {
> fastcgi_param SCRIPT_FILENAME > $document_root$fastcgi_script_name; > }

so SCRIPT_FILENAME will be /usr/share/nginx/piwik.domain.com/index.php

Which does not exist, and so is not found.

Any advice or pointers to docs where I can find a solution are most
appreciated.

Set “root” correctly in the nginx config. (Which is more or less the
same as “set the directory name correctly in the filesystem”.)

f

Francis D. [email protected]

On 01/08/2013 08:44 PM, Steve H. wrote:

At first glance I can’t see anything listening on port 443.

Thanks Steve. It was a copy & paste error. Here’s what it really should
be:

server {
listen IP:80; # IPv4
listen IP:80; # IPv6

 server_name  piwik.mydomain.com;

 # always redirect to the ssl version
 rewrite      ^ https://$server_name$request_uri? permanent;

}

server {
listen IP:443 ssl; # IPv4
listen IP:443 ssl ;

 ## SSL config
 ssl_protocols  SSLv3 TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers    HIGH:!aNULL:!MD5:!RC4;
 ssl_prefer_server_ciphers  on;

The SSL part works fine.

Regards,
Patrick

In my experience, that’s usually caused by access to parent dirs…
ie /home is made unreadable by nginx user when changed to 750 root:root.

Cheers,

Steve

On 01/08/2013 09:09 PM, Francis D. wrote:
[snip]

Set “root” correctly in the nginx config. (Which is more or less the
same as “set the directory name correctly in the filesystem”.)

Thanks Francis. Another sharp pair of eyes and mine not so much. The
error was introduced when redacting the configs to protect the innocent.
The root in piwik.conf points correctly to the actual location of the
site in /usr/share/nginx. I also tried turning off SELinux but that did
not make a difference.

I can make it work when I chmod all files to 644 and all directories to
755. But I do not understand why that is. If nginx and php-fpm are
running as nginx/ningx shouldn’t both be able to handle files & dirs
owned by nginx/nginx with mode 640 and mode 750?

Regards,
Patrick

On 01/08/2013 10:44 PM, Steve H. wrote:

In my experience, that’s usually caused by access to parent dirs…
ie /home is made unreadable by nginx user when changed to 750 root:root.

Gold star for you Steve :slight_smile: It works fine now. I guess that’s what you
get for staring at configs for way too long. Thank you very much!

Regards,
Patrick

On Tue, 2013-01-08 at 22:56 +0100, Patrick L. wrote:

On 01/08/2013 10:44 PM, Steve H. wrote:

In my experience, that’s usually caused by access to parent dirs…
ie /home is made unreadable by nginx user when changed to 750 root:root.

Gold star for you Steve :slight_smile: It works fine now. I guess that’s what you
get for staring at configs for way too long. Thank you very much!

Regards,
Patrick
Graag gedaan (:

Steve