NinjaFirewall (WP Edition)
[resolved] WP subdirectory install not supported (32 posts)

  1. GermanKiwi
    Posted 2 years ago #

    Hi, I am running WordPress in a subdirectory of my site, which is a supported configuration described here.

    So my site is available at http://www.example.com but the WP install itself is located at http://www.example.com/wp/

    Therefore, on the General Settings page of WordPress, my "WordPress Address" is http://www.example.com/wp and my "Site Address" is http://www.example.com.

    I've just installed the NinjaFirewall plugin, but it's not working, because it does not appear to support this configuration. It tries to find (or create) the .htaccess file and php.ini file inside the subdirectory (www.example.com/wp) but this is incorrect. The .htaccess and php.ini files should go in the root directory at http://www.example.com.

    Therefore, when I click the "Apply changes" button, and then I click the "Test NinjaFirewall configuration" button, it simply takes me back to the very first page again (the page which has the button "Enough chitchat let's go").

    Can you kindly fix this, so that the plugin supports the situation where WP is in a subdirectory?



  2. nintechnet
    Plugin Author

    Posted 2 years ago #


    That is right, the installer does not detect such an installation, I'll try to fix this in a future release.
    However, the firewall should work with your configuration. You will simply need to manually edit/copy the PHP ini and .htaccess.

    If you want to give it a try:

    1) access the NinjaFirewall installation page where it shows you the changes it wants to do. Do not click on 'Apply changes'.

    2) copy the PHP ini red lines and paste them into your http://example.com/php.ini file instead of the suggested http://example.com/wp/php.ini.

    3) copy the .htaccess red lines, and, before pasting them into your http://example.com/.htaccess file, remove the "wp/" substring so that it will now point to the PHP ini you have just created.
    For instance, if you had:
    "SetEnv PHPRC /home/user/public_html/wp/php.ini"
    It should be replaced with:
    "SetEnv PHPRC /home/user/public_html/php.ini"

    4) go back to your WordPress admin console and click on the NinjaFirewall menu in the left frame. Normally, it should be installed. You may need to wait a few minutes to have the PHP ini file reloaded by your HTTP server though, that really depends on your PHP configuration.

    I recommend you do those changes using an FTP client, so that, if something went wrong, you could undo them easily.

  3. GermanKiwi
    Posted 2 years ago #

    Hmm. I've just tried this, but no luck...

    The plugin already had created the php.ini file in the /wp/ subdirectory, so I just moved it from there to the root directory (ie. http://www.example.com).

    Then I added the following to my .htaccess file which is also in the root dir:

    # BEGIN NinjaFirewall
    <IfModule !mod_php5.c>
    SetEnv PHPRC /home/user/public_html/php.ini
    # END NinjaFirewall

    (Obviously with the correct path for my own server location)

    Then I went back and clicked on the NinjaFirewall menu to reload the page, after waiting actually for half an hour. But it just displays the initial page - the one which starts off saying "Thank you for using NinjaFirewall" and has the blue button "Enough chitchat let's go".

    Any other ideas?

  4. nintechnet
    Plugin Author

    Posted 2 years ago #

    This is a PHP config issue, because it does not load the firewall.

    - are you on a shared hosting account (which company?) or your own dedicated/VPS server ?
    - can you download this diagnostics file ( http://nintechnet.com/ninjacheck_php.txt ), rename it to ninjacheck.php, upload it into the folder were is located your wp-config.php, call it from your browser and paste the results here ?

  5. GermanKiwi
    Posted 2 years ago #

    Yes, I'm using a shared hosting account. Here is the output of your file. (I've removed the document root path as that contains sensitive info that I don't want to share publically)...

    ========================= START ============================

    HTTP server: Apache/2.2.22
    PHP version: 5.4.9
    Loaded INI file: /etc/php.ini/5/337084/php.ini
    auto_prepend_file: unknown
    user_ini.filename: .user.ini
    user_ini.cache_ttl: 300
    PHPRC: ./:/etc/php.ini/5/337084/1475259:/etc/php.ini/5/337084:/usr/local/php54-SECURE
    DOCUMENT_ROOT: [path removed]
    wp-config.php: found
    user INI: not found

    ========================== END =============================

    BTW, I placed the ninjacheck.php file into the /wp subdirectory which is where my wp-config.php file is located. But please remember that the Ninja Firewall "php.ini" is located in the root directory, not the /wp subdirectory, as per your earlier instructions. :)

  6. nintechnet
    Plugin Author

    Posted 2 years ago #

    The PHPRC variable is very important for the firewall but I can see that yours is already pointing to different INI files.

    Have you ever tried to use php.ini files previously? If you didn't, are you sure that your host allows you to use them? Most shared hosting will allow it, but a few may disable it. If you are unsure, please ask your host.

    The second solution is to use a .user.ini file, because since PHP 5.3, this is the best way to use per directory INI files. You are using 5.4.9. But some hosting companies disable them and use php.ini (or php5.ini like godaddy) instead.
    Assuming that your index.php is in /home/user/public_html/ and WP files are in /home/user/public_html/wp/, create a /home/user/public_html/.user.ini file with the following content:

    ; BEGIN NinjaFirewall
    auto_prepend_file = /home/user/public_html/wp/wp-content/plugins/ninjafirewall/lib/firewall.php
    ; END NinjaFirewall

    Create a /home/user/public_html/.htaccess file with the following content:

    # BEGIN NinjaFirewall
    <IfModule !mod_php5.c>
    SetEnv PHPRC /home/user/public_html/.user.ini
    # END NinjaFirewall

    You may need to wait up to 300 seconds before PHP will reload a .user.ini file (this is the user_ini.cache_ttl: 300 value returned by the diagnostics script).

  7. GermanKiwi
    Posted 2 years ago #

    No I haven't tried using per-directory php.ini files before, and I don't know if my host supports them - I will ask them about it.

    In the meantime I've tried the .user.ini solution and I'm happy to say that it works! I can now access all of the NinjaFirewall pages in the WordPress admin area. :)

    Maybe it would be a good idea to include some instructions about the .user.ini solution in the plugin's instructions, in case other users also need this. :)

    I hope you'll still be able to update the plugin, to support the subdirectory installation that I'm using, in any case!

    Now I have a couple of extra feedbacks for you:

    1) Although I can now access all of the firewall setting pages in the WordPress admin, I am nevertheless getting this error at the very top of every page in the admin area:
    "ERROR: NinjaFirewall cannot find WordPress configuration file."

    Additionally, this same error also appears at the very top of the webpages too (which the public can see!!), which is a disaster! That means I will have to disable the plugin completely until this is fixed. I can't have the public seeing such an error on every webpage!

    I would suggest that you change this error, so that it is only visible in the Admin pages and not on the actual website itself. The public don't need to see it! Only me (the admin) needs to see this.

    2) On the "Firewall Policies" page there is a setting which says, "Block direct access to any PHP file located in one of these directories". And one of the directories mentioned there is this:

    However, I have changed the name of my wp-content folder to something different. I've done this using the WP_CONTENT_URL and WP_CONTENT_DIR variables in my config.php file. Therefore I have no such folder as /wp-content anymore.

    Can you fix the firewall so that it recognises a different path from the WP_CONTENT_URL and WP_CONTENT_DIR variables please?

    3) On the "Email Alerts" page, there is an setting for "Send me an alert whenever XYZ logs in". Currently I can select for the admin only, or for any user, or for none. However I think it would also be nice, to have an extra option, for "a non-administrator". So that I can receive an email every time somebody logs in who is NOT an administrator. When I am the only administrator, I don't need to receive an email every time I myself log in!

    Maybe the "Plugins" and "Themes" and "Core" email alerts should also have an option to exclude the administrator too, so that I don't receive emails about my own actions.

    Lastly: where can I find some information and descriptions about the security rules? It only shows men "Rule ID 1" etc, which is meaningless to me. :)

    Thanks again for your help so far!

  8. nintechnet
    Plugin Author

    Posted 2 years ago #

    The PHP INI issue is now working, that is good.
    Note that during the installation, you are prompted to select the INI file you want to use: php.ini, php5.ini or .user.ini

    1) "ERROR: NinjaFirewall cannot find WordPress configuration file."
    This message is a critical one: it means the firewall is not working :( So that is why it will be displayed on the top of all pages.
    The firewall part of NinjaFirewall works independently of WordPress. It does not rely on it, in fact, it does not even know what WordPress is. It receives the data from PHP and will block or forward it to the corresponding application (WP or any other PHP script).
    The problem here is that you renamed the 'wp-content' folder, hence NinjaFirewall cannot find the wp-config.php file.
    The way it works is simple (and there isn't any alternative): the firewall.php script will subtract 50 character from the full path to itself, then append the 'wp-config.php' string to find it.
    For instance, take this path:

    Subtracting the 50 chars from the end give us:

    Append the '/wp-config.php':

    'wp-content' is a 10-character string. If the new name is not 10 chars, that will not work.

    I can see only 2 solutions:
    1) do not rename the wp-content. But that is too late !
    2) patch the firewall.php script. Very easy, but each time there will be a new NinjaFirewall update, you will have to disable the .user.ini first (very important), run the update from WP admin console, manually patch firewall.php, then re-enable the .user.ini.
    The code to patch is in /lib/firewall.php, line 45:

    $wp_config = substr(__FILE__, 0, -50) . '/wp-config.php';

    The '-50' value should match the correct number of characters to subtract.

    I will add a verification routine to the installer to detect changes to the WP_CONTENT_DIR and warn the user.

    3) "Email Alerts"
    The main goal here is to detect any hacker gaining access to the admin console. Therefore, if you disable sending an email when an admin logs in, you will never be informed if you get hacked :(
    Thousands of WP have been hacked that way lately. Hackers log in as the admin and upload an infected theme or plugin.

    4) Rules Editor
    See the contextual "Help" tab in the Rules Editor page for info about it.

  9. GermanKiwi
    Posted 2 years ago #

    Okay, thanks for explaining those things! I didn't notice that you already have .user.ini as an option to select. :)

    Regarding the error on every page: I do understand that this is a critical error, but it looks very unprofessional to have a big error message at the top of the public webpages that the customers see. They don't need to know about this error, and there is nothing that they can do about it anyway, and it will do damage to our reputation if our customers see such an error. So I really do think that this error should only appear on the Admin pages, where I will see it and fix it.

    There are many other plugins that I have used, which also will show a big, red error message when something goes wrong (including other WordPress security or firewall plugins) - but they only show this error on the Admin pages, and never on the front-end webpages. I would really like to suggest that you consider changing this too. Security is important, but so is public image. Causing confusion to the customers doesn't help anybody. :)

    Regarding the configuration file and the "wp-content" directory name: what about providing a new setting for the plugin, which lets me (the admin) override the path and provide a custom path to my wp-config.php file? You could have a new field on the setup page in the WP Admin, which lets me type in my own path if necessary. Then it would work, right? Could that be a solution?

  10. GermanKiwi
    Posted 2 years ago #

    ...I should also point out that exposing an error message on the public website is actually a security risk itself, as it alerts would-be hackers that there is a problem with the website (ie. the firewall is disabled) and this would encourage them to try to attack the site because they think there is a security hole.

  11. nintechnet
    Plugin Author

    Posted 2 years ago #

    It is not possible to add an option accessible in WP admin console, because it will be saved in the DB and in order to read it, the firewall would need to find and access the wp-config.php file :)
    Anything related to the loading of the firewall must be hardcoded into firewall.php.
    But that is not a big deal, there are several alternatives. For instance, open lib/firewall.php and replace:

    $wp_config = substr(__FILE__, 0, -50) . '/wp-config.php';


    $wp_config = dirname( strstr(__FILE__, '/plugins/ninjafirewall/lib', true) ) . '/wp-config.php';

    That should work, regardless of the new name/length of the 'wp-content' directory.

    About the error message, you can simply disable it, as indicated in firewall.php:

    // Set to '0' if you don't want NinjaFirewall to output error
    // and warning messages (not recommended, though) :
    $nfw_warn = 1;
  12. GermanKiwi
    Posted 2 years ago #

    I see your point about the database! :)

    I have now renamed the directory back to "wp-content" and this has solved this issue for me. I've decided that I don't really need to name it something else.

    I also don't want to edit the firewall.php file because that will be overridden the next time the plugin is updated. In principle I don't like editing plugin files directly.

    Regarding the error message, I don't want to turn off the error message completely! Of course the error messages are very important and need to be visible to the admin! I'm only asking (and urging) to have them turned off from the front-end website itself, which is visible to the rest of the internet including customers. I don't believe there is any valid reason for exposing such error messages to the public - and on the other hand, there are many reasons why this is a very bad idea - eg. it looks very unprofessional, it causes confusion to the web users and customers, and it is even a security risk as it alerts hackers that there is a problem on the website. These are all good reasons why such an error message should never be visible to the public. I have used many other WP security plugins which display error messages, but ALWAYS only in the Admin area, and NEVER on the public website.

    I hope you understand the point I'm trying to make here - the errors do need to remain in the Admin area! Just not on the website itself. I hope you will reconsider and change this behaviour.

    At the very least, perhaps you could add this as a new option, so I can turn off the public errors (but not the Admin errors) myself via a new setting in WordPress (without needing to edit firewall.php). But I think the best solution would be for you to hard-code this behaviour into the plugin directly. :)

  13. GermanKiwi
    Posted 2 years ago #

    Hi nintechnet,

    I've just upgraded to 1.1.1 today. I then did the setup configuration again from the beginning, in order to test it. (I deleted the .htaccess settings and the .user.ini file, so that the plugin would act like a brand new installation).

    However, the plugin still created the new .user.ini file, and the new .htaccess file, inside the WordPress subdirectory where I have installed WordPress (http://www.example.com/wp/), rather than in the root directory where it should be (http://www.example.com). So it's still not in the correct place.

    I don't know if you are still planning to fix this in a future version or not, but I just wanted to let you know, in case you thought it was already fixed now. :)

  14. nintechnet
    Plugin Author

    Posted 2 years ago #


    This will be fixed in the next release (1.1.2).
    The current v1.1.1 was written 2 weeks ago, hence does not include those changes.

  15. GermanKiwi
    Posted 2 years ago #

    Awesome, thanks!

  16. GermanKiwi
    Posted 2 years ago #

    Okay, now I'm getting a new error message - can you help me with this one please?

    The error says:
    "ERROR: NinjaFirewall cannot retrieve WordPress database credentials."

    I already know the cause of this error. It's because I have moved part of my wp-config.php file, to a different location. In other words, I split up my wp-config.php file into 2 files. This is done for security reasons, in order to harden WordPress. It's described in the WP codex here in the section "Securing wp-config.php" and also here.

    This means that in my default wp-config.php file - which is located at the standard location at http://www.example.com/wp/wp-config.php - I have only the following content:

    /** Absolute path to the WordPress directory. */
    if ( !defined('ABSPATH') )
    	define('ABSPATH', dirname(__FILE__) . '/');
    /** Location of your WordPress configuration. */
    require_once(ABSPATH . '../../wordpress-config/config.php');

    Then, I have another file called "config.php" inside a directory that is outside of my document root. In this file, I have all of the other WordPress settings that normally go in wp-config.php - including my database settings. This is a fully supported configuration for WordPress, and I've been using it for a long time without any problems, because every plugin can still find the database info by following the original "wp-config.php" file across to the "config.php" file where the database settings are located.

    I think NinjaFirewall is also able to read the "config.php" file too, because I can make the firewall actually work in WordPress now - I can access all of the NinjaFirewall settings, and change them and save them, and those settings are all saved in the database, right?

    So I'm not sure why I get this new error message which says "NinjaFirewall cannot retrieve WordPress database credentials."

    If I revert the configuration back to the "traditional" configuration, where all of the config settings are located in the original "wp-config.php" file at http://www.example.com/wp/wp-config.php, then the error message goes away.

    So my question is this: why does NinjaFirewall need to have the database credentials in the first place? This seems strange to me. It concerns me a little bit, that the plugin wants to try and read my database settings (username and password) directly from my wp-config.php file. I think it's not normal for a plugin to need to do this, because the plugin should access the database through WordPress, right? So can you please explain this error message and what it means?


  17. GermanKiwi
    Posted 2 years ago #

    BTW: this new error message also appears in big letters on my public, front-facing webpages, for everyone on the internet to read... :(

  18. nintechnet
    Plugin Author

    Posted 2 years ago #

    Regular plugins don't need to parse the wp-config file, everything is handled by WordPress.
    NinjaFirewall works before WordPress, hence it needs to do that itself.
    If you remove DB_NAME, DB_USER, DB_PASSWORD, DB_HOST and table_prefix, you will end up with the same red critical message on the screen.
    It must read the config file line by line, it cannot use PHP include() or require() functions (which would follow your require_once() instruction) because the wp-config file contains that line:

    require_once(ABSPATH . 'wp-settings.php');

    This would load the core part of WordPress before NinjaFirewall.

  19. GermanKiwi
    Posted 2 years ago #

    I see. I wonder if there could be another way to tell NinjaFirewall where to find my "config.php" file (the one which contains my database settings, which I have located outside of the document root).

    I just had the idea of some kind of configuration file for NinjaFirewall - it could be located in the root folder for example (independent of WordPress) - and NinjaFirewall could check for the existence of this file, and read it, and this file would point to the location of an alternative wp-config.php that exists in a non-standard location, as in my situation.

    This way, NinjaFirewall could still obtain the database settings from the alternative wp-config.php file, and still run itself before WordPress, and I still get to keep my wp-config.php file in an alternative location for extra security.

    Does that idea make sense? Would it be a solution that could work?

  20. nintechnet
    Plugin Author

    Posted 2 years ago #

    We cannot do that because that may work for you, but will not work for most shared hosting accounts using, for instance, open_basedir restriction.
    If you need to change the firewall.php config, you have one single choice: open and patch it :)
    Keeping the wp-config file is not a security issue. Most databases listen on localhost, and if a hacker was able to read the file and to get the DB pass, it would not be able to connect to it. It would be way much easier for him to find a vulnerable plugin to access the DB (there are plenty of those weak plugins!).

  21. GermanKiwi
    Posted 2 years ago #

    Unfortunately for me, my database server (from my web host provider) is not limited to listen on localhost only. It is accessible over the internet, and so the database hostname in my wp-config.php file needs to point to the full hostname of the SQL server (like "db.example.com").

    That's why I keep my WordPress database settings in a separate config.php file that is outside of the document root, for security. The benefit of this security technique is described here and also in the WordPress codex - it's a recommended security feature.

    I understand your point that "what will work for me, may not work for others". But what about the idea of having an *optional* configuration file for NinjaFirewall, which contains the path to my alternative config.php where my database settings are contained - that means, if this optional configuration file exists, then NinjaFirewall will read it and follow it. But if it doesn't exist, then NinjaFirewall will behave like normal/default and look in the normal place for the regular wp-config.php file. That way, every situation is covered. Surely this could work?

    I really don't want to move my database settings back into the default wp-config.php file for security reasons, because of what I described above. I want my site to be as secure as possible. :)

  22. GermanKiwi
    Posted 2 years ago #

    BTW, I'm happy that 1.1.2 works really perfectly now with my subdirectory installation of WordPress! I just tested it again today with a brand new installation of NinjaFirewall, and it was able to detect the subdirectory and create tne php.ini and .htaccess settings in the correct place, no problem! :)

  23. nintechnet
    Plugin Author

    Posted 2 years ago #

    But what about the idea of having an *optional* configuration file for NinjaFirewall

    WordPress will delete the file during each upgrade. At this stage (firewall initialization), you cannot rely on the DB or an external file to store the configuration.
    You have 2 choices:
    1) Either patch the firewall.php: easy to do. For each upgrade, you will need to download the new ZIP file from this site, patch the firewall.php and upload all files via FTP (or upload them via WP admin console plugin page).
    2) Or ensure that your user account has the correct privilege on the DB server: connection to the DB should only come from that user and IP. Nobody else should be allowed to connect to it.

    I would choose 2) because having a DB accessible to the whole world is a much greater risk IMHO.

  24. GermanKiwi
    Posted 2 years ago #

    But WordPress won't delete such a configuration file if it's in the root folder or some other location, other than the plugin folder. So that would still work then, right?

    Unfortunately these other 2 choices are not an option for me. I need to allow normal, automatic plugin updates via the WordPress Admin (without patching and FTPing), so the client can update automatically etc.

    And even if the DB server is restricted to only my web server's IP, I still would not want to move my wp-config.php back into the WordPress directory. There is still a big security advantage in keeping this file outside of the web root. Did you read the explanation in this article? (In the first Answer of the article).

    There it explains that not only is the database information from wp-config.php very sensitive info, but also "The authentication keys and salts can be used in any number of potential hijacking attacks."

    It goes on to say, "Conclusion: configuration files should always always always be located outside the web root. If you care about security, you will move wp-config.php outside your web root."

    This is an officially supported and recommended practice by WordPress for security purposes, so I hope that you can understand the reason for it, as the developer of a security plugin like NinjaFirewall! :)

    So what about putting a configuration file in the root folder where it won't be deleted by WordPress during each upgrade? Could you consider this as an option?

  25. nintechnet
    Plugin Author

    Posted 2 years ago #

    I totally disagree with that article: to me, hiding a file and pretending to be safe is nothing but a big weakness :)
    Most hacks we are dealing with on a daily basis, exploited vulnerable plugins to gain access to the DB. That is so easy to do.

    But regarding your question, the only reliable possibility I can see would be for the firewall to search for a wp-config.php file located in the directory above the server document root. Then, if there was one, it would use it. Otherwise it would use the one located in the current directory.
    That would require some testings though.

  26. GermanKiwi
    Posted 2 years ago #

    I'm not sure why you think that moving the file outside the web root is only "pretending" to keep it safe! The article explains all the reasons why this is legitimate, real-world safety, and it gives a real-world example of a bug with Plesk that resulted in the PHP interpreter being disabled and exposing the config file.

    This technique might not protect against an exploited plugin, but that doesn't mean it's useless. The more measures we can take to harden WordPress, the better - every technique helps - right?! :) The best security is using multiple layers of protection - multiple techniques to protect multiple things. This particular technique protects against the possibility of the config file being exposed when the PHP interpreter is accidentally disabled. It really does work and it really is valid, which is why it is also recommended in the official Codex, as well as on numerous other security blogs and articles, in addition to the one I quoted. :)

    Anyway... your idea of putting the config file in the directory above the doc root is a good one. But what about having a special NinjaFirewall config file in that location (above the doc root) - eg. a file called "ninjafirewall.cfg" or similar - which is above the doc root, and this file contains the path to the actual wp-config.php file where the DB stuff is located. Would that work?

    This means I can still keep my wp-config.php in another folder located elsewhere on the server, and NinjaFirewall will know where to find it. (And if this "ninjafirewall.cfg" file doesn't exist, then the NinjaFirewall plugin just behaves the normal, default way like always).

    Good idea??

  27. nintechnet
    Plugin Author

    Posted 2 years ago #

    Yes, it is possible too.

  28. GermanKiwi
    Posted 2 years ago #

    Great! Please let me know if I can help with any testing. I'm looking forward to being able to use this plugin on my site!

  29. nintechnet
    Plugin Author

    Posted 2 years ago #

    I added the optional configuration file feature today to the latest beta version 1.1.3, which is available here http://nintechnet.com/beta/

    How to use it: http://nintechnet.com/nfwp/1.1.3/

  30. GermanKiwi
    Posted 2 years ago #

    Nice!!! I've just installed the beta and tested it, and it works perfectly! I really like the way you've implemented this, using a .htninja file etc. And it even warns me about setting the permissions of the .htninja file to read-only, which is a nice bonus. Thanks for doing this!

    One question: will the beta version automatically update to the final 1.1.3 version when that is released, using the normal, built-in plugin update method? Or will I need to manually upload 1.1.3 Final once it's released?

Topic Closed

This topic has been closed to new replies.

About this Plugin

  • NinjaFirewall (WP Edition)
  • Frequently Asked Questions
  • Support Threads
  • Reviews

About this Topic


No tags yet.