Nginx multiple root depending on user agent - php

I have two applications one for mobile devices and other for other devices.
What I am trying to do is to show both application on the same domain instead of 2 different domain
I have google it but every one it showing url redirection.
Below is the code which, I have trying
server {
listen 80;
set $root /var/www/ng/webApplication;
if ($http_user_agent ~* "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos") {
set $root /var/www/html/mobileApplication;
}
root $root;
}
but nginx stop working if add this condition.
Edit
nginx -t result
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Edit
access.log
180.151.19.20 - - [02/Jul/2019:05:12:10 +0000] "GET / HTTP/1.1" 404 178 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
also in browser it shows 404 Not Found

Assuming both applications can respond independently. You can try to use the reverse proxy option. Here is an example.
proxy_pass http://localhost/webApplication;
if ($http_user_agent ~* "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos") {
proxy_pass http://localhost/mobileApplication;
}

Related

Laminas Framework Routing Issues

I am developing a website using the Laminas Framework. Some URIs (listed below) are not behaving as expected. I am unsure if the problem is Laminas or php:fpm or nginx.
Questions:
How can I have (G) and (H) be treated exactly the same by Laminas so that my custom '404 Page Not Found' is rendered?
Is it normal for (C) and (D) to return 404 Not found? Or should this be rendering index.phtml?
Examples of behavior when I use chrome to access www.domain.com (really it is 127.0.0.1:3080 via a virtual machine!)
(A) www.domain.com (Laminas renders custom index.phtml) -- OK, expected.
(B) www.domain.com/ (Laminas renders custom index.phtml) -- OK, expected.
(C) www.domain.com/index.php (Laminas renders custom 404 Not found) -- PROBLEM?? Or expected??
(D) www.domain.com/index.php/ (Laminas renders custom 404 Page Not Found) -- PROBLEM?? Or expected??
(E) www.domain.com/dog (Laminas renders custom 404 Page Not Found, page does not exist) -- OK, expected.
(F) www.domain.com/dog/ (Laminas renders custom 404 Page Not Found, page does not exist) -- OK, expected.
(G) www.domain.com/dog.php (Php:fpm "File Not Found", page does not exit) -- PROBLEM!
(H) www.domain.com/dog.php/ (Laminas renders custom 404 Page Not Found, page does not exit) -- OK, expected.
Nginx Configuration
index index.php;
server {
listen 80;
listen [::]:80;
server_name www.domain.com;
root /var/www/public;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass docker-php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
The relevant Laminas file/directory layout:
- website/public/index.php # Entry point of the web app
- website/module/Application/view/application/index.phtml # Custom index page to render
- module/Application/view/error/404.phtml # Custom 404 page
- dog, dog.php do not exist
EDIT:
I do not believe (G) is even making it Laminas. I get the following error message in this case (logs from running docker-compose):
docker-php | 172.20.0.5 - 30/Jan/2023:02:41:41 +0000 "GET /dog.php" 404
docker-nginx | 2023/01/30 02:41:41 [error] 24#24: *13 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 10.0.2.2, server: www.domain.com, request: "GET /dog.php HTTP/1.1", upstream: "fastcgi://172.20.0.3:9000", host: "127.0.0.1:3080"
docker-nginx | 10.0.2.2 - - [30/Jan/2023:02:41:41 +0000] "GET /dog.php HTTP/1.1" 404 27 "-" "Mozilla/5.0 [...]
Compared to the properly working (H) case: The properly routed 404.phtml (logs from running docker-compose):
docker-php | 172.20.0.5 - 30/Jan/2023:02:47:01 +0000 "GET /index.php" 404
docker-nginx | 10.0.2.2 - - [30/Jan/2023:02:47:01 +0000] "GET /dog.php/ HTTP/1.1" 404 311 "-" "Mozilla/5.0
To have (G) and (H) treated the same by Laminas, you should add routes to the same controller action for both URIs in your application's router configuration. To display your custom '404 Page Not Found', you can catch exceptions in your controller action and render the custom error page.
If (C) and (D) are not defined routes in your application, it is normal for them to return a 404 Not Found error. However, if you want them to render the index.phtml page, you should add a default route to your application's router configuration that maps to the controller action responsible for rendering index.phtml.

403 Forbidden Nginx on Ubuntu error only on some pages / directories

Been struggling with this problem for some days now, and can't seem to find a solution.
I made a server on my Raspberry PI with Ubuntu server and NGINX.
My goal is to host multiple webpages on the server, mainly using wordpress.
Subdomain is just a madeup domain.
The problem that I dont understand occurs when I want to visit my domain, www.subdomain.com.
The domain itself gives me a 403 Forbidden error - but if I visit www.subdomain.com/wordpress it automatically sends me to www.subdomain.com/wp-admin/installation.php as wanted, and I can create my wordpress page.
The same occurs when I log in to my new Wordpress installation and it refers me to www.subdomain.com/wp-admin/, again I get an 403 Forbidden Error, but if manually enters www.subdomain.com/wp-admin/index.php it all works fine.
STEP BY STEP
I made a subdomain /var/www/subdomain.com.
Installed WordPress /var/www/subdomain.com/wordpress.
Configured wp-config.
define( 'DB_NAME', 'wp_subdomain' );
/** Database username `*`/
define( 'DB_USER', 'user_subdomain' );
/`*`* Database password */
define( 'DB_PASSWORD', 'password' );
define('AUTH_KEY', '&jD{O Fid.qm7Ujf8JFO~nL84% cMRcW&^+`*`F,;sQ$Pv6aS0V?0keq5(/]ApGg#');
define('SECURE_AUTH_KEY', 'r^Z6)Hb(T9OJ= J{tZ4D?AYp+9R>b.YBu>{2{k|<7lX3Insw:#i|4jG|=Ih)Z- X');
define('LOGGED_IN_KEY', 'Y<L-SM%}#kO=f+lrx$V}#iePw9HbG7CwFr`*`X-eHz|z&T/Xi+Nb6S>Mlt=OT81B/');
define('NONCE_KEY', '.,ab^j2KfE4Ltv_]e=M<}R!]Df!.jrrE,g1|5>#6_om.#S/#L-L^,7Kdk)pnT>}U');`
`define('AUTH_SALT', '#NY5>IC,lX$2-#t3<(:jw.Ri!4V0bNVY/-I*;EJeX_ro5I9+D45v0=O *q[|Z8o ');
define('SECURE_AUTH_SALT', 'V(mG+uH6u3MWc|Uxxi{w2-p|*+Wc}OpPS5-[P.%)Gn+Cpn_MfN_2V#7jV?g]');
define('LOGGED_IN_SALT', 'r!f+Q&&FJk=V(UMIBxA=}ZB4++2:8xe3<sE/;QpXEHT%^z~m.{>]6{bV#q>N#O%'); define('NONCE_SALT', 'g7zUw}Rv+9&3.A&mp1GJ[4[;;T.{pE2aA!o:]]}k(#KgP#uISs~62~G3BQZveVK');
Configured /etc/nginx/sites-available/subdomain.com.conf & copied it to sites-enabled.
Both of them include:
upstream subdomain-php-handler {
server unix:/var/run/php/php8.1-fpm.sock;
}
server {
listen 80;
server_name subdomain.com www.subdomain.com;
root /var/www/subdomain.com/wordpress;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass subdomain-php-handler;
}
}
Setup database and granted permission with mysql mariadb.
Used mysql commands:
create database wp_subdomain default character set utf8 collate utf8_unicode_ci;
grant all on wp_subdomain.* to 'user_subdomain'#'localhost' identified by 'password';
flush privileges;
at last
nginx -t (all was fine)
systemctl restart nginx
All servers are connected and works.
Nginx error:
root#ubuntu:/# tail -20 /var/log/nginx/error.log`
6890#6890: *272 directory index of "/var/www/subdomain/wordpress/" is forbidden, client: 86.52.42.195, server: subdomain.com, request: "GET / HTTP/1.1", host: "subdomain.com"
10246#10246: *13 directory index of "/var/www/subdomain.com/wordpress/wp-content/" is forbidden, client: 86.52.42.195, server: subdomain.com, request: "GET /wp-content/ HTTP/1.1", host: "www.subdomain.com"
5-6 more 10246#10246 errors
10248#10248: *124 directory index of "/var/www/subdomain.com/wordpress/" is forbidden, client: 89.104.110.115, server: subdomain.com, request: "GET / HTTP/1.1", host: "subdomain.com"
I tried to chmod 755 /path/to/directory to all my directories inside.
Thanks you so much in advance.
Does anyone have an idea? or what i should look into, to make this work?

