nginx-ultimate-bad-bot-blocker
nginx-ultimate-bad-bot-blocker copied to clipboard
"update-ngxblocker" doesn't work on FreeBSD
FreeBSD's nginx package, by default, keeps its config at /usr/local/etc/nginx. Unfortunately, the commands specified in the badbotblocker documenation for using alternate config directories seem insufficient. Even after properly specifying -b and -c flags when running install- and update-, the config file paths in globalblacklist.conf are not fixed.... the includes are still in there referencing /etc/nginx (the default, at least on most Linux systems), and so nginx -t fails, looking for those files in /etc/nginx, which do not exist.
However, I think the fix is relatively simple. When running update-ngxblocker manually, the final output (after printing the blacklist version) is:
Updating bots.d path: /usr/local/etc/nginx/bots.d => /usr/local/etc/nginx/conf.d/globalblacklist.conf
sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command sed: 1: "/usr/local/etc/nginx/co ...": extra characters at the end of l command
That's 8 instances of a sed error, and there are 8 instances of those config files that should have different paths. So I'm guessing the sed that ships with FreeBSD doesn't support whatever syntax is being used here (maybe some GNU sed extension).
Can you please fix this? Maybe by adding an "if os=BSD then use different/compatible sed command" kind of thing in the update script?
Thank you.
Try changing line 148
of update-ngxblocker
from:
sed -i "s|$dir|$BOTS_DIR|" $blacklist
to:
sed -i "s/$dir/$BOTS_DIR/" $blacklist
& let me know if it fixes it
sed -i "s/$dir/$BOTS_DIR/" $blacklist
Unfortunately no! Same error.
- One option to fix this will be to install
gsed
alternatively to debug the error add above the sed
command:
echo "DEBUG: dir = '$dir' | BOTS_DIR = '$BOTS_DIR' | blacklist = '$blacklist'"
& re-run update-ngxblocker
DEBUG: dir = '/etc/nginx/bots.d' | BOTS_DIR = '/usr/local/etc/nginx/bots.d' | blacklist = '/usr/local/etc/nginx/conf.d/globalblacklist.conf'
according to the FreeBSD Wiki the sed
command I use should work
I don't have a freebsd system to play around with this on - you will need to work out a sed
substitution command that works with variables & let me know.
or install gsed
which is what other bsd users probably do.
I figured out the syntax issue. BSD sed requires an empty string after the -i flag if you want it to edit the file in place. Of course GNU sed doesn't like that, so there should be a check to see if the scripts are running on a BSD system.
I'm aware that it's possible to set the default CONF_DIR and BOTS_DIR variables at the head of the current script, but this really should be handled (more) automatically. That's the whole point of this great project, which otherwise has a very high quality of user experience.
You know, honestly, the script logic here should be totally different. Instead of allowing to specify separate directories for bots.d and conf.d, it should just be one argument: "nginx configuration directory", which specifies the directory under which bots.d and conf.d exist. Which most people will never have to use, if you change the logic to look more like this (apologies for the bad pseudocode):
if (uname = Linux) { default_ngxconfdir=/etc/nginx/ if ("nginx config directory" argument is specified) { custom_ngxconfdir=$argument_from_command_line sed -i "s|$default_ngxconfdir|$custom_ngxconfdir|" $blacklist } } else if (uname = FreeBSD) { default_ngxconfdir=/usr/local/etc/nginx/ if ("nginx config directory" argument is specified) { custom_ngxconfdir=$argument_from_command_line sed -i "" "s|$default_ngxconfdir|$custom_ngxconfdir|" $blacklist } } else //assuming system is using a non-GNU sed, but isn't FreeBSD { default_ngxconfdir=/etc/nginx/ if ("nginx config directory" argument is specified) { custom_ngxconfdir=$argument_from_command_line sed -i "" "s|$default_ngxconfdir|$custom_ngxconfdir|" $blacklist } }
That way you only have to run sed once, instead of 8 times. So it's more efficient too.
Related to #256 and #266
I've managed to do some fixes to setup-ngxblocker @wilchak so I'll try look into this too unless you want to send a PR for us?
I've managed to do some fixes to setup-ngxblocker @wilchak so I'll try look into this too unless you want to send a PR for us?
Honestly... I got frustrated and just installed Ubuntu. But thanks for following up.
The -i
parameter for in-place replacement of BSD sed
must be given a value. An empty string is a valid value for not creating a copy. `sed -i '' 's/…/…/' will do the trick.