From 8d03bbd4834b617a70b42a09de89d5f8e6a04360 Mon Sep 17 00:00:00 2001 From: Solene Rapenne Date: Wed, 10 Mar 2021 22:34:50 +0100 Subject: [PATCH] Add IPv6 support + many others improvements. Patch from prx@ybad.name --- Makefile | 10 ++++--- README.md | 4 ++- main.c | 80 ++++++++++++++++++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 710ba1d..5628332 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,15 @@ +CFLAGS += -pedantic -Wall -Wextra -Wmissing-prototypes \ + -Werror -Wshadow -Wstrict-overflow -fno-strict-aliasing \ + -Wstrict-prototypes -Wwrite-strings \ + -Os all: iblock -iblock: +iblock: main.c ${CC} -o iblock main.c clean: rm -f iblock test: clean iblock - @printf "hello\n" | nc -4 localhost 1965 - @printf "hello\n" | nc -6 localhost 1965 + @printf "hello\n" | nc -4 localhost 666 + @printf "hello\n" | nc -6 localhost 666 diff --git a/README.md b/README.md index a7ea991..e9df6cf 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Start inetd service with this in `/etc/inetd.conf`: ``` 666 stream tcp nowait root /usr/local/bin/iblock iblock +666 stream tcp6 nowait root /usr/local/bin/iblock iblock ``` Use this in `/etc/pf.conf`, choose which ports will trigger the ban from the variable: @@ -22,7 +23,8 @@ blocking_tcp="{ 21 23 53 111 135 137:139 445 1433 25565 5432 3389 3306 27019 }" table persist block in quick from label iblock -pass in quick on egress proto tcp to port $blocking_tcp rdr-to 127.0.0.1 port 666 +pass in quick on egress inet proto tcp to port $blocking_tcp rdr-to 127.0.0.1 port 666 +pass in quick on egress inet6 proto tcp to port $blocking_tcp rdr-to ::1 port 666 ``` Done! You can see IP banned using `pfctl -t blocked -T show` and iBlock will log blocking too. diff --git a/main.c b/main.c index 8c59cc6..6b9ac4f 100644 --- a/main.c +++ b/main.c @@ -1,45 +1,57 @@ -#include -#include -#include -#include #include +#include +#include +#include #include -#include +#include #include +#include -int main(void){ - struct sockaddr sock; - socklen_t slen = sizeof(sock); - char host[128] = ""; - char port[6] = ""; - int status; +#include - unveil("/sbin/pfctl", "rx"); - pledge("exec inet dns stdio", NULL); +#define DEFAULT_TABLE "blocked" +#define TABLE_LEN 128 /* not sure what is pf table name length limit... */ - if(getpeername(0, &sock, &slen)) - err(1, "getpeername"); +int main(int argc, char *argv[]){ + struct sockaddr_storage sock; + socklen_t slen = sizeof(sock); + char ip[INET6_ADDRSTRLEN] = {'\0'}; /* INET6_ADDRSTRLEN > INET_ADDRSTRLEN */ + char table[TABLE_LEN] = DEFAULT_TABLE; + int status; - status = getnameinfo(&sock, slen, host, sizeof host, port, sizeof port, - NI_NUMERICHOST|NI_NUMERICSERV); - if(status != 0) - { - syslog(LOG_DAEMON, "getnameinfo error"); - exit(1); + if (unveil("/sbin/pfctl", "rx") != 0) + err(1, "unveil"); + if (pledge("exec inet stdio", NULL) != 0) + err(1, "pledge"); + + /* configuration */ + if (argc == 2) { + if (strlen(argv[1]) > sizeof(table)) + errx(1, "table name is too long"); + strlcpy(table, argv[1], TABLE_LEN); } - syslog(LOG_DAEMON, "blocking %s", host); - switch(sock. sa_family) - { - case AF_INET: - execlp("/sbin/pfctl", "pfctl", "-t", "blocked", "-T", "add", host, NULL); - break; - // case AF_INET6: - // printf("%s %s\n", host, cmd); - // break; - default: - exit(2); - //puts("run from console"); - } + /* get socket structure */ + if(getpeername(STDIN_FILENO, (struct sockaddr *)&sock, &slen)) + err(1, "getpeername"); + + /* get ip */ + status = getnameinfo((struct sockaddr *)&sock, slen, ip, sizeof(ip), + NULL, 0, NI_NUMERICHOST); + + if(status != 0) { + syslog(LOG_DAEMON, "getnameinfo error"); + exit(1); + } + + syslog(LOG_DAEMON, "blocking %s", ip); + switch(sock.ss_family) { + case AF_INET: /* FALLTHROUGHT */ + case AF_INET6: + execlp("/sbin/pfctl", "pfctl", "-t", table, "-T", "add", ip, NULL); + break; + default: + exit(2); + } }