How do I get PHP-FPM to work with nginx-proxy with FastCGI?

I am attempting to get nginx-proxy to work with the php-fpm variant of the official php image via fastcgi. Unfortunately, I seem to be unable to do so. I'm sure the problem is just something simple that I don't know about.
I have followed the instructions for nginx-proxy to the best of my ability and have boiled it down to a very simple way to re-create the issue. Here's my docker-compose.yml file:
version: "3"
services:
proxy:
image: jwilder/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- DEFAULT_HOST=test.local
fpm:
image: php:fpm
environment:
- VIRTUAL_HOST=test.local
- VIRTUAL_PROTO=fastcgi
I then drop in a simple index.php file by running:
docker container exec -it web_fpm_1 /bin/bash -c 'echo "<?php phpinfo(); ?>" > /var/www/html/index.php'
(It puts web_ in front because this project is in a directory named web/.)
I also modify my hosts file to point test.local to 127.0.0.1, so I can test it.
However, every attempt to browse to test.local results in a blank white page.
The logs for the web_proxy_1 container don't indicate anything out of the ordinary, as far as I know:
❯ docker container logs web_proxy_1
WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one
is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded.
forego | starting dockergen.1 on port 5000
forego | starting nginx.1 on port 5100
dockergen.1 | 2020/07/20 19:24:54 Generated '/etc/nginx/conf.d/default.conf' from 2 containers
dockergen.1 | 2020/07/20 19:24:54 Watching docker events
dockergen.1 | 2020/07/20 19:24:54 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload'
nginx.1 | test.local 172.18.0.1 - - [20/Jul/2020:19:25:12 +0000] "GET / HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
nginx.1 | test.local 172.18.0.1 - - [20/Jul/2020:19:25:13 +0000] "GET /favicon.ico HTTP/1.1" 200 5 "http://test.local/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
The logs for the web_fpm_1 container show that nothing gets sent except a 200 response:
❯ docker container logs web_fpm_1
[20-Jul-2020 19:24:54] NOTICE: fpm is running, pid 1
[20-Jul-2020 19:24:54] NOTICE: ready to handle connections
172.18.0.3 - 20/Jul/2020:19:25:12 +0000 "- " 200
172.18.0.3 - 20/Jul/2020:19:25:13 +0000 "- " 200
What am I doing wrong?
Incidentally, I have asked this question on the nginx-proxy repo, the nginx-proxy Google Group, and the php repo. I either get no response or they pass the buck.
The default generated config of nginx-proxy is not fully working.
I think something is messed up with VIRTUAL_ROOT environment variable, because the root of the problem is PHP getting a wrong path via SCRIPT_FILENAME (that's why you see no PHP output) and there is no try_files with =404 symbol (that's why you get 200 with everything).
I have a prepared working setup using docker-compose in GitHub to demonstrate that it would work with an existing SCRIPT_FILENAME in the nginx config.
I have changed test.local to test.localhost.
I think to get it working as it should, you would have to use an nginx template for nginx-proxy, so the generated default.conf does work with php fpm and have the missing fastcgi param included.
Another, yet different approach would be to pack PHP and a manually configured webserver (nginx) in a project and having the automated reverse nginx proxy in a standalone project.
This would cost you an additional process running but gives you more control and easier deployment.
Alternatively, you might want to have a look into traefik which does essentially the same as nginx-proxy.
Daniel's answer is definitely on the right track. I use the php-fpm image with nginx as my main stack for php sites. Having said that, I don't use the nginx-proxy docker image. Instead, I use plain nginx on the host machine, and configure ports to point to backend php-fpm docker images.
I'm not using docker-compose either. Since it's just docker containers running single sites, I don't need it. Here's an example docker run command:
docker rm -f www.example.com || true
docker run -itd -p 9001:9000 -P \
--name www.example.com \
--volume /var/www/html/www.example.com:/var/www/html/www.example.com \
--link mariadb:database.example.com \
--restart="always" \
--hostname="example.com" \
--log-opt max-size=2m \
--log-opt max-file=5 \
mck7/php-fpm:7.4.x-wordpress
And here is an example nginx config:
server {
server_name example.com www.example.com;
location ~ /.well-known {
allow all;
}
location ~ /\.ht {
deny all;
}
root /var/www/html/www.example.com/src;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
}
}
A few things about this setup are key. The port re-mapping for the docker container. In this example I map port 9001 to 9000. The other "gotcha" is that the root for the container must be an actual location on the host. I have no idea why this is the case, but for whatever reason the path docker thinks it's using has to actually be the path on the host as well.

