diff --git a/.gitattributes b/.gitattributes index 9c2b8d7..4065fa1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ .git* export-ignore +Makefile export-subst ident ipblock export-subst ident diff --git a/.gitignore b/.gitignore index 9d165b6..4f80523 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ *.sig ipblock-* *.tar *.tar.gz *.tar.xz *tar.lzop *.tar.lzma *.tar.Z *.tar.zst *.tar.bz *.tar.bz2 +.tagged diff --git a/Makefile b/Makefile index e09cfd5..de2f230 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ # Copyright (C) 2023 Timothe Litt litt at acm ddot org +# $Id$ + # Install targets - can override on command line # Note that DESTDIR is supported for staging environments @@ -74,6 +76,14 @@ ipblock$(man1ext) : README.md ipblock Makefile $(SED) -e's,^`ipblock -h` for complete help$$,./ipblock -h,e' $< | \ $(LOWDOWN) -s -t man --parse-codeindent -M "title=ipblock" -M "date=$$(date -r ipblock +%d-%b-%Y)" -Msection=8 -o $@ - +.PHONY : viewreadme viewman + +viewreadme : README.md + @LANG=C $(LOWDOWN) -s -t term --parse-codeindent $< | less + +viewman : ipblock$(man1ext) + @LANG=C less $< + # Make tarball kits - various compressions .PHONY : dist unsigned-dist signed-dist @@ -112,7 +122,7 @@ install_dirs := $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) $(DESTDIR)$(confdir) install : ipblock ipblock$(man1ext) config/ipblock.conf installdirs $(INSTALL_PROGRAM) ipblock $(DESTDIR)$(bindir)/ipblock $(INSTALL_DATA) ipblock$(man1ext) $(DESTDIR)$(man1dir)/ipblock$(man1ext) - -if [ -f "$(confdir)/ipblock.conf" ]; then true ; else $(INSTALL_DATA) config/ipblock.conf $(DESTDIR)$(confdir)/ipblock.conf; fi + -if [ -f "$(confdir)/ipblock.conf" ]; then $(INSTALL_DATA) config/ipblock.conf $(DESTDIR)$(confdir)/ipblock.conf.new ; else $(INSTALL_DATA) config/ipblock.conf $(DESTDIR)$(confdir)/ipblock.conf; fi @echo "" @echo "Please read 'man 1 ipblock' before using the command'" @@ -166,7 +176,7 @@ tag : .tagged .tagged : $(shell git ls-tree --full-tree --name-only -r HEAD) unsigned-dist @if git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null || \ - [ -n "$$(git diff --stat)" ]; then \ + [ -n "$$(git diff --name-only)$$(git diff --name-only --staged)" ]; then \ echo " *** Not tagging V$(kitversion) because working directory is dirty"; echo ""; false ;\ elif [ "$(strip $(gittag))" == "V$(kitversion)" ]; then \ echo " *** Not tagging because V$(kitversion) already exists"; \ diff --git a/README.md b/README.md index 90b035b..6605c08 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,16 @@ Options, including the desired chain, should be specified in the configuration f `ipblock -h` for complete help ## Installation -Download the latest `Vn.m-Release` tarball using the `tar.gz` link at [GitHub](https://github.com/tlhackque/ipblock/releases). +Download the latest `ipblock-n.m.o-Release` tarball and signature using +the `tar.gz` or `tar.xz` and `.sig` links at +[GitHub](https://github.com/tlhackque/ipblock/releases). -- Do **not** select the `.zip` file, as it does not preserve file permissions. -- Do **NOT** use the **Clone or download** link on the main `ipblock` page, as it provides a `.zip` file. +- Do **NOT** use the **Clone or download** link on the main `ipblock` page. +- Building or installing from source requires `lowdown` -Unpack the `tar.gz`: - tar -xzf ipblock<n>.<m>-Release.tar.gz +Verify and npack the `tar.gz`: + gpg --verify ipblock<n>.<m>-Release.tar.gz.sig && \\ + tar -xzf ipblock<n>.<m>-Release.tar.gz This will create a subdirectory named ipblock-<version>. diff --git a/config/ipblock.conf b/config/ipblock.conf index 3b50c7a..e175f86 100644 --- a/config/ipblock.conf +++ b/config/ipblock.conf @@ -21,6 +21,10 @@ # If you leave -C at the default, "INPUT", the ipblock rule will # supersede any protection that you hav established, so don't. # +# The name of the IPv6 chain is defaulted to be the same as the IPv4 chain's. +# If they differ, specify the IPv6 chain name with -c (lowercase). +# Otherwise, -C will be used for both. +# # See ipblock -h for more information. #OPTIONS="-C mychain" diff --git a/ipblock b/ipblock index 5e1d3ad..9a734f3 100755 --- a/ipblock +++ b/ipblock @@ -8,7 +8,7 @@ VERSION='$Id$' # shellcheck disable=SC2034 # used by Makefile -RELEASE='1.6.0' +RELEASE='1.7.0' SELF="$(basename "$0")" @@ -16,7 +16,7 @@ function displayVersion() { if [[ "$VERSION" =~ ^'$''Id: '[[:xdigit:]]{24}([[:xdigit:]]{4})([[:xdigit:]]{4})([[:xdigit:]]{4})([[:xdigit:]]{4})' $'$ ]]; then printf "$SELF version %s-%s-%s-%s\n%*s release %s\n" \ "${BASH_REMATCH[-4]}" "${BASH_REMATCH[-3]}" "${BASH_REMATCH[-2]}" "${BASH_REMATCH[-1]}" "${#SELF}" "" "$RELEASE" - exit 0 + return 0 fi echo "$SELF version '$VERSION' - format error" exit 1 @@ -39,6 +39,7 @@ fi BlackList="BlackList" Chain="INPUT" +Chain6= DateFormat="+%a %d-%b-%Y %T %Z" # NOTE: The help text below is automagically inserted into README.md @@ -68,25 +69,33 @@ EOF -L List currently blocked IP addresses and last seen time (default) -S file Save current addresses as a script. (use - for stdout) -a With -S, add to existing output file + -r With -S, save in raw format (just IP address list, e.g. for BlockCountries) -T tps Use tps as the jiffys/sec (only if /boot/config- is not available. -t Estimate -T - -X Disable ipblock and remove its rule. Does not fluah list. + -X Disable ipblock and remove its rule. May not fluah list. -V Display version -D fmt Date format (strftime) (Default is '%a %d-%b-%Y %T %Z'), null for ctime -C:chain Specify chain to hook (default is INPUT) + -c:chain Specify chain for IPv6 hook (default is same name as IPv4) -N:table Recent table name that maintains list. (Default is BlackList) IPv6 adds '6' to the specified name (Thus, IPv6 default is BlackList6) ``` EOF cat </dev/null 2>&1 ; then @@ -288,7 +304,10 @@ fi # shellcheck disable=SC2086 # RULE needs word splitting if ! $IPT -C $RULE >/dev/null 2>&1 ; then - if $IPT -I $RULE ; then + if [[ "$ACTION" =~ ^(flush|list|remove|save)$ ]]; then + [ -n "$V" ] && echo "Not installed for IPv$IPV" + exit 0 + elif $IPT -I $RULE ; then [ -n "$V" ] && echo "Installed IPv$IPV input rule" [ -n "$DEBUG" ] && echo " $IPT -I $RULE" else @@ -351,61 +370,90 @@ fi if [ "$ACTION" == "save" ]; then export LC_ALL="C" - function save () { - cat <"$SCRIPT".tmph <>"$SCRIPT".tmp - grep -vh '^#' "$SCRIPT".tmp | sort -u | cat "$SCRIPT".tmph - >"$SCRIPT" - echo "# EOF" >>"$SCRIPT" - rm -f "$SCRIPT".tmp "$SCRIPT".tmph + if [ -n "$APPEND" ] && [ -f "${SCRIPT}" ]; then + rm -f "${SCRIPT}.tmp" + sed "${SCRIPT}" -Ee"/^#/d;/^\$/d;s,^[^ ]*/?${SELF}( +-[46])? *,,;;s/ /\n/g;" >"${SCRIPT}.tmp" + saveHdr >"${SCRIPT}" + RAW="y" save 'nohdr' >>"${SCRIPT}.tmp" + if [ "$IPV" == "4" ]; then + sort -u -t . -k1,1n -k2,2n -k3,3n -k4,4n "${SCRIPT}.tmp" | savelines -4 >>"${SCRIPT}" + else + sort -u -t : -f -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -k7,7 -k8,8 "${SCRIPT}.tmp" | savelines -6 >>"${SCRIPT}" + fi + echo "# EOF" >>"${SCRIPT}" + rm -f "${SCRIPT}.tmp" + else + save >"${SCRIPT}" + fi + if [ -z "$RAW" ]; then + chmod +x "${SCRIPT}" else - save >"$SCRIPT" + chmod -x "${SCRIPT}" fi - chmod +x "$SCRIPT" - [ -n "$V" ] && echo "Wrote $(readlink -en "$SCRIPT")" - CNT="$( grep -c -- ' -4 \| -6 ' "$SCRIPT")" + [ -n "$V" ] && echo "Wrote $(readlink -en "${SCRIPT}")" + CNT="$(sed "${SCRIPT}" -nEe's/^# Count = ([0-9]+).*$/\1/p')" + sed -i "${SCRIPT}" -Ee'/^# Count = ([0-9]+).*$/d' if [ "$CNT" -gt "$MAXENT" ]; then - echo "$(readlink -en "$SCRIPT") lists $CNT addresses, but only $MAXENT will be retained. See -h for more information." + echo "$(readlink -en "${SCRIPT}") lists $CNT addresses, but only $MAXENT will be retained. See -h for more information." exit 2 fi fi @@ -490,7 +538,7 @@ if [ "$ACTION" == "list" ]; then fi [ -n "$DEBUG" ] && echo "IP: $IP NOW: $NOW UP: $UPT TICKS: $TICKS SEEN: $SEEN SSE: $SSE DATE: $DATE$HN" - echo "$IP ${Dots:0:$(( ${#Dots} - ${#IP} ))} $DATE$HN" + echo "$IP ${Dots:${#IP}} $DATE$HN" done if [ -n "$V" ]; then diff --git a/ipblock.1 b/ipblock.1 index abfe502..1484576 100644 --- a/ipblock.1 +++ b/ipblock.1 @@ -1,5 +1,5 @@ .\" -*- mode: troff; coding: utf-8 -*- -.TH "ipblock" "8" "16-Jan-2023" +.TH "ipblock" "8" "18-Jan-2023" .SH IPBLOCK .LP @@ -77,23 +77,33 @@ Usage: ipblock [options] [addresses] -L List currently blocked IP addresses and last seen time (default) -S file Save current addresses as a script. (use - for stdout) -a With -S, add to existing output file + -r With -S, save in raw format (just IP address list, e.g. for BlockCountries) -T tps Use tps as the jiffys/sec (only if /boot/config- is not available. -t Estimate -T - -X Disable ipblock and remove its rule. Does not fluah list. + -X Disable ipblock and remove its rule. May not fluah list. -V Display version -D fmt Date format (strftime) (Default is '%a %d-%b-%Y %T %Z'), null for ctime -C:chain Specify chain to hook (default is INPUT) + -c:chain Specify chain for IPv6 hook (default is same name as IPv4) -N:table Recent table name that maintains list. (Default is BlackList) IPv6 adds '6' to the specified name (Thus, IPv6 default is BlackList6) .EE .PP +Most options should be placed in ipblock.conf, making use very simple. +.PP +The most common usage is +.LP +.EX +ipblock address +.EE +.PP If neither -4 nor -6 is specified: If a numeric address is specified, the address family is used. Otherwise, the default is -4 .PP -Options -L and -S ignore -4 & -6; they access all tables present. +Option -L ignores -4 & -6; it accesses all tables present. .PP Option -T is only required when the kernel configuration file is not mounted on /boot, as happens with some VPS providers. The value is the jiffies (ticks) per second of @@ -143,19 +153,23 @@ Copyright and license: see README.md, in the distribution kit. .SS Installation .LP -Download the latest \fCVn.m-Release\fR tarball using the \fCtar.gz\fR link at \fBGitHub\fR <\fIhttps://github.com/tlhackque/ipblock/releases\fR>. +Download the latest \fCipblock-n.m.o-Release\fR tarball and signature using +the \fCtar.gz\fR or \fCtar.xz\fR and \fC.sig\fR links at +\fBGitHub\fR <\fIhttps://github.com/tlhackque/ipblock/releases\fR>. .IP "\(bu" 2 -Do \fBnot\fR select the \fC.zip\fR file, as it does not preserve file permissions. +Do \fBNOT\fR use the \fBClone or download\fR link on the main \fCipblock\fR page. .if n \ .sp -1 .if t \ .sp -0.25v .IP "\(bu" 2 -Do \fBNOT\fR use the \fBClone or download\fR link on the main \fCipblock\fR page, as it provides a \fC.zip\fR file. +Building or installing from source requires \fClowdown\fR .LP -Unpack the \fCtar.gz\fR: +Verify and npack the \fCtar.gz\fR: +.br +gpg \(enverify ipblock.-Release.tar.gz.sig && \e .br -tar -xzf ipblock.-Release.tar.gz +tar -xzf ipblock.-Release.tar.gz .PP This will create a subdirectory named ipblock-. .PP