Nginx user defined rewrite rules - nginx

I'm wondering why this is question got not asked before: I want let the user make her own rewrite rules but not editing his configuration file.
/etc/nginx/sites-enabled/example.com: this file (or the original as this file is a symlinkn to sites-available...) is only writeable for root.
As for apache2 we can give him a way to write own rewrite rules, other expires configuration and so on without the need to edit the configuration file in /etc. Let's say it is a hosting provider and the user can't even access the /etc directory...

The whole .htaccess concept is not implemented in nginx, which one of the reasons why nginx is faster,
because if we have a file inside /var/www/site/folder1/folder2/file.php for example, the server needs to look for .htaccess inside folder2 and folder1 and site, and each will override the one above it, an overhead for each request.
The only way you might implement a kind of similar thing is add an include inside the config file that reads from a certain location
server {
# bla bla
include /var/www/site1/config.conf;
location bla {
# bla bla
}
}
The config file would include server level directives,
Or you could just skip the server block and include files, and those files should include server blocks, but this isn't good because you give them access to the whole server, not just theirs. eg:
# /etc/nginx/sites-enabled/site-name
include /var/www/site1/site.conf
include /var/www/site2/site.conf
# etc
Basically, my advice, if you really need this functionality, install apache, and maybe just use nginx to server assets and proxy to apache.

Related

Nginx - Do I really need sites-available and sites-enabled folders?

I noticed my install of nginx has three folders called
etc/nginx/sites-available
etc/nginx/sites-enabled
etc/nginx/conf.d
Do I really need these if I just want to work directly in the etc/nginx/nginx.conf file and remove the include lines that include these items in nginx.conf? Are these directories used for anything else that would mess things up if I delete them?
No, they are not needed if you define your server blocks properly in nginx.conf, but it's highly suggested. As you noticed, they are only used because of the include /etc/nginx/sites-enabled/*; in nginx.conf.
For curiosity, is there a reason why you do not want to use them? They are very useful; easier to add new sites, disabling sites, etc. Rather than having one large config file. This is a kind of a best practice of nginx folder layout.
Important information:
You should edit files only in sites-available directory.
Never edit files inside the sites-enabled directory, otherwise you can have problems if your editor runs out of memory or, for any reason, it receives a SIGHUP or SIGTERM.
For example: if you are using nano to edit the file sites-enabled/default and it runs out of memory or, for any reason, it receives a SIGHUP or SIGTERM, then nano will create an emergency file called default.save, inside the sites-enabled directory. So, there will be an extra file inside the sites-enabled directory. That will prevent Apache or NGINX to start. If your site was working, it will not be anymore. You will have a hard time until you find out, in the logs, something related to the default.save file and, then, remove it.
In the example above, if you were editing the file inside the sites-available directory, nothing bad would have happened. The file sites-available/default.save would have been created, but it wouldn't do any harm inside the sites-available directory.
I saw below comment in The Complete NGINX Cookbook in NGINX official site !.
The /etc/nginx/conf.d/ directory contains the default HTTP
server configuration file. Files in this directory ending in .conf
are included in the top-level http block from within the /etc/
nginx/nginx.conf file. It’s best practice to utilize include state‐
ments and organize your configuration in this way to keep your
configuration files concise. In some package repositories, this
folder is named sites-enabled, and configuration files are linked
from a folder named site-available; this convention is deprecated.
It is not a must, but a best practise if you host more than one sites on your box.
It will be easier to manage by keep http context and common directives (such as ssl_dhparam, ssl_ciphers, or even gzip settings, etc.) on the nginx.conf so that it applied across all sites.
Keep site-specific server context (such as ssl-certificate, location directives, etc.) at etc/nginx/sites-available/ and name the configuration file as your-domain.conf. The file in etc/nginx/sites-enabled can be just a link to the file to the etc/nginx/sites-available.

NGINX Rewrite Rule without access to the configuration file

