subdomain value in PHP (nginx) - php

I have a Nginx webserver (I'm very new at Nginx). This is my Nginx config file:
server {
listen 80;
listen [::]:80;
server_name example.com *.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 5m;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com *.example.com;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
I have a DNS-record set to allow wildcard subdomains. My question now is: how can I "catch" the current subdomain in PHP?
For example: if the subdomain is http://demo.example.com, I want to go to
http://example.com?subdomain=demo.
Thanks in advance!

The host header will already contain the client requested domain. You could just grab that in php
$domain = $_SERVER['HTTP_HOST'];
However, unless you have a wildcard SSL certificate then you are going to have a bad time.
SSL negotiation takes place before any HTTP exchange so if the subdomain and the SSL cert don't agree the connection will fail.
Also, changing the subdomain to a query string is a bad idea:
You'll lose the ability to configure each subdomain separately within
Nginx and force lots of redirects and rewrites for every client
connection.
Your SEO will suck.
What will your page links look like?
If I have one.example.com and you have two.example.com the requests will become:
example.com?subdomain=one
example.com?subdomain=two
Both of those requests are now being handled by the same index page on example.com. Is that really what you want?

Add the following server to your Nginx. don't forget to restart Nginx service
server {
server_name demo.example.com;
rewrite ^(.*) http://example.com?subdomain=demo;
}
Update
according to the comment, for dynamic redirection, you should get the subdomain name by regex
server {
listen 80;
server_name ~^(?<name>.+)\.example\.com$;
return 301 http://example.com/?subdomain=$name;
}
Also, you can rewrite it instead of 301 redirects by
rewrite ^(.*) http://example.com/?subdomain=$name;
See this document for more info.

Related

403 Forbidden for index.php on Nginx

I am trying to configure a simple wordpress site in nginx on Ubuntu. I'm no linux expert, but I usually manage between following tutorials online and tweaking a few bits myself. I've also had this very site running on a previous server with nginx, which I configured myself. I've migrated to a new server but I'm setting things up slightly differently this time round, so starting from scratch.
I've got nginx, php, and mysql installed and configured. I know php is working as I have checked it with domain.com/php.info. However, when I try to access domain.com or domain.com/index.php I get 403 forbidden. If I point the server block to index.html, that is served correctly.
I have set folder permissions to 755 and files to 644, and the owner to www-data.
If I rename index.php to index2.php, I can access the page at domain.com/index2.php but if I then point the server block to index2.php, I still get error 403.
I thought my server block config must be wrong, so I used the generator at digitalocean but the result is the same. I've tried almost every suggestion I can find on google and nothing has worked. Config below, can anyone help? Thanks!
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
set $base /var/www/example.com;
root $base/;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# security
include nginxconfig.io/security.conf;
# logging
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;
# index.php
index index.php;
# index.php fallback
location / {
try_files $uri $uri/ /index.php?$query_string;
#also tried the alternatives below
#try_files $uri /index.php;
#try_files $uri /index.php?$args;
}
# additional config
include nginxconfig.io/general.conf;
include nginxconfig.io/example.com.wordpress.conf;
# handle .php
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include nginxconfig.io/php_fastcgi.conf;
}
}
# non-www, subdomains redirect
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name .example.com;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
return 301 https://www.example.com$request_uri;
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name .example.com;
return 301 https://www.example.com$request_uri;
}

Why nginx always redirects to one of my virtual hosts?

