i am currently working on a wordpress website in which I've a special case. I want one specific search query to be allowed while rejecting all others.
For example:
www.example.com - PASS
www.example.com/page - PASS
www.example.com
www.example.com/?myQuery - PASS
www.example.com/?anyotherQuery - 404
Right now, I have tried it using the following re-write rule but it is also blocking access to other pages.
RewriteBase "/"
RewriteCond %{QUERY_STRING} ! myQuery
RewriteRule ^.* - [F]`
I'm new in rewrite and htaccess thing so need help in achieving this.
Try the following, at the top of your .htaccess file, before the WordPress front-controller.
RewriteCond %{QUERY_STRING} .
RewriteCond %{QUERY_STRING} !=myQuery
RewriteRule ^ - [F]
The above states... for any URL that contains a query string (first condition) and the query string is not exactly myQuery (second condition) then respond with a 403 Forbidden (Apache response, not WordPress).
The = prefix on the CondPattern makes it a lexicographical string comparison (not a regex) and the ! prefix negates the result.
RewriteBase "/"
RewriteCond %{QUERY_STRING} ! myQuery
RewriteRule ^.* - [F]`
The RewriteBase directive is irrelevant here. The space between ! and myQuery is erroneous. But this would potentially block anything where the query string does not contain myQuery, including when there is no query string at all.
Related
I developed a site that shows some products from a store. The site URL looks like that:
http://testsite.com
The site has the functionality of sharing the product (it's already working) generating a link that can be shared at facebook or WhatsApp or anywhere. The link of the shared product is:
http://testsite.com/product/1234
Where 1234 is the product ID. All the products have images with the ID name. Ex: 1234.jpg. The link for the image of the product ID 1234 is:
http://testsite.com/static/imgs/1234.jpg
This site is hosted using a simple NGINX server, that just provides the files.
At the head of my index.html file I have a default og:image for sharing:
<meta property="og:image" content="http://testsite.com/static/imgs/main.jpg">
I wanna the NGINX server to replace this default og:image by the shared ID image. I already know how to do that at NGINX. At the NGINX configuration file (/etc/nginx/conf.d/default.conf) I used the sub_filter option. My NGINX configuration file is:
server {
listen 80;
server_name *.testsite.com;
root /var/www/testsite.com/dist;
location / {
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location ~ /product/(.*) {
index index.html index.htm;
try_files $uri $uri/ /index.html;
sub_filter 'http://testsite.com/static/imgs/main.jpg'
'http://testsite.com/static/imgs/$1.jpg';
sub_filter_once on;
}
}
This configuration is working for the location /, but for the location ~ /product/(.*) it is not working.
When I test the sub_fiter option at the location / using any other image it replaces correctly.
QUESTIONS:
1) How can I get the product ID (1234) from the URL (http://testsite.com/product/1234)? $1 is not working.
2) I think that when entering at the location ~ /product/(.*), it also redirects for the location /. How can I fix this configuration file to works as expected?
I think your alias statement is the problem.
Reading in nginx docs:
location /i/ {
alias /data/w3/images/;
}
on request of “/i/top.gif”, the file /data/w3/images/top.gif will be sent.
It means that in your case on each ~/product/(.*) request /var/www/testsite.com/dist/index.html will be sent without taking product ID into account. You might want to configure alias on / to avoid that. This is also likely to be the reason you get "redirected" to /.
As for $1, it should work as you have it now. When you fix the alias, I think it will work then. If not, you can try the named match: (?<product>[0-9]+) instead of (.*), then you can use the $product variable to reference the id.
There's another small glitch in your code — you're adding extra quote marks on replace. The second argument to sub_filter is in quotes twice.
Working Example
UPDATE: Ok, I got it working on localhost with the following nginx config (testing on "Hello World"):
location ~ /product/(\d+)$ {
set $product $1;
try_files $uri $uri/ /index.html;
}
location / {
if ( $product = '' ) {
set $search 'Non-Existent-String';
}
if ( $product != '' ) {
set $search 'World'; # the string you want to replace
}
index index.html index.htm;
sub_filter '$search' 'Product #$product';
}
The key here is that when you use try_files, it does get to location /. So we need to sub_filter in /. We also don't want to sub_filter regular /index.html requests. Something like if ($product) sub_filter would be nice, but is impossible with nginx. So I just leave sub_filter but only set real search string for product requests.
Is there a way to enable the module 'mod_exec' only with a certain proftdp user?
I've compiled proftp with --with-modules=mod_exec:mod_ifsession and then configured in this way...
<IfModule mod_exec.c>
<IfUser stefano>
ExecEngine on
ExecLog /opt/proftpd-master/logs/proftpd.semics.mod_exec.log
ExecOptions logStderr logStdout
ExecBeforeCommand STOR,RETR /path/to/handler.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /path/to/handler.sh EVENT=OnCommand FILE='%f'
</IfUser>
</IfModule>
or this:
<IfUser stefano>
<IfModule mod_exec.c>
ExecEngine on
ExecLog /opt/proftpd-master/logs/proftpd.semics.mod_exec.log
ExecOptions logStderr logStdout
ExecBeforeCommand STOR,RETR /path/to/handler.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /path/to/handler.sh EVENT=OnCommand FILE='%f'
</IfModule>
</IfUser>
without success. Seems that mod_exec works only if configured outside the conditional statement.
My goal is to enable mod_exec only for user 'stefano' and/or to have several mod_exec configuration accordingly with each user configured.
Any suggestion?
mod_exec.c must be enabled by default and then inside it is possible to configure different actions for different users:
<IfModule mod_exec.c>
ExecEngine on
ExecLog /opt/proftpd-master/logs/proftpd_mod_exec.log
ExecOptions logStderr logStdout
<IfUser stefano>
ExecBeforeCommand STOR,RETR /path/to/script.sh EVENT=BeforeCommand FILE='%f'
ExecOnCommand STOR,RETR /path/to/script.sh EVENT=OnCommand FILE='%f'
</IfUser>
</IfModule>
Thanks to TJ Saunders. I hope this helps.
I have this configuration of nginx + phpfpm + phpmyadmin:
root /var/www/utils;
location ~ ^/phpmyadmin/.*\.(jpg|jpeg|gif|png|css|js|ico)$ {
root /var/www/utils;
}
location = /phpmyadmin {
index index.php;
}
location ~ ^/phpmyadmin.*(\.php|)$ {
index index.php;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
All is good, but if I remove "location = /phpmyadmin", I get 403 error on _http://server/phpmyadmin.
How can I access to the ALL subdirectories such as _http://server/phpmyadmin/setup ?
I get "Access to the script '/var/www/utils/phpmyadmin/setup' has been denied - on every directory without slash at the end, if I haven't written a special config for an each one.
As stated in nginx documentation:
$fastcgi_script_name variable takes value of incoming request URI, and in case URI is finished by a slash, then $fastcgi_script_name is appended with what is defined with fastcgi_index directive.
So if your request is "/phpmyadmin/setup/" and fastcgi_index is set to "index.php", then $fastcgi_script_name variable will be "/phpmyadmin/setup/index.php". Therefore $document_root plus $fastcgi_script_name will be "/var/www/utils/phpmyadmin/setup/index.php", which should work fine.
But if you make request like "/phpmyadmin/setup" (without slash at the end), then $fastcgi_script_name will not be appended by fastcgi_index, i.e. it would be just "/phpmyadmin/setup". And $document_root plus $fastcgi_script_name will be "/var/www/utils/phpmyadmin/setup", which won't work since there is not such file.
You should either use URIs with slashes, or define a rewrite rule (in a "server" block of configuration), which will be adding slash to the URIs that do not end with some extension (so that URIs like "/phpmyadmin/myscript.php" won't transformed into "/phpmyadmin/myscript.php/".
It should be like:
rewrite ^([^\.]*[^\/])$ $1/ break;
Did not test that myself, though.
A bit down on this nginx config reference page you'll see:
rewrite ^ http://example.com$request_uri? permanent;
What is the meaning of ^ above?
For rewrite, the first argument is the match pattern and only applies to the path portion of the url, not the domain. In regular expressions, ^ matches the beginning of the input. For example, ^/photos/.*$ would match paths beginning in '/photos/'. By itself, ^ is a shortcut for all paths (since they all have a beginning).
So the jist of this is,
I have a file:
search.php
When I goto:
search.php?search=%23HashTag
The search returns: #HashTag
But when I use my .htaccess method:
/search/%23HashTag
Nothing is returned. And i've tested by putting the number sign later in the search and it returns upto that point.
This is what I have:
RewriteRule ^search/([^\.]+)$ search.php?search=$1 [NE,L]
What am I doing wrong..?
Change your flags to [NE,B,L].
http://httpd.apache.org/docs/current/rewrite/flags.html#flag_b
mod_rewrite unescapes the url before applying transformations. I'm not sure why it loses anything after the hash (maybe it re-interprets it as a url, and discards the fragment?). In any case, [B] re-escapes the url before running it through the rewrite rule.
Does replacing it with \%23 work ok?
(Clarity: Opposed to writing the # in the .htaccess file)