In apache, the rewrite rule can be written in the configuration file or in .htaccess file. How about in nginx? Can I use url rewriting without access to the configuration file?
Unfortunately, you can't. This is one of the reasons shared hostings typically use apache or litespeed, not nginx or lighttpd.
A (very ugly) workaround would be to handle all requests with a script which would contain the rewrite rules and would serve the file/script according to the request URI (and which could be modified by a user without having root privileges). However you'd have a bad performance serving static files and you'd need to handle all the request headers by this script, which is not very practical.

Set nginx root based on existance of another directory

I'm building a system which uses dynamic DNS for user accounts, so you register for a sub domain.
I have a few server directives in place to catch things like api. and www. and other special cases, and I have a directive which reads the wildcard domain name and uses it to set a domain specific assets location.
server {
server_name "~^(?<domain>[a-z0-9]+)\.example\.com$";
root /sites/core;
location /assets {
alias /site-assets/$domain;
}
}
What I want to do is check for the existence of the assets directory and present, on the same domain, a different site.
To clarify, if the assets directory in the example above exists, serve one set of files, otherwise, serve another. Since the site I want to serve won't be IN the directory in question, I can't use try_files or anything like that.
I read all the horror stories about using the if directive but I think I need something like
if (-d /site-assets/$domain) {
... Do something
}
Then change the root, but that doesn't work.
Any ideas how I can achieve this?
OK. I figured this out. If there's a problem with it, let me know.
I have the following in a server directive
server {
server_name "~^(?<domain>[a-z0-9]+)\.example\.com$";
set $site core;
if (!-d /path/to/assets/$domain) {
set $site join;
}
root /path/to/sites/$site;
}
If the assets directory for the given domain name does NOT exist, then I can serve up a joining page for my site, which can pick up the domain name and allow the user to register. If it does exist, then serve up the main app.
This seems to me like a simple use of the if directive so shouldn't get me in too much trouble.

What is the default file to be visited behind a website?

When I open a website's url such as www.stackoverflow.com via curl, which file is actually being visited in the server? I know usually it is index.html. But I cannot find such a convention in the RFC2616 document. How can I know it?
BR
The document dilivered by calling a website without a path in the URL is configured by the webserver. So you have no standard there. Is a users joice.
Curl will download the file the webserver is delivering him, or follow the redirect (if -L option is given) when webserver responses a redirect.
There is no way for the client to know how the data for the HTTP response was generated. It might not even be related to a specific file.
The last time I wrote a significant bit of server side code, everything outside of /static/ was routed (via mod_rewrite) though a FastCGI program that got its data from a few different controller libraries, a dozen database schema libraries, a database and a dozen template files.
The WWW is built on links between URLs, not files. Don't worry about files if you are writing client code.
It's not necessarily index.html, and you can't actually know that it could be anything depending on the Server Configuration, for instance in Apache you can change the directory index to the one that suits you
DirectoryIndex home.php
in this case the default file accessed is home.php
in IIS you can take a look about default index and how to change it
but the defaults are
in Apache
index.php (usually: depending on the server configuration)
index.html (is the default that comes with a fresh install)
in IIS
Default.htm
Default.asp
Index.htm
Index.html
Iisstart.htm

How can I setup default directives for all servers in nginx? (Issues with Plesk)

I have a DV 4.0 server on media temple which is setup with nginx as a reverse proxy to apache. I want to configure some far future expires headers (using location blocks) and other settings for my (multiple) domains running through nginx.
Normally this wouldn't be an issue, just create a common set of rules and include them in a server {} block. However, Plesk creates and updates the server {} blocks automatically in separate files, meaning any changes made in these files are wiped out.
Ideally I'd like a way to set up a generic server {} block that gets applied all servers as defaults, but if this doesn't exist I'd like to know how to add custom directives within Plesk so they don't get wiped out when it rewrites the files.
Check this page
Yoг can customize default nginx virtual hosting template:
mkdir /usr/local/psa/admin/conf/templates/custom/domain
cp /usr/local/psa/admin/conf/templates/default/domain/nginxDomainVirtualHost.php /usr/local/psa/admin/conf/templates/custom/domain/
add or change what you need in /usr/local/psa/admin/conf/templates/custom/domain/nginxDomainVirtualHost.php
/usr/local/psa/admin/bin/httpdmng --reconfigure-all # to apply new configuration for all domains

Resources