Rewrite code from htaccess to nginx config? - apache

I have problem with implement my rewrite code from htaccess file into nginx config.
I've already tried generator : http://winginx.com/htaccess for generate my rewrite
code.
My nginx config code:
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 80;
root /usr/share/nginx/www;
index index.php;
server_name www.example.com;
error_page 404 http://www.example.com/404.php;
autoindex off;
error_log /usr/share/nginx/www/nginx_error.log warn;
location / {
rewrite ^([^\.]*)$ /$1.php;
}
location = / {
rewrite ^ /index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
I wanna implement this from my .htaccess:
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ admin/index.php?hotelname=$1&do=$2 [QSA]
RewriteRule ^(([A-Za-z0-9-/]+)+)$ admin/index.php?hotelname=$1 [L]
Generated code from tool:
location / {
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ /admin/index.php?hotelname=$1&do=$2;
rewrite ^/(([A-Za-z0-9-/]+)+)$ /admin/index.php?hotelname=$1 break;
}
I have alredy tried implement this last lines of code to my location blocks but not working at all..
I will be very greateful for every opinion!
Regards
Makromat

The blind kind of conversion would be
rewrite ^([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ admin/index.php?hotelname=$1&do=$2&$query_string last;
rewrite ^(([A-Za-z0-9-/]+)+)$ admin/index.php?hotelname=$1 last;
But I would prefer if I understand the question more to produce a more optimum rewrite.
When do I know if the URL should be passed to /admin or not, give me an actual URI for backend and for frontend.

Usually rewrites are better managed in nginx using nginx way of thinking. And this new way of thinking is more based on try_file.
So you may try something like that (untested):
location ^~ "/([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)" {
try_files $uri admin/index.php?hotelname=$1&do=$2&$args;
}
location ^~ "(([A-Za-z0-9-/]+)+)" {
try_files $uri /admin/index.php?hotelname=$1;
}
location = / {
rewrite ^ /index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
If direct access on given $urishould never happen, then remove that part from the try_files. Now I'm also unsure of your second regex (([A-Za-z0-9-/]+)+), why not using:
location ^~ "/([A-Za-z0-9-/])+"
Or
location ^~ "/([A-Za-z0-9-])+/"
So there's maybe something I do not see, even in your apache rewrites.

Related

Nginx Equivalent of Apache .htaccess

I've installed a PHP web application using a LEMP stack and I need to port some Apache .htaccess rewrite rules to the Nginx equivalents.
.htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?/$0 [PT,L]
I've tried these two services as recommended in other Stackoverflow answers:
http://winginx.com/en/htaccess
http://www.anilcetin.com/convert-apache-htaccess-to-nginx/
This is my server block:
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES$
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhp-2048.pem;
root /var/www/example;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com;
# return 302 https://example.com$request_uri;
access_log /var/log/nginx/example.access.log;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
The first converter generated this which I added as an addition location stanza before the last curly bracket. A syntax check nginx -t checks out but Nginx fails to restart.
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?/$0 break;
}
}
The second converter generated a different rule (below) which I added inside the first location stanza (under try_files) but that also breaks the configuration as Nginx won't restart.
if (!-f $request_filename){
set $rule_0 1$rule_0;
}
if (!-d $request_filename){
set $rule_0 2$rule_0;
}
if ($rule_0 = "21"){
rewrite /.* /index.php?/$0 last;
}
What am I doing wrong? Any help to fix this is appreciated and welcome.
Update:
I still need help with this. I've not been able to get the first solution posted to work for me.
Change the =404 term in your try_files statement to /index.php?$uri.
For example:
location / {
try_files $uri $uri/ /index.php?$uri;
}
Your try_files statement was only missing the final rewrite rule. Note that all URIs in nginx contain a leading /. Substituting $uri for $0 should work for you.
See this document for more.

Nginx Configuration/Rewrite

I want to configure nginx to behave in this way :
[OK] If i browse to domain.com/, the /var/www/index.php file is called
[HOW ?] If i browse to domain.com/blah, /var/www/controller.php is called
On apache, is done by a rewrite condition :
RewriteRule (.*) controller.php [L,QSA]
[HOW ?] If i browse to domain.com/api/someMethod, /var/www/api/controller.php is called
On apache, is done by a rewrite condition :
RewriteRule ^api api/controller.php [L,NC]
[HOW ?] If i browse to domain.com/image.png, nginx display the image /var/www/image.png
On apache, is done by a rewrite condition :
RewriteRule \.(js|css|gif|png|jpg|ico|txt|woff|woff2)$ - [L,NC]
And my nginx config :
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl;
listen [::]:443 ssl;
server_name _;
root /var/www;
index index.php;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
location ~ {
try_files $uri $uri/ /index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
The significant parts of the configuration would be:
root /var/www;
index index.php;
location = / { }
location / {
try_files $uri $uri/ /controller.php;
}
location /api {
try_files $uri $uri/ /api/controller.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
The first two lines are from your original configuration.
The location = will ensure that the URI / obeys the index index.php rather than the try_files rule next.
The location / defines the default action, serving image.png, index.php on subdirectories and controller.php on anything else.
The location /api modifies this behaviour with respect to controller.php.
The location ~ \.php$ block implements the fastcgi interface. Notice that include fastcgi_params; should come before any fastcgi_param directives to avoid the latter being silently overridden.
If you would like the URI domain.com/blah.php to call controller.php instead of throwing a 404, then change the =404 to /controller.php.
Please see this for a list of nginx directives.

Nginx auth_basic not working for a specific url

I would like to password protect one of the URLs I have and I am trying to do it with:
location /about/payment {
auth_basic "secured site";
auth_basic_user_file /var/www/my.passwd;
}
The problem is that I am asked for the username and paasword. AS soon as I put the right username and password, I am getting a 404 Error with this log:
*55268 open() "/var/www/mysite.com/deployment/web/about/payment" failed (2: No such file or directory), client: 172.16.0.53, server: ~^(?<branch>\w+)\.mysite\.dev$, request: "GET /about/payment HTTP/1.1", host: "deployment.mysite.dev"
EDIT:
The entire nginx conf file is here
server {
listen 80;
access_log ...;
error_log ...;
server_name ~^(?<branch>\w+)\.mysite\.dev$ ~^(?<branch>\w+)\.mysite\.com$;
root /var/www/git/branches/mysite.com/$branch/web;
location /about/payment {
auth_basic "secured site";
auth_basic_user_file /var/www/mysite.passwd;
}
# strip app_eudev.php/ prefix if it is present
rewrite ^/app_eudev\.php/?(.*)$ /$1 permanent;
# remove trailing slash
rewrite ^/(.*)/$ /$1 permanent;
# sitemap rewrite
rewrite ^/sitemap_(.*)$ /sitemap/$1 last;
location / {
try_files $uri #symfonyapp;
}
location #symfonyapp {
rewrite ^(.*)$ /app_eudev.php/$1 last;
}
location /var/www/dms/ {
internal;
alias /var/www/dms/;
}
location #htmlimages {
root /var/www/dms/;
}
location ~ /html/.*\.(png|gif|jpg|pdf)$ {
root ...;
try_files $uri #htmlimages;
}
location /files {
root ...;
}
location /assets {
root ...;
}
location /img {
root ...
}
location ~ \.php(/|$) {
fastcgi_pass 127.0.0.1:9001;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
When nginx find matching location that will process request it ignores any other location that could possibly match request.
In your case before you add auth, request to /about/payment was proceeded by location / which finally passed request to PHP. But as soon as you add location /about/payment request to that URL will be processed by this location which has no special directives so nginx will try to serve static files.
You should add directives that pass request to PHP, in this case it's really simple:
location /about/payment {
auth_basic "secured site";
auth_basic_user_file /var/www/my.passwd;
root ...;
try_files $uri #symfonyapp;
}
E.g. for Wordpress site, I wanna lock the URL
location ~* /block-url/ {
auth_basic "Internal Staging Site";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ /index.php?$args; # Most important!
}

Nginx rewrite rule for cms backend

I need to make url rewrite rules (server blocks) in nginx server same like in my previous apache server.
This is code from .htaccess what I need to implement (convert) into my existing one:
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ admin/index.php?hotelname=$1&do=$2 [QSA]
RewriteRule ^(([A-Za-z0-9-/]+)+)$ admin/index.php?hotelname=$1 [L]
This code is in my website because I need to hide in adress bar folder(/admin/) where is located files after login. And when somebody is already login, adress bar is like www.domain.com/username and when you click to menu adress is like www.domain.com/username/page1, www.domain.com/username/page2, www.domain.com/username/page3.
This is what I need to achive in nginx. Because now is complete backend without function. When I login to backend, I'm redirected to www.domain.com/username but on screen I can see only File not found. In backend working only when I manualy add www.domain.com/admin/index.php.
This is my actual config for nginx :
server_names_hash_bucket_size 64;
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 80;
root /usr/share/nginx/www;
index index.php;
server_name www.example.com;
error_page 404 http://www.example.com/404.php;
autoindex off;
location / {
rewrite ^([^\.]*)$ /$1.php;
}
location = / {
rewrite ^ /index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
When I try to change my block to:
location / {
rewrite ^([^\.]*)$ /$1.php;
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ /admin/index.php?hotelname=$1&do=$2;
rewrite ^/(([A-Za-z0-9-/]+)+)$ /admin/index.php?hotelname=$1 break;
}
Each my css file have error 500...
I will be very grateful with any help!
Thanks a lot.
You are putting this in your / location, that means that all your requests not matched before you drop here. You have to create a location role specific for this entry before the location /
location ^/([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ {
rewrite ^/([A-Za-z0-9-]+)/([A-Za-z0-9-/_]+)$ /admin/index.php?hotelname=$1&do=$2;
}

SSL Redirection Fails

I have a server that runs both development and staging instances of a site and each version has to answer on ports 80 & 443. The staging instance -- there's only one -- works exactly as I'd expect, but the development instances -- configured for each user -- loads a given page on either protocol directly just fine, but if I'm on a page on one port and try to link to the other it fails.
My Config
server {
listen 80;
server_name ~^dev\.(?<username>[^.]+)\.client\.tld\.net$
~^(?<username>[^.]+)\.client\.dev\.tld\.net$
~^(?<username>[^.]+)\.dev\.client\.tld\.net$;
location / {
rewrite ^(.*) http://$username.client.tld.net$1 permanent;
}
}
# This is the primary host that will ultimately answer requests.
server {
listen 80;
server_name ~^(?<username>[^.]+)\.client\.tld\.net$;
root /home/$username/client/www/app/webroot;
index index.php;
access_log /var/log/nginx/client.sandbox.access.log;
error_log /var/log/nginx/client.sandbox.error.log;
location / {
try_files $uri $uri/ /index.php?url=$uri;
}
location ~ \.php$ {
include /etc/nginx/conf/php;
}
include /etc/nginx/conf/expire_content;
include /etc/nginx/conf/ignore;
}
server {
listen 443 ssl;
server_name ~^dev\.(?<username>[^.]+)\.client\.tld\.net$
~^(?<username>[^.]+)\.client\.dev\.tld\.net$
~^(?<username>[^.]+)\.dev\.client\.tld\.net$;
location / {
rewrite ^(.*) https://$username.client.tld.net$1 permanent;
}
}
# This is the primary host that will ultimately answer requests.
server {
listen 443 ssl;
server_name ~^(?<username>[^.]+)\.client\.tld\.net$;
root /home/$username/client/www/app/webroot;
index index.php;
include /etc/nginx/conf/ssl;
access_log /var/log/nginx/client.sandbox.access.log;
error_log /var/log/nginx/client.sandbox.error.log;
location / {
try_files $uri $uri/ /index.php?url=$uri;
}
location ~ \.php$ {
include /etc/nginx/conf/php;
}
include /etc/nginx/conf/expire_content;
include /etc/nginx/conf/ignore;
}
Any idea where I've borked up my config?
First of all, there is no need to create four separate configurations, as both your servers (HTTP and HTTPS) have exactly the same body. You can use the $scheme variable which contains either http or https according to the context your're just working in (for the redirects). Secondly I don't see any root declaration in your dev configuration, also no certificates which might cause problems with browsers.
Other then that the configuration looks okay to me (well, you could move the index declaration to your http configuration; so you don't have to repeat it all the time).
Please check out the following (commented) example configuration I made up for you. Maybe it helps.
# Put this in http context!
index index.php;
server {
# One server configuration to rule them all!
listen 80;
listen 443 ssl;
# Seems legit.
server_name ~^dev\.(?<username>[^.]+)\.client\.tld\.net$
~^(?<username>[^.]+)\.client\.dev\.tld\.net$
~^(?<username>[^.]+)\.dev\.client\.tld\.net$;
# Where am I?
#root /home/$username/client/www/app/webroot;
# No wildcard certificate? No need to specify /etc/nginx as all paths
# in the configuration are relative to the installation path.
#include conf/ssl;
location / {
# May work as well, can't test.
#rewrite ^(.*) $scheme://$server_name$1 permanent;
rewrite ^(.*) $scheme://$username.client.tld.net$1 permanent;
}
}
server {
listen 80;
listen 443 ssl;
server_name ~^(?<username>[^.]+)\.client\.tld\.net$;
root /home/$username/client/www/app/webroot;
include conf/ssl;
access_log /var/log/nginx/client.sandbox.access.log;
error_log /var/log/nginx/client.sandbox.error.log;
location / {
try_files $uri $uri/ /index.php?url=$uri;
}
location ~ \.php$ {
include conf/php;
}
include conf/expire_content;
include conf/ignore;
}