Configuration Issues: multi-domain auto SSL from LetsCncrypt using OpenResty & lua-resty-auto-ssl

Please excuse lengthy write up - I would really appreciate any help in following regard.
I am trying to setup multi tenant subdomain + custom domain with SSL using LetsEncrypt:
(some will use subdomain some will use custom domain)
https://customer1.myapp.com
https://customer2.myapp.com
https://customer1.com (customer sets up A/CNAME recoreds at his DNS provider)
I am on EC2 instance using Ubuntu OS with username 'ubuntu'.
I learned from following tutorials:
https://sandeep.dev/how-we-generate-and-renew-ssl-certs-for-arbitrary-custom-domains-using-letsencrypt-cjtk0utui000c1cs1f7y9ua5n
https://www.digitalocean.com/community/tutorials/how-to-use-the-openresty-web-framework-for-nginx-on-ubuntu-16-04
https://sandro-keil.de/blog/openresty-nginx-with-auto-generated-ssl-certificate-from-lets-encrypt/
I have successfully done following:
Installed build-essential on server
Install OpenResty (Comes with its own Nginx & OpenSSL)
Install LuaRocks
Install lua-resty-auto-ssl
Created directory for resty auto ssl
sudo mkdir /etc/resty-auto-ssl
sudo chown -R ubuntu /etc/resty-auto-ssl
sudo chown -R www-data /etc/resty-auto-ssl
chmod -R 777 /etc/resty-auto-ssl/
Created Fallback Self-signed Certificate which expires in 3600 days
This is my starter conf file (/usr/local/openresty/nginx/conf/nginx.conf)
(I would refine it further to suite my redirect & security needs)
#user nginx;
error_log /usr/local/openresty/nginx/logs/error.log warn;
events {
worker_connections 1024;
}
http {
lua_shared_dict auto_ssl 1m;
lua_shared_dict auto_ssl_settings 64k;
init_by_lua_block {
auto_ssl = (require "resty.auto-ssl").new()
auto_ssl:set("allow_domain", function(domain)
return true
end)
auto_ssl:set("dir", "/etc/resty-auto-ssl")
auto_ssl:init()
}
init_worker_by_lua_block {
auto_ssl:init_worker()
}
# access_log /usr/local/openresty/nginx/logs/access.log main;
server {
listen 443 ssl;
ssl_certificate_by_lua_block {
auto_ssl:ssl_certificate()
}
ssl_certificate /etc/ssl/resty-auto-ssl-fallback.crt;
ssl_certificate_key /etc/ssl/resty-auto-ssl-fallback.key;
root /var/www/myapp.com/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# location ~ \.php$ {
# include snippets/fastcgi-php.conf;
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# fastcgi_read_timeout 600;
# }
location ~ /\.ht {
deny all;
}
}
server {
listen 80;
server_name *.myapp.com myapp.com;
location /.well-known/acme-challenge/ {
content_by_lua_block {
auto_ssl:challenge_server()
}
}
location / {
return 301 https://myapp.com$request_uri;
}
}
server {
listen 8999;
location / {
content_by_lua_block {
auto_ssl:hook_server()
}
}
}
}
I am facing multiple issues like:
Cant mention user in nginx config - still works without it also
Trying to mention user in 1st line of config files gives me error.
So i commented it out and tried to caryy on anyways
Dehydrated Failure but certificate is created
keep getting following error in my log:
lets_encrypt.lua:40: issue_cert(): auto-ssl: dehydrated failed: env HOOK_SECRET=XXXX HOOK_SERVER_PORT=8999 /usr/local/openresty/luajit/bin/resty-auto-ssl/dehydrated --cron --accept-terms --no-lock --domain myapp.com --challenge http-01 --config /etc/resty-auto-ssl/letsencrypt/config --hook /usr/local/openresty/luajit/bin/resty-auto-ssl/letsencrypt_hooks status: 256 out: # INFO: Using main config file /etc/resty-auto-ssl/letsencrypt/config
But it still goes on & does create a certificate after which it gives random number generator error.
Sometimes, if I delete everything inside /etc/resty-auto-ssl - it dosent give me such errors.
Can't find OpenSSL random number generator
I keep getting following error in my log:
Can't load ./.rnd into RNG
random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=./.rnd
curl: (22) The requested URL returned error: 500 Internal Server Error
PHP-FPM on nginx provided with OpenResty
I have properly installed php-fpm and have tested it when using nginx standalone.
But, now that I am using nginx provided with openresty, it dosent seem to work
Error (Shown when tested config using: nginx -t command):
"/usr/local/openresty/nginx/conf/snippets/fastcgi-php.conf" failed (2: No such file or directory)
Failed to create certificate
Sometimes this error is followed by error in above point number 2:
auto-ssl: could not get certificate for myapp.com - using fallback - failed to get or issue certificate, context: ssl_certificate_by_lua*, client: 123.201.226.209, server: 0.0.0.0:443
set_response_cert(): auto-ssl: failed to set ocsp stapling for xxxx.myapp.com - continuing anyway - failed to get ocsp response: OCSP responder query failed (http://ocsp.int-x3.letsencrypt.org): no resolver defined to resolve "ocsp.int-x3.letsencrypt.org", context: ssl_certificate_by_lua*, client: 123.201.226.209, server: 0.0.0.0:443
connect() to unix:/run/php/php7.4-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 123.201.226.209, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:", host: "xxxx.myapp.com"
When trying to access customer1.com whoes A record points to myapp.com server IP
"Error creating new order :: Cannot issue for \"X.X.X.X\": The ACME server can not issue a certificate for an IP address"
ssl_certificate.lua:281: auto-ssl: could not determine domain for request (SNI not supported?) - using fallback - , context: ssl_certificate_by_lua*, client: 45.148.10.72, server: 0.0.0.0:443
... where x.x.x.x is A recored for customer1.com whch was opened from browser
I have following confusions:
Should I get one proper (paid) wildcard positive ssl certificate for myapp.com ? (And use it as fallback)
This covers all my subdomain and I won't have to deal with limits on subdomain by letsencrypt.
This way I only have to use lets encrypt for custom domains like customer1.com
I am not sure if my users & permission are properly set up - any pointers would help
I would wish my final nginx config to fulfill following needs
Redirect http://myapp.com & http://www.myapp.com to -> https://myapp.com
Redirect https://www.myapp.com to -> https://myapp.com
Redirect http://customer1.com & http://www.customer1.com to -> https://customer1.com
And then on my acutal ssl server block - write all logic for auto ssl generation
It is somewhat hard to answer all these question, so I'll attempt to answer part of 5 & 6. I have setup open resty myself in a prod environment, see link.
I ran into this OCSP stapling issue. I found that it was resolved by adding this to my NGINX config:
# A DNS resolver must be defined for OSCP stapling to function.
resolver 172.20.0.10 ipv6=off;
Regarding question 6, I would suggest that customer1.com should be a CNAME to myapp.com.
I would also recommend using as a base the openresty docker image, or at least a reverse engineered version of the docker image into an EC2 instance. Here is my dockerfile:
FROM openresty/openresty:latest-xenial
RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-auto-ssl
RUN /usr/local/openresty/luajit/bin/luarocks install lua-resty-http
RUN apt-get update
RUN apt-get install -y dnsutils
RUN openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj '/CN=sni-support-required-for-valid-ssl' -keyout /etc/ssl/resty-auto-ssl-fallback.key -out /etc/ssl/resty-auto-ssl-fallback.crt
ADD nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
Hopefully this is helpful.

Nginx with php-fpm in a docker container is not loggin php errors

I'm using docker for setting up a nginx and php-fpm server. And I have the next problem, when I have an error in php nginx does not log the error anywhere.
I have this in my project conf.
project.conf
error_log /LOGS/simple_error.log debug;
access_log /LOGS/custom_access.log;
Inside the access file, I can see this lanes. That means I have a 500 status error, and I cannot see why.
Both of project error log, nginx error log are completely empty and I cannot see why.
172.17.0.1 - - [05/Apr/2019:11:51:31 +0000] "POST /user/create/ HTTP/1.1" 500 5 "-" "PostmanRuntime/7.6.1"
172.17.0.1 - - [05/Apr/2019:11:52:20 +0000] "POST /user/create/ HTTP/1.1" 200 58 "-" "PostmanRuntime/7.6.1"
I added this in the www.conf inside php configuration folder, and I still don't have error log from php.
www.conf
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
Inside /var/log/ directory there are two directories but there is not php-fpm log I'm looking for`.
Thanks in advance.

Categories