I have several virtual hosts configured with nginx. They are very simiral to each other and for most of them, everything seems to be working fine.
However,
If I hit the server through a url that does not have any virtual host configured, nginx always redirects to one of the existing virtual hosts (seems to be the first one in the list.
Same happens if I simply go there using IP address.
Most of the virtual hosts look like this:
server {
server_name iibs.co;
return 302 $scheme://www.iibs.co$request_uri;
}
server {
server_name www.iibs.co;
root /var/www/iibs.co;
index index.php;
include global/restrictions.conf;
client_max_body_size 64M;
# Additional rules go here.
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi.conf;
fastcgi_intercept_errors on;
fastcgi_pass php;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
# Only include one of the files below.
# include global/wordpress.conf;
# include global/wordpress-ms-subdir.conf;
# include global/wordpress-ms-subdomain.conf;
}
I just tried adding another one, very similar just with different domain and root. And that particular one, also getting redirected to the same first vhost on the list.
At this point, I have no idea where and what should I looks for.
This is an example of default NGINX config for prevent redirects to the first of the existing virtual hosts .
### Block all illegal host headers. Taken from a discussion on nginx
### forums. Cf. http://forum.nginx.org/read.php?2,3482,3518 following
### a suggestion by Maxim Dounin. Also suggested in
### http://nginx.org/en/docs/http/request_processing.html#how_to_prevent_undefined_server_names.
server {
listen 80 default_server; # IPv4
#listen [::]:80 default_server ipv6only=on; # IPv6
server_name _;
server_name "";
return 444;
}

Nginx - Redirect 404 PHP files

I'm using Laravel's valet on my local. I did not have a problem with this on my local. My remote server uses Ubuntu 16.04.
I have an index.php like so in my website's root:
<?php
require __dir__ . '/src/core/bootstrap.php';
require __dir__ . '/src/controllers/index.php';
src/core/bootstrap.php is stuff for composer and databases. But this is what src/controllers/index.php is:
<?php
session_start();
use App\UserTools\User;
use App\Core\Router;
$page = Router::load()->fetchPage();
include "src/controllers/{$page}.controller.php";
include "src/views/{$page}.view.php";
So, when users visit site.com, it goes to main since it's the home page. But, let's say, for example, they visit: site.com/about, then $page would be about and viola... routing. This was all taught to me on Laracasts, so excuse me if this seems... rudimentary.
The problem lies, when I visit site.com/api, it just shows me a blank page. Or, like, book?id=1 blank page. Or
Here is the nginx block from valet which tells the server what to do with files not found:
location / {
rewrite VALET_SERVER_PATH last;
}
How can I apply that to my site? I tried substituting VALET_SERVER_PATH with /var/www/html but I just got a Server Error 500.
Here is my current nginx block:
server {
server_name www.site.org;
return 301 $scheme://site.org$request_uri;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name site.org;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/ssl-site.org.conf;
include snippets/ssl-params.conf;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name site.org;
location / {
try_files $uri $uri/ /index.php;
}
location ~ /.well-known {
allow all;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}
It works. But only for the front page. Yes, I have HTTPS enabled and www traffic gets re-directed to non-www URI.
Make changes on the following directives:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
}

Not able to redirect https site to another url - nginx server block

I am trying to attach a promo subdomain to my site which is already on https, and then use a redirect url to redirect to another page in the site. For eg., basically if my site were https://example.com and had a page https://example.com/xyz/xyz/promo then I want a browser redirect when I type in https://promo.example.com to this page. I have set up all the relevant AWS route 53 settings.
My nginx server blocks have this
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://example.com$request_uri;
}
server {
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
server_name promo.example.com;
return 301 https://example.com/xyz/xyz/promo;
}
ssl_certificate /..path/..;
ssl_certificate_key //..path/..;
ssl_dhparam /..path/...;
ssl_trusted_certificate /..path/..;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
ssl_prefer_server_ciphers on;
ssl_ciphers .......; //hidden
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_buffer_size 1400;
spdy_headers_comp 0;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10;
server {
listen 443 ssl spdy;
server_name example.com;
include /etc/nginx/helper.conf;
root /var/www/example/ ;
index index.php index.html;
charset utf-8;
location / {
add_header "Access-Control-Allow-Origin" "*";
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Current behaviour:
It redirects correctly when I type in promo.example.com directly without the https. But if I type in https://promo.example.com it just shows me example.com, with the url being https://promo.example.com
Expected behaviour:
If I type in https://promo.example.com, it should redirect to https://example.com/xyz/xyz/promo
I can't put https://promo.example.com and then redirect with the server blocks, because nginx throws an error.
How can I redirect https://promo.example.com to go to https://example.com/xyz/xyz/promo
Due to use Strict-Transport-Security header the browser provides 301 redirect automatically by itself so this server block has never been used:
server {
server_name promo.example.com;
return 301 https://example.com/xyz/xyz/promo;
}
Port redirection 80->443 happens before even browser connected to server, so Nginx always serves latest server block based on port 443. This should help you:
server {
listen 443 ssl;
listen 80;
server_name promo.example.com;
return 301 https://example.com/xyz/xyz/promo;
}
Try this:
server {
server_name promo.example.com;
rewrite ^ https://example.com/xyz/xyz/promo permanent;
Each Server can have a single instance of https, which in this case is example.com, thus when https is prefixed to any of the url, irrespective of the urls, the user is redirected to the example.com.
To have the user redirected to the intended url with https, you need to have a separate port or a separate IP for that site.
As per http://nginx.org/r/listen, the default for the listen directive is listen *:80 | *:8000;.
If the directive is not present then either *:80 is used if nginx runs with the superuser privileges, or *:8000 otherwise.
As such, the snippets you've provided have no effect on https connections at all, since they don't apply to port 443 over ssl.
You haven't provided your ssl configuration snippets, nor the certificate details, for us to provide you with a complete answer, but once the above is understood, the answer would likely avail itself.
You can refer to http://nginx.org/en/docs/http/configuring_https_servers.html#single_http_https_server in regards to configuring a single server to handle both HTTP and HTTPS requests.
P.S. In general, HTTPS itself doesn't plan nicely with subdomains, and unless you've paid extra, your certificate likely doesn't cover any of the subdomains, which means that it'll result in browser warnings should you or your users attempt to access such sites via the https:// address scheme.
There are two ways to work around this:
Have a wildcard certificate for *.example.com, so all subdomains can share the same certificate.
Run each SSL site at a different IP address. This way, the webserver knows which SSL certificate it can send to the browser. - by inspecting the IP address which received the incoming connection.

Drupal, nginx, ssl, and php - a nightmare

I think I'll cross post to stackoverflow as well; Here's my issue:
I have installed an ssl certificate on my server, and read a whole lot and did all the different suggested things, but I cannot seem to get the $_SERVER['HTTPS'] variable to show up. Someone please help. Here's my config:
Server:
Linode
Ubuntu 8.02LTS
nginx - latest
created a vhost:
server {
listen 443;
server_name www.buzzonstage.com;
rewrite ^/(.*) https://buzzonstage.com/$1 permanent;
}
server {
listen 443;
server_name buzzonstage.com;
ssl on;
ssl_certificate /usr/local/nginx/conf/buzzonstage.com.pem;
ssl_certificate_key /usr/local/nginx/conf/buzzonstage.com.key;
access_log /home/maksimize/public_html/buzzonstage.com/log/access.log;
error_log /home/maksimize/public_html/buzzonstage.com/log/error.log;
location / {
root /home/maksimize/public_html/buzzonstage.com/public/;
index index.php index.html;
if (!-e $request_filename)
{
rewrite ^/(.*)$ /index.php?q=$1 last;
}
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include /usr/local/nginx/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /home/maksimize/public_html/buzzonstage.com/public/$fastcgi_script_name;
fastcgi_param HTTPS on;
}
}
server {
listen 80;
server_name www.buzzonstage.com;
rewrite ^/(.*) http://buzzonstage.com/$1 permanent;
}
server {
listen 80;
server_name buzzonstage.com;
access_log /home/maksimize/public_html/buzzonstage.com/log/access.log;
error_log /home/maksimize/public_html/buzzonstage.com/log/error.log;
location / {
root /home/maksimize/public_html/buzzonstage.com/public/;
index index.php index.html;
if (!-e $request_filename)
{
rewrite ^/(.*)$ /index.php?q=$1 last;
}
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include /usr/local/nginx/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /home/maksimize/public_html/buzzonstage.com/public/$fastcgi_script_name;
The verification from digicert comes back accurate, but I get a message saying that some info may not be secure - I understand this is the case because of the various links to non-secure pages on the site. The phpinfo shows up green https;
But in order for a certain drupal module to work - securepages - I need to be able to show a that variable in the $_SERVER array. Can someone please help?
Thanks!
That Twitter module is breaking SSL. Modify it so it will pass only through SSL (requires rewriting the widget so it loads locally, yes it's possible), and everything should work.
The phpinfo shows up green https;
This is good. Because phpinfo works with $_SERVER['HTTPS'] variable. And it's certainly defined.
but I get a message saying that some info may not be secure
But in order for a certain drupal module to work - securepages
I need to be able to show a that variable in the $_SERVER array.
Hmm, may be this modules trying to work without https? For example through AJAX?
And where they getting answer, HTTPS is not defined.
Try to check this, by adding fastcgi_param HTTPS on; to NON https section of your config. I think all will start working. But obvious, it's a cheat...

Categories